Skip to content

Commit

Permalink
The constraints on compute power a program can consume is limited onl…
Browse files Browse the repository at this point in the history
…y to its instruction count (#11717)
  • Loading branch information
jackcmay authored Aug 21, 2020
1 parent 418b483 commit 8d362f6
Show file tree
Hide file tree
Showing 17 changed files with 348 additions and 135 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion genesis-programs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ extern crate solana_exchange_program;
extern crate solana_vest_program;

use log::*;
use solana_runtime::bank::{Bank, EnteredEpochCallback};
use solana_runtime::{
bank::{Bank, EnteredEpochCallback},
message_processor::{DEFAULT_COMPUTE_BUDGET, DEFAULT_MAX_INVOKE_DEPTH},
};
use solana_sdk::{
clock::Epoch, entrypoint_native::ProcessInstructionWithContext, genesis_config::OperatingMode,
inflation::Inflation, pubkey::Pubkey,
Expand Down Expand Up @@ -145,6 +148,9 @@ pub fn get_entered_epoch_callback(operating_mode: OperatingMode) -> EnteredEpoch
} else {
bank.set_cross_program_support(true);
}

bank.set_max_invoke_depth(DEFAULT_MAX_INVOKE_DEPTH);
bank.set_compute_budget(DEFAULT_COMPUTE_BUDGET);
})
}

Expand Down
4 changes: 2 additions & 2 deletions programs/bpf/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion programs/bpf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ solana-bpf-loader-program = { path = "../bpf_loader", version = "1.4.0" }
solana-logger = { path = "../../logger", version = "1.4.0" }
solana-runtime = { path = "../../runtime", version = "1.4.0" }
solana-sdk = { path = "../../sdk", version = "1.4.0" }
solana_rbpf = "=0.1.28"
solana_rbpf = "=0.1.30"

[[bench]]
name = "bpf_loader"
Expand Down
24 changes: 22 additions & 2 deletions programs/bpf/benches/bpf_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
use solana_rbpf::EbpfVm;
use solana_sdk::{
account::Account,
entrypoint_native::{InvokeContext, Logger, ProcessInstruction},
entrypoint_native::{ComputeMeter, InvokeContext, Logger, ProcessInstruction},
instruction::{CompiledInstruction, InstructionError},
message::Message,
pubkey::Pubkey,
Expand Down Expand Up @@ -96,7 +96,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
bencher.iter(|| {
vm.execute_program(&mut inner_iter, &[], &[]).unwrap();
});
let instructions = vm.get_last_instruction_count();
let instructions = vm.get_total_instruction_count();
let summary = bencher.bench(|_bencher| {}).unwrap();
println!(" {:?} instructions", instructions);
println!(" {:?} ns/iter median", summary.median as u64);
Expand Down Expand Up @@ -136,6 +136,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
pub struct MockInvokeContext {
key: Pubkey,
mock_logger: MockLogger,
mock_compute_meter: MockComputeMeter,
}
impl InvokeContext for MockInvokeContext {
fn push(&mut self, _key: &Pubkey) -> Result<(), InstructionError> {
Expand All @@ -162,6 +163,9 @@ impl InvokeContext for MockInvokeContext {
fn is_cross_program_supported(&self) -> bool {
true
}
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
Rc::new(RefCell::new(self.mock_compute_meter.clone()))
}
}
#[derive(Debug, Default, Clone)]
pub struct MockLogger {
Expand All @@ -175,3 +179,19 @@ impl Logger for MockLogger {
self.log.borrow_mut().push(message.to_string());
}
}
#[derive(Debug, Default, Clone)]
pub struct MockComputeMeter {
pub remaining: u64,
}
impl ComputeMeter for MockComputeMeter {
fn consume(&mut self, amount: u64) -> Result<(), InstructionError> {
self.remaining = self.remaining.saturating_sub(amount);
if self.remaining == 0 {
return Err(InstructionError::ComputationalBudgetExceeded);
}
Ok(())
}
fn get_remaining(&self) -> u64 {
self.remaining
}
}
27 changes: 27 additions & 0 deletions programs/bpf/c/src/invoke/invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,33 @@ extern uint64_t entrypoint(const uint8_t *input) {
SOL_ARRAY_SIZE(signers_seeds)));
}

