Skip to content

Commit

Permalink
add requested limits to static meta
Browse files Browse the repository at this point in the history
  • Loading branch information
tao-stones committed Dec 7, 2023
1 parent f6403e3 commit e785c15
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
33 changes: 32 additions & 1 deletion runtime-transaction/src/runtime_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
//! ALT, RuntimeTransaction<SanitizedMessage> transits into Dynamically Loaded state,
//! with its dynamic metadata loaded.
use {
crate::transaction_meta::{DynamicMeta, StaticMeta, TransactionMeta},
crate::transaction_meta::{DynamicMeta, RequestedLimits, StaticMeta, TransactionMeta},
solana_program_runtime::compute_budget_processor::ComputeBudgetLimits,
solana_sdk::{
hash::Hash,
message::{AddressLoader, SanitizedMessage, SanitizedVersionedMessage},
signature::Signature,
simple_vote_transaction_checker::is_simple_vote_transaction,
slot_history::Slot,
transaction::{Result, SanitizedVersionedTransaction},
},
};
Expand All @@ -41,13 +43,36 @@ impl StaticMetaAccess for SanitizedVersionedMessage {}
impl StaticMetaAccess for SanitizedMessage {}
impl DynamicMetaAccess for SanitizedMessage {}

impl<M: StaticMetaAccess> RequestedLimits for RuntimeTransaction<M> {
fn requested_limits(&self, current_slot: Option<Slot>) -> Option<&ComputeBudgetLimits> {
if let Some(current_slot) = current_slot {
(current_slot <= self.meta.requested_limits.expiry)
.then(|| &self.meta.requested_limits.compute_budget_limits)
} else {
Some(&self.meta.requested_limits.compute_budget_limits)
}
}
}

impl<M: StaticMetaAccess> StaticMeta for RuntimeTransaction<M> {
fn message_hash(&self) -> &Hash {
&self.meta.message_hash
}
fn is_simple_vote_tx(&self) -> bool {
self.meta.is_simple_vote_tx
}
fn compute_unit_limit(&self, current_slot: Option<Slot>) -> Option<u32> {
self.requested_limits(current_slot)
.and_then(|requested_limits| Some(requested_limits.compute_unit_limit))
}
fn compute_unit_price(&self, current_slot: Option<Slot>) -> Option<u64> {
self.requested_limits(current_slot)
.and_then(|requested_limits| Some(requested_limits.compute_unit_price))
}
fn loaded_accounts_bytes(&self, current_slot: Option<Slot>) -> Option<u32> {
self.requested_limits(current_slot)
.and_then(|requested_limits| Some(requested_limits.loaded_accounts_bytes))
}
}

impl<M: DynamicMetaAccess> DynamicMeta for RuntimeTransaction<M> {}
Expand Down Expand Up @@ -103,6 +128,7 @@ impl RuntimeTransaction<SanitizedMessage> {
mod tests {
use {
super::*,
crate::transaction_meta::RequestedLimitsWithExpiry,
solana_program::{
system_instruction,
vote::{self, state::Vote},
Expand Down Expand Up @@ -162,11 +188,13 @@ mod tests {
fn test_new_runtime_transaction_static() {
let hash = Hash::new_unique();
let compute_unit_price = 1_000;
let requested_limits = RequestedLimitsWithExpiry::default();

assert_eq!(
TransactionMeta {
message_hash: hash,
is_simple_vote_tx: false,
requested_limits: requested_limits.clone(),
},
get_transaction_meta(
non_vote_sanitized_versioned_transaction(compute_unit_price),
Expand All @@ -179,6 +207,7 @@ mod tests {
TransactionMeta {
message_hash: hash,
is_simple_vote_tx: true,
requested_limits: requested_limits.clone(),
},
get_transaction_meta(
non_vote_sanitized_versioned_transaction(compute_unit_price),
Expand All @@ -191,6 +220,7 @@ mod tests {
TransactionMeta {
message_hash: hash,
is_simple_vote_tx: true,
requested_limits: requested_limits.clone(),
},
get_transaction_meta(vote_sanitized_versioned_transaction(), Some(hash), None)
);
Expand All @@ -199,6 +229,7 @@ mod tests {
TransactionMeta {
message_hash: hash,
is_simple_vote_tx: false,
requested_limits,
},
get_transaction_meta(
vote_sanitized_versioned_transaction(),
Expand Down
32 changes: 29 additions & 3 deletions runtime-transaction/src/transaction_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,29 @@
//! The StaticMeta and DynamicMeta traits are accessor traits on the
//! RuntimeTransaction types, not the TransactionMeta itself.
//!
use solana_sdk::hash::Hash;
use {
solana_program_runtime::compute_budget_processor::ComputeBudgetLimits,
solana_sdk::{hash::Hash, slot_history::Slot},
};

/// private trait to avoid exposing `ComputeBudgetLimits` to callsite of RuntimeTransaction.
pub(crate) trait RequestedLimits {
fn requested_limits(&self, current_slot: Option<Slot>) -> Option<&ComputeBudgetLimits>;
}

/// metadata can be extracted statically from sanitized transaction,
/// for example: message hash, simple-vote-tx flag, compute budget limits,
pub trait StaticMeta {
/// for example: message hash, simple-vote-tx flag, limits set by instructions
#[allow(private_bounds)]
pub trait StaticMeta: RequestedLimits {
fn message_hash(&self) -> &Hash;
fn is_simple_vote_tx(&self) -> bool;

// get fields' value from RequestedLimitsWithExpiry,
// `current_slot`, sets to None to skip expiry check, otherwise if current_slot is
// before expiry, Some(value) is returned, otherwise return None.
fn compute_unit_limit(&self, current_slot: Option<Slot>) -> Option<u32>;
fn compute_unit_price(&self, current_slot: Option<Slot>) -> Option<u64>;
fn loaded_accounts_bytes(&self, current_slot: Option<Slot>) -> Option<u32>;
}

/// Statically loaded meta is a supertrait of Dynamically loaded meta, when
Expand All @@ -31,6 +47,16 @@ pub trait DynamicMeta: StaticMeta {}
pub struct TransactionMeta {
pub(crate) message_hash: Hash,
pub(crate) is_simple_vote_tx: bool,
pub(crate) requested_limits: RequestedLimitsWithExpiry,
}

/// Processing compute_budget_instructions with feature_set resolves RequestedLimits,
/// and the resolved values expire at the end of the current epoch, as feature_set
/// may change between epochs.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub(crate) struct RequestedLimitsWithExpiry {
pub(crate) expiry: Slot,
pub(crate) compute_budget_limits: ComputeBudgetLimits,
}

impl TransactionMeta {
Expand Down

0 comments on commit e785c15

Please sign in to comment.