Store address table lookups in blockstore and bigtable (#22402)
This commit is contained in:
@@ -4,14 +4,19 @@ use {
|
||||
solana_sdk::{
|
||||
hash::Hash,
|
||||
instruction::{CompiledInstruction, InstructionError},
|
||||
message::{Message, MessageHeader},
|
||||
message::{
|
||||
legacy::Message as LegacyMessage,
|
||||
v0::{self, LoadedAddresses, MessageAddressTableLookup},
|
||||
MessageHeader, VersionedMessage,
|
||||
},
|
||||
pubkey::Pubkey,
|
||||
signature::Signature,
|
||||
transaction::{Transaction, TransactionError},
|
||||
transaction::{Transaction, TransactionError, VersionedTransaction},
|
||||
},
|
||||
solana_transaction_status::{
|
||||
ConfirmedBlock, InnerInstructions, Reward, RewardType, TransactionByAddrInfo,
|
||||
TransactionStatusMeta, TransactionTokenBalance, TransactionWithStatusMeta,
|
||||
VersionedConfirmedBlock, VersionedTransactionWithStatusMeta,
|
||||
},
|
||||
std::{
|
||||
convert::{TryFrom, TryInto},
|
||||
@@ -111,6 +116,30 @@ impl From<generated::Reward> for Reward {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VersionedConfirmedBlock> for generated::ConfirmedBlock {
|
||||
fn from(confirmed_block: VersionedConfirmedBlock) -> Self {
|
||||
let VersionedConfirmedBlock {
|
||||
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(|r| r.into()).collect(),
|
||||
block_time: block_time.map(|timestamp| generated::UnixTimestamp { timestamp }),
|
||||
block_height: block_height.map(|block_height| generated::BlockHeight { block_height }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ConfirmedBlock> for generated::ConfirmedBlock {
|
||||
fn from(confirmed_block: ConfirmedBlock) -> Self {
|
||||
let ConfirmedBlock {
|
||||
@@ -135,7 +164,7 @@ impl From<ConfirmedBlock> for generated::ConfirmedBlock {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<generated::ConfirmedBlock> for ConfirmedBlock {
|
||||
impl TryFrom<generated::ConfirmedBlock> for VersionedConfirmedBlock {
|
||||
type Error = bincode::Error;
|
||||
fn try_from(
|
||||
confirmed_block: generated::ConfirmedBlock,
|
||||
@@ -157,7 +186,7 @@ impl TryFrom<generated::ConfirmedBlock> for ConfirmedBlock {
|
||||
transactions: transactions
|
||||
.into_iter()
|
||||
.map(|tx| tx.try_into())
|
||||
.collect::<std::result::Result<Vec<TransactionWithStatusMeta>, Self::Error>>()?,
|
||||
.collect::<std::result::Result<Vec<_>, Self::Error>>()?,
|
||||
rewards: rewards.into_iter().map(|r| r.into()).collect(),
|
||||
block_time: block_time.map(|generated::UnixTimestamp { timestamp }| timestamp),
|
||||
block_height: block_height.map(|generated::BlockHeight { block_height }| block_height),
|
||||
@@ -175,7 +204,17 @@ impl From<TransactionWithStatusMeta> for generated::ConfirmedTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<generated::ConfirmedTransaction> for TransactionWithStatusMeta {
|
||||
impl From<VersionedTransactionWithStatusMeta> for generated::ConfirmedTransaction {
|
||||
fn from(value: VersionedTransactionWithStatusMeta) -> Self {
|
||||
let meta = value.meta.map(|meta| meta.into());
|
||||
Self {
|
||||
transaction: Some(value.transaction.into()),
|
||||
meta,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<generated::ConfirmedTransaction> for VersionedTransactionWithStatusMeta {
|
||||
type Error = bincode::Error;
|
||||
fn try_from(value: generated::ConfirmedTransaction) -> std::result::Result<Self, Self::Error> {
|
||||
let meta = value.meta.map(|meta| meta.try_into()).transpose()?;
|
||||
@@ -199,7 +238,20 @@ impl From<Transaction> for generated::Transaction {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<generated::Transaction> for Transaction {
|
||||
impl From<VersionedTransaction> for generated::Transaction {
|
||||
fn from(value: VersionedTransaction) -> Self {
|
||||
Self {
|
||||
signatures: value
|
||||
.signatures
|
||||
.into_iter()
|
||||
.map(|signature| <Signature as AsRef<[u8]>>::as_ref(&signature).into())
|
||||
.collect(),
|
||||
message: Some(value.message.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<generated::Transaction> for VersionedTransaction {
|
||||
fn from(value: generated::Transaction) -> Self {
|
||||
Self {
|
||||
signatures: value
|
||||
@@ -212,32 +264,86 @@ impl From<generated::Transaction> for Transaction {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Message> for generated::Message {
|
||||
fn from(value: Message) -> Self {
|
||||
impl From<LegacyMessage> for generated::Message {
|
||||
fn from(message: LegacyMessage) -> Self {
|
||||
Self {
|
||||
header: Some(value.header.into()),
|
||||
account_keys: value
|
||||
header: Some(message.header.into()),
|
||||
account_keys: message
|
||||
.account_keys
|
||||
.into_iter()
|
||||
.map(|key| <Pubkey as AsRef<[u8]>>::as_ref(&key).into())
|
||||
.iter()
|
||||
.map(|key| <Pubkey as AsRef<[u8]>>::as_ref(key).into())
|
||||
.collect(),
|
||||
recent_blockhash: value.recent_blockhash.to_bytes().into(),
|
||||
instructions: value.instructions.into_iter().map(|ix| ix.into()).collect(),
|
||||
recent_blockhash: message.recent_blockhash.to_bytes().into(),
|
||||
instructions: message
|
||||
.instructions
|
||||
.into_iter()
|
||||
.map(|ix| ix.into())
|
||||
.collect(),
|
||||
versioned: false,
|
||||
address_table_lookups: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<generated::Message> for Message {
|
||||
impl From<VersionedMessage> for generated::Message {
|
||||
fn from(message: VersionedMessage) -> Self {
|
||||
match message {
|
||||
VersionedMessage::Legacy(message) => Self::from(message),
|
||||
VersionedMessage::V0(message) => Self {
|
||||
header: Some(message.header.into()),
|
||||
account_keys: message
|
||||
.account_keys
|
||||
.iter()
|
||||
.map(|key| <Pubkey as AsRef<[u8]>>::as_ref(key).into())
|
||||
.collect(),
|
||||
recent_blockhash: message.recent_blockhash.to_bytes().into(),
|
||||
instructions: message
|
||||
.instructions
|
||||
.into_iter()
|
||||
.map(|ix| ix.into())
|
||||
.collect(),
|
||||
versioned: true,
|
||||
address_table_lookups: message
|
||||
.address_table_lookups
|
||||
.into_iter()
|
||||
.map(|lookup| lookup.into())
|
||||
.collect(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<generated::Message> for VersionedMessage {
|
||||
fn from(value: generated::Message) -> Self {
|
||||
Self {
|
||||
header: value.header.expect("header is required").into(),
|
||||
account_keys: value
|
||||
.account_keys
|
||||
.into_iter()
|
||||
.map(|key| Pubkey::new(&key))
|
||||
.collect(),
|
||||
recent_blockhash: Hash::new(&value.recent_blockhash),
|
||||
instructions: value.instructions.into_iter().map(|ix| ix.into()).collect(),
|
||||
let header = value.header.expect("header is required").into();
|
||||
let account_keys = value
|
||||
.account_keys
|
||||
.into_iter()
|
||||
.map(|key| Pubkey::new(&key))
|
||||
.collect();
|
||||
let recent_blockhash = Hash::new(&value.recent_blockhash);
|
||||
let instructions = value.instructions.into_iter().map(|ix| ix.into()).collect();
|
||||
let address_table_lookups = value
|
||||
.address_table_lookups
|
||||
.into_iter()
|
||||
.map(|lookup| lookup.into())
|
||||
.collect();
|
||||
|
||||
if !value.versioned {
|
||||
Self::Legacy(LegacyMessage {
|
||||
header,
|
||||
account_keys,
|
||||
recent_blockhash,
|
||||
instructions,
|
||||
})
|
||||
} else {
|
||||
Self::V0(v0::Message {
|
||||
header,
|
||||
account_keys,
|
||||
recent_blockhash,
|
||||
instructions,
|
||||
address_table_lookups,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,6 +380,7 @@ impl From<TransactionStatusMeta> for generated::TransactionStatusMeta {
|
||||
pre_token_balances,
|
||||
post_token_balances,
|
||||
rewards,
|
||||
loaded_addresses,
|
||||
} = value;
|
||||
let err = match status {
|
||||
Ok(()) => None,
|
||||
@@ -304,6 +411,16 @@ impl From<TransactionStatusMeta> for generated::TransactionStatusMeta {
|
||||
.into_iter()
|
||||
.map(|reward| reward.into())
|
||||
.collect();
|
||||
let loaded_writable_addresses = loaded_addresses
|
||||
.writable
|
||||
.into_iter()
|
||||
.map(|key| <Pubkey as AsRef<[u8]>>::as_ref(&key).into())
|
||||
.collect();
|
||||
let loaded_readonly_addresses = loaded_addresses
|
||||
.readonly
|
||||
.into_iter()
|
||||
.map(|key| <Pubkey as AsRef<[u8]>>::as_ref(&key).into())
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
err,
|
||||
@@ -317,6 +434,8 @@ impl From<TransactionStatusMeta> for generated::TransactionStatusMeta {
|
||||
pre_token_balances,
|
||||
post_token_balances,
|
||||
rewards,
|
||||
loaded_writable_addresses,
|
||||
loaded_readonly_addresses,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,6 +463,8 @@ impl TryFrom<generated::TransactionStatusMeta> for TransactionStatusMeta {
|
||||
pre_token_balances,
|
||||
post_token_balances,
|
||||
rewards,
|
||||
loaded_writable_addresses,
|
||||
loaded_readonly_addresses,
|
||||
} = value;
|
||||
let status = match &err {
|
||||
None => Ok(()),
|
||||
@@ -377,6 +498,16 @@ impl TryFrom<generated::TransactionStatusMeta> for TransactionStatusMeta {
|
||||
.collect(),
|
||||
);
|
||||
let rewards = Some(rewards.into_iter().map(|reward| reward.into()).collect());
|
||||
let loaded_addresses = LoadedAddresses {
|
||||
writable: loaded_writable_addresses
|
||||
.into_iter()
|
||||
.map(|key| Pubkey::new(&key))
|
||||
.collect(),
|
||||
readonly: loaded_readonly_addresses
|
||||
.into_iter()
|
||||
.map(|key| Pubkey::new(&key))
|
||||
.collect(),
|
||||
};
|
||||
Ok(Self {
|
||||
status,
|
||||
fee,
|
||||
@@ -387,6 +518,7 @@ impl TryFrom<generated::TransactionStatusMeta> for TransactionStatusMeta {
|
||||
pre_token_balances,
|
||||
post_token_balances,
|
||||
rewards,
|
||||
loaded_addresses,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -453,6 +585,26 @@ impl From<generated::TokenBalance> for TransactionTokenBalance {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MessageAddressTableLookup> for generated::MessageAddressTableLookup {
|
||||
fn from(lookup: MessageAddressTableLookup) -> Self {
|
||||
Self {
|
||||
account_key: <Pubkey as AsRef<[u8]>>::as_ref(&lookup.account_key).into(),
|
||||
writable_indexes: lookup.writable_indexes,
|
||||
readonly_indexes: lookup.readonly_indexes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<generated::MessageAddressTableLookup> for MessageAddressTableLookup {
|
||||
fn from(value: generated::MessageAddressTableLookup) -> Self {
|
||||
Self {
|
||||
account_key: Pubkey::new(&value.account_key),
|
||||
writable_indexes: value.writable_indexes,
|
||||
readonly_indexes: value.readonly_indexes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CompiledInstruction> for generated::CompiledInstruction {
|
||||
fn from(value: CompiledInstruction) -> Self {
|
||||
Self {
|
||||
|
@@ -4,7 +4,9 @@ use {
|
||||
parse_token::{real_number_string_trimmed, UiTokenAmount},
|
||||
StringAmount,
|
||||
},
|
||||
solana_sdk::{deserialize_utils::default_on_eof, transaction::Result},
|
||||
solana_sdk::{
|
||||
deserialize_utils::default_on_eof, message::v0::LoadedAddresses, transaction::Result,
|
||||
},
|
||||
solana_transaction_status::{
|
||||
InnerInstructions, Reward, RewardType, TransactionStatusMeta, TransactionTokenBalance,
|
||||
},
|
||||
@@ -193,12 +195,14 @@ impl From<StoredTransactionStatusMeta> for TransactionStatusMeta {
|
||||
.map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
|
||||
rewards: rewards
|
||||
.map(|rewards| rewards.into_iter().map(|reward| reward.into()).collect()),
|
||||
loaded_addresses: LoadedAddresses::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionStatusMeta> for StoredTransactionStatusMeta {
|
||||
fn from(value: TransactionStatusMeta) -> Self {
|
||||
impl TryFrom<TransactionStatusMeta> for StoredTransactionStatusMeta {
|
||||
type Error = bincode::Error;
|
||||
fn try_from(value: TransactionStatusMeta) -> std::result::Result<Self, Self::Error> {
|
||||
let TransactionStatusMeta {
|
||||
status,
|
||||
fee,
|
||||
@@ -209,8 +213,18 @@ impl From<TransactionStatusMeta> for StoredTransactionStatusMeta {
|
||||
pre_token_balances,
|
||||
post_token_balances,
|
||||
rewards,
|
||||
loaded_addresses,
|
||||
} = value;
|
||||
Self {
|
||||
|
||||
if !loaded_addresses.is_empty() {
|
||||
// Deprecated bincode serialized status metadata doesn't support
|
||||
// loaded addresses.
|
||||
return Err(
|
||||
bincode::ErrorKind::Custom("Bincode serialization is deprecated".into()).into(),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
status,
|
||||
fee,
|
||||
pre_balances,
|
||||
@@ -223,6 +237,6 @@ impl From<TransactionStatusMeta> for StoredTransactionStatusMeta {
|
||||
.map(|balances| balances.into_iter().map(|balance| balance.into()).collect()),
|
||||
rewards: rewards
|
||||
.map(|rewards| rewards.into_iter().map(|reward| reward.into()).collect()),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user