Passing -v/--verbose to `solana confirm` now displays the full transaction
This commit is contained in:
parent
4ac15e68cf
commit
7e7cbec8a1
|
@ -3868,6 +3868,7 @@ dependencies = [
|
||||||
"solana-sdk 1.2.0",
|
"solana-sdk 1.2.0",
|
||||||
"solana-stake-program 1.2.0",
|
"solana-stake-program 1.2.0",
|
||||||
"solana-storage-program 1.2.0",
|
"solana-storage-program 1.2.0",
|
||||||
|
"solana-transaction-status 1.2.0",
|
||||||
"solana-vote-program 1.2.0",
|
"solana-vote-program 1.2.0",
|
||||||
"solana-vote-signer 1.2.0",
|
"solana-vote-signer 1.2.0",
|
||||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -4249,11 +4250,13 @@ dependencies = [
|
||||||
"serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"solana-clap-utils 1.2.0",
|
"solana-clap-utils 1.2.0",
|
||||||
|
"solana-cli 1.2.0",
|
||||||
"solana-ledger 1.2.0",
|
"solana-ledger 1.2.0",
|
||||||
"solana-logger 1.2.0",
|
"solana-logger 1.2.0",
|
||||||
"solana-runtime 1.2.0",
|
"solana-runtime 1.2.0",
|
||||||
"solana-sdk 1.2.0",
|
"solana-sdk 1.2.0",
|
||||||
"solana-stake-program 1.2.0",
|
"solana-stake-program 1.2.0",
|
||||||
|
"solana-transaction-status 1.2.0",
|
||||||
"solana-vote-program 1.2.0",
|
"solana-vote-program 1.2.0",
|
||||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
|
@ -40,6 +40,7 @@ solana-runtime = { path = "../runtime", version = "1.2.0" }
|
||||||
solana-sdk = { path = "../sdk", version = "1.2.0" }
|
solana-sdk = { path = "../sdk", version = "1.2.0" }
|
||||||
solana-stake-program = { path = "../programs/stake", version = "1.2.0" }
|
solana-stake-program = { path = "../programs/stake", version = "1.2.0" }
|
||||||
solana-storage-program = { path = "../programs/storage", version = "1.2.0" }
|
solana-storage-program = { path = "../programs/storage", version = "1.2.0" }
|
||||||
|
solana-transaction-status = { path = "../transaction-status", version = "1.2.0" }
|
||||||
solana-vote-program = { path = "../programs/vote", version = "1.2.0" }
|
solana-vote-program = { path = "../programs/vote", version = "1.2.0" }
|
||||||
solana-vote-signer = { path = "../vote-signer", version = "1.2.0" }
|
solana-vote-signer = { path = "../vote-signer", version = "1.2.0" }
|
||||||
thiserror = "1.0.15"
|
thiserror = "1.0.15"
|
||||||
|
|
|
@ -1165,12 +1165,48 @@ fn process_balance(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_confirm(rpc_client: &RpcClient, signature: &Signature) -> ProcessResult {
|
fn process_confirm(
|
||||||
match rpc_client.get_signature_status(&signature) {
|
rpc_client: &RpcClient,
|
||||||
|
config: &CliConfig,
|
||||||
|
signature: &Signature,
|
||||||
|
) -> ProcessResult {
|
||||||
|
match rpc_client.get_signature_status_with_commitment_and_history(
|
||||||
|
&signature,
|
||||||
|
CommitmentConfig::max(),
|
||||||
|
true,
|
||||||
|
) {
|
||||||
Ok(status) => {
|
Ok(status) => {
|
||||||
if let Some(result) = status {
|
if let Some(result) = status {
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => Ok("Confirmed".to_string()),
|
Ok(_) => {
|
||||||
|
if config.verbose {
|
||||||
|
match rpc_client.get_confirmed_transaction(
|
||||||
|
signature,
|
||||||
|
solana_transaction_status::TransactionEncoding::Binary,
|
||||||
|
) {
|
||||||
|
Ok(confirmed_transaction) => {
|
||||||
|
println!("\nTransaction:");
|
||||||
|
crate::display::println_transaction(
|
||||||
|
&confirmed_transaction
|
||||||
|
.transaction
|
||||||
|
.transaction
|
||||||
|
.decode()
|
||||||
|
.expect("Successful decode"),
|
||||||
|
&confirmed_transaction.transaction.meta,
|
||||||
|
" ",
|
||||||
|
);
|
||||||
|
println!();
|
||||||
|
Ok(format!("Confirmed in slot {}", confirmed_transaction.slot))
|
||||||
|
}
|
||||||
|
Err(err) => Ok(format!(
|
||||||
|
"Confirmed. Unable to get confirmed transaction details: {}",
|
||||||
|
err
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok("Confirmed".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(err) => Ok(format!("Transaction failed with error: {}", err)),
|
Err(err) => Ok(format!("Transaction failed with error: {}", err)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2063,7 +2099,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
||||||
// Cancel a contract by contract Pubkey
|
// Cancel a contract by contract Pubkey
|
||||||
CliCommand::Cancel(pubkey) => process_cancel(&rpc_client, config, &pubkey),
|
CliCommand::Cancel(pubkey) => process_cancel(&rpc_client, config, &pubkey),
|
||||||
// Confirm the last client transaction by signature
|
// Confirm the last client transaction by signature
|
||||||
CliCommand::Confirm(signature) => process_confirm(&rpc_client, signature),
|
CliCommand::Confirm(signature) => process_confirm(&rpc_client, config, signature),
|
||||||
// If client has positive balance, pay lamports to another address
|
// If client has positive balance, pay lamports to another address
|
||||||
CliCommand::Pay(PayCommand {
|
CliCommand::Pay(PayCommand {
|
||||||
lamports,
|
lamports,
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
use crate::cli::SettingType;
|
use crate::cli::SettingType;
|
||||||
use console::style;
|
use console::style;
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::{
|
||||||
|
hash::Hash, native_token::lamports_to_sol, program_utils::limited_deserialize,
|
||||||
|
transaction::Transaction,
|
||||||
|
};
|
||||||
|
use solana_transaction_status::RpcTransactionStatusMeta;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
// Pretty print a "name value"
|
// Pretty print a "name value"
|
||||||
|
@ -59,3 +63,106 @@ pub fn println_signers(
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn println_transaction(
|
||||||
|
transaction: &Transaction,
|
||||||
|
transaction_status: &Option<RpcTransactionStatusMeta>,
|
||||||
|
prefix: &str,
|
||||||
|
) {
|
||||||
|
let message = &transaction.message;
|
||||||
|
println!("{}Recent Blockhash: {:?}", prefix, message.recent_blockhash);
|
||||||
|
for (signature_index, signature) in transaction.signatures.iter().enumerate() {
|
||||||
|
println!("{}Signature {}: {:?}", prefix, signature_index, signature);
|
||||||
|
}
|
||||||
|
println!("{}{:?}", prefix, message.header);
|
||||||
|
for (account_index, account) in message.account_keys.iter().enumerate() {
|
||||||
|
println!("{}Account {}: {:?}", prefix, account_index, account);
|
||||||
|
}
|
||||||
|
for (instruction_index, instruction) in message.instructions.iter().enumerate() {
|
||||||
|
let program_pubkey = message.account_keys[instruction.program_id_index as usize];
|
||||||
|
println!("{}Instruction {}", prefix, instruction_index);
|
||||||
|
println!(
|
||||||
|
"{} Program: {} ({})",
|
||||||
|
prefix, program_pubkey, instruction.program_id_index
|
||||||
|
);
|
||||||
|
for (account_index, account) in instruction.accounts.iter().enumerate() {
|
||||||
|
let account_pubkey = message.account_keys[*account as usize];
|
||||||
|
println!(
|
||||||
|
"{} Account {}: {} ({})",
|
||||||
|
prefix, account_index, account_pubkey, account
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut raw = true;
|
||||||
|
if program_pubkey == solana_vote_program::id() {
|
||||||
|
if let Ok(vote_instruction) = limited_deserialize::<
|
||||||
|
solana_vote_program::vote_instruction::VoteInstruction,
|
||||||
|
>(&instruction.data)
|
||||||
|
{
|
||||||
|
println!("{} {:?}", prefix, vote_instruction);
|
||||||
|
raw = false;
|
||||||
|
}
|
||||||
|
} else if program_pubkey == solana_stake_program::id() {
|
||||||
|
if let Ok(stake_instruction) = limited_deserialize::<
|
||||||
|
solana_stake_program::stake_instruction::StakeInstruction,
|
||||||
|
>(&instruction.data)
|
||||||
|
{
|
||||||
|
println!("{} {:?}", prefix, stake_instruction);
|
||||||
|
raw = false;
|
||||||
|
}
|
||||||
|
} else if program_pubkey == solana_sdk::system_program::id() {
|
||||||
|
if let Ok(system_instruction) = limited_deserialize::<
|
||||||
|
solana_sdk::system_instruction::SystemInstruction,
|
||||||
|
>(&instruction.data)
|
||||||
|
{
|
||||||
|
println!("{} {:?}", prefix, system_instruction);
|
||||||
|
raw = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if raw {
|
||||||
|
println!("{} Data: {:?}", prefix, instruction.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(transaction_status) = transaction_status {
|
||||||
|
println!(
|
||||||
|
"{}Status: {}",
|
||||||
|
prefix,
|
||||||
|
match &transaction_status.status {
|
||||||
|
Ok(_) => "Ok".into(),
|
||||||
|
Err(err) => err.to_string(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
println!("{} Fee: {}", prefix, transaction_status.fee);
|
||||||
|
assert_eq!(
|
||||||
|
transaction_status.pre_balances.len(),
|
||||||
|
transaction_status.post_balances.len()
|
||||||
|
);
|
||||||
|
for (i, (pre, post)) in transaction_status
|
||||||
|
.pre_balances
|
||||||
|
.iter()
|
||||||
|
.zip(transaction_status.post_balances.iter())
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
if pre == post {
|
||||||
|
println!(
|
||||||
|
"{} Account {} balance: {} SOL",
|
||||||
|
prefix,
|
||||||
|
i,
|
||||||
|
lamports_to_sol(*pre)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"{} Account {} balance: {} SOL -> {} SOL",
|
||||||
|
prefix,
|
||||||
|
i,
|
||||||
|
lamports_to_sol(*pre),
|
||||||
|
lamports_to_sol(*post)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("{}Status: Unavailable", prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,7 +23,9 @@ use solana_sdk::{
|
||||||
signers::Signers,
|
signers::Signers,
|
||||||
transaction::{self, Transaction, TransactionError},
|
transaction::{self, Transaction, TransactionError},
|
||||||
};
|
};
|
||||||
use solana_transaction_status::{ConfirmedBlock, TransactionEncoding, TransactionStatus};
|
use solana_transaction_status::{
|
||||||
|
ConfirmedBlock, ConfirmedTransaction, TransactionEncoding, TransactionStatus,
|
||||||
|
};
|
||||||
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
||||||
use std::{
|
use std::{
|
||||||
error,
|
error,
|
||||||
|
@ -158,6 +160,28 @@ impl RpcClient {
|
||||||
.map(|status_meta| status_meta.status))
|
.map(|status_meta| status_meta.status))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_signature_status_with_commitment_and_history(
|
||||||
|
&self,
|
||||||
|
signature: &Signature,
|
||||||
|
commitment_config: CommitmentConfig,
|
||||||
|
search_transaction_history: bool,
|
||||||
|
) -> ClientResult<Option<transaction::Result<()>>> {
|
||||||
|
let signature_status = self.client.send(
|
||||||
|
&RpcRequest::GetSignatureStatuses,
|
||||||
|
json!([[signature.to_string()], {
|
||||||
|
"searchTransactionHistory": search_transaction_history
|
||||||
|
}]),
|
||||||
|
5,
|
||||||
|
)?;
|
||||||
|
let result: Response<Vec<Option<TransactionStatus>>> =
|
||||||
|
serde_json::from_value(signature_status)
|
||||||
|
.map_err(|err| ClientError::new_with_command(err.into(), "GetSignatureStatuses"))?;
|
||||||
|
Ok(result.value[0]
|
||||||
|
.clone()
|
||||||
|
.filter(|result| result.satisfies_commitment(commitment_config))
|
||||||
|
.map(|status_meta| status_meta.status))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_slot(&self) -> ClientResult<Slot> {
|
pub fn get_slot(&self) -> ClientResult<Slot> {
|
||||||
self.get_slot_with_commitment(CommitmentConfig::default())
|
self.get_slot_with_commitment(CommitmentConfig::default())
|
||||||
}
|
}
|
||||||
|
@ -255,6 +279,44 @@ impl RpcClient {
|
||||||
.map_err(|err| ClientError::new_with_command(err.into(), "GetConfirmedBlocks"))
|
.map_err(|err| ClientError::new_with_command(err.into(), "GetConfirmedBlocks"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_confirmed_signatures_for_address(
|
||||||
|
&self,
|
||||||
|
address: &Pubkey,
|
||||||
|
start_slot: Slot,
|
||||||
|
end_slot: Slot,
|
||||||
|
) -> ClientResult<Vec<Signature>> {
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.send(
|
||||||
|
&RpcRequest::GetConfirmedSignaturesForAddress,
|
||||||
|
json!([address, start_slot, end_slot]),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
.map_err(|err| err.into_with_command("GetConfirmedSignaturesForAddress"))?;
|
||||||
|
|
||||||
|
serde_json::from_value(response).map_err(|err| {
|
||||||
|
ClientError::new_with_command(err.into(), "GetConfirmedSignaturesForAddress")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_confirmed_transaction(
|
||||||
|
&self,
|
||||||
|
signature: &Signature,
|
||||||
|
encoding: TransactionEncoding,
|
||||||
|
) -> ClientResult<ConfirmedTransaction> {
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.send(
|
||||||
|
&RpcRequest::GetConfirmedTransaction,
|
||||||
|
json!([signature.to_string(), encoding]),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
.map_err(|err| err.into_with_command("GetConfirmedTransaction"))?;
|
||||||
|
|
||||||
|
serde_json::from_value(response)
|
||||||
|
.map_err(|err| ClientError::new_with_command(err.into(), "GetConfirmedTransaction"))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_block_time(&self, slot: Slot) -> ClientResult<UnixTimestamp> {
|
pub fn get_block_time(&self, slot: Slot) -> ClientResult<UnixTimestamp> {
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
|
|
|
@ -11,6 +11,8 @@ pub enum RpcRequest {
|
||||||
GetClusterNodes,
|
GetClusterNodes,
|
||||||
GetConfirmedBlock,
|
GetConfirmedBlock,
|
||||||
GetConfirmedBlocks,
|
GetConfirmedBlocks,
|
||||||
|
GetConfirmedSignaturesForAddress,
|
||||||
|
GetConfirmedTransaction,
|
||||||
GetEpochInfo,
|
GetEpochInfo,
|
||||||
GetEpochSchedule,
|
GetEpochSchedule,
|
||||||
GetGenesisHash,
|
GetGenesisHash,
|
||||||
|
@ -52,6 +54,8 @@ impl RpcRequest {
|
||||||
RpcRequest::GetClusterNodes => "getClusterNodes",
|
RpcRequest::GetClusterNodes => "getClusterNodes",
|
||||||
RpcRequest::GetConfirmedBlock => "getConfirmedBlock",
|
RpcRequest::GetConfirmedBlock => "getConfirmedBlock",
|
||||||
RpcRequest::GetConfirmedBlocks => "getConfirmedBlocks",
|
RpcRequest::GetConfirmedBlocks => "getConfirmedBlocks",
|
||||||
|
RpcRequest::GetConfirmedSignaturesForAddress => "getConfirmedSignaturesForAddress",
|
||||||
|
RpcRequest::GetConfirmedTransaction => "getConfirmedTransaction",
|
||||||
RpcRequest::GetEpochInfo => "getEpochInfo",
|
RpcRequest::GetEpochInfo => "getEpochInfo",
|
||||||
RpcRequest::GetEpochSchedule => "getEpochSchedule",
|
RpcRequest::GetEpochSchedule => "getEpochSchedule",
|
||||||
RpcRequest::GetGenesisHash => "getGenesisHash",
|
RpcRequest::GetGenesisHash => "getGenesisHash",
|
||||||
|
|
|
@ -15,12 +15,14 @@ histogram = "*"
|
||||||
serde_json = "1.0.51"
|
serde_json = "1.0.51"
|
||||||
serde_yaml = "0.8.11"
|
serde_yaml = "0.8.11"
|
||||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.0" }
|
solana-clap-utils = { path = "../clap-utils", version = "1.2.0" }
|
||||||
|
solana-cli = { path = "../cli", version = "1.2.0" }
|
||||||
solana-ledger = { path = "../ledger", version = "1.2.0" }
|
solana-ledger = { path = "../ledger", version = "1.2.0" }
|
||||||
solana-logger = { path = "../logger", version = "1.2.0" }
|
solana-logger = { path = "../logger", version = "1.2.0" }
|
||||||
solana-runtime = { path = "../runtime", version = "1.2.0" }
|
solana-runtime = { path = "../runtime", version = "1.2.0" }
|
||||||
solana-sdk = { path = "../sdk", version = "1.2.0" }
|
solana-sdk = { path = "../sdk", version = "1.2.0" }
|
||||||
solana-vote-program = { path = "../programs/vote", version = "1.2.0" }
|
|
||||||
solana-stake-program = { path = "../programs/stake", version = "1.2.0" }
|
solana-stake-program = { path = "../programs/stake", version = "1.2.0" }
|
||||||
|
solana-transaction-status = { path = "../transaction-status", version = "1.2.0" }
|
||||||
|
solana-vote-program = { path = "../programs/vote", version = "1.2.0" }
|
||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -17,8 +17,8 @@ use solana_ledger::{
|
||||||
snapshot_utils,
|
snapshot_utils,
|
||||||
};
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
clock::Slot, genesis_config::GenesisConfig, native_token::lamports_to_sol,
|
clock::Slot, genesis_config::GenesisConfig, native_token::lamports_to_sol, pubkey::Pubkey,
|
||||||
program_utils::limited_deserialize, pubkey::Pubkey, shred_version::compute_shred_version,
|
shred_version::compute_shred_version,
|
||||||
};
|
};
|
||||||
use solana_vote_program::vote_state::VoteState;
|
use solana_vote_program::vote_state::VoteState;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -100,112 +100,23 @@ fn output_slot(
|
||||||
entry.transactions.len()
|
entry.transactions.len()
|
||||||
);
|
);
|
||||||
for (transactions_index, transaction) in entry.transactions.iter().enumerate() {
|
for (transactions_index, transaction) in entry.transactions.iter().enumerate() {
|
||||||
let message = &transaction.message;
|
|
||||||
println!(" Transaction {}", transactions_index);
|
println!(" Transaction {}", transactions_index);
|
||||||
println!(" Recent Blockhash: {:?}", message.recent_blockhash);
|
let transaction_status = blockstore
|
||||||
for (signature_index, signature) in transaction.signatures.iter().enumerate() {
|
.read_transaction_status((transaction.signatures[0], slot))
|
||||||
println!(" Signature {}: {:?}", signature_index, signature);
|
.unwrap_or_else(|err| {
|
||||||
}
|
eprintln!(
|
||||||
println!(" {:?}", message.header);
|
"Failed to read transaction status for {} at slot {}: {}",
|
||||||
for (account_index, account) in message.account_keys.iter().enumerate() {
|
transaction.signatures[0], slot, err
|
||||||
println!(" Account {}: {:?}", account_index, account);
|
|
||||||
}
|
|
||||||
for (instruction_index, instruction) in message.instructions.iter().enumerate()
|
|
||||||
{
|
|
||||||
let program_pubkey =
|
|
||||||
message.account_keys[instruction.program_id_index as usize];
|
|
||||||
println!(" Instruction {}", instruction_index);
|
|
||||||
println!(
|
|
||||||
" Program: {} ({})",
|
|
||||||
program_pubkey, instruction.program_id_index
|
|
||||||
);
|
|
||||||
for (account_index, account) in instruction.accounts.iter().enumerate() {
|
|
||||||
let account_pubkey = message.account_keys[*account as usize];
|
|
||||||
println!(
|
|
||||||
" Account {}: {} ({})",
|
|
||||||
account_index, account_pubkey, account
|
|
||||||
);
|
);
|
||||||
}
|
None
|
||||||
|
})
|
||||||
|
.map(|transaction_status| transaction_status.into());
|
||||||
|
|
||||||
let mut raw = true;
|
solana_cli::display::println_transaction(
|
||||||
if program_pubkey == solana_vote_program::id() {
|
&transaction,
|
||||||
if let Ok(vote_instruction) =
|
&transaction_status,
|
||||||
limited_deserialize::<
|
" ",
|
||||||
solana_vote_program::vote_instruction::VoteInstruction,
|
);
|
||||||
>(&instruction.data)
|
|
||||||
{
|
|
||||||
println!(" {:?}", vote_instruction);
|
|
||||||
raw = false;
|
|
||||||
}
|
|
||||||
} else if program_pubkey == solana_stake_program::id() {
|
|
||||||
if let Ok(stake_instruction) =
|
|
||||||
limited_deserialize::<
|
|
||||||
solana_stake_program::stake_instruction::StakeInstruction,
|
|
||||||
>(&instruction.data)
|
|
||||||
{
|
|
||||||
println!(" {:?}", stake_instruction);
|
|
||||||
raw = false;
|
|
||||||
}
|
|
||||||
} else if program_pubkey == solana_sdk::system_program::id() {
|
|
||||||
if let Ok(system_instruction) =
|
|
||||||
limited_deserialize::<
|
|
||||||
solana_sdk::system_instruction::SystemInstruction,
|
|
||||||
>(&instruction.data)
|
|
||||||
{
|
|
||||||
println!(" {:?}", system_instruction);
|
|
||||||
raw = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if raw {
|
|
||||||
println!(" Data: {:?}", instruction.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match blockstore.read_transaction_status((transaction.signatures[0], slot)) {
|
|
||||||
Ok(transaction_status) => {
|
|
||||||
if let Some(transaction_status) = transaction_status {
|
|
||||||
println!(
|
|
||||||
" Status: {}",
|
|
||||||
if transaction_status.status.is_ok() {
|
|
||||||
"Ok".into()
|
|
||||||
} else {
|
|
||||||
transaction_status.status.unwrap_err().to_string()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
println!(" Fee: {}", transaction_status.fee);
|
|
||||||
assert_eq!(
|
|
||||||
transaction_status.pre_balances.len(),
|
|
||||||
transaction_status.post_balances.len()
|
|
||||||
);
|
|
||||||
for (i, (pre, post)) in transaction_status
|
|
||||||
.pre_balances
|
|
||||||
.iter()
|
|
||||||
.zip(transaction_status.post_balances.iter())
|
|
||||||
.enumerate()
|
|
||||||
{
|
|
||||||
if pre == post {
|
|
||||||
println!(
|
|
||||||
" Account {} balance: {} SOL",
|
|
||||||
i,
|
|
||||||
lamports_to_sol(*pre)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
println!(
|
|
||||||
" Account {} balance: {} SOL -> {} SOL",
|
|
||||||
i,
|
|
||||||
lamports_to_sol(*pre),
|
|
||||||
lamports_to_sol(*post)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
println!(" Status: Unavailable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
println!(" Status: {:?}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LedgerOutputMethod::Json => {
|
LedgerOutputMethod::Json => {
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl From<TransactionStatusMeta> for RpcTransactionStatusMeta {
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct TransactionStatus {
|
pub struct TransactionStatus {
|
||||||
pub slot: Slot,
|
pub slot: Slot,
|
||||||
pub confirmations: Option<usize>,
|
pub confirmations: Option<usize>, // None = rooted
|
||||||
pub status: Result<()>,
|
pub status: Result<()>,
|
||||||
pub err: Option<TransactionError>,
|
pub err: Option<TransactionError>,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue