Update syscall base costs
This commit is contained in:
parent
74498650bc
commit
4d891043d1
@ -60,6 +60,8 @@ pub struct ComputeBudget {
|
|||||||
/// Number of compute units per additional 32k heap above the default (~.5
|
/// Number of compute units per additional 32k heap above the default (~.5
|
||||||
/// us per 32k at 15 units/us rounded up)
|
/// us per 32k at 15 units/us rounded up)
|
||||||
pub heap_cost: u64,
|
pub heap_cost: u64,
|
||||||
|
/// Memory operation syscall base cost
|
||||||
|
pub mem_op_base_cost: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ComputeBudget {
|
impl Default for ComputeBudget {
|
||||||
@ -88,6 +90,7 @@ impl ComputeBudget {
|
|||||||
syscall_base_cost: 100,
|
syscall_base_cost: 100,
|
||||||
heap_size: None,
|
heap_size: None,
|
||||||
heap_cost: 8,
|
heap_cost: 8,
|
||||||
|
mem_op_base_cost: 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1380,18 +1380,18 @@ fn assert_instruction_count() {
|
|||||||
{
|
{
|
||||||
programs.extend_from_slice(&[
|
programs.extend_from_slice(&[
|
||||||
("alloc", 1237),
|
("alloc", 1237),
|
||||||
("bpf_to_bpf", 96),
|
("bpf_to_bpf", 313),
|
||||||
("multiple_static", 52),
|
("multiple_static", 208),
|
||||||
("noop", 5),
|
("noop", 5),
|
||||||
("noop++", 5),
|
("noop++", 5),
|
||||||
("relative_call", 26),
|
("relative_call", 210),
|
||||||
("return_data", 980),
|
("return_data", 980),
|
||||||
("sanity", 1255),
|
("sanity", 2378),
|
||||||
("sanity++", 1260),
|
("sanity++", 2278),
|
||||||
("secp256k1_recover", 25383),
|
("secp256k1_recover", 25383),
|
||||||
("sha", 1328),
|
("sha", 1895),
|
||||||
("struct_pass", 108),
|
("struct_pass", 108),
|
||||||
("struct_ret", 28),
|
("struct_ret", 122),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "bpf_rust")]
|
#[cfg(feature = "bpf_rust")]
|
||||||
@ -1403,14 +1403,14 @@ fn assert_instruction_count() {
|
|||||||
("solana_bpf_rust_dep_crate", 47),
|
("solana_bpf_rust_dep_crate", 47),
|
||||||
("solana_bpf_rust_external_spend", 507),
|
("solana_bpf_rust_external_spend", 507),
|
||||||
("solana_bpf_rust_iter", 824),
|
("solana_bpf_rust_iter", 824),
|
||||||
("solana_bpf_rust_many_args", 941),
|
("solana_bpf_rust_many_args", 1289),
|
||||||
("solana_bpf_rust_mem", 3086),
|
("solana_bpf_rust_mem", 5997),
|
||||||
("solana_bpf_rust_membuiltins", 3976),
|
("solana_bpf_rust_membuiltins", 3976),
|
||||||
("solana_bpf_rust_noop", 481),
|
("solana_bpf_rust_noop", 481),
|
||||||
("solana_bpf_rust_param_passing", 146),
|
("solana_bpf_rust_param_passing", 146),
|
||||||
("solana_bpf_rust_rand", 488),
|
("solana_bpf_rust_rand", 488),
|
||||||
("solana_bpf_rust_sanity", 8455),
|
("solana_bpf_rust_sanity", 9128),
|
||||||
("solana_bpf_rust_secp256k1_recover", 25624),
|
("solana_bpf_rust_secp256k1_recover", 25889),
|
||||||
("solana_bpf_rust_sha", 30692),
|
("solana_bpf_rust_sha", 30692),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ use {
|
|||||||
blake3_syscall_enabled, disable_fees_sysvar, do_support_realloc,
|
blake3_syscall_enabled, disable_fees_sysvar, do_support_realloc,
|
||||||
libsecp256k1_0_5_upgrade_enabled, prevent_calling_precompiles_as_programs,
|
libsecp256k1_0_5_upgrade_enabled, prevent_calling_precompiles_as_programs,
|
||||||
return_data_syscall_enabled, secp256k1_recover_syscall_enabled,
|
return_data_syscall_enabled, secp256k1_recover_syscall_enabled,
|
||||||
sol_log_data_syscall_enabled,
|
sol_log_data_syscall_enabled, update_syscall_base_costs,
|
||||||
},
|
},
|
||||||
hash::{Hasher, HASH_BYTES},
|
hash::{Hasher, HASH_BYTES},
|
||||||
instruction::{AccountMeta, Instruction, InstructionError},
|
instruction::{AccountMeta, Instruction, InstructionError},
|
||||||
@ -41,7 +41,7 @@ use {
|
|||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
cell::{RefCell, RefMut},
|
cell::{Ref, RefCell, RefMut},
|
||||||
mem::{align_of, size_of},
|
mem::{align_of, size_of},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
slice::from_raw_parts_mut,
|
slice::from_raw_parts_mut,
|
||||||
@ -574,8 +574,12 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallPanic<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
|
if !invoke_context
|
||||||
|
.feature_set
|
||||||
|
.is_active(&update_syscall_base_costs::id())
|
||||||
|
{
|
||||||
question_mark!(invoke_context.get_compute_meter().consume(len), result);
|
question_mark!(invoke_context.get_compute_meter().consume(len), result);
|
||||||
|
}
|
||||||
let loader_id = question_mark!(
|
let loader_id = question_mark!(
|
||||||
invoke_context
|
invoke_context
|
||||||
.get_loader()
|
.get_loader()
|
||||||
@ -613,7 +617,18 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLog<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
question_mark!(invoke_context.get_compute_meter().consume(len), result);
|
let cost = if invoke_context
|
||||||
|
.feature_set
|
||||||
|
.is_active(&update_syscall_base_costs::id())
|
||||||
|
{
|
||||||
|
invoke_context
|
||||||
|
.get_compute_budget()
|
||||||
|
.syscall_base_cost
|
||||||
|
.max(len)
|
||||||
|
} else {
|
||||||
|
len
|
||||||
|
};
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
|
||||||
let loader_id = question_mark!(
|
let loader_id = question_mark!(
|
||||||
invoke_context
|
invoke_context
|
||||||
@ -694,7 +709,15 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallLogBpfComputeUnits<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
question_mark!(invoke_context.get_compute_meter().consume(0), result);
|
let cost = if invoke_context
|
||||||
|
.feature_set
|
||||||
|
.is_active(&update_syscall_base_costs::id())
|
||||||
|
{
|
||||||
|
invoke_context.get_compute_budget().syscall_base_cost
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
|
||||||
ic_logger_msg!(
|
ic_logger_msg!(
|
||||||
invoke_context.get_log_collector(),
|
invoke_context.get_log_collector(),
|
||||||
@ -972,9 +995,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSha256<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let base_cost = invoke_context.get_compute_budget().sha256_base_cost;
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
question_mark!(
|
question_mark!(
|
||||||
invoke_context.get_compute_meter().consume(base_cost),
|
invoke_context
|
||||||
|
.get_compute_meter()
|
||||||
|
.consume(compute_budget.sha256_base_cost),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1004,13 +1029,8 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSha256<'a, 'b> {
|
|||||||
),
|
),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let byte_cost = invoke_context.get_compute_budget().sha256_byte_cost;
|
let cost = compute_budget.sha256_byte_cost * (val.len() as u64 / 2);
|
||||||
question_mark!(
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
invoke_context
|
|
||||||
.get_compute_meter()
|
|
||||||
.consume(byte_cost * (val.len() as u64 / 2)),
|
|
||||||
result
|
|
||||||
);
|
|
||||||
hasher.hash(bytes);
|
hasher.hash(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1204,9 +1224,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallKeccak256<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let base_cost = invoke_context.get_compute_budget().sha256_base_cost;
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
question_mark!(
|
question_mark!(
|
||||||
invoke_context.get_compute_meter().consume(base_cost),
|
invoke_context
|
||||||
|
.get_compute_meter()
|
||||||
|
.consume(compute_budget.sha256_base_cost),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1241,13 +1263,9 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallKeccak256<'a, 'b> {
|
|||||||
),
|
),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let byte_cost = invoke_context.get_compute_budget().sha256_byte_cost;
|
let cost = compute_budget.sha256_byte_cost * (val.len() as u64 / 2);
|
||||||
question_mark!(
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
invoke_context
|
|
||||||
.get_compute_meter()
|
|
||||||
.consume(byte_cost * (val.len() as u64 / 2)),
|
|
||||||
result
|
|
||||||
);
|
|
||||||
hasher.hash(bytes);
|
hasher.hash(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1261,6 +1279,24 @@ fn check_overlapping(src_addr: u64, dst_addr: u64, n: u64) -> bool {
|
|||||||
|| (dst_addr <= src_addr && dst_addr + n > src_addr)
|
|| (dst_addr <= src_addr && dst_addr + n > src_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mem_op_consume<'a, 'b>(
|
||||||
|
invoke_context: &Ref<&'a mut InvokeContext<'b>>,
|
||||||
|
n: u64,
|
||||||
|
) -> Result<(), EbpfError<BpfError>> {
|
||||||
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
|
let cost = if invoke_context
|
||||||
|
.feature_set
|
||||||
|
.is_active(&update_syscall_base_costs::id())
|
||||||
|
{
|
||||||
|
compute_budget
|
||||||
|
.mem_op_base_cost
|
||||||
|
.max(n / compute_budget.cpi_bytes_per_unit)
|
||||||
|
} else {
|
||||||
|
n / compute_budget.cpi_bytes_per_unit
|
||||||
|
};
|
||||||
|
invoke_context.get_compute_meter().consume(cost)
|
||||||
|
}
|
||||||
|
|
||||||
/// memcpy
|
/// memcpy
|
||||||
pub struct SyscallMemcpy<'a, 'b> {
|
pub struct SyscallMemcpy<'a, 'b> {
|
||||||
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
|
invoke_context: Rc<RefCell<&'a mut InvokeContext<'b>>>,
|
||||||
@ -1287,8 +1323,22 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcpy<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let cost = invoke_context.get_compute_budget().cpi_bytes_per_unit;
|
// When deprecating `update_syscall_base_costs` switch to `mem_op_consume`
|
||||||
question_mark!(invoke_context.get_compute_meter().consume(n / cost), result);
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
|
let update_syscall_base_costs = invoke_context
|
||||||
|
.feature_set
|
||||||
|
.is_active(&update_syscall_base_costs::id());
|
||||||
|
if update_syscall_base_costs {
|
||||||
|
let cost = compute_budget
|
||||||
|
.mem_op_base_cost
|
||||||
|
.max(n / compute_budget.cpi_bytes_per_unit);
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !update_syscall_base_costs {
|
||||||
|
let cost = n / compute_budget.cpi_bytes_per_unit;
|
||||||
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
|
};
|
||||||
|
|
||||||
let loader_id = question_mark!(
|
let loader_id = question_mark!(
|
||||||
invoke_context
|
invoke_context
|
||||||
@ -1331,8 +1381,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemmove<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let cost = invoke_context.get_compute_budget().cpi_bytes_per_unit;
|
question_mark!(mem_op_consume(&invoke_context, n), result);
|
||||||
question_mark!(invoke_context.get_compute_meter().consume(n / cost), result);
|
|
||||||
|
|
||||||
let loader_id = question_mark!(
|
let loader_id = question_mark!(
|
||||||
invoke_context
|
invoke_context
|
||||||
@ -1375,8 +1424,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemcmp<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let cost = invoke_context.get_compute_budget().cpi_bytes_per_unit;
|
question_mark!(mem_op_consume(&invoke_context, n), result);
|
||||||
question_mark!(invoke_context.get_compute_meter().consume(n / cost), result);
|
|
||||||
|
|
||||||
let loader_id = question_mark!(
|
let loader_id = question_mark!(
|
||||||
invoke_context
|
invoke_context
|
||||||
@ -1432,8 +1480,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallMemset<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let cost = invoke_context.get_compute_budget().cpi_bytes_per_unit;
|
question_mark!(mem_op_consume(&invoke_context, n), result);
|
||||||
question_mark!(invoke_context.get_compute_meter().consume(n / cost), result);
|
|
||||||
|
|
||||||
let loader_id = question_mark!(
|
let loader_id = question_mark!(
|
||||||
invoke_context
|
invoke_context
|
||||||
@ -1576,9 +1623,11 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallBlake3<'a, 'b> {
|
|||||||
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let base_cost = invoke_context.get_compute_budget().sha256_base_cost;
|
let compute_budget = invoke_context.get_compute_budget();
|
||||||
question_mark!(
|
question_mark!(
|
||||||
invoke_context.get_compute_meter().consume(base_cost),
|
invoke_context
|
||||||
|
.get_compute_meter()
|
||||||
|
.consume(compute_budget.sha256_base_cost),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1613,13 +1662,10 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallBlake3<'a, 'b> {
|
|||||||
),
|
),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
let byte_cost = invoke_context.get_compute_budget().sha256_byte_cost;
|
|
||||||
question_mark!(
|
let cost = compute_budget.sha256_byte_cost * (val.len() as u64 / 2);
|
||||||
invoke_context
|
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
|
||||||
.get_compute_meter()
|
|
||||||
.consume(byte_cost * (val.len() as u64 / 2)),
|
|
||||||
result
|
|
||||||
);
|
|
||||||
hasher.hash(bytes);
|
hasher.hash(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3078,7 +3124,7 @@ mod tests {
|
|||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.get_compute_meter()
|
.get_compute_meter()
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.mock_set_remaining((string.len() as u64 * 5) - 1);
|
.mock_set_remaining(400 - 1);
|
||||||
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
|
||||||
syscall_sol_log.call(
|
syscall_sol_log.call(
|
||||||
0x100000001, // AccessViolation
|
0x100000001, // AccessViolation
|
||||||
@ -3464,7 +3510,7 @@ mod tests {
|
|||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.mock_set_remaining(
|
.mock_set_remaining(
|
||||||
(invoke_context.get_compute_budget().sha256_base_cost
|
(invoke_context.get_compute_budget().sha256_base_cost
|
||||||
+ (bytes1.len() + bytes2.len()) as u64
|
+ ((bytes1.len() + bytes2.len()) as u64 / 2)
|
||||||
* invoke_context.get_compute_budget().sha256_byte_cost)
|
* invoke_context.get_compute_budget().sha256_byte_cost)
|
||||||
* 4,
|
* 4,
|
||||||
);
|
);
|
||||||
|
@ -295,6 +295,10 @@ pub mod spl_associated_token_account_v1_0_4 {
|
|||||||
solana_sdk::declare_id!("FaTa4SpiaSNH44PGC4z8bnGVTkSRYaWvrBs3KTu8XQQq");
|
solana_sdk::declare_id!("FaTa4SpiaSNH44PGC4z8bnGVTkSRYaWvrBs3KTu8XQQq");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod update_syscall_base_costs {
|
||||||
|
solana_sdk::declare_id!("2h63t332mGCCsWK2nqqqHhN4U9ayyqhLVFvczznHDoTZ");
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||||
@ -363,6 +367,7 @@ lazy_static! {
|
|||||||
(require_rent_exempt_accounts::id(), "require all new transaction accounts with data to be rent-exempt"),
|
(require_rent_exempt_accounts::id(), "require all new transaction accounts with data to be rent-exempt"),
|
||||||
(vote_withdraw_authority_may_change_authorized_voter::id(), "vote account withdraw authority may change the authorized voter #22521"),
|
(vote_withdraw_authority_may_change_authorized_voter::id(), "vote account withdraw authority may change the authorized voter #22521"),
|
||||||
(spl_associated_token_account_v1_0_4::id(), "SPL Associated Token Account Program release version 1.0.4, tied to token 3.3.0 #22648"),
|
(spl_associated_token_account_v1_0_4::id(), "SPL Associated Token Account Program release version 1.0.4, tied to token 3.3.0 #22648"),
|
||||||
|
(update_syscall_base_costs::id(), "Update syscall base costs"),
|
||||||
/*************** ADD NEW FEATURES HERE ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user