Convert blockstore TransactionStatus column family to protobufs (#15733)
* Prevent panic if TransactionStatus can't be deserialized * Convert Blockstore TransactionStatus column to protobuf * Add compatability test
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
use crate::StoredExtendedRewards;
|
||||
use crate::{StoredExtendedRewards, StoredTransactionStatusMeta};
|
||||
use solana_account_decoder::parse_token::{real_number_string_trimmed, UiTokenAmount};
|
||||
use solana_sdk::{
|
||||
hash::Hash,
|
||||
@ -312,6 +312,13 @@ impl From<TransactionStatusMeta> for generated::TransactionStatusMeta {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StoredTransactionStatusMeta> for generated::TransactionStatusMeta {
|
||||
fn from(meta: StoredTransactionStatusMeta) -> Self {
|
||||
let meta: TransactionStatusMeta = meta.into();
|
||||
meta.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<generated::TransactionStatusMeta> for TransactionStatusMeta {
|
||||
type Error = bincode::Error;
|
||||
|
||||
|
@ -1,6 +1,13 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use solana_sdk::deserialize_utils::default_on_eof;
|
||||
use solana_transaction_status::{Reward, RewardType};
|
||||
use solana_account_decoder::{
|
||||
parse_token::{real_number_string_trimmed, UiTokenAmount},
|
||||
StringAmount,
|
||||
};
|
||||
use solana_sdk::{deserialize_utils::default_on_eof, transaction::Result};
|
||||
use solana_transaction_status::{
|
||||
InnerInstructions, Reward, RewardType, TransactionStatusMeta, TransactionTokenBalance,
|
||||
};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub mod convert;
|
||||
|
||||
@ -50,3 +57,151 @@ impl From<Reward> for StoredExtendedReward {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StoredTokenAmount {
|
||||
pub ui_amount: f64,
|
||||
pub decimals: u8,
|
||||
pub amount: StringAmount,
|
||||
}
|
||||
|
||||
impl From<StoredTokenAmount> for UiTokenAmount {
|
||||
fn from(value: StoredTokenAmount) -> Self {
|
||||
let StoredTokenAmount {
|
||||
ui_amount,
|
||||
decimals,
|
||||
amount,
|
||||
} = value;
|
||||
let ui_amount_string =
|
||||
real_number_string_trimmed(u64::from_str(&amount).unwrap_or(0), decimals);
|
||||
Self {
|
||||
ui_amount: Some(ui_amount),
|
||||
decimals,
|
||||
amount,
|
||||
ui_amount_string,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UiTokenAmount> for StoredTokenAmount {
|
||||
fn from(value: UiTokenAmount) -> Self {
|
||||
let UiTokenAmount {
|
||||
ui_amount,
|
||||
decimals,
|
||||
amount,
|
||||
..
|
||||
} = value;
|
||||
Self {
|
||||
ui_amount: ui_amount.unwrap_or(0.0),
|
||||
decimals,
|
||||
amount,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StoredTransactionTokenBalance {
|
||||
pub account_index: u8,
|
||||
pub mint: String,
|
||||
pub ui_token_amount: StoredTokenAmount,
|
||||
}
|
||||
|
||||
impl From<StoredTransactionTokenBalance> for TransactionTokenBalance {
|
||||
fn from(value: StoredTransactionTokenBalance) -> Self {
|
||||
let StoredTransactionTokenBalance {
|
||||
account_index,
|
||||
mint,
|
||||
ui_token_amount,
|
||||
} = value;
|
||||
Self {
|
||||
account_index,
|
||||
mint,
|
||||
ui_token_amount: ui_token_amount.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionTokenBalance> for StoredTransactionTokenBalance {
|
||||
fn from(value: TransactionTokenBalance) -> Self {
|
||||
let TransactionTokenBalance {
|
||||
account_index,
|
||||
mint,
|
||||
ui_token_amount,
|
||||
} = value;
|
||||
Self {
|
||||
account_index,
|
||||
mint,
|
||||
ui_token_amount: ui_token_amount.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StoredTransactionStatusMeta {
|
||||
pub status: Result<()>,
|
||||
pub fee: u64,
|
||||
pub pre_balances: Vec<u64>,
|
||||
pub post_balances: Vec<u64>,
|
||||
#[serde(deserialize_with = "default_on_eof")]
|
||||
pub inner_instructions: Option<Vec<InnerInstructions>>,
|
||||
#[serde(deserialize_with = "default_on_eof")]
|
||||
pub log_messages: Option<Vec<String>>,
|
||||
#[serde(deserialize_with = "default_on_eof")]
|
||||
pub pre_token_balances: Option<Vec<StoredTransactionTokenBalance>>,
|
||||
#[serde(deserialize_with = "default_on_eof")]
|
||||
pub post_token_balances: Option<Vec<StoredTransactionTokenBalance>>,
|
||||
}
|
||||
|
||||
impl From<StoredTransactionStatusMeta> for TransactionStatusMeta {
|
||||
fn from(value: StoredTransactionStatusMeta) -> Self {
|
||||
let StoredTransactionStatusMeta {
|
||||
status,
|
||||
fee,
|
||||
pre_balances,
|
||||
post_balances,
|
||||
inner_instructions,
|
||||
log_messages,
|
||||
pre_token_balances,
|
||||
post_token_balances,
|
||||
} = value;
|
||||
Self {
|
||||
status,
|
||||
fee,
|
||||
pre_balances,
|
||||
post_balances,
|
||||
inner_instructions,
|
||||
log_messages,
|
||||
pre_token_balances: pre_token_balances
|
||||
.map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
|
||||
post_token_balances: post_token_balances
|
||||
.map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionStatusMeta> for StoredTransactionStatusMeta {
|
||||
fn from(value: TransactionStatusMeta) -> Self {
|
||||
let TransactionStatusMeta {
|
||||
status,
|
||||
fee,
|
||||
pre_balances,
|
||||
post_balances,
|
||||
inner_instructions,
|
||||
log_messages,
|
||||
pre_token_balances,
|
||||
post_token_balances,
|
||||
} = value;
|
||||
Self {
|
||||
status,
|
||||
fee,
|
||||
pre_balances,
|
||||
post_balances,
|
||||
inner_instructions,
|
||||
log_messages,
|
||||
pre_token_balances: pre_token_balances
|
||||
.map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
|
||||
post_token_balances: post_token_balances
|
||||
.map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user