RPC: Don't send base64 TXs to old clusters
This commit is contained in:
parent
7a5934082f
commit
86a982150c
|
@ -2443,6 +2443,15 @@ version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest"
|
||||||
|
version = "2.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||||
|
dependencies = [
|
||||||
|
"ucd-trie",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pickledb"
|
name = "pickledb"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -3016,7 +3025,7 @@ version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"semver",
|
"semver 0.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3139,7 +3148,16 @@ version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"semver-parser",
|
"semver-parser 0.7.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3148,6 +3166,15 @@ version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42ef146c2ad5e5f4b037cd6ce2ebb775401729b19a82040c1beac9d36c7d1428"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.112"
|
version = "1.0.112"
|
||||||
|
@ -3682,6 +3709,7 @@ dependencies = [
|
||||||
"log 0.4.8",
|
"log 0.4.8",
|
||||||
"rayon",
|
"rayon",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"semver 0.11.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -3691,6 +3719,7 @@ dependencies = [
|
||||||
"solana-net-utils",
|
"solana-net-utils",
|
||||||
"solana-sdk 1.5.0",
|
"solana-sdk 1.5.0",
|
||||||
"solana-transaction-status",
|
"solana-transaction-status",
|
||||||
|
"solana-version",
|
||||||
"solana-vote-program",
|
"solana-vote-program",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tungstenite",
|
"tungstenite",
|
||||||
|
@ -3993,7 +4022,7 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"nix",
|
"nix",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"semver",
|
"semver 0.9.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
|
@ -4349,7 +4378,7 @@ dependencies = [
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"parking_lot 0.10.2",
|
"parking_lot 0.10.2",
|
||||||
"semver",
|
"semver 0.9.0",
|
||||||
"solana-sdk 1.5.0",
|
"solana-sdk 1.5.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"url 2.1.1",
|
"url 2.1.1",
|
||||||
|
@ -5879,6 +5908,12 @@ version = "1.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ucd-trie"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unicase"
|
||||||
version = "1.4.2"
|
version = "1.4.2"
|
||||||
|
|
|
@ -18,6 +18,7 @@ jsonrpc-core = "15.0.0"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
rayon = "1.4.0"
|
rayon = "1.4.0"
|
||||||
reqwest = { version = "0.10.8", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
reqwest = { version = "0.10.8", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||||
|
semver = "0.11.0"
|
||||||
serde = "1.0.112"
|
serde = "1.0.112"
|
||||||
serde_derive = "1.0.103"
|
serde_derive = "1.0.103"
|
||||||
serde_json = "1.0.56"
|
serde_json = "1.0.56"
|
||||||
|
@ -26,6 +27,7 @@ solana-clap-utils = { path = "../clap-utils", version = "1.5.0" }
|
||||||
solana-net-utils = { path = "../net-utils", version = "1.5.0" }
|
solana-net-utils = { path = "../net-utils", version = "1.5.0" }
|
||||||
solana-sdk = { path = "../sdk", version = "1.5.0" }
|
solana-sdk = { path = "../sdk", version = "1.5.0" }
|
||||||
solana-transaction-status = { path = "../transaction-status", version = "1.5.0" }
|
solana-transaction-status = { path = "../transaction-status", version = "1.5.0" }
|
||||||
|
solana-version = { path = "../version", version = "1.5.0" }
|
||||||
solana-vote-program = { path = "../programs/vote", version = "1.5.0" }
|
solana-vote-program = { path = "../programs/vote", version = "1.5.0" }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tungstenite = "0.10.1"
|
tungstenite = "0.10.1"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
client_error::Result,
|
client_error::Result,
|
||||||
rpc_request::RpcRequest,
|
rpc_request::RpcRequest,
|
||||||
rpc_response::{Response, RpcResponseContext},
|
rpc_response::{Response, RpcResponseContext, RpcVersionInfo},
|
||||||
rpc_sender::RpcSender,
|
rpc_sender::RpcSender,
|
||||||
};
|
};
|
||||||
use serde_json::{Number, Value};
|
use serde_json::{json, Number, Value};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
||||||
instruction::InstructionError,
|
instruction::InstructionError,
|
||||||
|
@ -12,6 +12,7 @@ use solana_sdk::{
|
||||||
transaction::{self, Transaction, TransactionError},
|
transaction::{self, Transaction, TransactionError},
|
||||||
};
|
};
|
||||||
use solana_transaction_status::TransactionStatus;
|
use solana_transaction_status::TransactionStatus;
|
||||||
|
use solana_version::Version;
|
||||||
use std::{collections::HashMap, sync::RwLock};
|
use std::{collections::HashMap, sync::RwLock};
|
||||||
|
|
||||||
pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
|
pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
|
||||||
|
@ -119,6 +120,13 @@ impl RpcSender for MockSender {
|
||||||
Value::String(signature)
|
Value::String(signature)
|
||||||
}
|
}
|
||||||
RpcRequest::GetMinimumBalanceForRentExemption => Value::Number(Number::from(20)),
|
RpcRequest::GetMinimumBalanceForRentExemption => Value::Number(Number::from(20)),
|
||||||
|
RpcRequest::GetVersion => {
|
||||||
|
let version = Version::default();
|
||||||
|
json!(RpcVersionInfo {
|
||||||
|
solana_core: version.to_string(),
|
||||||
|
feature_set: Some(version.feature_set),
|
||||||
|
})
|
||||||
|
}
|
||||||
_ => Value::Null,
|
_ => Value::Null,
|
||||||
};
|
};
|
||||||
Ok(val)
|
Ok(val)
|
||||||
|
|
|
@ -41,12 +41,14 @@ use solana_transaction_status::{
|
||||||
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
||||||
use std::{
|
use std::{
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
|
sync::RwLock,
|
||||||
thread::sleep,
|
thread::sleep,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct RpcClient {
|
pub struct RpcClient {
|
||||||
sender: Box<dyn RpcSender + Send + Sync + 'static>,
|
sender: Box<dyn RpcSender + Send + Sync + 'static>,
|
||||||
|
default_cluster_transaction_encoding: RwLock<Option<UiTransactionEncoding>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_encode_transaction(
|
fn serialize_encode_transaction(
|
||||||
|
@ -73,6 +75,7 @@ impl RpcClient {
|
||||||
pub fn new_sender<T: RpcSender + Send + Sync + 'static>(sender: T) -> Self {
|
pub fn new_sender<T: RpcSender + Send + Sync + 'static>(sender: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
sender: Box::new(sender),
|
sender: Box::new(sender),
|
||||||
|
default_cluster_transaction_encoding: RwLock::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +131,41 @@ impl RpcClient {
|
||||||
self.send_transaction_with_config(transaction, RpcSendTransactionConfig::default())
|
self.send_transaction_with_config(transaction, RpcSendTransactionConfig::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_cluster_transaction_encoding(&self) -> Result<UiTransactionEncoding, RpcError> {
|
||||||
|
let default_cluster_transaction_encoding =
|
||||||
|
self.default_cluster_transaction_encoding.read().unwrap();
|
||||||
|
if let Some(encoding) = *default_cluster_transaction_encoding {
|
||||||
|
Ok(encoding)
|
||||||
|
} else {
|
||||||
|
drop(default_cluster_transaction_encoding);
|
||||||
|
let cluster_version = self.get_version().map_err(|e| {
|
||||||
|
RpcError::RpcRequestError(format!("cluster version query failed: {}", e))
|
||||||
|
})?;
|
||||||
|
let cluster_version =
|
||||||
|
semver::Version::parse(&cluster_version.solana_core).map_err(|e| {
|
||||||
|
RpcError::RpcRequestError(format!("failed to parse cluster version: {}", e))
|
||||||
|
})?;
|
||||||
|
// Prefer base64 since 1.3.16
|
||||||
|
let encoding = if cluster_version < semver::Version::new(1, 3, 16) {
|
||||||
|
UiTransactionEncoding::Base58
|
||||||
|
} else {
|
||||||
|
UiTransactionEncoding::Base64
|
||||||
|
};
|
||||||
|
*self.default_cluster_transaction_encoding.write().unwrap() = Some(encoding);
|
||||||
|
Ok(encoding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn send_transaction_with_config(
|
pub fn send_transaction_with_config(
|
||||||
&self,
|
&self,
|
||||||
transaction: &Transaction,
|
transaction: &Transaction,
|
||||||
config: RpcSendTransactionConfig,
|
config: RpcSendTransactionConfig,
|
||||||
) -> ClientResult<Signature> {
|
) -> ClientResult<Signature> {
|
||||||
let encoding = config.encoding.unwrap_or(UiTransactionEncoding::Base64);
|
let encoding = if let Some(encoding) = config.encoding {
|
||||||
|
encoding
|
||||||
|
} else {
|
||||||
|
self.default_cluster_transaction_encoding()?
|
||||||
|
};
|
||||||
let config = RpcSendTransactionConfig {
|
let config = RpcSendTransactionConfig {
|
||||||
encoding: Some(encoding),
|
encoding: Some(encoding),
|
||||||
..config
|
..config
|
||||||
|
@ -174,7 +206,11 @@ impl RpcClient {
|
||||||
transaction: &Transaction,
|
transaction: &Transaction,
|
||||||
config: RpcSimulateTransactionConfig,
|
config: RpcSimulateTransactionConfig,
|
||||||
) -> RpcResult<RpcSimulateTransactionResult> {
|
) -> RpcResult<RpcSimulateTransactionResult> {
|
||||||
let encoding = config.encoding.unwrap_or(UiTransactionEncoding::Base64);
|
let encoding = if let Some(encoding) = config.encoding {
|
||||||
|
encoding
|
||||||
|
} else {
|
||||||
|
self.default_cluster_transaction_encoding()?
|
||||||
|
};
|
||||||
let config = RpcSimulateTransactionConfig {
|
let config = RpcSimulateTransactionConfig {
|
||||||
encoding: Some(encoding),
|
encoding: Some(encoding),
|
||||||
..config
|
..config
|
||||||
|
|
Loading…
Reference in New Issue