Skip to content

Commit

Permalink
Combine builtin and BPF execution cost into programs_execution_cost s…
Browse files Browse the repository at this point in the history
…ince VM has started to consume CUs uniformly
  • Loading branch information
tao-stones committed Mar 3, 2024
1 parent 5f6d66e commit 463e136
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 66 deletions.
3 changes: 1 addition & 2 deletions core/src/banking_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,7 @@ pub struct BatchedTransactionCostDetails {
pub batched_signature_cost: u64,
pub batched_write_lock_cost: u64,
pub batched_data_bytes_cost: u64,
pub batched_builtins_execute_cost: u64,
pub batched_bpf_execute_cost: u64,
pub batched_programs_execute_cost: u64,
}

#[derive(Debug, Default)]
Expand Down
42 changes: 12 additions & 30 deletions core/src/banking_stage/qos_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,10 @@ impl QosService {
batched_transaction_details.costs.batched_data_bytes_cost,
Ordering::Relaxed,
);
self.metrics.stats.estimated_builtins_execute_cu.fetch_add(
self.metrics.stats.estimated_programs_execute_cu.fetch_add(
batched_transaction_details
.costs
.batched_builtins_execute_cost,
Ordering::Relaxed,
);
self.metrics.stats.estimated_bpf_execute_cu.fetch_add(
batched_transaction_details.costs.batched_bpf_execute_cost,
.batched_programs_execute_cost,
Ordering::Relaxed,
);

Expand Down Expand Up @@ -297,7 +293,7 @@ impl QosService {
pub fn accumulate_actual_execute_cu(&self, units: u64) {
self.metrics
.stats
.actual_bpf_execute_cu
.actual_programs_execute_cu
.fetch_add(units, Ordering::Relaxed);
}

Expand Down Expand Up @@ -331,12 +327,8 @@ impl QosService {
saturating_add_assign!(
batched_transaction_details
.costs
.batched_builtins_execute_cost,
cost.builtins_execution_cost()
);
saturating_add_assign!(
batched_transaction_details.costs.batched_bpf_execute_cost,
cost.bpf_execution_cost()
.batched_programs_execute_cost,
cost.programs_execution_cost()
);
}
Err(transaction_error) => match transaction_error {
Expand Down Expand Up @@ -427,14 +419,11 @@ struct QosServiceMetricsStats {
/// accumulated estimated instruction data Compute Units to be packed into block
estimated_data_bytes_cu: AtomicU64,

/// accumulated estimated builtin programs Compute Units to be packed into block
estimated_builtins_execute_cu: AtomicU64,

/// accumulated estimated SBF program Compute Units to be packed into block
estimated_bpf_execute_cu: AtomicU64,
/// accumulated estimated program Compute Units to be packed into block
estimated_programs_execute_cu: AtomicU64,

/// accumulated actual program Compute Units that have been packed into block
actual_bpf_execute_cu: AtomicU64,
actual_programs_execute_cu: AtomicU64,

/// accumulated actual program execute micro-sec that have been packed into block
actual_execute_time_us: AtomicU64,
Expand Down Expand Up @@ -515,22 +504,15 @@ impl QosServiceMetrics {
i64
),
(
"estimated_builtins_execute_cu",
self.stats
.estimated_builtins_execute_cu
.swap(0, Ordering::Relaxed),
i64
),
(
"estimated_bpf_execute_cu",
"estimated_programs_execute_cu",
self.stats
.estimated_bpf_execute_cu
.estimated_programs_execute_cu
.swap(0, Ordering::Relaxed),
i64
),
(
"actual_bpf_execute_cu",
self.stats.actual_bpf_execute_cu.swap(0, Ordering::Relaxed),
"actual_programs_execute_cu",
self.stats.actual_programs_execute_cu.swap(0, Ordering::Relaxed),
i64
),
(
Expand Down
26 changes: 11 additions & 15 deletions cost-model/src/cost_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,21 @@ impl CostModel {
transaction: &SanitizedTransaction,
feature_set: &FeatureSet,
) {
let mut builtin_costs = 0u64;
let mut bpf_costs = 0u64;
let mut programs_execution_costs = 0u64;
let mut loaded_accounts_data_size_cost = 0u64;
let mut data_bytes_len_total = 0u64;
let mut compute_unit_limit_is_set = false;
let mut has_user_space_instructions = false;

for (program_id, instruction) in transaction.message().program_instructions_iter() {
// to keep the same behavior, look for builtin first
if let Some(builtin_cost) = BUILT_IN_INSTRUCTION_COSTS.get(program_id) {
builtin_costs = builtin_costs.saturating_add(*builtin_cost);
programs_execution_costs = if let Some(builtin_cost) = BUILT_IN_INSTRUCTION_COSTS.get(program_id) {
programs_execution_costs.saturating_add(*builtin_cost)
} else {
bpf_costs = bpf_costs
has_user_space_instructions = true;
programs_execution_costs
.saturating_add(u64::from(DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT))
.min(u64::from(MAX_COMPUTE_UNIT_LIMIT));
}
.min(u64::from(MAX_COMPUTE_UNIT_LIMIT));
data_bytes_len_total =
data_bytes_len_total.saturating_add(instruction.data.len() as u64);

Expand All @@ -120,8 +120,6 @@ impl CostModel {
}
}

// calculate bpf cost based on compute budget instructions

// if failed to process compute_budget instructions, the transaction will not be executed
// by `bank`, therefore it should be considered as no execution cost by cost model.
match process_compute_budget_instructions(transaction.message().program_instructions_iter())
Expand All @@ -132,8 +130,8 @@ impl CostModel {
// 'compute_unit_limit_is_set' flag, because compute_budget does not distinguish
// builtin and bpf instructions when calculating default compute-unit-limit. (see
// compute_budget.rs test `test_process_mixed_instructions_without_compute_budget`)
if bpf_costs > 0 && compute_unit_limit_is_set {
bpf_costs = u64::from(compute_budget_limits.compute_unit_limit);
if has_user_space_instructions && compute_unit_limit_is_set {
programs_execution_costs = u64::from(compute_budget_limits.compute_unit_limit);
}

if feature_set
Expand All @@ -146,13 +144,11 @@ impl CostModel {
}
}
Err(_) => {
builtin_costs = 0;
bpf_costs = 0;
programs_execution_costs = 0;
}
}

tx_cost.builtins_execution_cost = builtin_costs;
tx_cost.bpf_execution_cost = bpf_costs;
tx_cost.programs_execution_cost = programs_execution_costs;
tx_cost.loaded_accounts_data_size_cost = loaded_accounts_data_size_cost;
tx_cost.data_bytes_cost = data_bytes_len_total / INSTRUCTION_DATA_BYTES_COST;
}
Expand Down
2 changes: 1 addition & 1 deletion cost-model/src/cost_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl CostTracker {
estimated_tx_cost: &TransactionCost,
actual_execution_units: u64,
) {
let estimated_execution_units = estimated_tx_cost.bpf_execution_cost();
let estimated_execution_units = estimated_tx_cost.programs_execution_cost();
match actual_execution_units.cmp(&estimated_execution_units) {
Ordering::Equal => (),
Ordering::Greater => {
Expand Down
28 changes: 10 additions & 18 deletions cost-model/src/transaction_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ impl TransactionCost {
}
}

pub fn bpf_execution_cost(&self) -> u64 {
pub fn programs_execution_cost(&self) -> u64 {
match self {
Self::SimpleVote { .. } => 0,
Self::Transaction(usage_cost) => usage_cost.bpf_execution_cost,
Self::SimpleVote { .. } => solana_vote_program::vote_processor::DEFAULT_COMPUTE_UNITS,
Self::Transaction(usage_cost) => usage_cost.programs_execution_cost,
}
}

Expand Down Expand Up @@ -74,13 +74,6 @@ impl TransactionCost {
}
}

pub fn builtins_execution_cost(&self) -> u64 {
match self {
Self::SimpleVote { .. } => solana_vote_program::vote_processor::DEFAULT_COMPUTE_UNITS,
Self::Transaction(usage_cost) => usage_cost.builtins_execution_cost,
}
}

pub fn writable_accounts(&self) -> &[Pubkey] {
match self {
Self::SimpleVote { writable_accounts } => writable_accounts,
Expand All @@ -98,8 +91,10 @@ pub struct UsageCostDetails {
pub signature_cost: u64,
pub write_lock_cost: u64,
pub data_bytes_cost: u64,
pub builtins_execution_cost: u64,
pub bpf_execution_cost: u64,
// since https://github.com/solana-labs/solana/issues/30620 activated everywhere,
// all builtins consume compute units same as bpf. It is no longer necessary
// to separate builtin execution cost from bpf's
pub programs_execution_cost: u64,
pub loaded_accounts_data_size_cost: u64,
pub account_data_size: u64,
}
Expand All @@ -111,8 +106,7 @@ impl Default for UsageCostDetails {
signature_cost: 0u64,
write_lock_cost: 0u64,
data_bytes_cost: 0u64,
builtins_execution_cost: 0u64,
bpf_execution_cost: 0u64,
programs_execution_cost: 0u64,
loaded_accounts_data_size_cost: 0u64,
account_data_size: 0u64,
}
Expand All @@ -129,8 +123,7 @@ impl PartialEq for UsageCostDetails {
self.signature_cost == other.signature_cost
&& self.write_lock_cost == other.write_lock_cost
&& self.data_bytes_cost == other.data_bytes_cost
&& self.builtins_execution_cost == other.builtins_execution_cost
&& self.bpf_execution_cost == other.bpf_execution_cost
&& self.programs_execution_cost == other.programs_execution_cost
&& self.loaded_accounts_data_size_cost == other.loaded_accounts_data_size_cost
&& self.account_data_size == other.account_data_size
&& to_hash_set(&self.writable_accounts) == to_hash_set(&other.writable_accounts)
Expand All @@ -157,8 +150,7 @@ impl UsageCostDetails {
self.signature_cost
.saturating_add(self.write_lock_cost)
.saturating_add(self.data_bytes_cost)
.saturating_add(self.builtins_execution_cost)
.saturating_add(self.bpf_execution_cost)
.saturating_add(self.programs_execution_cost)
.saturating_add(self.loaded_accounts_data_size_cost)
}
}
Expand Down

0 comments on commit 463e136

Please sign in to comment.