Store address table lookups in blockstore and bigtable (#22402)

This commit is contained in:
Justin Starry
2022-01-14 15:24:41 +08:00
committed by GitHub
parent 4c577d7f8c
commit f804ccdece
28 changed files with 836 additions and 199 deletions

View File

@@ -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 {

View File

@@ -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()),
}
})
}
}