solana_runtime_transaction/
runtime_transaction.rs

1//! RuntimeTransaction is `runtime` facing representation of transaction, while
2//! solana_transaction::sanitized::SanitizedTransaction is client facing representation.
3//!
4//! It has two states:
5//! 1. Statically Loaded: after receiving `packet` from sigverify and deserializing
6//!    it into `solana_transaction::versioned::VersionedTransaction`, then sanitizing into
7//!    `solana_transaction::versioned::sanitized::SanitizedVersionedTransaction`, which can be wrapped into
8//!    `RuntimeTransaction` with static transaction metadata extracted.
9//! 2. Dynamically Loaded: after successfully loaded account addresses from onchain
10//!    ALT, RuntimeTransaction<SanitizedMessage> transits into Dynamically Loaded state,
11//!    with its dynamic metadata loaded.
12use {
13    crate::transaction_meta::{DynamicMeta, StaticMeta, TransactionMeta},
14    core::ops::Deref,
15    solana_compute_budget_instruction::compute_budget_instruction_details::*,
16    solana_hash::Hash,
17    solana_message::{AccountKeys, TransactionSignatureDetails},
18    solana_pubkey::Pubkey,
19    solana_signature::Signature,
20    solana_svm_transaction::{
21        instruction::SVMInstruction, message_address_table_lookup::SVMMessageAddressTableLookup,
22        svm_message::SVMMessage, svm_transaction::SVMTransaction,
23    },
24};
25
26mod sdk_transactions;
27mod transaction_view;
28
29#[cfg_attr(feature = "dev-context-only-utils", derive(Clone))]
30#[derive(Debug)]
31pub struct RuntimeTransaction<T> {
32    transaction: T,
33    // transaction meta is a collection of fields, it is updated
34    // during message state transition
35    meta: TransactionMeta,
36}
37
38impl<T> StaticMeta for RuntimeTransaction<T> {
39    fn message_hash(&self) -> &Hash {
40        &self.meta.message_hash
41    }
42    fn is_simple_vote_transaction(&self) -> bool {
43        self.meta.is_simple_vote_transaction
44    }
45    fn signature_details(&self) -> &TransactionSignatureDetails {
46        &self.meta.signature_details
47    }
48    fn compute_budget_instruction_details(&self) -> &ComputeBudgetInstructionDetails {
49        &self.meta.compute_budget_instruction_details
50    }
51}
52
53impl<T: SVMMessage> DynamicMeta for RuntimeTransaction<T> {}
54
55impl<T> Deref for RuntimeTransaction<T> {
56    type Target = T;
57
58    fn deref(&self) -> &Self::Target {
59        &self.transaction
60    }
61}
62
63impl<T: SVMMessage> SVMMessage for RuntimeTransaction<T> {
64    fn num_transaction_signatures(&self) -> u64 {
65        self.transaction.num_transaction_signatures()
66    }
67    // override to access from the cached meta instead of re-calculating
68    fn num_ed25519_signatures(&self) -> u64 {
69        self.meta
70            .signature_details
71            .num_ed25519_instruction_signatures()
72    }
73    // override to access from the cached meta instead of re-calculating
74    fn num_secp256k1_signatures(&self) -> u64 {
75        self.meta
76            .signature_details
77            .num_secp256k1_instruction_signatures()
78    }
79    // override to access form the cached meta instead of re-calculating
80    fn num_secp256r1_signatures(&self) -> u64 {
81        self.meta
82            .signature_details
83            .num_secp256r1_instruction_signatures()
84    }
85
86    fn num_write_locks(&self) -> u64 {
87        self.transaction.num_write_locks()
88    }
89
90    fn recent_blockhash(&self) -> &Hash {
91        self.transaction.recent_blockhash()
92    }
93
94    fn num_instructions(&self) -> usize {
95        self.transaction.num_instructions()
96    }
97
98    fn instructions_iter(&self) -> impl Iterator<Item = SVMInstruction> {
99        self.transaction.instructions_iter()
100    }
101
102    fn program_instructions_iter(&self) -> impl Iterator<Item = (&Pubkey, SVMInstruction)> + Clone {
103        self.transaction.program_instructions_iter()
104    }
105
106    fn account_keys(&self) -> AccountKeys {
107        self.transaction.account_keys()
108    }
109
110    fn fee_payer(&self) -> &Pubkey {
111        self.transaction.fee_payer()
112    }
113
114    fn is_writable(&self, index: usize) -> bool {
115        self.transaction.is_writable(index)
116    }
117
118    fn is_signer(&self, index: usize) -> bool {
119        self.transaction.is_signer(index)
120    }
121
122    fn is_invoked(&self, key_index: usize) -> bool {
123        self.transaction.is_invoked(key_index)
124    }
125
126    fn num_lookup_tables(&self) -> usize {
127        self.transaction.num_lookup_tables()
128    }
129
130    fn message_address_table_lookups(&self) -> impl Iterator<Item = SVMMessageAddressTableLookup> {
131        self.transaction.message_address_table_lookups()
132    }
133}
134
135impl<T: SVMTransaction> SVMTransaction for RuntimeTransaction<T> {
136    fn signature(&self) -> &Signature {
137        self.transaction.signature()
138    }
139
140    fn signatures(&self) -> &[Signature] {
141        self.transaction.signatures()
142    }
143}