directly use compute_budget MAX_UNITS and DEFAULT_UNITS
This commit is contained in:
parent
a4cacf3389
commit
0ed23899e7
|
@ -33,7 +33,7 @@ use {
|
|||
rpc_request::DELINQUENT_VALIDATOR_SLOT_DISTANCE,
|
||||
rpc_response::SlotInfo,
|
||||
},
|
||||
solana_program_runtime::compute_budget::ComputeBudget,
|
||||
solana_program_runtime::compute_budget,
|
||||
solana_remote_wallet::remote_wallet::RemoteWalletManager,
|
||||
solana_sdk::{
|
||||
account::from_account,
|
||||
|
@ -1409,7 +1409,7 @@ pub fn process_ping(
|
|||
)];
|
||||
if let Some(additional_fee) = additional_fee {
|
||||
ixs.push(ComputeBudgetInstruction::request_units(
|
||||
ComputeBudget::new(false).max_units as u32,
|
||||
compute_budget::DEFAULT_UNITS,
|
||||
*additional_fee,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -288,7 +288,7 @@ mod tests {
|
|||
// new erroring compute costs
|
||||
let cost_per_error = 1000;
|
||||
// the expect cost is (previous_cost + new_cost)/2 = (100 + 1000)/2 = 550
|
||||
let expect_units = 550;
|
||||
let expected_units = 550;
|
||||
{
|
||||
let errored_txs_compute_consumed = vec![cost_per_error; 3];
|
||||
let total_errored_units = errored_txs_compute_consumed.iter().sum();
|
||||
|
@ -307,7 +307,7 @@ mod tests {
|
|||
1
|
||||
);
|
||||
assert_eq!(
|
||||
Some(&expect_units),
|
||||
Some(&expected_units),
|
||||
cost_model
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -319,7 +319,7 @@ mod tests {
|
|||
// Test updating cost model with only erroring compute costs where the error cost is
|
||||
// `smaller_cost_per_error`, less than the current instruction cost for the program.
|
||||
// The cost should not decrease for these new lesser errors
|
||||
let smaller_cost_per_error = expect_units - 10;
|
||||
let smaller_cost_per_error = expected_units - 10;
|
||||
{
|
||||
let errored_txs_compute_consumed = vec![smaller_cost_per_error; 3];
|
||||
let total_errored_units = errored_txs_compute_consumed.iter().sum();
|
||||
|
@ -338,7 +338,7 @@ mod tests {
|
|||
1
|
||||
);
|
||||
assert_eq!(
|
||||
Some(&expect_units),
|
||||
Some(&expected_units),
|
||||
cost_model
|
||||
.read()
|
||||
.unwrap()
|
||||
|
|
|
@ -7,7 +7,8 @@ use solana_sdk::{
|
|||
transaction::TransactionError,
|
||||
};
|
||||
|
||||
const MAX_UNITS: u32 = 1_400_000;
|
||||
pub const DEFAULT_UNITS: u32 = 200_000;
|
||||
pub const MAX_UNITS: u32 = 1_400_000;
|
||||
const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024;
|
||||
|
||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||
|
@ -67,14 +68,14 @@ pub struct ComputeBudget {
|
|||
|
||||
impl Default for ComputeBudget {
|
||||
fn default() -> Self {
|
||||
Self::new(true)
|
||||
Self::new(MAX_UNITS)
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeBudget {
|
||||
pub fn new(use_max_units_default: bool) -> Self {
|
||||
pub fn new(max_units: u32) -> Self {
|
||||
ComputeBudget {
|
||||
max_units: ComputeBudget::get_max_units(use_max_units_default),
|
||||
max_units: max_units as u64,
|
||||
log_64_units: 100,
|
||||
create_program_address_units: 1500,
|
||||
invoke_units: 1000,
|
||||
|
@ -97,14 +98,6 @@ impl ComputeBudget {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_max_units(use_max_units_default: bool) -> u64 {
|
||||
if use_max_units_default {
|
||||
MAX_UNITS as u64
|
||||
} else {
|
||||
200_000
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_message(
|
||||
&mut self,
|
||||
message: &SanitizedMessage,
|
||||
|
|
|
@ -1193,6 +1193,7 @@ pub fn visit_each_account_once<E>(
|
|||
mod tests {
|
||||
use {
|
||||
super::*,
|
||||
crate::compute_budget,
|
||||
serde::{Deserialize, Serialize},
|
||||
solana_sdk::account::{ReadableAccount, WritableAccount},
|
||||
};
|
||||
|
@ -1674,12 +1675,12 @@ mod tests {
|
|||
let mut transaction_context = TransactionContext::new(accounts, 1, 3);
|
||||
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
||||
invoke_context.feature_set = Arc::new(feature_set);
|
||||
invoke_context.compute_budget = ComputeBudget::new(false);
|
||||
invoke_context.compute_budget = ComputeBudget::new(compute_budget::DEFAULT_UNITS);
|
||||
|
||||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
assert_eq!(
|
||||
*invoke_context.get_compute_budget(),
|
||||
ComputeBudget::new(false)
|
||||
ComputeBudget::new(compute_budget::DEFAULT_UNITS)
|
||||
);
|
||||
invoke_context.pop().unwrap();
|
||||
|
||||
|
@ -1687,7 +1688,7 @@ mod tests {
|
|||
let expected_compute_budget = ComputeBudget {
|
||||
max_units: 500_000,
|
||||
heap_size: Some(256_usize.saturating_mul(1024)),
|
||||
..ComputeBudget::new(false)
|
||||
..ComputeBudget::new(compute_budget::DEFAULT_UNITS)
|
||||
};
|
||||
assert_eq!(
|
||||
*invoke_context.get_compute_budget(),
|
||||
|
@ -1698,7 +1699,7 @@ mod tests {
|
|||
invoke_context.push(&[], &[0], &[]).unwrap();
|
||||
assert_eq!(
|
||||
*invoke_context.get_compute_budget(),
|
||||
ComputeBudget::new(false)
|
||||
ComputeBudget::new(compute_budget::DEFAULT_UNITS)
|
||||
);
|
||||
invoke_context.pop().unwrap();
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ use {
|
|||
solana_metrics::{inc_new_counter_debug, inc_new_counter_info},
|
||||
solana_program_runtime::{
|
||||
accounts_data_meter::MAX_ACCOUNTS_DATA_LEN,
|
||||
compute_budget::ComputeBudget,
|
||||
compute_budget::{self, ComputeBudget},
|
||||
invoke_context::{
|
||||
BuiltinProgram, Executor, Executors, ProcessInstructionWithContext, TransactionExecutor,
|
||||
},
|
||||
|
@ -4053,9 +4053,14 @@ impl Bank {
|
|||
signature_count += u64::from(tx.message().header().num_required_signatures);
|
||||
|
||||
let tx_wide_compute_cap = feature_set.is_active(&tx_wide_compute_cap::id());
|
||||
let compute_budget_max_units = if tx_wide_compute_cap {
|
||||
compute_budget::MAX_UNITS
|
||||
} else {
|
||||
compute_budget::DEFAULT_UNITS
|
||||
};
|
||||
let mut compute_budget = self
|
||||
.compute_budget
|
||||
.unwrap_or_else(|| ComputeBudget::new(tx_wide_compute_cap));
|
||||
.unwrap_or_else(|| ComputeBudget::new(compute_budget_max_units));
|
||||
if tx_wide_compute_cap {
|
||||
let mut compute_budget_process_transaction_time =
|
||||
Measure::start("compute_budget_process_transaction_time");
|
||||
|
@ -16925,7 +16930,7 @@ pub(crate) mod tests {
|
|||
|
||||
let compute_budget = bank
|
||||
.compute_budget
|
||||
.unwrap_or_else(|| ComputeBudget::new(false));
|
||||
.unwrap_or_else(|| ComputeBudget::new(compute_budget::DEFAULT_UNITS));
|
||||
let transaction_context = TransactionContext::new(
|
||||
loaded_txs[0].0.as_ref().unwrap().accounts.clone(),
|
||||
compute_budget.max_invoke_depth.saturating_add(1),
|
||||
|
|
|
@ -115,7 +115,7 @@ impl CostModel {
|
|||
None => {
|
||||
let default_value = self.instruction_execution_cost_table.get_default_units();
|
||||
debug!(
|
||||
"Instruction {:?} does not have aggregated cost, using default value {}",
|
||||
"Program {:?} does not have aggregated cost, using default value {}",
|
||||
program_key, default_value
|
||||
);
|
||||
default_value
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/// When its capacity limit is reached, it prunes old and less-used programs
|
||||
/// to make room for new ones.
|
||||
use {
|
||||
log::*, solana_program_runtime::compute_budget::ComputeBudget, solana_sdk::pubkey::Pubkey,
|
||||
log::*, solana_program_runtime::compute_budget::DEFAULT_UNITS, solana_sdk::pubkey::Pubkey,
|
||||
std::collections::HashMap,
|
||||
};
|
||||
|
||||
|
@ -47,13 +47,12 @@ impl ExecuteCostTable {
|
|||
self.table.len()
|
||||
}
|
||||
|
||||
// default program cost to max_units
|
||||
/// default program cost, set to ComputeBudget::DEFAULT_UNITS
|
||||
pub fn get_default_units(&self) -> u64 {
|
||||
let use_max_units_default = false;
|
||||
ComputeBudget::get_max_units(use_max_units_default)
|
||||
DEFAULT_UNITS as u64
|
||||
}
|
||||
|
||||
// average cost of all recorded programs
|
||||
/// average cost of all recorded programs
|
||||
pub fn get_average_units(&self) -> u64 {
|
||||
if self.table.is_empty() {
|
||||
self.get_default_units()
|
||||
|
@ -62,8 +61,8 @@ impl ExecuteCostTable {
|
|||
}
|
||||
}
|
||||
|
||||
// the most frequently occurring program's cost
|
||||
pub fn get_mode_units(&self) -> u64 {
|
||||
/// the most frequently occurring program's cost
|
||||
pub fn get_statistical_mode_units(&self) -> u64 {
|
||||
if self.occurrences.is_empty() {
|
||||
self.get_default_units()
|
||||
} else {
|
||||
|
@ -78,15 +77,15 @@ impl ExecuteCostTable {
|
|||
}
|
||||
}
|
||||
|
||||
// returns None if program doesn't exist in table. In this case,
|
||||
// `get_default_units()`, `get_average_units()` or `get_mode_units()`
|
||||
// can be used to assign a value to new program.
|
||||
/// returns None if program doesn't exist in table. In this case,
|
||||
/// `get_default_units()`, `get_average_units()` or `get_statistical_mode_units()`
|
||||
/// can be used to assign a value to new program.
|
||||
pub fn get_cost(&self, key: &Pubkey) -> Option<&u64> {
|
||||
self.table.get(key)
|
||||
}
|
||||
|
||||
// update-or-insert should be infallible. Query the result of upsert,
|
||||
// often requires additional calculation, should be lazy.
|
||||
/// update-or-insert should be infallible. Query the result of upsert,
|
||||
/// often requires additional calculation, should be lazy.
|
||||
pub fn upsert(&mut self, key: &Pubkey, value: u64) {
|
||||
let need_to_add = !self.table.contains_key(key);
|
||||
let current_size = self.get_count();
|
||||
|
@ -105,11 +104,9 @@ impl ExecuteCostTable {
|
|||
*timestamp = Self::micros_since_epoch();
|
||||
}
|
||||
|
||||
// prune the old programs so the table contains `new_size` of records,
|
||||
// where `old` is defined as weighted age, which is negatively correlated
|
||||
// with program's age and
|
||||
// positively correlated with how frequently the program
|
||||
// is executed (eg. occurrence),
|
||||
/// prune the old programs so the table contains `new_size` of records,
|
||||
/// where `old` is defined as weighted age, which is negatively correlated
|
||||
/// with program's age and how frequently the program is occurrenced.
|
||||
fn prune_to(&mut self, new_size: &usize) {
|
||||
debug!(
|
||||
"prune cost table, current size {}, new size {}",
|
||||
|
@ -228,14 +225,14 @@ mod tests {
|
|||
testee.upsert(&key1, cost1);
|
||||
assert_eq!(1, testee.get_count());
|
||||
assert_eq!(cost1, testee.get_average_units());
|
||||
assert_eq!(cost1, testee.get_mode_units());
|
||||
assert_eq!(cost1, testee.get_statistical_mode_units());
|
||||
assert_eq!(&cost1, testee.get_cost(&key1).unwrap());
|
||||
|
||||
// insert 2nd record
|
||||
testee.upsert(&key2, cost2);
|
||||
assert_eq!(2, testee.get_count());
|
||||
assert_eq!((cost1 + cost2) / 2_u64, testee.get_average_units());
|
||||
assert_eq!(cost2, testee.get_mode_units());
|
||||
assert_eq!(cost2, testee.get_statistical_mode_units());
|
||||
assert_eq!(&cost1, testee.get_cost(&key1).unwrap());
|
||||
assert_eq!(&cost2, testee.get_cost(&key2).unwrap());
|
||||
|
||||
|
@ -246,7 +243,7 @@ mod tests {
|
|||
((cost1 + cost2) / 2 + cost2) / 2_u64,
|
||||
testee.get_average_units()
|
||||
);
|
||||
assert_eq!((cost1 + cost2) / 2, testee.get_mode_units());
|
||||
assert_eq!((cost1 + cost2) / 2, testee.get_statistical_mode_units());
|
||||
assert_eq!(&((cost1 + cost2) / 2), testee.get_cost(&key1).unwrap());
|
||||
assert_eq!(&cost2, testee.get_cost(&key2).unwrap());
|
||||
}
|
||||
|
@ -281,7 +278,7 @@ mod tests {
|
|||
testee.upsert(&key3, cost3);
|
||||
assert_eq!(2, testee.get_count());
|
||||
assert_eq!((cost2 + cost3) / 2_u64, testee.get_average_units());
|
||||
assert_eq!(cost3, testee.get_mode_units());
|
||||
assert_eq!(cost3, testee.get_statistical_mode_units());
|
||||
assert!(testee.get_cost(&key1).is_none());
|
||||
assert_eq!(&cost2, testee.get_cost(&key2).unwrap());
|
||||
assert_eq!(&cost3, testee.get_cost(&key3).unwrap());
|
||||
|
@ -294,7 +291,7 @@ mod tests {
|
|||
((cost1 + cost2) / 2 + cost4) / 2_u64,
|
||||
testee.get_average_units()
|
||||
);
|
||||
assert_eq!((cost1 + cost2) / 2, testee.get_mode_units());
|
||||
assert_eq!((cost1 + cost2) / 2, testee.get_statistical_mode_units());
|
||||
assert_eq!(2, testee.get_count());
|
||||
assert!(testee.get_cost(&key1).is_none());
|
||||
assert_eq!(&((cost1 + cost2) / 2), testee.get_cost(&key2).unwrap());
|
||||
|
|
Loading…
Reference in New Issue