Ensure blocks do not exceed the max accounts data size during Replay Stage (backport #23422) (#23589)

* Ensure blocks do not exceed the max accounts data size during Replay Stage (#23422)

(cherry picked from commit 3c6840050c)

# Conflicts:
#	runtime/src/bank.rs

* fix conflicts

Co-authored-by: Brooks Prumo <brooks@solana.com>
This commit is contained in:
mergify[bot]
2022-03-10 18:59:46 +00:00
committed by GitHub
parent 49952e05cf
commit e0f5fb887b
9 changed files with 60 additions and 26 deletions

View File

@ -42,6 +42,7 @@ use {
feature_set,
genesis_config::GenesisConfig,
hash::Hash,
instruction::InstructionError,
pubkey::Pubkey,
signature::{Keypair, Signature},
timing,
@ -224,6 +225,13 @@ fn execute_batch(
..
} = tx_results;
if bank
.feature_set
.is_active(&feature_set::cap_accounts_data_len::id())
{
check_accounts_data_size(&execution_results)?;
}
if let Some(transaction_status_sender) = transaction_status_sender {
let transactions = batch.sanitized_transactions().to_vec();
let post_token_balances = if record_token_balances {
@ -1583,6 +1591,30 @@ pub fn fill_blockstore_slot_with_ticks(
last_entry_hash
}
/// Check the transaction execution results to see if any instruction errored by exceeding the max
/// accounts data size limit for all slots. If yes, the whole block needs to be failed.
fn check_accounts_data_size<'a>(
execution_results: impl IntoIterator<Item = &'a TransactionExecutionResult>,
) -> Result<()> {
if let Some(result) = execution_results
.into_iter()
.map(|execution_result| execution_result.flattened_result())
.find(|result| {
matches!(
result,
Err(TransactionError::InstructionError(
_,
InstructionError::MaxAccountsDataSizeExceeded
)),
)
})
{
return result;
}
Ok(())
}
#[cfg(test)]
pub mod tests {
use {