add requested limits to static meta (#34361)
* add requested limits to static meta * rebase to catch up on compue_budget_processor no longer needs feature_set; update requested limits as flat fields of static meta without expiry
This commit is contained in:
parent
86c88d7ff6
commit
310c7a4f9d
|
@ -11,6 +11,9 @@
|
|||
//! with its dynamic metadata loaded.
|
||||
use {
|
||||
crate::transaction_meta::{DynamicMeta, StaticMeta, TransactionMeta},
|
||||
solana_program_runtime::compute_budget_processor::{
|
||||
process_compute_budget_instructions, ComputeBudgetLimits,
|
||||
},
|
||||
solana_sdk::{
|
||||
hash::Hash,
|
||||
message::{AddressLoader, SanitizedMessage, SanitizedVersionedMessage},
|
||||
|
@ -48,6 +51,15 @@ impl<M: StaticMetaAccess> StaticMeta for RuntimeTransaction<M> {
|
|||
fn is_simple_vote_tx(&self) -> bool {
|
||||
self.meta.is_simple_vote_tx
|
||||
}
|
||||
fn compute_unit_limit(&self) -> u32 {
|
||||
self.meta.compute_unit_limit
|
||||
}
|
||||
fn compute_unit_price(&self) -> u64 {
|
||||
self.meta.compute_unit_price
|
||||
}
|
||||
fn loaded_accounts_bytes(&self) -> u32 {
|
||||
self.meta.loaded_accounts_bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: DynamicMetaAccess> DynamicMeta for RuntimeTransaction<M> {}
|
||||
|
@ -65,9 +77,18 @@ impl RuntimeTransaction<SanitizedVersionedMessage> {
|
|||
);
|
||||
|
||||
let (signatures, message) = sanitized_versioned_tx.destruct();
|
||||
|
||||
meta.set_message_hash(message_hash.unwrap_or_else(|| message.message.hash()));
|
||||
|
||||
let ComputeBudgetLimits {
|
||||
compute_unit_limit,
|
||||
compute_unit_price,
|
||||
loaded_accounts_bytes,
|
||||
..
|
||||
} = process_compute_budget_instructions(message.program_instructions_iter())?;
|
||||
meta.set_compute_unit_limit(compute_unit_limit);
|
||||
meta.set_compute_unit_price(compute_unit_price);
|
||||
meta.set_loaded_accounts_bytes(loaded_accounts_bytes);
|
||||
|
||||
Ok(Self {
|
||||
signatures,
|
||||
message,
|
||||
|
@ -109,6 +130,7 @@ mod tests {
|
|||
},
|
||||
solana_sdk::{
|
||||
compute_budget::ComputeBudgetInstruction,
|
||||
instruction::Instruction,
|
||||
message::Message,
|
||||
signer::{keypair::Keypair, Signer},
|
||||
transaction::{SimpleAddressLoader, Transaction, VersionedTransaction},
|
||||
|
@ -131,91 +153,98 @@ mod tests {
|
|||
SanitizedVersionedTransaction::try_from(VersionedTransaction::from(vote_tx)).unwrap()
|
||||
}
|
||||
|
||||
fn non_vote_sanitized_versioned_transaction(
|
||||
compute_unit_price: u64,
|
||||
) -> SanitizedVersionedTransaction {
|
||||
let from_keypair = Keypair::new();
|
||||
let ixs = vec![
|
||||
system_instruction::transfer(
|
||||
fn non_vote_sanitized_versioned_transaction() -> SanitizedVersionedTransaction {
|
||||
TestTransaction::new().to_sanitized_versioned_transaction()
|
||||
}
|
||||
|
||||
// Simple transfer transaction for testing, it does not support vote instruction
|
||||
// because simple vote transaction will not request limits
|
||||
struct TestTransaction {
|
||||
from_keypair: Keypair,
|
||||
hash: Hash,
|
||||
instructions: Vec<Instruction>,
|
||||
}
|
||||
|
||||
impl TestTransaction {
|
||||
fn new() -> Self {
|
||||
let from_keypair = Keypair::new();
|
||||
let instructions = vec![system_instruction::transfer(
|
||||
&from_keypair.pubkey(),
|
||||
&solana_sdk::pubkey::new_rand(),
|
||||
1,
|
||||
),
|
||||
ComputeBudgetInstruction::set_compute_unit_price(compute_unit_price),
|
||||
];
|
||||
let message = Message::new(&ixs, Some(&from_keypair.pubkey()));
|
||||
let tx = Transaction::new(&[&from_keypair], message, Hash::new_unique());
|
||||
SanitizedVersionedTransaction::try_from(VersionedTransaction::from(tx)).unwrap()
|
||||
}
|
||||
)];
|
||||
TestTransaction {
|
||||
from_keypair,
|
||||
hash: Hash::new_unique(),
|
||||
instructions,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_transaction_meta(
|
||||
svt: SanitizedVersionedTransaction,
|
||||
hash: Option<Hash>,
|
||||
is_simple_vote: Option<bool>,
|
||||
) -> TransactionMeta {
|
||||
RuntimeTransaction::<SanitizedVersionedMessage>::try_from(svt, hash, is_simple_vote)
|
||||
.unwrap()
|
||||
.meta
|
||||
fn add_compute_unit_limit(&mut self, val: u32) -> &mut TestTransaction {
|
||||
self.instructions
|
||||
.push(ComputeBudgetInstruction::set_compute_unit_limit(val));
|
||||
self
|
||||
}
|
||||
|
||||
fn add_compute_unit_price(&mut self, val: u64) -> &mut TestTransaction {
|
||||
self.instructions
|
||||
.push(ComputeBudgetInstruction::set_compute_unit_price(val));
|
||||
self
|
||||
}
|
||||
|
||||
fn add_loaded_accounts_bytes(&mut self, val: u32) -> &mut TestTransaction {
|
||||
self.instructions
|
||||
.push(ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(val));
|
||||
self
|
||||
}
|
||||
|
||||
fn to_sanitized_versioned_transaction(&self) -> SanitizedVersionedTransaction {
|
||||
let message = Message::new(&self.instructions, Some(&self.from_keypair.pubkey()));
|
||||
let tx = Transaction::new(&[&self.from_keypair], message, self.hash);
|
||||
SanitizedVersionedTransaction::try_from(VersionedTransaction::from(tx)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_runtime_transaction_static() {
|
||||
let hash = Hash::new_unique();
|
||||
let compute_unit_price = 1_000;
|
||||
fn test_runtime_transaction_is_vote_meta() {
|
||||
fn get_is_simple_vote(
|
||||
svt: SanitizedVersionedTransaction,
|
||||
is_simple_vote: Option<bool>,
|
||||
) -> bool {
|
||||
RuntimeTransaction::<SanitizedVersionedMessage>::try_from(svt, None, is_simple_vote)
|
||||
.unwrap()
|
||||
.meta
|
||||
.is_simple_vote_tx
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
TransactionMeta {
|
||||
message_hash: hash,
|
||||
is_simple_vote_tx: false,
|
||||
},
|
||||
get_transaction_meta(
|
||||
non_vote_sanitized_versioned_transaction(compute_unit_price),
|
||||
Some(hash),
|
||||
None
|
||||
)
|
||||
);
|
||||
assert!(!get_is_simple_vote(
|
||||
non_vote_sanitized_versioned_transaction(),
|
||||
None
|
||||
));
|
||||
|
||||
assert_eq!(
|
||||
TransactionMeta {
|
||||
message_hash: hash,
|
||||
is_simple_vote_tx: true,
|
||||
},
|
||||
get_transaction_meta(
|
||||
non_vote_sanitized_versioned_transaction(compute_unit_price),
|
||||
Some(hash),
|
||||
Some(true), // override
|
||||
)
|
||||
);
|
||||
assert!(get_is_simple_vote(
|
||||
non_vote_sanitized_versioned_transaction(),
|
||||
Some(true), // override
|
||||
));
|
||||
|
||||
assert_eq!(
|
||||
TransactionMeta {
|
||||
message_hash: hash,
|
||||
is_simple_vote_tx: true,
|
||||
},
|
||||
get_transaction_meta(vote_sanitized_versioned_transaction(), Some(hash), None)
|
||||
);
|
||||
assert!(get_is_simple_vote(
|
||||
vote_sanitized_versioned_transaction(),
|
||||
None
|
||||
));
|
||||
|
||||
assert_eq!(
|
||||
TransactionMeta {
|
||||
message_hash: hash,
|
||||
is_simple_vote_tx: false,
|
||||
},
|
||||
get_transaction_meta(
|
||||
vote_sanitized_versioned_transaction(),
|
||||
Some(hash),
|
||||
Some(false), // override
|
||||
)
|
||||
);
|
||||
assert!(!get_is_simple_vote(
|
||||
vote_sanitized_versioned_transaction(),
|
||||
Some(false), // override
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_advance_transaction_type() {
|
||||
fn test_advancing_transaction_type() {
|
||||
let hash = Hash::new_unique();
|
||||
let compute_unit_price = 999;
|
||||
|
||||
let statically_loaded_transaction =
|
||||
RuntimeTransaction::<SanitizedVersionedMessage>::try_from(
|
||||
non_vote_sanitized_versioned_transaction(compute_unit_price),
|
||||
non_vote_sanitized_versioned_transaction(),
|
||||
Some(hash),
|
||||
None,
|
||||
)
|
||||
|
@ -234,4 +263,39 @@ mod tests {
|
|||
assert_eq!(hash, *dynamically_loaded_transaction.message_hash());
|
||||
assert!(!dynamically_loaded_transaction.is_simple_vote_tx());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_runtime_transaction_static_meta() {
|
||||
let hash = Hash::new_unique();
|
||||
let compute_unit_limit = 250_000;
|
||||
let compute_unit_price = 1_000;
|
||||
let loaded_accounts_bytes = 1_024;
|
||||
let mut test_transaction = TestTransaction::new();
|
||||
|
||||
let runtime_transaction_static = RuntimeTransaction::<SanitizedVersionedMessage>::try_from(
|
||||
test_transaction
|
||||
.add_compute_unit_limit(compute_unit_limit)
|
||||
.add_compute_unit_price(compute_unit_price)
|
||||
.add_loaded_accounts_bytes(loaded_accounts_bytes)
|
||||
.to_sanitized_versioned_transaction(),
|
||||
Some(hash),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&hash, runtime_transaction_static.message_hash());
|
||||
assert!(!runtime_transaction_static.is_simple_vote_tx());
|
||||
assert_eq!(
|
||||
compute_unit_limit,
|
||||
runtime_transaction_static.compute_unit_limit()
|
||||
);
|
||||
assert_eq!(
|
||||
compute_unit_price,
|
||||
runtime_transaction_static.compute_unit_price()
|
||||
);
|
||||
assert_eq!(
|
||||
loaded_accounts_bytes,
|
||||
runtime_transaction_static.loaded_accounts_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,13 @@
|
|||
use solana_sdk::hash::Hash;
|
||||
|
||||
/// metadata can be extracted statically from sanitized transaction,
|
||||
/// for example: message hash, simple-vote-tx flag, compute budget limits,
|
||||
/// for example: message hash, simple-vote-tx flag, limits set by instructions
|
||||
pub trait StaticMeta {
|
||||
fn message_hash(&self) -> &Hash;
|
||||
fn is_simple_vote_tx(&self) -> bool;
|
||||
fn compute_unit_limit(&self) -> u32;
|
||||
fn compute_unit_price(&self) -> u64;
|
||||
fn loaded_accounts_bytes(&self) -> u32;
|
||||
}
|
||||
|
||||
/// Statically loaded meta is a supertrait of Dynamically loaded meta, when
|
||||
|
@ -31,6 +34,9 @@ pub trait DynamicMeta: StaticMeta {}
|
|||
pub struct TransactionMeta {
|
||||
pub(crate) message_hash: Hash,
|
||||
pub(crate) is_simple_vote_tx: bool,
|
||||
pub(crate) compute_unit_limit: u32,
|
||||
pub(crate) compute_unit_price: u64,
|
||||
pub(crate) loaded_accounts_bytes: u32,
|
||||
}
|
||||
|
||||
impl TransactionMeta {
|
||||
|
@ -41,4 +47,16 @@ impl TransactionMeta {
|
|||
pub(crate) fn set_is_simple_vote_tx(&mut self, is_simple_vote_tx: bool) {
|
||||
self.is_simple_vote_tx = is_simple_vote_tx;
|
||||
}
|
||||
|
||||
pub(crate) fn set_compute_unit_limit(&mut self, compute_unit_limit: u32) {
|
||||
self.compute_unit_limit = compute_unit_limit;
|
||||
}
|
||||
|
||||
pub(crate) fn set_compute_unit_price(&mut self, compute_unit_price: u64) {
|
||||
self.compute_unit_price = compute_unit_price;
|
||||
}
|
||||
|
||||
pub(crate) fn set_loaded_accounts_bytes(&mut self, loaded_accounts_bytes: u32) {
|
||||
self.loaded_accounts_bytes = loaded_accounts_bytes;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue