Skip to content

Commit 440ccd1

Browse files
Add program heap bump instruction (backport solana-labs#20607) (solana-labs#20815)
* Add program heap bump instruction (solana-labs#20607) (cherry picked from commit 5816451) * nudge Co-authored-by: Jack May <jack@solana.com>
1 parent d5fc81e commit 440ccd1

File tree

7 files changed

+247
-70
lines changed

7 files changed

+247
-70
lines changed

programs/bpf/benches/bpf_loader.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,54 @@ fn bench_program_execute_noop(bencher: &mut Bencher) {
193193
});
194194
}
195195

196+
#[bench]
197+
fn bench_create_vm(bencher: &mut Bencher) {
198+
const BUDGET: u64 = 200_000;
199+
let loader_id = bpf_loader::id();
200+
201+
let accounts = [RefCell::new(AccountSharedData::new(
202+
1,
203+
10000001,
204+
&solana_sdk::pubkey::new_rand(),
205+
))];
206+
let keys = [solana_sdk::pubkey::new_rand()];
207+
let keyed_accounts: Vec<_> = keys
208+
.iter()
209+
.zip(&accounts)
210+
.map(|(key, account)| solana_sdk::keyed_account::KeyedAccount::new(&key, false, &account))
211+
.collect();
212+
let instruction_data = vec![0u8];
213+
214+
let mut invoke_context = MockInvokeContext::new(keyed_accounts);
215+
invoke_context.compute_meter.remaining = BUDGET;
216+
217+
// Serialize account data
218+
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();
219+
let mut serialized = serialize_parameters(
220+
&bpf_loader::id(),
221+
&solana_sdk::pubkey::new_rand(),
222+
keyed_accounts,
223+
&instruction_data,
224+
)
225+
.unwrap();
226+
227+
let elf = load_elf("noop").unwrap();
228+
let mut executable =
229+
<dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(&elf, None, Config::default())
230+
.unwrap();
231+
executable.set_syscall_registry(register_syscalls(&mut invoke_context).unwrap());
232+
233+
bencher.iter(|| {
234+
let _ = create_vm(
235+
&loader_id,
236+
executable.as_ref(),
237+
serialized.as_slice_mut(),
238+
&mut invoke_context,
239+
)
240+
.unwrap();
241+
});
242+
}
243+
196244
#[bench]
197245
fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
198246
const BUDGET: u64 = 200_000;

programs/bpf_loader/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use solana_sdk::{
3434
entrypoint::{HEAP_LENGTH, SUCCESS},
3535
feature_set::{
3636
add_missing_program_error_mappings, close_upgradeable_program_accounts, fix_write_privs,
37-
reduce_required_deploy_balance, upgradeable_close_instruction,
37+
reduce_required_deploy_balance, requestable_heap_size, upgradeable_close_instruction,
3838
},
3939
ic_logger_msg, ic_msg,
4040
instruction::{AccountMeta, InstructionError},
@@ -150,6 +150,12 @@ pub fn create_vm<'a>(
150150
invoke_context: &'a mut dyn InvokeContext,
151151
) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
152152
let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
153+
let heap_size = bpf_compute_budget.heap_size.unwrap_or(HEAP_LENGTH);
154+
if invoke_context.is_feature_active(&requestable_heap_size::id()) {
155+
let _ = invoke_context.get_compute_meter().borrow_mut().consume(
156+
(heap_size as u64 / (32 * 1024)).saturating_sub(1) * bpf_compute_budget.heap_cost,
157+
);
158+
}
153159
let heap = AlignedMemory::new_with_size(
154160
bpf_compute_budget.heap_size.unwrap_or(HEAP_LENGTH),
155161
HOST_ALIGN,

runtime/src/bank.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3677,7 +3677,11 @@ impl Bank {
36773677
.unwrap_or_else(BpfComputeBudget::new);
36783678

36793679
let mut process_result = if feature_set.is_active(&tx_wide_compute_cap::id()) {
3680-
compute_budget::process_request(&mut bpf_compute_budget, tx)
3680+
compute_budget::process_request(
3681+
&mut bpf_compute_budget,
3682+
tx,
3683+
feature_set.clone(),
3684+
)
36813685
} else {
36823686
Ok(())
36833687
};
@@ -14253,6 +14257,7 @@ pub(crate) mod tests {
1425314257
*compute_budget,
1425414258
BpfComputeBudget {
1425514259
max_units: 1,
14260+
heap_size: Some(48 * 1024),
1425614261
..BpfComputeBudget::default()
1425714262
}
1425814263
);
@@ -14264,6 +14269,7 @@ pub(crate) mod tests {
1426414269
let message = Message::new(
1426514270
&[
1426614271
compute_budget::request_units(1),
14272+
compute_budget::request_heap_frame(48 * 1024),
1426714273
Instruction::new_with_bincode(program_id, &0, vec![]),
1426814274
],
1426914275
Some(&mint_keypair.pubkey()),

runtime/src/message_processor.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use solana_sdk::{
1111
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
1212
feature_set::{
1313
demote_program_write_locks, fix_write_privs, instructions_sysvar_enabled,
14-
neon_evm_compute_budget, remove_native_loader, tx_wide_compute_cap, updated_verify_policy,
15-
FeatureSet,
14+
neon_evm_compute_budget, remove_native_loader, requestable_heap_size, tx_wide_compute_cap,
15+
updated_verify_policy, FeatureSet,
1616
},
1717
ic_logger_msg, ic_msg,
1818
instruction::{CompiledInstruction, Instruction, InstructionError},
@@ -1227,11 +1227,17 @@ impl MessageProcessor {
12271227
let program_id = instruction.program_id(&message.account_keys);
12281228

12291229
let mut bpf_compute_budget = bpf_compute_budget;
1230-
if feature_set.is_active(&neon_evm_compute_budget::id())
1230+
if !feature_set.is_active(&tx_wide_compute_cap::id())
1231+
&& feature_set.is_active(&neon_evm_compute_budget::id())
12311232
&& *program_id == crate::neon_evm_program::id()
12321233
{
12331234
// Bump the compute budget for neon_evm
12341235
bpf_compute_budget.max_units = bpf_compute_budget.max_units.max(500_000);
1236+
}
1237+
if !feature_set.is_active(&requestable_heap_size::id())
1238+
&& feature_set.is_active(&neon_evm_compute_budget::id())
1239+
&& *program_id == crate::neon_evm_program::id()
1240+
{
12351241
bpf_compute_budget.heap_size = Some(256 * 1024);
12361242
}
12371243

0 commit comments

Comments
 (0)