use {
serde::{Deserialize, Serialize},
solana_clock::{
Slot,
UnixTimestamp,
},
solana_message::{
v0::LoadedAddresses,
},
solana_serde::{
default_on_eof,
},
solana_transaction::{
versioned::VersionedTransaction,
},
solana_transaction_error::{
TransactionError,
},
solana_transaction_status::{
ConfirmedBlock,
TransactionStatusMeta,
TransactionWithStatusMeta,
VersionedTransactionWithStatusMeta,
Reward,
},
};
#[derive(Serialize, Deserialize)]
pub struct StoredConfirmedBlock {
previous_blockhash: String,
blockhash: String,
parent_slot: Slot,
transactions: Vec<StoredConfirmedBlockTransaction>,
rewards: StoredConfirmedBlockRewards,
block_time: Option<UnixTimestamp>,
#[serde(deserialize_with = "default_on_eof")]
block_height: Option<u64>,
}
impl From<ConfirmedBlock> for StoredConfirmedBlock {
fn from(confirmed_block: ConfirmedBlock) -> Self {
let ConfirmedBlock {
previous_blockhash,
blockhash,
parent_slot,
transactions,
rewards,
num_partitions: _num_partitions,
block_time,
block_height,
} = confirmed_block;
Self {
previous_blockhash,
blockhash,
parent_slot,
transactions: transactions.into_iter().map(|tx| tx.into()).collect(),
rewards: rewards.into_iter().map(|reward| reward.into()).collect(),
block_time,
block_height,
}
}
}
impl From<StoredConfirmedBlock> for ConfirmedBlock {
fn from(confirmed_block: StoredConfirmedBlock) -> Self {
let StoredConfirmedBlock {
previous_blockhash,
blockhash,
parent_slot,
transactions,
rewards,
block_time,
block_height,
} = confirmed_block;
Self {
previous_blockhash,
blockhash,
parent_slot,
transactions: transactions.into_iter().map(|tx| tx.into()).collect(),
rewards: rewards.into_iter().map(|reward| reward.into()).collect(),
num_partitions: None,
block_time,
block_height,
}
}
}
#[derive(Serialize, Deserialize)]
pub struct StoredConfirmedBlockTransaction {
transaction: VersionedTransaction,
meta: Option<StoredConfirmedBlockTransactionStatusMeta>,
}
type StoredConfirmedBlockRewards = Vec<StoredConfirmedBlockReward>;
#[derive(Serialize, Deserialize)]
pub struct StoredConfirmedBlockReward {
pubkey: String,
lamports: i64,
}
impl From<StoredConfirmedBlockReward> for Reward {
fn from(value: StoredConfirmedBlockReward) -> Self {
let StoredConfirmedBlockReward { pubkey, lamports } = value;
Self {
pubkey,
lamports,
post_balance: 0,
reward_type: None,
commission: None,
}
}
}
impl From<Reward> for StoredConfirmedBlockReward {
fn from(value: Reward) -> Self {
let Reward {
pubkey, lamports, ..
} = value;
Self { pubkey, lamports }
}
}
impl From<TransactionWithStatusMeta> for StoredConfirmedBlockTransaction {
fn from(value: TransactionWithStatusMeta) -> Self {
match value {
TransactionWithStatusMeta::MissingMetadata(transaction) => Self {
transaction: VersionedTransaction::from(transaction),
meta: None,
},
TransactionWithStatusMeta::Complete(VersionedTransactionWithStatusMeta {
transaction,
meta,
}) => Self {
transaction,
meta: Some(meta.into()),
},
}
}
}
impl From<StoredConfirmedBlockTransaction> for TransactionWithStatusMeta {
fn from(tx_with_meta: StoredConfirmedBlockTransaction) -> Self {
let StoredConfirmedBlockTransaction { transaction, meta } = tx_with_meta;
match meta {
None => Self::MissingMetadata(
transaction
.into_legacy_transaction()
.expect("versioned transactions always have meta"),
),
Some(meta) => Self::Complete(VersionedTransactionWithStatusMeta {
transaction,
meta: meta.into(),
}),
}
}
}
#[derive(Serialize, Deserialize)]
pub struct StoredConfirmedBlockTransactionStatusMeta {
err: Option<TransactionError>,
fee: u64,
pre_balances: Vec<u64>,
post_balances: Vec<u64>,
}
impl From<StoredConfirmedBlockTransactionStatusMeta> for TransactionStatusMeta {
fn from(value: StoredConfirmedBlockTransactionStatusMeta) -> Self {
let StoredConfirmedBlockTransactionStatusMeta {
err,
fee,
pre_balances,
post_balances,
} = value;
let status = match &err {
None => Ok(()),
Some(err) => Err(err.clone()),
};
Self {
status,
fee,
pre_balances,
post_balances,
inner_instructions: None,
log_messages: None,
pre_token_balances: None,
post_token_balances: None,
rewards: None,
loaded_addresses: LoadedAddresses::default(),
return_data: None,
compute_units_consumed: None,
cost_units: None,
}
}
}
impl From<TransactionStatusMeta> for StoredConfirmedBlockTransactionStatusMeta {
fn from(value: TransactionStatusMeta) -> Self {
let TransactionStatusMeta {
status,
fee,
pre_balances,
post_balances,
..
} = value;
Self {
err: status.err(),
fee,
pre_balances,
post_balances,
}
}
}