RPC: Don't send base64 TXs to old clusters

This commit is contained in:
Trent Nelson 2020-10-20 20:50:24 -06:00 committed by mergify[bot]
parent 7a5934082f
commit 86a982150c
4 changed files with 89 additions and 8 deletions

43
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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)

View File

@ -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