From ae9be65c323bb7ceba998d6a2d9ce805e4fccc33 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Wed, 29 Nov 2023 19:07:39 +0000 Subject: [PATCH 1/4] generalize message type for runtime-transaction --- .../src/runtime_transaction.rs | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/runtime-transaction/src/runtime_transaction.rs b/runtime-transaction/src/runtime_transaction.rs index ef8bbbe1e706ff..0ffa46645a8b25 100644 --- a/runtime-transaction/src/runtime_transaction.rs +++ b/runtime-transaction/src/runtime_transaction.rs @@ -21,15 +21,15 @@ use { }; #[derive(Debug, Clone, Eq, PartialEq)] -pub struct RuntimeTransactionStatic { +pub struct RuntimeTransaction { signatures: Vec, - message: SanitizedVersionedMessage, + message: M, // transaction meta is a collection of fields, it is updated // during message state transition meta: TransactionMeta, } -impl StaticMeta for RuntimeTransactionStatic { +impl StaticMeta for RuntimeTransaction { fn message_hash(&self) -> &Hash { &self.meta.message_hash } @@ -38,7 +38,9 @@ impl StaticMeta for RuntimeTransactionStatic { } } -impl RuntimeTransactionStatic { +impl DynamicMeta for RuntimeTransaction {} + +impl RuntimeTransaction { pub fn try_from( sanitized_versioned_tx: SanitizedVersionedTransaction, message_hash: Option, @@ -62,31 +64,9 @@ impl RuntimeTransactionStatic { } } -/// Statically Loaded transaction can transit to Dynamically Loaded with supplied -/// address_loader, to load accounts from on-chain ALT, then resolve dynamic metadata -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct RuntimeTransactionDynamic { - signatures: Vec, - message: SanitizedMessage, - // transaction meta is a collection of fields, it is updated - // during message state transition - meta: TransactionMeta, -} - -impl DynamicMeta for RuntimeTransactionDynamic {} - -impl StaticMeta for RuntimeTransactionDynamic { - fn message_hash(&self) -> &Hash { - &self.meta.message_hash - } - fn is_simple_vote_tx(&self) -> bool { - self.meta.is_simple_vote_tx - } -} - -impl RuntimeTransactionDynamic { +impl RuntimeTransaction { pub fn try_from( - statically_loaded_runtime_tx: RuntimeTransactionStatic, + statically_loaded_runtime_tx: RuntimeTransaction, address_loader: impl AddressLoader, ) -> Result { let mut tx = Self { @@ -119,7 +99,7 @@ mod tests { compute_budget::ComputeBudgetInstruction, message::Message, signer::{keypair::Keypair, Signer}, - transaction::{Transaction, VersionedTransaction}, + transaction::{SimpleAddressLoader, Transaction, VersionedTransaction}, }, }; @@ -161,7 +141,7 @@ mod tests { hash: Option, is_simple_vote: Option, ) -> TransactionMeta { - RuntimeTransactionStatic::try_from(svt, hash, is_simple_vote) + RuntimeTransaction::::try_from(svt, hash, is_simple_vote) .unwrap() .meta } @@ -215,4 +195,24 @@ mod tests { ) ); } + + #[test] + fn test_advance_transaction_type() { + let hash = Hash::new_unique(); + let compute_unit_price = 999; + + let statically_loaded_transaction = + RuntimeTransaction::::try_from( + non_vote_sanitized_versioned_transaction(compute_unit_price), + Some(hash), + None, + ) + .unwrap(); + + let dynamically_loaded_transaction = RuntimeTransaction::::try_from( + statically_loaded_transaction, + SimpleAddressLoader::Disabled, + ); + assert!(dynamically_loaded_transaction.is_ok()); + } } From 17223b861baf125b25014cd548b9fb73710e8877 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Tue, 5 Dec 2023 17:03:55 +0000 Subject: [PATCH 2/4] specialize meta traits implementation --- .../src/runtime_transaction.rs | 30 +++++++++++++++++-- runtime-transaction/src/transaction_meta.rs | 4 ++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/runtime-transaction/src/runtime_transaction.rs b/runtime-transaction/src/runtime_transaction.rs index 0ffa46645a8b25..78d0f341c521da 100644 --- a/runtime-transaction/src/runtime_transaction.rs +++ b/runtime-transaction/src/runtime_transaction.rs @@ -29,7 +29,7 @@ pub struct RuntimeTransaction { meta: TransactionMeta, } -impl StaticMeta for RuntimeTransaction { +impl StaticMeta for RuntimeTransaction { fn message_hash(&self) -> &Hash { &self.meta.message_hash } @@ -38,7 +38,20 @@ impl StaticMeta for RuntimeTransaction { } } -impl DynamicMeta for RuntimeTransaction {} +impl StaticMeta for RuntimeTransaction { + fn message_hash(&self) -> &Hash { + &self.meta.message_hash + } + fn is_simple_vote_tx(&self) -> bool { + self.meta.is_simple_vote_tx + } +} + +impl DynamicMeta for RuntimeTransaction { + fn i_am_dynamic(&self) -> bool { + true + } +} impl RuntimeTransaction { pub fn try_from( @@ -209,10 +222,21 @@ mod tests { ) .unwrap(); + assert_eq!(hash, *statically_loaded_transaction.message_hash()); + assert!(!statically_loaded_transaction.is_simple_vote_tx()); + // DynamicMeta::i_am_dynamic() is not implemented for RuntimeTransaction. + // Below line won't compile + // assert_eq!(false, statically_loaded_transaction.i_am_dynamic()); + let dynamically_loaded_transaction = RuntimeTransaction::::try_from( statically_loaded_transaction, SimpleAddressLoader::Disabled, ); - assert!(dynamically_loaded_transaction.is_ok()); + let dynamically_loaded_transaction = + dynamically_loaded_transaction.expect("created from statically loaded tx"); + + assert_eq!(hash, *dynamically_loaded_transaction.message_hash()); + assert!(!dynamically_loaded_transaction.is_simple_vote_tx()); + assert!(dynamically_loaded_transaction.i_am_dynamic()); } } diff --git a/runtime-transaction/src/transaction_meta.rs b/runtime-transaction/src/transaction_meta.rs index 2eec699f291e36..6ae1f5c49419f8 100644 --- a/runtime-transaction/src/transaction_meta.rs +++ b/runtime-transaction/src/transaction_meta.rs @@ -25,7 +25,9 @@ pub trait StaticMeta { /// have both meta data populated and available. /// Dynamic metadata available after accounts addresses are loaded from /// on-chain ALT, examples are: transaction usage costs, nonce account. -pub trait DynamicMeta: StaticMeta {} +pub trait DynamicMeta: StaticMeta { + fn i_am_dynamic(&self) -> bool; +} #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct TransactionMeta { From df369e9913aeb736cd6b7913d4363a0731b83401 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Tue, 5 Dec 2023 21:11:56 +0000 Subject: [PATCH 3/4] use trait bounds --- .../src/runtime_transaction.rs | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/runtime-transaction/src/runtime_transaction.rs b/runtime-transaction/src/runtime_transaction.rs index 78d0f341c521da..48127f7b0ecc64 100644 --- a/runtime-transaction/src/runtime_transaction.rs +++ b/runtime-transaction/src/runtime_transaction.rs @@ -29,7 +29,19 @@ pub struct RuntimeTransaction { meta: TransactionMeta, } -impl StaticMeta for RuntimeTransaction { +// These traits gate access to static and dynamic metadata +// so that only transactions with supporting message types +// can access them. +trait StaticMetaAccess {} +trait DynamicMetaAccess: StaticMetaAccess {} + +// Implement the gate traits for the message types that should +// have access to the static and dynamic metadata. +impl StaticMetaAccess for SanitizedVersionedMessage {} +impl StaticMetaAccess for SanitizedMessage {} +impl DynamicMetaAccess for SanitizedMessage {} + +impl StaticMeta for RuntimeTransaction { fn message_hash(&self) -> &Hash { &self.meta.message_hash } @@ -38,16 +50,7 @@ impl StaticMeta for RuntimeTransaction { } } -impl StaticMeta for RuntimeTransaction { - fn message_hash(&self) -> &Hash { - &self.meta.message_hash - } - fn is_simple_vote_tx(&self) -> bool { - self.meta.is_simple_vote_tx - } -} - -impl DynamicMeta for RuntimeTransaction { +impl DynamicMeta for RuntimeTransaction { fn i_am_dynamic(&self) -> bool { true } From cbd3193f03bf20d36142082c0f4e306f7bf397d5 Mon Sep 17 00:00:00 2001 From: Tao Zhu Date: Tue, 5 Dec 2023 22:53:06 +0000 Subject: [PATCH 4/4] cleanup --- runtime-transaction/src/runtime_transaction.rs | 18 +++++------------- runtime-transaction/src/transaction_meta.rs | 4 +--- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/runtime-transaction/src/runtime_transaction.rs b/runtime-transaction/src/runtime_transaction.rs index 48127f7b0ecc64..df6acbccdd2905 100644 --- a/runtime-transaction/src/runtime_transaction.rs +++ b/runtime-transaction/src/runtime_transaction.rs @@ -4,11 +4,11 @@ //! It has two states: //! 1. Statically Loaded: after receiving `packet` from sigverify and deserializing //! it into `solana_sdk::VersionedTransaction`, then sanitizing into -//! `solana_sdk::SanitizedVersionedTransaction`, `RuntimeTransactionStatic` -//! can be created from it with static transaction metadata extracted. +//! `solana_sdk::SanitizedVersionedTransaction`, which can be wrapped into +//! `RuntimeTransaction` with static transaction metadata extracted. //! 2. Dynamically Loaded: after successfully loaded account addresses from onchain -//! ALT, RuntimeTransaction transits into Dynamically Loaded state, with -//! its dynamic metadata loaded. +//! ALT, RuntimeTransaction transits into Dynamically Loaded state, +//! with its dynamic metadata loaded. use { crate::transaction_meta::{DynamicMeta, StaticMeta, TransactionMeta}, solana_sdk::{ @@ -50,11 +50,7 @@ impl StaticMeta for RuntimeTransaction { } } -impl DynamicMeta for RuntimeTransaction { - fn i_am_dynamic(&self) -> bool { - true - } -} +impl DynamicMeta for RuntimeTransaction {} impl RuntimeTransaction { pub fn try_from( @@ -227,9 +223,6 @@ mod tests { assert_eq!(hash, *statically_loaded_transaction.message_hash()); assert!(!statically_loaded_transaction.is_simple_vote_tx()); - // DynamicMeta::i_am_dynamic() is not implemented for RuntimeTransaction. - // Below line won't compile - // assert_eq!(false, statically_loaded_transaction.i_am_dynamic()); let dynamically_loaded_transaction = RuntimeTransaction::::try_from( statically_loaded_transaction, @@ -240,6 +233,5 @@ mod tests { assert_eq!(hash, *dynamically_loaded_transaction.message_hash()); assert!(!dynamically_loaded_transaction.is_simple_vote_tx()); - assert!(dynamically_loaded_transaction.i_am_dynamic()); } } diff --git a/runtime-transaction/src/transaction_meta.rs b/runtime-transaction/src/transaction_meta.rs index 6ae1f5c49419f8..2eec699f291e36 100644 --- a/runtime-transaction/src/transaction_meta.rs +++ b/runtime-transaction/src/transaction_meta.rs @@ -25,9 +25,7 @@ pub trait StaticMeta { /// have both meta data populated and available. /// Dynamic metadata available after accounts addresses are loaded from /// on-chain ALT, examples are: transaction usage costs, nonce account. -pub trait DynamicMeta: StaticMeta { - fn i_am_dynamic(&self) -> bool; -} +pub trait DynamicMeta: StaticMeta {} #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct TransactionMeta {