diff --git a/core/src/banking_stage/consumer.rs b/core/src/banking_stage/consumer.rs index 667ffa8c7c6066..1b8487a923b972 100644 --- a/core/src/banking_stage/consumer.rs +++ b/core/src/banking_stage/consumer.rs @@ -403,12 +403,20 @@ impl Consumer { let pre_results = vec![Ok(()); txs.len()]; let check_results = bank.check_transactions(txs, &pre_results, MAX_PROCESSING_AGE, &mut error_counters); - let check_results = check_results.into_iter().map(|(result, _nonce)| result); + // If checks passed, verify pre-compiles and continue processing on success. + let check_results: Vec<_> = txs + .iter() + .zip(check_results) + .map(|(tx, (result, _nonce))| match result { + Ok(_) => tx.verify_precompiles(&bank.feature_set), + Err(err) => Err(err), + }) + .collect(); let mut output = self.process_and_record_transactions_with_pre_results( bank, txs, chunk_offset, - check_results, + check_results.into_iter(), ); // Accumulate error counters from the initial checks into final results @@ -425,11 +433,13 @@ impl Consumer { txs: &[SanitizedTransaction], max_slot_ages: &[Slot], ) -> ProcessTransactionBatchOutput { + // Verify pre-compiles. // Need to filter out transactions since they were sanitized earlier. // This means that the transaction may cross and epoch boundary (not allowed), // or account lookup tables may have been closed. let pre_results = txs.iter().zip(max_slot_ages).map(|(tx, max_slot_age)| { if *max_slot_age < bank.slot() { + // Pre-compiles are verified here. // Attempt re-sanitization after epoch-cross. // Re-sanitized transaction should be equal to the original transaction, // but whether it will pass sanitization needs to be checked. @@ -440,6 +450,8 @@ impl Consumer { return Err(TransactionError::ResanitizationNeeded); } } else { + // Verify pre-compiles. + tx.verify_precompiles(&bank.feature_set)?; // Any transaction executed between sanitization time and now may have closed the lookup table(s). // Above re-sanitization already loads addresses, so don't need to re-check in that case. let lookup_tables = tx.message().message_address_table_lookups(); diff --git a/core/src/banking_stage/immutable_deserialized_packet.rs b/core/src/banking_stage/immutable_deserialized_packet.rs index 51152d69dc3c70..d5acbd3fe0d182 100644 --- a/core/src/banking_stage/immutable_deserialized_packet.rs +++ b/core/src/banking_stage/immutable_deserialized_packet.rs @@ -104,10 +104,10 @@ impl ImmutableDeserializedPacket { } // This function deserializes packets into transactions, computes the blake3 hash of transaction - // messages, and verifies secp256k1 instructions. + // messages. pub fn build_sanitized_transaction( &self, - feature_set: &Arc, + _feature_set: &Arc, votes_only: bool, address_loader: impl AddressLoader, ) -> Option { @@ -121,7 +121,6 @@ impl ImmutableDeserializedPacket { address_loader, ) .ok()?; - tx.verify_precompiles(feature_set).ok()?; Some(tx) } }