Skip to content

Commit

Permalink
Fix reserve minimal compute units for builtins (#3799)
Browse files Browse the repository at this point in the history
- Add feature gate, issue #2562;
- Implement SIMD-170;

---------

Co-authored-by: Justin Starry <[email protected]>
(cherry picked from commit 3e9af14)

# Conflicts:
#	builtins-default-costs/src/lib.rs
#	core/src/banking_stage/consumer.rs
#	core/src/banking_stage/immutable_deserialized_packet.rs
#	core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs
#	cost-model/src/cost_model.rs
#	programs/compute-budget-bench/benches/compute_budget.rs
#	runtime-transaction/src/lib.rs
#	runtime-transaction/src/runtime_transaction/sdk_transactions.rs
#	runtime/src/prioritization_fee_cache.rs
  • Loading branch information
tao-stones committed Dec 11, 2024
1 parent aca7bbe commit 0db3df0
Show file tree
Hide file tree
Showing 29 changed files with 1,800 additions and 295 deletions.
63 changes: 63 additions & 0 deletions builtins-default-costs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,66 @@ lazy_static! {
temp_table
};
}
<<<<<<< HEAD
=======

pub fn get_builtin_instruction_cost<'a>(
program_id: &'a Pubkey,
feature_set: &'a FeatureSet,
) -> Option<u64> {
BUILTIN_INSTRUCTION_COSTS
.get(program_id)
.filter(
// Returns true if builtin program id has no core_bpf_migration_feature or feature is not activated;
// otherwise returns false because it's not considered as builtin
|builtin_cost| -> bool {
builtin_cost
.core_bpf_migration_feature
.map(|feature_id| !feature_set.is_active(&feature_id))
.unwrap_or(true)
},
)
.map(|builtin_cost| builtin_cost.native_cost)
}

#[inline]
pub fn is_builtin_program(program_id: &Pubkey) -> bool {
BUILTIN_INSTRUCTION_COSTS.contains_key(program_id)
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_get_builtin_instruction_cost() {
// use native cost if no migration planned
assert_eq!(
Some(solana_compute_budget_program::DEFAULT_COMPUTE_UNITS),
get_builtin_instruction_cost(&compute_budget::id(), &FeatureSet::all_enabled())
);

// use native cost if migration is planned but not activated
assert_eq!(
Some(solana_stake_program::stake_instruction::DEFAULT_COMPUTE_UNITS),
get_builtin_instruction_cost(&solana_stake_program::id(), &FeatureSet::default())
);

// None if migration is planned and activated, in which case, it's no longer builtin
assert!(get_builtin_instruction_cost(
&solana_stake_program::id(),
&FeatureSet::all_enabled()
)
.is_none());

// None if not builtin
assert!(
get_builtin_instruction_cost(&Pubkey::new_unique(), &FeatureSet::default()).is_none()
);
assert!(
get_builtin_instruction_cost(&Pubkey::new_unique(), &FeatureSet::all_enabled())
.is_none()
);
}
}
>>>>>>> 3e9af14f3a (Fix reserve minimal compute units for builtins (#3799))
3 changes: 3 additions & 0 deletions compute-budget/src/compute_budget_limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use {
/// default heap page cost = 0.5 * 15 ~= 8CU/page
pub const DEFAULT_HEAP_COST: u64 = 8;
pub const DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT: u32 = 200_000;
// SIMD-170 defines max CUs to be allocated for any builtin program instructions, that
// have not been migrated to sBPF programs.
pub const MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT: u32 = 3_000;
pub const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000;
pub const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024;
pub const MIN_HEAP_FRAME_BYTES: u32 = HEAP_LENGTH as u32;
Expand Down
13 changes: 13 additions & 0 deletions core/src/banking_stage/consumer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,11 +574,19 @@ impl Consumer {
.sanitized_transactions()
.iter()
.filter_map(|transaction| {
<<<<<<< HEAD
process_compute_budget_instructions(SVMMessage::program_instructions_iter(
transaction,
))
.ok()
.map(|limits| limits.compute_unit_price)
=======
transaction
.compute_budget_instruction_details()
.sanitize_and_convert_to_compute_budget_limits(&bank.feature_set)
.ok()
.map(|limits| limits.compute_unit_price)
>>>>>>> 3e9af14f3a (Fix reserve minimal compute units for builtins (#3799))
})
.minmax();
let (min_prioritization_fees, max_prioritization_fees) =
Expand Down Expand Up @@ -757,7 +765,12 @@ impl Consumer {
) -> Result<(), TransactionError> {
let fee_payer = message.fee_payer();
let fee_budget_limits = FeeBudgetLimits::from(process_compute_budget_instructions(
<<<<<<< HEAD
SVMMessage::program_instructions_iter(message),
=======
message.program_instructions_iter(),
&bank.feature_set,
>>>>>>> 3e9af14f3a (Fix reserve minimal compute units for builtins (#3799))
)?);
let fee = solana_fee::calculate_fee(
message,
Expand Down
12 changes: 12 additions & 0 deletions core/src/banking_stage/immutable_deserialized_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use {
solana_sanitize::SanitizeError,
solana_sdk::{
clock::Slot,
feature_set::FeatureSet,
hash::Hash,
message::{v0::LoadedAddresses, AddressLoaderError, Message, SimpleAddressLoader},
pubkey::Pubkey,
Expand Down Expand Up @@ -40,7 +41,17 @@ pub enum DeserializedPacketError {
FailedFilter(#[from] PacketFilterFailure),
}

<<<<<<< HEAD
#[derive(Debug, Eq)]
=======
lazy_static::lazy_static! {
// Make a dummy feature_set with all features enabled to
// fetch compute_unit_price and compute_unit_limit for legacy leader.
static ref FEATURE_SET: FeatureSet = FeatureSet::all_enabled();
}

#[derive(Debug)]
>>>>>>> 3e9af14f3a (Fix reserve minimal compute units for builtins (#3799))
pub struct ImmutableDeserializedPacket {
original_packet: Packet,
transaction: SanitizedVersionedTransaction,
Expand Down Expand Up @@ -68,6 +79,7 @@ impl ImmutableDeserializedPacket {
.get_message()
.program_instructions_iter()
.map(|(pubkey, ix)| (pubkey, SVMInstruction::from(ix))),
&FEATURE_SET,
)
.map_err(|_| DeserializedPacketError::PrioritizationFailure)?;

Expand Down
Loading

0 comments on commit 0db3df0

Please sign in to comment.