Skip to content

Commit

Permalink
RPC: Don't send base64 TXs to old clusters (#13062)
Browse files Browse the repository at this point in the history
Co-authored-by: Trent Nelson <[email protected]>
  • Loading branch information
mergify[bot] and t-nelson authored Oct 21, 2020
1 parent a86a781 commit 15a49d7
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 8 deletions.
43 changes: 39 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jsonrpc-core = "15.0.0"
log = "0.4.8"
rayon = "1.4.0"
reqwest = { version = "0.10.6", default-features = false, features = ["blocking", "rustls-tls", "json"] }
semver = "0.11.0"
serde = "1.0.112"
serde_derive = "1.0.103"
serde_json = "1.0.56"
Expand All @@ -26,6 +27,7 @@ solana-clap-utils = { path = "../clap-utils", version = "1.3.19" }
solana-net-utils = { path = "../net-utils", version = "1.3.19" }
solana-sdk = { path = "../sdk", version = "1.3.19" }
solana-transaction-status = { path = "../transaction-status", version = "1.3.19" }
solana-version = { path = "../version", version = "1.3.19" }
solana-vote-program = { path = "../programs/vote", version = "1.3.19" }
thiserror = "1.0"
tungstenite = "0.10.1"
Expand Down
12 changes: 10 additions & 2 deletions client/src/mock_sender.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use crate::{
client_error::Result,
rpc_request::RpcRequest,
rpc_response::{Response, RpcResponseContext},
rpc_response::{Response, RpcResponseContext, RpcVersionInfo},
rpc_sender::RpcSender,
};
use serde_json::{Number, Value};
use serde_json::{json, Number, Value};
use solana_sdk::{
fee_calculator::{FeeCalculator, FeeRateGovernor},
instruction::InstructionError,
signature::Signature,
transaction::{self, Transaction, TransactionError},
};
use solana_transaction_status::TransactionStatus;
use solana_version::Version;
use std::{collections::HashMap, sync::RwLock};

pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
Expand Down Expand Up @@ -119,6 +120,13 @@ impl RpcSender for MockSender {
Value::String(signature)
}
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,
};
Ok(val)
Expand Down
40 changes: 38 additions & 2 deletions client/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ use solana_transaction_status::{
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
use std::{
net::SocketAddr,
sync::RwLock,
thread::sleep,
time::{Duration, Instant},
};

pub struct RpcClient {
sender: Box<dyn RpcSender + Send + Sync + 'static>,
default_cluster_transaction_encoding: RwLock<Option<UiTransactionEncoding>>,
}

fn serialize_encode_transaction(
Expand All @@ -73,6 +75,7 @@ impl RpcClient {
pub fn new_sender<T: RpcSender + Send + Sync + 'static>(sender: T) -> Self {
Self {
sender: Box::new(sender),
default_cluster_transaction_encoding: RwLock::new(None),
}
}

Expand Down Expand Up @@ -128,12 +131,41 @@ impl RpcClient {
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(
&self,
transaction: &Transaction,
config: RpcSendTransactionConfig,
) -> 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 {
encoding: Some(encoding),
..config
Expand Down Expand Up @@ -174,7 +206,11 @@ impl RpcClient {
transaction: &Transaction,
config: RpcSimulateTransactionConfig,
) -> 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 {
encoding: Some(encoding),
..config
Expand Down

0 comments on commit 15a49d7

Please sign in to comment.