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

View File

@@ -18,6 +18,7 @@ jsonrpc-core = "15.0.0"
log = "0.4.8"
rayon = "1.4.0"
reqwest = { version = "0.10.8", 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"
@@ -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-sdk = { path = "../sdk", 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" }
thiserror = "1.0"
tungstenite = "0.10.1"

View File

@@ -1,10 +1,10 @@
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,
@@ -12,6 +12,7 @@ use solana_sdk::{
transaction::{self, Transaction, TransactionError},
};
use solana_transaction_status::TransactionStatus;
use solana_version::Version;
use std::{collections::HashMap, sync::RwLock};
pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
@@ -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)

View File

@@ -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(
@@ -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),
}
}
@@ -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
@@ -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