Skip to content

Commit

Permalink
Replicates AccountsDataMeter in TransactionContext.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Jul 6, 2022
1 parent 37f4621 commit 0c977b7
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 41 deletions.
2 changes: 1 addition & 1 deletion cli/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2074,7 +2074,7 @@ fn read_and_verify_elf(program_location: &str) -> Result<Vec<u8>, Box<dyn std::e
let mut program_data = Vec::new();
file.read_to_end(&mut program_data)
.map_err(|err| format!("Unable to read program file: {}", err))?;
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1);
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1, 0);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);

// Verify the program
Expand Down
54 changes: 41 additions & 13 deletions program-runtime/src/invoke_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use solana_sdk::keyed_account::{create_keyed_accounts_unified, KeyedAccount};
use {
crate::{
accounts_data_meter::AccountsDataMeter,
accounts_data_meter::{AccountsDataMeter, MAX_ACCOUNTS_DATA_LEN},
compute_budget::ComputeBudget,
ic_logger_msg, ic_msg,
log_collector::LogCollector,
Expand Down Expand Up @@ -252,7 +252,7 @@ impl<'a> InvokeContext<'a> {
feature_set: Arc<FeatureSet>,
blockhash: Hash,
lamports_per_signature: u64,
initial_accounts_data_len: u64,
prev_accounts_data_len: u64,
) -> Self {
Self {
transaction_context,
Expand All @@ -265,7 +265,7 @@ impl<'a> InvokeContext<'a> {
current_compute_budget: compute_budget,
compute_budget,
compute_meter: ComputeMeter::new_ref(compute_budget.compute_unit_limit),
accounts_data_meter: AccountsDataMeter::new(initial_accounts_data_len),
accounts_data_meter: AccountsDataMeter::new(prev_accounts_data_len),
executors,
feature_set,
timings: ExecuteDetailsTimings::default(),
Expand Down Expand Up @@ -1152,6 +1152,7 @@ pub fn with_mock_invoke_context<R, F: FnMut(&mut InvokeContext) -> R>(
preparation.transaction_accounts,
ComputeBudget::default().max_invoke_depth.saturating_add(1),
1,
MAX_ACCOUNTS_DATA_LEN,
);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context
Expand Down Expand Up @@ -1182,6 +1183,7 @@ pub fn mock_process_instruction(
preparation.transaction_accounts,
ComputeBudget::default().max_invoke_depth.saturating_add(1),
1,
MAX_ACCOUNTS_DATA_LEN,
);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
if let Some(sysvar_cache) = sysvar_cache_override {
Expand Down Expand Up @@ -1226,7 +1228,7 @@ mod tests {
desired_result: Result<(), InstructionError>,
},
Resize {
new_len: usize,
new_len: u64,
},
}

Expand Down Expand Up @@ -1312,7 +1314,7 @@ mod tests {
}
MockInstruction::Resize { new_len } => instruction_context
.try_borrow_instruction_account(transaction_context, 0)?
.set_data(&vec![0; new_len])
.set_data(&vec![0; new_len as usize])
.unwrap(),
}
} else {
Expand Down Expand Up @@ -1355,7 +1357,7 @@ mod tests {
});
}
let mut transaction_context =
TransactionContext::new(accounts, ComputeBudget::default().max_invoke_depth, 1);
TransactionContext::new(accounts, ComputeBudget::default().max_invoke_depth, 1, 0);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);

// Check call depth increases and has a limit
Expand Down Expand Up @@ -1463,7 +1465,7 @@ mod tests {
let accounts = vec![(solana_sdk::pubkey::new_rand(), AccountSharedData::default())];
let instruction_accounts = vec![];
let program_indices = vec![0];
let mut transaction_context = TransactionContext::new(accounts, 1, 1);
let mut transaction_context = TransactionContext::new(accounts, 1, 1, 0);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context
.push(&instruction_accounts, &program_indices, &[])
Expand Down Expand Up @@ -1508,7 +1510,7 @@ mod tests {
is_writable: instruction_account_index < 2,
})
.collect::<Vec<_>>();
let mut transaction_context = TransactionContext::new(accounts, 2, 8);
let mut transaction_context = TransactionContext::new(accounts, 2, 8, 0);
let mut invoke_context =
InvokeContext::new_mock(&mut transaction_context, builtin_programs);

Expand Down Expand Up @@ -1640,7 +1642,7 @@ mod tests {
fn test_invoke_context_compute_budget() {
let accounts = vec![(solana_sdk::pubkey::new_rand(), AccountSharedData::default())];

let mut transaction_context = TransactionContext::new(accounts, 1, 3);
let mut transaction_context = TransactionContext::new(accounts, 1, 3, 0);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context.compute_budget =
ComputeBudget::new(compute_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64);
Expand All @@ -1658,8 +1660,9 @@ mod tests {
solana_logger::setup();

let program_key = Pubkey::new_unique();
let user_account_data_len = 123;
let user_account = AccountSharedData::new(100, user_account_data_len, &program_key);
let user_account_data_len = 123u64;
let user_account =
AccountSharedData::new(100, user_account_data_len as usize, &program_key);
let dummy_account = AccountSharedData::new(10, 0, &program_key);
let mut program_account = AccountSharedData::new(500, 500, &native_loader::id());
program_account.set_executable(true);
Expand All @@ -1674,7 +1677,8 @@ mod tests {
process_instruction: mock_process_instruction,
}];

let mut transaction_context = TransactionContext::new(accounts, 1, 3);
let mut transaction_context =
TransactionContext::new(accounts, 1, 3, user_account_data_len * 2);
let mut invoke_context =
InvokeContext::new_mock(&mut transaction_context, &builtin_programs);

Expand All @@ -1684,7 +1688,13 @@ mod tests {
invoke_context
.accounts_data_meter
.set_maximum(user_account_data_len as u64 * 3);
let remaining_account_data_len = invoke_context.accounts_data_meter.remaining() as usize;
let remaining_account_data_len = invoke_context
.transaction_context
.get_total_resize_remaining();
assert_eq!(
remaining_account_data_len,
invoke_context.accounts_data_meter.remaining(),
);

let instruction_accounts = [
InstructionAccount {
Expand Down Expand Up @@ -1719,6 +1729,12 @@ mod tests {

assert!(result.is_ok());
assert_eq!(invoke_context.accounts_data_meter.remaining(), 0);
assert_eq!(
invoke_context
.transaction_context
.get_total_resize_remaining(),
0
);
}

// Test 2: Resize the account to *the same size*, so not consuming any additional size; this must succeed
Expand All @@ -1737,6 +1753,12 @@ mod tests {

assert!(result.is_ok());
assert_eq!(invoke_context.accounts_data_meter.remaining(), 0);
assert_eq!(
invoke_context
.transaction_context
.get_total_resize_remaining(),
0
);
}

// Test 3: Resize the account to exceed the budget; this must fail
Expand All @@ -1759,6 +1781,12 @@ mod tests {
Err(solana_sdk::instruction::InstructionError::MaxAccountsDataSizeExceeded)
));
assert_eq!(invoke_context.accounts_data_meter.remaining(), 0);
assert_eq!(
invoke_context
.transaction_context
.get_total_resize_remaining(),
0
);
}
}
}
2 changes: 1 addition & 1 deletion programs/bpf_loader/benches/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ fn create_inputs() -> TransactionContext {
},
)
.collect::<Vec<_>>();
let mut transaction_context = TransactionContext::new(transaction_accounts, 1, 1);
let mut transaction_context = TransactionContext::new(transaction_accounts, 1, 1, 0);
let instruction_data = vec![1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
transaction_context
.push(&[0], &instruction_accounts, &instruction_data, true)
Expand Down
2 changes: 1 addition & 1 deletion programs/bpf_loader/src/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ mod tests {
&program_indices,
);
let mut transaction_context =
TransactionContext::new(preparation.transaction_accounts, 1, 1);
TransactionContext::new(preparation.transaction_accounts, 1, 1, 0);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context
.push(
Expand Down
19 changes: 8 additions & 11 deletions programs/bpf_loader/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3366,17 +3366,14 @@ mod tests {
$program_key:ident,
$loader_key:expr $(,)?) => {
let $program_key = Pubkey::new_unique();
let mut $transaction_context = TransactionContext::new(
vec![
(
$loader_key,
AccountSharedData::new(0, 0, &native_loader::id()),
),
($program_key, AccountSharedData::new(0, 0, &$loader_key)),
],
1,
1,
);
let transaction_accounts = vec![
(
$loader_key,
AccountSharedData::new(0, 0, &native_loader::id()),
),
($program_key, AccountSharedData::new(0, 0, &$loader_key)),
];
let mut $transaction_context = TransactionContext::new(transaction_accounts, 1, 1, 0);
let mut $invoke_context = InvokeContext::new_mock(&mut $transaction_context, &[]);
$invoke_context.push(&[], &[0, 1], &[]).unwrap();
};
Expand Down
9 changes: 5 additions & 4 deletions programs/stake/src/stake_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2785,6 +2785,7 @@ mod tests {
)],
1,
1,
0,
)
}

