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

This commit is contained in:
Brooks Prumo
2022-03-10 10:24:31 -06:00
committed by GitHub
parent 58c0db9704
commit 3c6840050c
9 changed files with 56 additions and 24 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 {
@ -1540,6 +1548,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 {