Use optimistic confirmation in getSignatureStatuses, and various downstream client methods (#14430)
* Add optimistically_confirmed field to TransactionStatus * Update docs * Convert new field to confirmation_status * Update docs to confirmationStatus * Update variants * Update docs * Just Confirmed
This commit is contained in:
@ -10,11 +10,19 @@ use solana_sdk::{
|
|||||||
transaction::{self, Transaction, TransactionError},
|
transaction::{self, Transaction, TransactionError},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum TransactionConfirmationStatus {
|
||||||
|
Processed,
|
||||||
|
Confirmed,
|
||||||
|
Finalized,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct TransactionStatus {
|
pub struct TransactionStatus {
|
||||||
pub slot: Slot,
|
pub slot: Slot,
|
||||||
pub confirmations: Option<usize>, // None = rooted
|
pub confirmations: Option<usize>, // None = rooted
|
||||||
pub err: Option<TransactionError>,
|
pub err: Option<TransactionError>,
|
||||||
|
pub confirmation_status: Option<TransactionConfirmationStatus>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tarpc::service]
|
#[tarpc::service]
|
||||||
|
@ -4,7 +4,9 @@ use futures::{
|
|||||||
future,
|
future,
|
||||||
prelude::stream::{self, StreamExt},
|
prelude::stream::{self, StreamExt},
|
||||||
};
|
};
|
||||||
use solana_banks_interface::{Banks, BanksRequest, BanksResponse, TransactionStatus};
|
use solana_banks_interface::{
|
||||||
|
Banks, BanksRequest, BanksResponse, TransactionConfirmationStatus, TransactionStatus,
|
||||||
|
};
|
||||||
use solana_runtime::{bank::Bank, bank_forks::BankForks, commitment::BlockCommitmentCache};
|
use solana_runtime::{bank::Bank, bank_forks::BankForks, commitment::BlockCommitmentCache};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
@ -169,6 +171,10 @@ impl Banks for BanksServer {
|
|||||||
let (slot, status) = bank.get_signature_status_slot(&signature)?;
|
let (slot, status) = bank.get_signature_status_slot(&signature)?;
|
||||||
let r_block_commitment_cache = self.block_commitment_cache.read().unwrap();
|
let r_block_commitment_cache = self.block_commitment_cache.read().unwrap();
|
||||||
|
|
||||||
|
let optimistically_confirmed_bank = self.bank(CommitmentLevel::SingleGossip);
|
||||||
|
let optimistically_confirmed =
|
||||||
|
optimistically_confirmed_bank.get_signature_status_slot(&signature);
|
||||||
|
|
||||||
let confirmations = if r_block_commitment_cache.root() >= slot
|
let confirmations = if r_block_commitment_cache.root() >= slot
|
||||||
&& r_block_commitment_cache.highest_confirmed_root() >= slot
|
&& r_block_commitment_cache.highest_confirmed_root() >= slot
|
||||||
{
|
{
|
||||||
@ -182,6 +188,13 @@ impl Banks for BanksServer {
|
|||||||
slot,
|
slot,
|
||||||
confirmations,
|
confirmations,
|
||||||
err: status.err(),
|
err: status.err(),
|
||||||
|
confirmation_status: if confirmations.is_none() {
|
||||||
|
Some(TransactionConfirmationStatus::Finalized)
|
||||||
|
} else if optimistically_confirmed.is_some() {
|
||||||
|
Some(TransactionConfirmationStatus::Confirmed)
|
||||||
|
} else {
|
||||||
|
Some(TransactionConfirmationStatus::Processed)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ use solana_sdk::{
|
|||||||
system_program,
|
system_program,
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
};
|
};
|
||||||
|
use solana_transaction_status::TransactionConfirmationStatus;
|
||||||
use std::{
|
use std::{
|
||||||
cmp::min, collections::HashMap, error, fs::File, io::Read, net::UdpSocket, path::PathBuf,
|
cmp::min, collections::HashMap, error, fs::File, io::Read, net::UdpSocket, path::PathBuf,
|
||||||
sync::Arc, thread::sleep, time::Duration,
|
sync::Arc, thread::sleep, time::Duration,
|
||||||
@ -1578,7 +1579,11 @@ fn send_and_confirm_transactions_with_spinner<T: Signers>(
|
|||||||
|
|
||||||
for (signature, status) in pending_signatures.into_iter().zip(statuses.into_iter()) {
|
for (signature, status) in pending_signatures.into_iter().zip(statuses.into_iter()) {
|
||||||
if let Some(status) = status {
|
if let Some(status) = status {
|
||||||
if status.confirmations.is_none() || status.confirmations.unwrap() > 1 {
|
if let Some(confirmation_status) = &status.confirmation_status {
|
||||||
|
if *confirmation_status != TransactionConfirmationStatus::Processed {
|
||||||
|
let _ = pending_transactions.remove(&signature);
|
||||||
|
}
|
||||||
|
} else if status.confirmations.is_none() || status.confirmations.unwrap() > 1 {
|
||||||
let _ = pending_transactions.remove(&signature);
|
let _ = pending_transactions.remove(&signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use solana_sdk::{
|
|||||||
signature::Signature,
|
signature::Signature,
|
||||||
transaction::{self, Transaction, TransactionError},
|
transaction::{self, Transaction, TransactionError},
|
||||||
};
|
};
|
||||||
use solana_transaction_status::TransactionStatus;
|
use solana_transaction_status::{TransactionConfirmationStatus, TransactionStatus};
|
||||||
use solana_version::Version;
|
use solana_version::Version;
|
||||||
use std::{collections::HashMap, sync::RwLock};
|
use std::{collections::HashMap, sync::RwLock};
|
||||||
|
|
||||||
@ -106,6 +106,7 @@ impl RpcSender for MockSender {
|
|||||||
slot: 1,
|
slot: 1,
|
||||||
confirmations: None,
|
confirmations: None,
|
||||||
err,
|
err,
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let statuses: Vec<Option<TransactionStatus>> = params.as_array().unwrap()[0]
|
let statuses: Vec<Option<TransactionStatus>> = params.as_array().unwrap()[0]
|
||||||
|
@ -37,6 +37,7 @@ 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::{
|
||||||
|
cmp::min,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
sync::RwLock,
|
sync::RwLock,
|
||||||
thread::sleep,
|
thread::sleep,
|
||||||
@ -1359,29 +1360,20 @@ impl RpcClient {
|
|||||||
}
|
}
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
loop {
|
loop {
|
||||||
match commitment.commitment {
|
// Return when specified commitment is reached
|
||||||
CommitmentLevel::Max | CommitmentLevel::Root =>
|
// Failed transactions have already been eliminated, `is_some` check is sufficient
|
||||||
// Return when default (max) commitment is reached
|
if self
|
||||||
// Failed transactions have already been eliminated, `is_some` check is sufficient
|
.get_signature_status_with_commitment(&signature, commitment)?
|
||||||
{
|
.is_some()
|
||||||
if self.get_signature_status(&signature)?.is_some() {
|
{
|
||||||
progress_bar.set_message("Transaction confirmed");
|
progress_bar.set_message("Transaction confirmed");
|
||||||
progress_bar.finish_and_clear();
|
progress_bar.finish_and_clear();
|
||||||
return Ok(signature);
|
return Ok(signature);
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// Return when one confirmation has been reached
|
|
||||||
if confirmations >= desired_confirmations {
|
|
||||||
progress_bar.set_message("Transaction reached commitment");
|
|
||||||
progress_bar.finish_and_clear();
|
|
||||||
return Ok(signature);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progress_bar.set_message(&format!(
|
progress_bar.set_message(&format!(
|
||||||
"[{}/{}] Finalizing transaction {}",
|
"[{}/{}] Finalizing transaction {}",
|
||||||
confirmations + 1,
|
min(confirmations + 1, desired_confirmations),
|
||||||
desired_confirmations,
|
desired_confirmations,
|
||||||
signature,
|
signature,
|
||||||
));
|
));
|
||||||
|
@ -62,7 +62,8 @@ use solana_sdk::{
|
|||||||
};
|
};
|
||||||
use solana_stake_program::stake_state::StakeState;
|
use solana_stake_program::stake_state::StakeState;
|
||||||
use solana_transaction_status::{
|
use solana_transaction_status::{
|
||||||
EncodedConfirmedBlock, EncodedConfirmedTransaction, TransactionStatus, UiTransactionEncoding,
|
EncodedConfirmedBlock, EncodedConfirmedTransaction, TransactionConfirmationStatus,
|
||||||
|
TransactionStatus, UiTransactionEncoding,
|
||||||
};
|
};
|
||||||
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
||||||
use spl_token_v2_0::{
|
use spl_token_v2_0::{
|
||||||
@ -858,6 +859,7 @@ impl JsonRpcRequestProcessor {
|
|||||||
status: status_meta.status,
|
status: status_meta.status,
|
||||||
confirmations: None,
|
confirmations: None,
|
||||||
err,
|
err,
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
@ -886,6 +888,10 @@ impl JsonRpcRequestProcessor {
|
|||||||
let (slot, status) = bank.get_signature_status_slot(&signature)?;
|
let (slot, status) = bank.get_signature_status_slot(&signature)?;
|
||||||
let r_block_commitment_cache = self.block_commitment_cache.read().unwrap();
|
let r_block_commitment_cache = self.block_commitment_cache.read().unwrap();
|
||||||
|
|
||||||
|
let optimistically_confirmed_bank = self.bank(Some(CommitmentConfig::single_gossip()));
|
||||||
|
let optimistically_confirmed =
|
||||||
|
optimistically_confirmed_bank.get_signature_status_slot(&signature);
|
||||||
|
|
||||||
let confirmations = if r_block_commitment_cache.root() >= slot
|
let confirmations = if r_block_commitment_cache.root() >= slot
|
||||||
&& is_confirmed_rooted(&r_block_commitment_cache, bank, &self.blockstore, slot)
|
&& is_confirmed_rooted(&r_block_commitment_cache, bank, &self.blockstore, slot)
|
||||||
{
|
{
|
||||||
@ -901,6 +907,13 @@ impl JsonRpcRequestProcessor {
|
|||||||
status,
|
status,
|
||||||
confirmations,
|
confirmations,
|
||||||
err,
|
err,
|
||||||
|
confirmation_status: if confirmations.is_none() {
|
||||||
|
Some(TransactionConfirmationStatus::Finalized)
|
||||||
|
} else if optimistically_confirmed.is_some() {
|
||||||
|
Some(TransactionConfirmationStatus::Confirmed)
|
||||||
|
} else {
|
||||||
|
Some(TransactionConfirmationStatus::Processed)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1945,6 +1945,7 @@ An array of:
|
|||||||
- `slot: <u64>` - The slot the transaction was processed
|
- `slot: <u64>` - The slot the transaction was processed
|
||||||
- `confirmations: <usize | null>` - Number of blocks since signature confirmation, null if rooted, as well as finalized by a supermajority of the cluster
|
- `confirmations: <usize | null>` - Number of blocks since signature confirmation, null if rooted, as well as finalized by a supermajority of the cluster
|
||||||
- `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L24)
|
- `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L24)
|
||||||
|
- `confirmationStatus: <string | null>` - The transaction's cluster confirmation status; either `processed`, `confirmed`, or `finalized`. See [Commitment](jsonrpc-api.md#configuring-state-commitment) for more on optimistic confirmation.
|
||||||
- DEPRECATED: `status: <object>` - Transaction status
|
- DEPRECATED: `status: <object>` - Transaction status
|
||||||
- `"Ok": <null>` - Transaction was successful
|
- `"Ok": <null>` - Transaction was successful
|
||||||
- `"Err": <ERR>` - Transaction failed with TransactionError
|
- `"Err": <ERR>` - Transaction failed with TransactionError
|
||||||
@ -1983,7 +1984,8 @@ Result:
|
|||||||
"err": null,
|
"err": null,
|
||||||
"status": {
|
"status": {
|
||||||
"Ok": null
|
"Ok": null
|
||||||
}
|
},
|
||||||
|
"confirmationStatus": "confirmed",
|
||||||
},
|
},
|
||||||
null
|
null
|
||||||
]
|
]
|
||||||
@ -2027,7 +2029,8 @@ Result:
|
|||||||
"err": null,
|
"err": null,
|
||||||
"status": {
|
"status": {
|
||||||
"Ok": null
|
"Ok": null
|
||||||
}
|
},
|
||||||
|
"confirmationStatus": "finalized",
|
||||||
},
|
},
|
||||||
null
|
null
|
||||||
]
|
]
|
||||||
|
@ -10,7 +10,8 @@ use solana_sdk::{
|
|||||||
use solana_storage_proto::convert::generated;
|
use solana_storage_proto::convert::generated;
|
||||||
use solana_transaction_status::{
|
use solana_transaction_status::{
|
||||||
ConfirmedBlock, ConfirmedTransaction, ConfirmedTransactionStatusWithSignature, Reward,
|
ConfirmedBlock, ConfirmedTransaction, ConfirmedTransactionStatusWithSignature, Reward,
|
||||||
TransactionStatus, TransactionStatusMeta, TransactionWithStatusMeta,
|
TransactionConfirmationStatus, TransactionStatus, TransactionStatusMeta,
|
||||||
|
TransactionWithStatusMeta,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, convert::TryInto};
|
use std::{collections::HashMap, convert::TryInto};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -257,6 +258,7 @@ impl From<TransactionInfo> for TransactionStatus {
|
|||||||
confirmations: None,
|
confirmations: None,
|
||||||
status,
|
status,
|
||||||
err,
|
err,
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1038,6 +1038,7 @@ mod tests {
|
|||||||
use solana_core::test_validator::TestValidator;
|
use solana_core::test_validator::TestValidator;
|
||||||
use solana_sdk::signature::{read_keypair_file, write_keypair_file, Signer};
|
use solana_sdk::signature::{read_keypair_file, write_keypair_file, Signer};
|
||||||
use solana_stake_program::stake_instruction::StakeInstruction;
|
use solana_stake_program::stake_instruction::StakeInstruction;
|
||||||
|
use solana_transaction_status::TransactionConfirmationStatus;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_process_token_allocations() {
|
fn test_process_token_allocations() {
|
||||||
@ -2105,6 +2106,7 @@ mod tests {
|
|||||||
confirmations: Some(15),
|
confirmations: Some(15),
|
||||||
status: Ok(()),
|
status: Ok(()),
|
||||||
err: None,
|
err: None,
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||||
})],
|
})],
|
||||||
&mut confirmations,
|
&mut confirmations,
|
||||||
)
|
)
|
||||||
@ -2124,6 +2126,7 @@ mod tests {
|
|||||||
confirmations: None,
|
confirmations: None,
|
||||||
status: Ok(()),
|
status: Ok(()),
|
||||||
err: None,
|
err: None,
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||||
})],
|
})],
|
||||||
&mut confirmations,
|
&mut confirmations,
|
||||||
)
|
)
|
||||||
|
@ -211,6 +211,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use csv::{ReaderBuilder, Trim};
|
use csv::{ReaderBuilder, Trim};
|
||||||
use solana_sdk::transaction::TransactionError;
|
use solana_sdk::transaction::TransactionError;
|
||||||
|
use solana_transaction_status::TransactionConfirmationStatus;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -307,6 +308,7 @@ mod tests {
|
|||||||
confirmations: Some(1),
|
confirmations: Some(1),
|
||||||
err: None,
|
err: None,
|
||||||
status: Ok(()),
|
status: Ok(()),
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Confirmed),
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0)
|
update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0)
|
||||||
@ -334,6 +336,7 @@ mod tests {
|
|||||||
confirmations: None,
|
confirmations: None,
|
||||||
err: Some(TransactionError::AccountNotFound),
|
err: Some(TransactionError::AccountNotFound),
|
||||||
status: Ok(()),
|
status: Ok(()),
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0)
|
update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0)
|
||||||
@ -358,6 +361,7 @@ mod tests {
|
|||||||
confirmations: None,
|
confirmations: None,
|
||||||
err: None,
|
err: None,
|
||||||
status: Ok(()),
|
status: Ok(()),
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0)
|
update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0)
|
||||||
|
@ -20,7 +20,7 @@ use solana_account_decoder::parse_token::UiTokenAmount;
|
|||||||
pub use solana_runtime::bank::RewardType;
|
pub use solana_runtime::bank::RewardType;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
clock::{Slot, UnixTimestamp},
|
clock::{Slot, UnixTimestamp},
|
||||||
commitment_config::CommitmentConfig,
|
commitment_config::{CommitmentConfig, CommitmentLevel},
|
||||||
deserialize_utils::default_on_eof,
|
deserialize_utils::default_on_eof,
|
||||||
instruction::CompiledInstruction,
|
instruction::CompiledInstruction,
|
||||||
message::{Message, MessageHeader},
|
message::{Message, MessageHeader},
|
||||||
@ -260,6 +260,14 @@ impl From<TransactionStatusMeta> for UiTransactionStatusMeta {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub enum TransactionConfirmationStatus {
|
||||||
|
Processed,
|
||||||
|
Confirmed,
|
||||||
|
Finalized,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct TransactionStatus {
|
pub struct TransactionStatus {
|
||||||
@ -267,12 +275,28 @@ pub struct TransactionStatus {
|
|||||||
pub confirmations: Option<usize>, // None = rooted
|
pub confirmations: Option<usize>, // None = rooted
|
||||||
pub status: Result<()>, // legacy field
|
pub status: Result<()>, // legacy field
|
||||||
pub err: Option<TransactionError>,
|
pub err: Option<TransactionError>,
|
||||||
|
pub confirmation_status: Option<TransactionConfirmationStatus>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionStatus {
|
impl TransactionStatus {
|
||||||
pub fn satisfies_commitment(&self, commitment_config: CommitmentConfig) -> bool {
|
pub fn satisfies_commitment(&self, commitment_config: CommitmentConfig) -> bool {
|
||||||
(commitment_config == CommitmentConfig::default() && self.confirmations.is_none())
|
match commitment_config.commitment {
|
||||||
|| commitment_config == CommitmentConfig::recent()
|
CommitmentLevel::Max | CommitmentLevel::Root => self.confirmations.is_none(),
|
||||||
|
CommitmentLevel::SingleGossip => {
|
||||||
|
if let Some(status) = &self.confirmation_status {
|
||||||
|
*status != TransactionConfirmationStatus::Processed
|
||||||
|
} else {
|
||||||
|
// These fallback cases handle TransactionStatus RPC responses from older software
|
||||||
|
self.confirmations.is_some() && self.confirmations.unwrap() > 1
|
||||||
|
|| self.confirmations.is_none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CommitmentLevel::Single => match self.confirmations {
|
||||||
|
Some(confirmations) => confirmations >= 1,
|
||||||
|
None => true,
|
||||||
|
},
|
||||||
|
CommitmentLevel::Recent => true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,9 +569,13 @@ mod test {
|
|||||||
confirmations: None,
|
confirmations: None,
|
||||||
status: Ok(()),
|
status: Ok(()),
|
||||||
err: None,
|
err: None,
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Finalized),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(status.satisfies_commitment(CommitmentConfig::default()));
|
assert!(status.satisfies_commitment(CommitmentConfig::default()));
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::root()));
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::single()));
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::single_gossip()));
|
||||||
assert!(status.satisfies_commitment(CommitmentConfig::recent()));
|
assert!(status.satisfies_commitment(CommitmentConfig::recent()));
|
||||||
|
|
||||||
let status = TransactionStatus {
|
let status = TransactionStatus {
|
||||||
@ -555,9 +583,69 @@ mod test {
|
|||||||
confirmations: Some(10),
|
confirmations: Some(10),
|
||||||
status: Ok(()),
|
status: Ok(()),
|
||||||
err: None,
|
err: None,
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Confirmed),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(!status.satisfies_commitment(CommitmentConfig::default()));
|
assert!(!status.satisfies_commitment(CommitmentConfig::default()));
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::root()));
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::single()));
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::single_gossip()));
|
||||||
assert!(status.satisfies_commitment(CommitmentConfig::recent()));
|
assert!(status.satisfies_commitment(CommitmentConfig::recent()));
|
||||||
|
|
||||||
|
let status = TransactionStatus {
|
||||||
|
slot: 0,
|
||||||
|
confirmations: Some(1),
|
||||||
|
status: Ok(()),
|
||||||
|
err: None,
|
||||||
|
confirmation_status: Some(TransactionConfirmationStatus::Processed),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::default()));
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::root()));
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::single()));
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::single_gossip()));
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::recent()));
|
||||||
|
|
||||||
|
let status = TransactionStatus {
|
||||||
|
slot: 0,
|
||||||
|
confirmations: Some(0),
|
||||||
|
status: Ok(()),
|
||||||
|
err: None,
|
||||||
|
confirmation_status: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::default()));
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::root()));
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::single()));
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::single_gossip()));
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::recent()));
|
||||||
|
|
||||||
|
// Test single_gossip fallback cases
|
||||||
|
let status = TransactionStatus {
|
||||||
|
slot: 0,
|
||||||
|
confirmations: Some(1),
|
||||||
|
status: Ok(()),
|
||||||
|
err: None,
|
||||||
|
confirmation_status: None,
|
||||||
|
};
|
||||||
|
assert!(!status.satisfies_commitment(CommitmentConfig::single_gossip()));
|
||||||
|
|
||||||
|
let status = TransactionStatus {
|
||||||
|
slot: 0,
|
||||||
|
confirmations: Some(2),
|
||||||
|
status: Ok(()),
|
||||||
|
err: None,
|
||||||
|
confirmation_status: None,
|
||||||
|
};
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::single_gossip()));
|
||||||
|
|
||||||
|
let status = TransactionStatus {
|
||||||
|
slot: 0,
|
||||||
|
confirmations: None,
|
||||||
|
status: Ok(()),
|
||||||
|
err: None,
|
||||||
|
confirmation_status: None,
|
||||||
|
};
|
||||||
|
assert!(status.satisfies_commitment(CommitmentConfig::single_gossip()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user