Expand Down Expand Up @@ -2894,7 +2895,7 @@ mod tests {

#[test]
fn test_things_can_merge() {
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1);
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1, 0);
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
let good_stake = Stake {
credits_observed: 4242,
Expand Down Expand Up @@ -2993,7 +2994,7 @@ mod tests {

#[test]
fn test_metas_can_merge() {
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1);
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1, 0);
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
// Identical Metas can merge
assert!(MergeKind::metas_can_merge(
Expand Down Expand Up @@ -3140,7 +3141,7 @@ mod tests {

#[test]
fn test_merge_kind_get_if_mergeable() {
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1);
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1, 0);
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
let authority_pubkey = Pubkey::new_unique();
let initial_lamports = 4242424242;
Expand Down Expand Up @@ -3379,7 +3380,7 @@ mod tests {

#[test]
fn test_merge_kind_merge() {
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1);
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1, 0);
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
let clock = Clock::default();
let lamports = 424242;
Expand Down
3 changes: 2 additions & 1 deletion programs/vote/benches/process_vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ fn bench_process_vote_instruction(
instruction_data: Vec<u8>,
) {
bencher.iter(|| {
let mut transaction_context = TransactionContext::new(transaction_accounts.clone(), 1, 1);
let mut transaction_context =
TransactionContext::new(transaction_accounts.clone(), 1, 1, 0);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context
.push(&instruction_accounts, &[0], &instruction_data)
Expand Down
3 changes: 2 additions & 1 deletion rbpf-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ native machine code before execting it in the virtual machine.",
let program_indices = [0, 1];
let preparation =
prepare_mock_invoke_context(transaction_accounts, instruction_accounts, &program_indices);
let mut transaction_context = TransactionContext::new(preparation.transaction_accounts, 1, 1);
let mut transaction_context =
TransactionContext::new(preparation.transaction_accounts, 1, 1, 0);
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
invoke_context
.push(
Expand Down
6 changes: 5 additions & 1 deletion runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4309,12 +4309,14 @@ impl Bank {
get_executors_time.as_us()
);

let prev_accounts_data_len = self.load_accounts_data_size();
let mut transaction_accounts = Vec::new();
std::mem::swap(&mut loaded_transaction.accounts, &mut transaction_accounts);
let mut transaction_context = TransactionContext::new(
transaction_accounts,
compute_budget.max_invoke_depth.saturating_add(1),
tx.message().instructions().len(),
MAX_ACCOUNTS_DATA_LEN.saturating_sub(prev_accounts_data_len),
);

let pre_account_state_info =
Expand Down Expand Up @@ -4345,7 +4347,7 @@ impl Bank {
&*self.sysvar_cache.read().unwrap(),
blockhash,
lamports_per_signature,
self.load_accounts_data_size(),
prev_accounts_data_len,
&mut executed_units,
);
process_message_time.stop();
Expand Down Expand Up @@ -4402,6 +4404,7 @@ impl Bank {
accounts,
instruction_trace,
mut return_data,
..
} = transaction_context.into();
loaded_transaction.accounts = accounts;

Expand Down Expand Up @@ -18634,6 +18637,7 @@ pub(crate) mod tests {
loaded_txs[0].0.as_ref().unwrap().accounts.clone(),
compute_budget.max_invoke_depth.saturating_add(1),
number_of_instructions_at_transaction_level,
0,
);

assert_eq!(
Expand Down
6 changes: 3 additions & 3 deletions runtime/src/message_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ mod tests {
create_loadable_account_for_test("mock_system_program"),
),
];
let mut transaction_context = TransactionContext::new(accounts, 1, 3);
let mut transaction_context = TransactionContext::new(accounts, 1, 3, 0);
let program_indices = vec![vec![2]];
let executors = Rc::new(RefCell::new(Executors::default()));
let account_keys = transaction_context.get_keys_of_accounts().to_vec();
Expand Down Expand Up @@ -502,7 +502,7 @@ mod tests {
create_loadable_account_for_test("mock_system_program"),
),
];
let mut transaction_context = TransactionContext::new(accounts, 1, 3);
let mut transaction_context = TransactionContext::new(accounts, 1, 3, 0);
let program_indices = vec![vec![2]];
let executors = Rc::new(RefCell::new(Executors::default()));
let account_metas = vec![
Expand Down Expand Up @@ -661,7 +661,7 @@ mod tests {
(secp256k1_program::id(), secp256k1_account),
(mock_program_id, mock_program_account),
];
let mut transaction_context = TransactionContext::new(accounts, 1, 2);
let mut transaction_context = TransactionContext::new(accounts, 1, 2, 0);

let message = SanitizedMessage::Legacy(Message::new(
&[
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/nonce_keyed_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ mod test {
is_writable: true,
},
];
let mut transaction_context = TransactionContext::new(accounts, 1, 2);
let mut transaction_context = TransactionContext::new(accounts, 1, 2, 0);
let mut $invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
};
}
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/system_instruction_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ mod tests {

#[test]
fn test_address_create_with_seed_mismatch() {
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1);
let mut transaction_context = TransactionContext::new(Vec::new(), 1, 1, 0);
let invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
let from = Pubkey::new_unique();
let seed = "dull boy";
Expand Down
Loading

0 comments on commit 0c977b7

Please sign in to comment.