sol_log("Test multiple derived signers");
{
SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY1_INDEX].key, true, false},
{accounts[DERIVED_KEY2_INDEX].key, true, true},
{accounts[DERIVED_KEY3_INDEX].key, false, true}};
uint8_t data[] = {TEST_VERIFY_NESTED_SIGNERS};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
uint8_t seed1[] = {'L', 'i', 'l', '\''};
uint8_t seed2[] = {'B', 'i', 't', 's'};
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
{seed2, SOL_ARRAY_SIZE(seed2)},
{&nonce2, 1}};
const SolSignerSeed seeds2[] = {
{(uint8_t *)accounts[DERIVED_KEY2_INDEX].key, SIZE_PUBKEY},
{&nonce3, 1}};
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)},
{seeds2, SOL_ARRAY_SIZE(seeds2)}};

sol_assert(SUCCESS == sol_invoke_signed(&instruction, accounts,
SOL_ARRAY_SIZE(accounts),
signers_seeds,
SOL_ARRAY_SIZE(signers_seeds)));
}

sol_log("Test readonly with writable account");
{
SolAccountMeta arguments[] = {
Expand Down
25 changes: 0 additions & 25 deletions programs/bpf/c/src/invoked/invoked.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,31 +97,6 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);

uint8_t nonce2 = params.data[1];
uint8_t nonce3 = params.data[2];

SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY1_INDEX].key, true, false},
{accounts[DERIVED_KEY2_INDEX].key, true, true},
{accounts[DERIVED_KEY3_INDEX].key, false, true}};
uint8_t data[] = {TEST_VERIFY_NESTED_SIGNERS};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
uint8_t seed1[] = {'L', 'i', 'l', '\''};
uint8_t seed2[] = {'B', 'i', 't', 's'};
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
{seed2, SOL_ARRAY_SIZE(seed2)},
{&nonce2, 1}};
const SolSignerSeed seeds2[] = {
{(uint8_t *)accounts[DERIVED_KEY2_INDEX].key, SIZE_PUBKEY},
{&nonce3, 1}};
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)},
{seeds2, SOL_ARRAY_SIZE(seeds2)}};

sol_assert(SUCCESS == sol_invoke_signed(
&instruction, accounts, SOL_ARRAY_SIZE(accounts),
signers_seeds, SOL_ARRAY_SIZE(signers_seeds)));
break;
}

Expand Down
28 changes: 21 additions & 7 deletions programs/bpf/rust/invoke/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,24 @@ fn process_instruction(
accounts,
&[&[b"You pass butter", &[nonce1]]],
)?;

let invoked_instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[
(accounts[DERIVED_KEY1_INDEX].key, true, false),
(accounts[DERIVED_KEY2_INDEX].key, true, true),
(accounts[DERIVED_KEY3_INDEX].key, false, true),
],
vec![TEST_VERIFY_NESTED_SIGNERS],
);
invoke_signed(
&invoked_instruction,
accounts,
&[
&[b"Lil'", b"Bits", &[nonce2]],
&[accounts[DERIVED_KEY2_INDEX].key.as_ref(), &[nonce3]],
],
)?;
}

info!("Test readonly with writable account");
Expand All @@ -188,20 +206,16 @@ fn process_instruction(
&[
(accounts[ARGUMENT_INDEX].key, true, true),
(accounts[INVOKED_ARGUMENT_INDEX].key, true, true),
(accounts[INVOKED_PROGRAM_DUP_INDEX].key, false, false),
(accounts[INVOKED_PROGRAM_DUP_INDEX].key, false, false),
],
vec![TEST_NESTED_INVOKE],
);
invoke(&instruction, accounts)?;
info!("2nd invoke from first program");
invoke(&instruction, accounts)?;

