Deprecate commitment variants (#14797)
* Deprecate commitment variants * Add new CommitmentConfig builders * Add helpers to avoid allowing deprecated variants * Remove deprecated transaction-status code * Include new commitment variants in runtime commitment; allow deprecated as long as old variants persist * Remove deprecated banks code * Remove deprecated variants in core; allow deprecated in rpc/rpc-subscriptions for now * Heavier hand with rpc/rpc-subscription commitment * Remove deprecated variants from local-cluster * Remove deprecated variants from various tools * Remove deprecated variants from validator * Update docs * Remove deprecated client code * Add new variants to cli; remove deprecated variants as possible * Don't send new commitment variants to old clusters * Retain deprecated method in test_validator_saves_tower * Fix clippy matches! suggestion for BPF solana-sdk legacy compile test * Refactor node version check to handle commitment variants and transaction encoding * Hide deprecated variants from cli help * Add cli App comments
This commit is contained in:
@@ -33,7 +33,7 @@ pub fn sample_txs<T>(
|
||||
let mut now = Instant::now();
|
||||
let start_time = now;
|
||||
let initial_txs = client
|
||||
.get_transaction_count_with_commitment(CommitmentConfig::recent())
|
||||
.get_transaction_count_with_commitment(CommitmentConfig::processed())
|
||||
.expect("transaction count");
|
||||
let mut last_txs = initial_txs;
|
||||
|
||||
@@ -42,7 +42,7 @@ pub fn sample_txs<T>(
|
||||
let elapsed = now.elapsed();
|
||||
now = Instant::now();
|
||||
let mut txs;
|
||||
match client.get_transaction_count_with_commitment(CommitmentConfig::recent()) {
|
||||
match client.get_transaction_count_with_commitment(CommitmentConfig::processed()) {
|
||||
Err(e) => {
|
||||
// ThinClient with multiple options should pick a better one now.
|
||||
info!("Couldn't get transaction count {:?}", e);
|
||||
|
@@ -47,7 +47,7 @@ use std::{
|
||||
pub struct RpcClient {
|
||||
sender: Box<dyn RpcSender + Send + Sync + 'static>,
|
||||
commitment_config: CommitmentConfig,
|
||||
default_cluster_transaction_encoding: RwLock<Option<UiTransactionEncoding>>,
|
||||
node_version: RwLock<Option<semver::Version>>,
|
||||
}
|
||||
|
||||
fn serialize_encode_transaction(
|
||||
@@ -77,7 +77,7 @@ impl RpcClient {
|
||||
) -> Self {
|
||||
Self {
|
||||
sender: Box::new(sender),
|
||||
default_cluster_transaction_encoding: RwLock::new(None),
|
||||
node_version: RwLock::new(None),
|
||||
commitment_config,
|
||||
}
|
||||
}
|
||||
@@ -128,16 +128,54 @@ impl RpcClient {
|
||||
Self::new_with_timeout(url, timeout)
|
||||
}
|
||||
|
||||
pub fn confirm_transaction(&self, signature: &Signature) -> ClientResult<bool> {
|
||||
Ok(self
|
||||
.confirm_transaction_with_commitment(signature, self.commitment_config)?
|
||||
.value)
|
||||
fn get_node_version(&self) -> Result<semver::Version, RpcError> {
|
||||
let r_node_version = self.node_version.read().unwrap();
|
||||
if let Some(version) = &*r_node_version {
|
||||
Ok(version.clone())
|
||||
} else {
|
||||
drop(r_node_version);
|
||||
let mut w_node_version = self.node_version.write().unwrap();
|
||||
let node_version = self.get_version().map_err(|e| {
|
||||
RpcError::RpcRequestError(format!("cluster version query failed: {}", e))
|
||||
})?;
|
||||
let node_version = semver::Version::parse(&node_version.solana_core).map_err(|e| {
|
||||
RpcError::RpcRequestError(format!("failed to parse cluster version: {}", e))
|
||||
})?;
|
||||
*w_node_version = Some(node_version.clone());
|
||||
Ok(node_version)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn commitment(&self) -> CommitmentConfig {
|
||||
self.commitment_config
|
||||
}
|
||||
|
||||
fn use_deprecated_commitment(&self) -> Result<bool, RpcError> {
|
||||
Ok(self.get_node_version()? < semver::Version::new(1, 5, 5))
|
||||
}
|
||||
|
||||
fn maybe_map_commitment(
|
||||
&self,
|
||||
requested_commitment: CommitmentConfig,
|
||||
) -> Result<CommitmentConfig, RpcError> {
|
||||
if matches!(
|
||||
requested_commitment.commitment,
|
||||
CommitmentLevel::Finalized | CommitmentLevel::Confirmed | CommitmentLevel::Processed
|
||||
) && self.use_deprecated_commitment()?
|
||||
{
|
||||
return Ok(CommitmentConfig::use_deprecated_commitment(
|
||||
requested_commitment,
|
||||
));
|
||||
}
|
||||
Ok(requested_commitment)
|
||||
}
|
||||
|
||||
pub fn confirm_transaction(&self, signature: &Signature) -> ClientResult<bool> {
|
||||
Ok(self
|
||||
.confirm_transaction_with_commitment(signature, self.commitment_config)?
|
||||
.value)
|
||||
}
|
||||
|
||||
pub fn confirm_transaction_with_commitment(
|
||||
&self,
|
||||
signature: &Signature,
|
||||
@@ -159,34 +197,20 @@ impl RpcClient {
|
||||
self.send_transaction_with_config(
|
||||
transaction,
|
||||
RpcSendTransactionConfig {
|
||||
preflight_commitment: Some(self.commitment_config.commitment),
|
||||
preflight_commitment: Some(
|
||||
self.maybe_map_commitment(self.commitment_config)?
|
||||
.commitment,
|
||||
),
|
||||
..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)
|
||||
if self.get_node_version()? < semver::Version::new(1, 3, 16) {
|
||||
Ok(UiTransactionEncoding::Base58)
|
||||
} 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)
|
||||
Ok(UiTransactionEncoding::Base64)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,8 +224,13 @@ impl RpcClient {
|
||||
} else {
|
||||
self.default_cluster_transaction_encoding()?
|
||||
};
|
||||
let preflight_commitment = CommitmentConfig {
|
||||
commitment: config.preflight_commitment.unwrap_or_default(),
|
||||
};
|
||||
let preflight_commitment = self.maybe_map_commitment(preflight_commitment)?;
|
||||
let config = RpcSendTransactionConfig {
|
||||
encoding: Some(encoding),
|
||||
preflight_commitment: Some(preflight_commitment.commitment),
|
||||
..config
|
||||
};
|
||||
let serialized_encoded = serialize_encode_transaction(transaction, encoding)?;
|
||||
@@ -274,8 +303,11 @@ impl RpcClient {
|
||||
} else {
|
||||
self.default_cluster_transaction_encoding()?
|
||||
};
|
||||
let commitment = config.commitment.unwrap_or_default();
|
||||
let commitment = self.maybe_map_commitment(commitment)?;
|
||||
let config = RpcSimulateTransactionConfig {
|
||||
encoding: Some(encoding),
|
||||
commitment: Some(commitment),
|
||||
..config
|
||||
};
|
||||
let serialized_encoded = serialize_encode_transaction(transaction, encoding)?;
|
||||
@@ -358,7 +390,10 @@ impl RpcClient {
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> ClientResult<Slot> {
|
||||
self.send(RpcRequest::GetSlot, json!([commitment_config]))
|
||||
self.send(
|
||||
RpcRequest::GetSlot,
|
||||
json!([self.maybe_map_commitment(commitment_config)?]),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn supply(&self) -> RpcResult<RpcSupply> {
|
||||
@@ -369,7 +404,10 @@ impl RpcClient {
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> RpcResult<RpcSupply> {
|
||||
self.send(RpcRequest::GetSupply, json!([commitment_config]))
|
||||
self.send(
|
||||
RpcRequest::GetSupply,
|
||||
json!([self.maybe_map_commitment(commitment_config)?]),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn total_supply(&self) -> ClientResult<u64> {
|
||||
@@ -380,13 +418,22 @@ impl RpcClient {
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> ClientResult<u64> {
|
||||
self.send(RpcRequest::GetTotalSupply, json!([commitment_config]))
|
||||
self.send(
|
||||
RpcRequest::GetTotalSupply,
|
||||
json!([self.maybe_map_commitment(commitment_config)?]),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_largest_accounts_with_config(
|
||||
&self,
|
||||
config: RpcLargestAccountsConfig,
|
||||
) -> RpcResult<Vec<RpcAccountBalance>> {
|
||||
let commitment = config.commitment.unwrap_or_default();
|
||||
let commitment = self.maybe_map_commitment(commitment)?;
|
||||
let config = RpcLargestAccountsConfig {
|
||||
commitment: Some(commitment),
|
||||
..config
|
||||
};
|
||||
self.send(RpcRequest::GetLargestAccounts, json!([config]))
|
||||
}
|
||||
|
||||
@@ -398,7 +445,10 @@ impl RpcClient {
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> ClientResult<RpcVoteAccountStatus> {
|
||||
self.send(RpcRequest::GetVoteAccounts, json!([commitment_config]))
|
||||
self.send(
|
||||
RpcRequest::GetVoteAccounts,
|
||||
json!([self.maybe_map_commitment(commitment_config)?]),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn wait_for_max_stake(
|
||||
@@ -558,7 +608,10 @@ impl RpcClient {
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> ClientResult<EpochInfo> {
|
||||
self.send(RpcRequest::GetEpochInfo, json!([commitment_config]))
|
||||
self.send(
|
||||
RpcRequest::GetEpochInfo,
|
||||
json!([self.maybe_map_commitment(commitment_config)?]),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_leader_schedule(
|
||||
@@ -575,7 +628,7 @@ impl RpcClient {
|
||||
) -> ClientResult<Option<RpcLeaderSchedule>> {
|
||||
self.send(
|
||||
RpcRequest::GetLeaderSchedule,
|
||||
json!([slot, commitment_config]),
|
||||
json!([slot, self.maybe_map_commitment(commitment_config)?]),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -616,7 +669,7 @@ impl RpcClient {
|
||||
) -> ClientResult<Signature> {
|
||||
let signature = self.send_transaction(transaction)?;
|
||||
let recent_blockhash = if uses_durable_nonce(transaction).is_some() {
|
||||
self.get_recent_blockhash_with_commitment(CommitmentConfig::recent())?
|
||||
self.get_recent_blockhash_with_commitment(CommitmentConfig::processed())?
|
||||
.value
|
||||
.0
|
||||
} else {
|
||||
@@ -628,7 +681,7 @@ impl RpcClient {
|
||||
if self
|
||||
.get_fee_calculator_for_blockhash_with_commitment(
|
||||
&recent_blockhash,
|
||||
CommitmentConfig::recent(),
|
||||
CommitmentConfig::processed(),
|
||||
)?
|
||||
.value
|
||||
.is_none()
|
||||
@@ -674,7 +727,7 @@ impl RpcClient {
|
||||
) -> RpcResult<Option<Account>> {
|
||||
let config = RpcAccountInfoConfig {
|
||||
encoding: Some(UiAccountEncoding::Base64),
|
||||
commitment: Some(commitment_config),
|
||||
commitment: Some(self.maybe_map_commitment(commitment_config)?),
|
||||
data_slice: None,
|
||||
};
|
||||
let response = self.sender.send(
|
||||
@@ -721,7 +774,7 @@ impl RpcClient {
|
||||
) -> RpcResult<Vec<Option<Account>>> {
|
||||
let config = RpcAccountInfoConfig {
|
||||
encoding: Some(UiAccountEncoding::Base64),
|
||||
commitment: Some(commitment_config),
|
||||
commitment: Some(self.maybe_map_commitment(commitment_config)?),
|
||||
data_slice: None,
|
||||
};
|
||||
let pubkeys: Vec<_> = pubkeys.iter().map(|pubkey| pubkey.to_string()).collect();
|
||||
@@ -775,7 +828,10 @@ impl RpcClient {
|
||||
) -> RpcResult<u64> {
|
||||
self.send(
|
||||
RpcRequest::GetBalance,
|
||||
json!([pubkey.to_string(), commitment_config]),
|
||||
json!([
|
||||
pubkey.to_string(),
|
||||
self.maybe_map_commitment(commitment_config)?
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -798,6 +854,16 @@ impl RpcClient {
|
||||
pubkey: &Pubkey,
|
||||
config: RpcProgramAccountsConfig,
|
||||
) -> ClientResult<Vec<(Pubkey, Account)>> {
|
||||
let commitment = config.account_config.commitment.unwrap_or_default();
|
||||
let commitment = self.maybe_map_commitment(commitment)?;
|
||||
let account_config = RpcAccountInfoConfig {
|
||||
commitment: Some(commitment),
|
||||
..config.account_config
|
||||
};
|
||||
let config = RpcProgramAccountsConfig {
|
||||
account_config,
|
||||
..config
|
||||
};
|
||||
let accounts: Vec<RpcKeyedAccount> = self.send(
|
||||
RpcRequest::GetProgramAccounts,
|
||||
json!([pubkey.to_string(), config]),
|
||||
@@ -814,7 +880,10 @@ impl RpcClient {
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> ClientResult<u64> {
|
||||
self.send(RpcRequest::GetTransactionCount, json!([commitment_config]))
|
||||
self.send(
|
||||
RpcRequest::GetTransactionCount,
|
||||
json!([self.maybe_map_commitment(commitment_config)?]),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_recent_blockhash(&self) -> ClientResult<(Hash, FeeCalculator)> {
|
||||
@@ -836,9 +905,11 @@ impl RpcClient {
|
||||
fee_calculator,
|
||||
last_valid_slot,
|
||||
},
|
||||
}) =
|
||||
self.send::<Response<RpcFees>>(RpcRequest::GetFees, json!([commitment_config]))
|
||||
{
|
||||
}) = self
|
||||
.send::<Response<RpcFees>>(
|
||||
RpcRequest::GetFees,
|
||||
json!([self.maybe_map_commitment(commitment_config)?]),
|
||||
) {
|
||||
(context, blockhash, fee_calculator, last_valid_slot)
|
||||
} else if let Ok(Response {
|
||||
context,
|
||||
@@ -849,7 +920,7 @@ impl RpcClient {
|
||||
},
|
||||
}) = self.send::<Response<RpcBlockhashFeeCalculator>>(
|
||||
RpcRequest::GetRecentBlockhash,
|
||||
json!([commitment_config]),
|
||||
json!([self.maybe_map_commitment(commitment_config)?]),
|
||||
) {
|
||||
(context, blockhash, fee_calculator, 0)
|
||||
} else {
|
||||
@@ -887,7 +958,10 @@ impl RpcClient {
|
||||
) -> RpcResult<Option<FeeCalculator>> {
|
||||
let Response { context, value } = self.send::<Response<Option<RpcFeeCalculator>>>(
|
||||
RpcRequest::GetFeeCalculatorForBlockhash,
|
||||
json!([blockhash.to_string(), commitment_config]),
|
||||
json!([
|
||||
blockhash.to_string(),
|
||||
self.maybe_map_commitment(commitment_config)?
|
||||
]),
|
||||
)?;
|
||||
|
||||
Ok(Response {
|
||||
@@ -966,7 +1040,7 @@ impl RpcClient {
|
||||
) -> RpcResult<Option<UiTokenAccount>> {
|
||||
let config = RpcAccountInfoConfig {
|
||||
encoding: Some(UiAccountEncoding::JsonParsed),
|
||||
commitment: Some(commitment_config),
|
||||
commitment: Some(self.maybe_map_commitment(commitment_config)?),
|
||||
data_slice: None,
|
||||
};
|
||||
let response = self.sender.send(
|
||||
@@ -1027,7 +1101,10 @@ impl RpcClient {
|
||||
) -> RpcResult<UiTokenAmount> {
|
||||
self.send(
|
||||
RpcRequest::GetTokenAccountBalance,
|
||||
json!([pubkey.to_string(), commitment_config]),
|
||||
json!([
|
||||
pubkey.to_string(),
|
||||
self.maybe_map_commitment(commitment_config)?
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1060,7 +1137,7 @@ impl RpcClient {
|
||||
|
||||
let config = RpcAccountInfoConfig {
|
||||
encoding: Some(UiAccountEncoding::JsonParsed),
|
||||
commitment: Some(commitment_config),
|
||||
commitment: Some(self.maybe_map_commitment(commitment_config)?),
|
||||
data_slice: None,
|
||||
};
|
||||
|
||||
@@ -1099,7 +1176,7 @@ impl RpcClient {
|
||||
|
||||
let config = RpcAccountInfoConfig {
|
||||
encoding: Some(UiAccountEncoding::JsonParsed),
|
||||
commitment: Some(commitment_config),
|
||||
commitment: Some(self.maybe_map_commitment(commitment_config)?),
|
||||
data_slice: None,
|
||||
};
|
||||
|
||||
@@ -1122,7 +1199,10 @@ impl RpcClient {
|
||||
) -> RpcResult<UiTokenAmount> {
|
||||
self.send(
|
||||
RpcRequest::GetTokenSupply,
|
||||
json!([mint.to_string(), commitment_config]),
|
||||
json!([
|
||||
mint.to_string(),
|
||||
self.maybe_map_commitment(commitment_config)?
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1327,9 +1407,10 @@ impl RpcClient {
|
||||
commitment: CommitmentConfig,
|
||||
config: RpcSendTransactionConfig,
|
||||
) -> ClientResult<Signature> {
|
||||
let desired_confirmations = match commitment.commitment {
|
||||
CommitmentLevel::Max | CommitmentLevel::Root => MAX_LOCKOUT_HISTORY + 1,
|
||||
_ => 1,
|
||||
let desired_confirmations = if commitment.is_finalized() {
|
||||
MAX_LOCKOUT_HISTORY + 1
|
||||
} else {
|
||||
1
|
||||
};
|
||||
let mut confirmations = 0;
|
||||
|
||||
@@ -1340,7 +1421,7 @@ impl RpcClient {
|
||||
confirmations, desired_confirmations, transaction.signatures[0],
|
||||
));
|
||||
let recent_blockhash = if uses_durable_nonce(transaction).is_some() {
|
||||
self.get_recent_blockhash_with_commitment(CommitmentConfig::recent())?
|
||||
self.get_recent_blockhash_with_commitment(CommitmentConfig::processed())?
|
||||
.value
|
||||
.0
|
||||
} else {
|
||||
@@ -1349,13 +1430,13 @@ impl RpcClient {
|
||||
let signature = self.send_transaction_with_config(transaction, config)?;
|
||||
let (signature, status) = loop {
|
||||
// Get recent commitment in order to count confirmations for successful transactions
|
||||
let status =
|
||||
self.get_signature_status_with_commitment(&signature, CommitmentConfig::recent())?;
|
||||
let status = self
|
||||
.get_signature_status_with_commitment(&signature, CommitmentConfig::processed())?;
|
||||
if status.is_none() {
|
||||
if self
|
||||
.get_fee_calculator_for_blockhash_with_commitment(
|
||||
&recent_blockhash,
|
||||
CommitmentConfig::recent(),
|
||||
CommitmentConfig::processed(),
|
||||
)?
|
||||
.value
|
||||
.is_none()
|
||||
|
@@ -248,7 +248,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_build_request_json_config_options() {
|
||||
let commitment_config = CommitmentConfig {
|
||||
commitment: CommitmentLevel::Max,
|
||||
commitment: CommitmentLevel::Finalized,
|
||||
};
|
||||
let addr = json!("deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx");
|
||||
|
||||
|
Reference in New Issue
Block a user