Implement OutputFormat for confirm in Cli and ledger-tool bigtable (#15528)

* Add CliTransaction struct

* Impl DisplayFormat for decode-transaction

* Add block-time to transaction println, writeln

* Impl DisplayFormat for confirm

* Use DisplayFormat in ledger-tool bigtable confirm
This commit is contained in:
Tyera Eulberg
2021-02-25 14:15:52 -07:00
committed by GitHub
parent f59ec3d1a7
commit d521dfe63c
7 changed files with 225 additions and 94 deletions

View File

@ -26,10 +26,13 @@ use {
pubkey::Pubkey,
signature::Signature,
stake_history::StakeHistoryEntry,
transaction::Transaction,
transaction::{Transaction, TransactionError},
},
solana_stake_program::stake_state::{Authorized, Lockup},
solana_transaction_status::EncodedConfirmedBlock,
solana_transaction_status::{
EncodedConfirmedBlock, EncodedTransaction, TransactionConfirmationStatus,
UiTransactionStatusMeta,
},
solana_vote_program::{
authorized_voters::AuthorizedVoters,
vote_state::{BlockTimestamp, Lockout, MAX_EPOCH_CREDITS_HISTORY, MAX_LOCKOUT_HISTORY},
@ -1711,7 +1714,8 @@ pub fn parse_sign_only_reply_string(reply: &str) -> SignOnly {
}
}
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum CliSignatureVerificationStatus {
None,
Pass,
@ -1743,6 +1747,7 @@ impl fmt::Display for CliSignatureVerificationStatus {
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CliBlock {
#[serde(flatten)]
pub encoded_confirmed_block: EncodedConfirmedBlock,
@ -1830,12 +1835,103 @@ impl fmt::Display for CliBlock {
&transaction_with_meta.meta,
" ",
None,
None,
)?;
}
Ok(())
}
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CliTransaction {
pub transaction: EncodedTransaction,
pub meta: Option<UiTransactionStatusMeta>,
pub block_time: Option<UnixTimestamp>,
#[serde(skip_serializing)]
pub slot: Option<Slot>,
#[serde(skip_serializing)]
pub decoded_transaction: Transaction,
#[serde(skip_serializing)]
pub prefix: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub sigverify_status: Vec<CliSignatureVerificationStatus>,
}
impl QuietDisplay for CliTransaction {}
impl VerboseDisplay for CliTransaction {}
impl fmt::Display for CliTransaction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln_transaction(
f,
&self.decoded_transaction,
&self.meta,
&self.prefix,
if !self.sigverify_status.is_empty() {
Some(&self.sigverify_status)
} else {
None
},
self.block_time,
)
}
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CliTransactionConfirmation {
pub confirmation_status: Option<TransactionConfirmationStatus>,
#[serde(flatten, skip_serializing_if = "Option::is_none")]
pub transaction: Option<CliTransaction>,
#[serde(skip_serializing)]
pub get_transaction_error: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub err: Option<TransactionError>,
}
impl QuietDisplay for CliTransactionConfirmation {}
impl VerboseDisplay for CliTransactionConfirmation {
fn write_str(&self, w: &mut dyn std::fmt::Write) -> std::fmt::Result {
if let Some(transaction) = &self.transaction {
writeln!(
w,
"\nTransaction executed in slot {}:",
transaction.slot.expect("slot should exist")
)?;
write!(w, "{}", transaction)?;
} else if let Some(confirmation_status) = &self.confirmation_status {
if confirmation_status != &TransactionConfirmationStatus::Finalized {
writeln!(w)?;
writeln!(
w,
"Unable to get finalized transaction details: not yet finalized"
)?;
} else if let Some(err) = &self.get_transaction_error {
writeln!(w)?;
writeln!(w, "Unable to get finalized transaction details: {}", err)?;
}
}
writeln!(w)?;
write!(w, "{}", self)
}
}
impl fmt::Display for CliTransactionConfirmation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.confirmation_status {
None => write!(f, "Not found"),
Some(confirmation_status) => {
if let Some(err) = &self.err {
write!(f, "Transaction failed: {}", err)
} else {
write!(f, "{:?}", confirmation_status)
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;