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:
Tyera Eulberg
2021-01-26 12:23:07 -07:00
committed by GitHub
parent e08d2e6fcc
commit ffa5c7dcc8
37 changed files with 540 additions and 322 deletions

View File

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

View File

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

View File

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