Enforce tx metadata upload with static types (#23028)
This commit is contained in:
@ -388,7 +388,7 @@ pub struct Reward {
|
||||
|
||||
pub type Rewards = Vec<Reward>;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ConfirmedBlock {
|
||||
pub previous_blockhash: String,
|
||||
pub blockhash: String,
|
||||
@ -399,7 +399,9 @@ pub struct ConfirmedBlock {
|
||||
pub block_height: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
// Confirmed block with type guarantees that transaction metadata
|
||||
// is always present. Used for uploading to BigTable.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct VersionedConfirmedBlock {
|
||||
pub previous_blockhash: String,
|
||||
pub blockhash: String,
|
||||
@ -410,11 +412,23 @@ pub struct VersionedConfirmedBlock {
|
||||
pub block_height: Option<u64>,
|
||||
}
|
||||
|
||||
impl VersionedConfirmedBlock {
|
||||
// Confirmed block which only supports legacy transactions. Used
|
||||
// until migration to versioned transactions is completed.
|
||||
pub struct LegacyConfirmedBlock {
|
||||
pub previous_blockhash: String,
|
||||
pub blockhash: String,
|
||||
pub parent_slot: Slot,
|
||||
pub transactions: Vec<LegacyTransactionWithStatusMeta>,
|
||||
pub rewards: Rewards,
|
||||
pub block_time: Option<UnixTimestamp>,
|
||||
pub block_height: Option<u64>,
|
||||
}
|
||||
|
||||
impl ConfirmedBlock {
|
||||
/// Downgrades a versioned block into a legacy block type
|
||||
/// if it only contains legacy transactions
|
||||
pub fn into_legacy_block(self) -> Option<ConfirmedBlock> {
|
||||
Some(ConfirmedBlock {
|
||||
pub fn into_legacy_block(self) -> Option<LegacyConfirmedBlock> {
|
||||
Some(LegacyConfirmedBlock {
|
||||
previous_blockhash: self.previous_blockhash,
|
||||
blockhash: self.blockhash,
|
||||
parent_slot: self.parent_slot,
|
||||
@ -430,13 +444,17 @@ impl VersionedConfirmedBlock {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ConfirmedBlock> for VersionedConfirmedBlock {
|
||||
fn from(block: ConfirmedBlock) -> Self {
|
||||
VersionedConfirmedBlock {
|
||||
impl From<VersionedConfirmedBlock> for ConfirmedBlock {
|
||||
fn from(block: VersionedConfirmedBlock) -> Self {
|
||||
Self {
|
||||
previous_blockhash: block.previous_blockhash,
|
||||
blockhash: block.blockhash,
|
||||
parent_slot: block.parent_slot,
|
||||
transactions: block.transactions.into_iter().map(|tx| tx.into()).collect(),
|
||||
transactions: block
|
||||
.transactions
|
||||
.into_iter()
|
||||
.map(TransactionWithStatusMeta::Complete)
|
||||
.collect(),
|
||||
rewards: block.rewards,
|
||||
block_time: block.block_time,
|
||||
block_height: block.block_height,
|
||||
@ -444,7 +462,7 @@ impl From<ConfirmedBlock> for VersionedConfirmedBlock {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for ConfirmedBlock {
|
||||
impl Encodable for LegacyConfirmedBlock {
|
||||
type Encoded = EncodedConfirmedBlock;
|
||||
fn encode(self, encoding: UiTransactionEncoding) -> Self::Encoded {
|
||||
Self::Encoded {
|
||||
@ -463,7 +481,7 @@ impl Encodable for ConfirmedBlock {
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfirmedBlock {
|
||||
impl LegacyConfirmedBlock {
|
||||
pub fn configure(
|
||||
self,
|
||||
encoding: UiTransactionEncoding,
|
||||
@ -565,44 +583,68 @@ impl From<EncodedConfirmedBlock> for UiConfirmedBlock {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum TransactionWithStatusMeta {
|
||||
// Very old transactions may be missing metadata
|
||||
MissingMetadata(Transaction),
|
||||
// Versioned stored transaction always have metadata
|
||||
Complete(VersionedTransactionWithStatusMeta),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct VersionedTransactionWithStatusMeta {
|
||||
pub transaction: VersionedTransaction,
|
||||
pub meta: TransactionStatusMeta,
|
||||
}
|
||||
|
||||
pub struct LegacyTransactionWithStatusMeta {
|
||||
pub transaction: Transaction,
|
||||
pub meta: Option<TransactionStatusMeta>,
|
||||
}
|
||||
|
||||
impl TransactionWithStatusMeta {
|
||||
pub fn transaction_signature(&self) -> &Signature {
|
||||
match self {
|
||||
Self::MissingMetadata(transaction) => &transaction.signatures[0],
|
||||
Self::Complete(VersionedTransactionWithStatusMeta { transaction, .. }) => {
|
||||
&transaction.signatures[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_legacy_transaction_with_meta(self) -> Option<LegacyTransactionWithStatusMeta> {
|
||||
match self {
|
||||
TransactionWithStatusMeta::MissingMetadata(transaction) => {
|
||||
Some(LegacyTransactionWithStatusMeta {
|
||||
transaction,
|
||||
meta: None,
|
||||
})
|
||||
}
|
||||
TransactionWithStatusMeta::Complete(tx_with_meta) => {
|
||||
tx_with_meta.into_legacy_transaction_with_meta()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VersionedTransactionWithStatusMeta {
|
||||
pub fn account_keys(&self) -> AccountKeys {
|
||||
AccountKeys::new(
|
||||
self.transaction.message.static_account_keys(),
|
||||
self.meta.as_ref().map(|meta| &meta.loaded_addresses),
|
||||
Some(&self.meta.loaded_addresses),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn into_legacy_transaction_with_meta(self) -> Option<TransactionWithStatusMeta> {
|
||||
Some(TransactionWithStatusMeta {
|
||||
pub fn into_legacy_transaction_with_meta(self) -> Option<LegacyTransactionWithStatusMeta> {
|
||||
Some(LegacyTransactionWithStatusMeta {
|
||||
transaction: self.transaction.into_legacy_transaction()?,
|
||||
meta: self.meta,
|
||||
meta: Some(self.meta),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionWithStatusMeta> for VersionedTransactionWithStatusMeta {
|
||||
fn from(tx_with_meta: TransactionWithStatusMeta) -> Self {
|
||||
Self {
|
||||
transaction: tx_with_meta.transaction.into(),
|
||||
meta: tx_with_meta.meta,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct TransactionWithStatusMeta {
|
||||
pub transaction: Transaction,
|
||||
pub meta: Option<TransactionStatusMeta>,
|
||||
}
|
||||
|
||||
impl Encodable for TransactionWithStatusMeta {
|
||||
impl Encodable for LegacyTransactionWithStatusMeta {
|
||||
type Encoded = EncodedTransactionWithStatusMeta;
|
||||
fn encode(self, encoding: UiTransactionEncoding) -> Self::Encoded {
|
||||
Self::Encoded {
|
||||
@ -627,21 +669,10 @@ pub struct EncodedTransactionWithStatusMeta {
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ConfirmedTransactionWithStatusMeta {
|
||||
pub slot: Slot,
|
||||
pub transaction: TransactionWithStatusMeta,
|
||||
pub tx_with_meta: TransactionWithStatusMeta,
|
||||
pub block_time: Option<UnixTimestamp>,
|
||||
}
|
||||
|
||||
impl Encodable for ConfirmedTransactionWithStatusMeta {
|
||||
type Encoded = EncodedConfirmedTransactionWithStatusMeta;
|
||||
fn encode(self, encoding: UiTransactionEncoding) -> Self::Encoded {
|
||||
Self::Encoded {
|
||||
slot: self.slot,
|
||||
transaction: self.transaction.encode(encoding),
|
||||
block_time: self.block_time,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct VersionedConfirmedTransactionWithStatusMeta {
|
||||
pub slot: Slot,
|
||||
@ -649,15 +680,31 @@ pub struct VersionedConfirmedTransactionWithStatusMeta {
|
||||
pub block_time: Option<UnixTimestamp>,
|
||||
}
|
||||
|
||||
impl VersionedConfirmedTransactionWithStatusMeta {
|
||||
pub struct LegacyConfirmedTransactionWithStatusMeta {
|
||||
pub slot: Slot,
|
||||
pub tx_with_meta: LegacyTransactionWithStatusMeta,
|
||||
pub block_time: Option<UnixTimestamp>,
|
||||
}
|
||||
|
||||
impl Encodable for LegacyConfirmedTransactionWithStatusMeta {
|
||||
type Encoded = EncodedConfirmedTransactionWithStatusMeta;
|
||||
fn encode(self, encoding: UiTransactionEncoding) -> Self::Encoded {
|
||||
Self::Encoded {
|
||||
slot: self.slot,
|
||||
transaction: self.tx_with_meta.encode(encoding),
|
||||
block_time: self.block_time,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfirmedTransactionWithStatusMeta {
|
||||
/// Downgrades a versioned confirmed transaction into a legacy
|
||||
/// confirmed transaction if it contains a legacy transaction.
|
||||
pub fn into_legacy_confirmed_transaction(self) -> Option<ConfirmedTransactionWithStatusMeta> {
|
||||
Some(ConfirmedTransactionWithStatusMeta {
|
||||
transaction: TransactionWithStatusMeta {
|
||||
transaction: self.tx_with_meta.transaction.into_legacy_transaction()?,
|
||||
meta: self.tx_with_meta.meta,
|
||||
},
|
||||
pub fn into_legacy_confirmed_transaction(
|
||||
self,
|
||||
) -> Option<LegacyConfirmedTransactionWithStatusMeta> {
|
||||
Some(LegacyConfirmedTransactionWithStatusMeta {
|
||||
tx_with_meta: self.tx_with_meta.into_legacy_transaction_with_meta()?,
|
||||
block_time: self.block_time,
|
||||
slot: self.slot,
|
||||
})
|
||||
|
Reference in New Issue
Block a user