Skip to content

Commit

Permalink
Check lamports balance before and after tx execution -- 1.16 (#33189)
Browse files Browse the repository at this point in the history
Check lamports balance before and after tx execution

Co-authored-by: Alessandro Decina <[email protected]>
  • Loading branch information
t-nelson and alessandrod authored Sep 8, 2023
1 parent 90d9839 commit b2a38f6
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
50 changes: 49 additions & 1 deletion runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ use {
hash::{extend_and_hash, hashv, Hash},
incinerator,
inflation::Inflation,
instruction::{CompiledInstruction, TRANSACTION_LEVEL_STACK_HEIGHT},
instruction::{CompiledInstruction, InstructionError, TRANSACTION_LEVEL_STACK_HEIGHT},
lamports::LamportsError,
loader_v4,
message::{AccountKeys, SanitizedMessage},
Expand Down Expand Up @@ -4052,6 +4052,42 @@ impl Bank {
) -> TransactionExecutionResult {
let prev_accounts_data_len = self.load_accounts_data_size();
let transaction_accounts = std::mem::take(&mut loaded_transaction.accounts);

fn transaction_accounts_lamports_sum(
accounts: &[(Pubkey, AccountSharedData)],
message: &SanitizedMessage,
) -> Option<u128> {
let mut lamports_sum = 0u128;
for i in 0..message.account_keys().len() {
let account = match accounts.get(i) {
Some((_, account)) => account,
None => return None,
};

lamports_sum = match lamports_sum.checked_add(u128::from(account.lamports())) {
Some(lamports_sum) => lamports_sum,
None => {
return None;
}
}
}

Some(lamports_sum)
}

let lamports_before_tx =
match transaction_accounts_lamports_sum(&transaction_accounts, tx.message()) {
Some(lamports) => lamports,
None => {
return TransactionExecutionResult::NotExecuted(
TransactionError::InstructionError(
0,
InstructionError::UnbalancedInstruction,
),
)
}
};

let mut transaction_context = TransactionContext::new(
transaction_accounts,
if self
Expand Down Expand Up @@ -4178,6 +4214,18 @@ impl Bank {
touched_account_count,
accounts_resize_delta,
} = transaction_context.into();

if status.is_ok()
&& transaction_accounts_lamports_sum(&accounts, tx.message())
.filter(|lamports_after_tx| lamports_before_tx == *lamports_after_tx)
.is_none()
{
return TransactionExecutionResult::NotExecuted(TransactionError::InstructionError(
0,
InstructionError::UnbalancedInstruction,
));
}

loaded_transaction.accounts = accounts;
if self
.feature_set
Expand Down
1 change: 1 addition & 0 deletions runtime/src/bank/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6696,6 +6696,7 @@ fn test_bank_hash_consistency() {
}

#[test]
#[ignore]
fn test_same_program_id_uses_unqiue_executable_accounts() {
declare_process_instruction!(process_instruction, 1, |invoke_context| {
let transaction_context = &invoke_context.transaction_context;
Expand Down

0 comments on commit b2a38f6

Please sign in to comment.