assert_eq!(accounts[ARGUMENT_INDEX].lamports(), 42 - 5 + 1 + 1 + 1 + 1);
assert_eq!(
accounts[INVOKED_ARGUMENT_INDEX].lamports(),
10 + 5 - 1 - 1 - 1 - 1
);
info!(line!(), 0, 0, 0, accounts[ARGUMENT_INDEX].lamports());
assert_eq!(accounts[ARGUMENT_INDEX].lamports(), 42 - 5 + 1 + 1);
assert_eq!(accounts[INVOKED_ARGUMENT_INDEX].lamports(), 10 + 5 - 1 - 1);
}

info!("Verify data values are retained and updated");
Expand Down
30 changes: 2 additions & 28 deletions programs/bpf/rust/invoked/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,8 @@ extern crate solana_sdk;

use crate::instruction::*;
use solana_sdk::{
account_info::AccountInfo,
bpf_loader, entrypoint,
entrypoint::ProgramResult,
info,
program::{invoke, invoke_signed},
program_error::ProgramError,
pubkey::Pubkey,
account_info::AccountInfo, bpf_loader, entrypoint, entrypoint::ProgramResult, info,
program::invoke, program_error::ProgramError, pubkey::Pubkey,
};

entrypoint!(process_instruction);
Expand Down Expand Up @@ -111,34 +106,13 @@ fn process_instruction(
}
TEST_DERIVED_SIGNERS => {
info!("verify derived signers");
const INVOKED_PROGRAM_INDEX: usize = 0;
const DERIVED_KEY1_INDEX: usize = 1;
const DERIVED_KEY2_INDEX: usize = 2;
const DERIVED_KEY3_INDEX: usize = 3;

assert!(accounts[DERIVED_KEY1_INDEX].is_signer);
assert!(!accounts[DERIVED_KEY2_INDEX].is_signer);
assert!(!accounts[DERIVED_KEY3_INDEX].is_signer);

let nonce2 = instruction_data[1];
let nonce3 = instruction_data[2];
let invoked_instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[
(accounts[DERIVED_KEY1_INDEX].key, true, false),
(accounts[DERIVED_KEY2_INDEX].key, true, true),
(accounts[DERIVED_KEY3_INDEX].key, false, true),
],
vec![TEST_VERIFY_NESTED_SIGNERS],
);
invoke_signed(
&invoked_instruction,
accounts,
&[
&[b"Lil'", b"Bits", &[nonce2]],
&[accounts[DERIVED_KEY2_INDEX].key.as_ref(), &[nonce3]],
],
)?;
}
TEST_VERIFY_NESTED_SIGNERS => {
info!("verify nested derived signers");
Expand Down
4 changes: 2 additions & 2 deletions programs/bpf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,9 @@ fn test_program_bpf_invoke() {
let (derived_key1, nonce1) =
Pubkey::find_program_address(&[b"You pass butter"], &invoke_program_id);
let (derived_key2, nonce2) =
Pubkey::find_program_address(&[b"Lil'", b"Bits"], &invoked_program_id);
Pubkey::find_program_address(&[b"Lil'", b"Bits"], &invoke_program_id);
let (derived_key3, nonce3) =
Pubkey::find_program_address(&[derived_key2.as_ref()], &invoked_program_id);
Pubkey::find_program_address(&[derived_key2.as_ref()], &invoke_program_id);

let mint_pubkey = mint_keypair.pubkey();
let account_metas = vec![
Expand Down
2 changes: 1 addition & 1 deletion programs/bpf_loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ num-derive = { version = "0.3" }
num-traits = { version = "0.2" }
solana-runtime = { path = "../../runtime", version = "1.4.0" }
solana-sdk = { path = "../../sdk", version = "1.4.0" }
solana_rbpf = "=0.1.28"
solana_rbpf = "=0.1.30"
thiserror = "1.0"

[dev-dependencies]
Expand Down
Loading

0 comments on commit 8d362f6

Please sign in to comment.