From 0a89990cc9ef76159782d1a49eb539085504b240 Mon Sep 17 00:00:00 2001 From: Josh Lind Date: Fri, 26 Jul 2024 08:20:53 -0400 Subject: [PATCH] [Consensus Observer] Add missing tests for paylod store. --- .../src/consensus_observer/payload_store.rs | 92 ++++++++++++++++++- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/consensus/src/consensus_observer/payload_store.rs b/consensus/src/consensus_observer/payload_store.rs index 01798555c6bbf..047a44b182746 100644 --- a/consensus/src/consensus_observer/payload_store.rs +++ b/consensus/src/consensus_observer/payload_store.rs @@ -267,9 +267,11 @@ impl BlockPayloadStore { mod test { use super::*; use crate::consensus_observer::network_message::BlockTransactionPayload; + use aptos_bitvec::BitVec; use aptos_consensus_types::{ block::Block, block_data::{BlockData, BlockType}, + common::{Author, Payload, ProofWithData}, proof_of_store::{BatchId, BatchInfo, ProofOfStore}, quorum_cert::QuorumCert, }; @@ -277,11 +279,13 @@ mod test { use aptos_types::{ aggregate_signature::AggregateSignature, block_info::{BlockInfo, Round}, + ledger_info::{LedgerInfo, LedgerInfoWithSignatures}, transaction::Version, validator_signer::ValidatorSigner, validator_verifier::{ValidatorConsensusInfo, ValidatorVerifier}, PeerId, }; + use claims::assert_matches; use rand::{rngs::OsRng, Rng}; #[test] @@ -816,7 +820,7 @@ mod test { let epoch_state = EpochState::new(next_epoch, ValidatorVerifier::new(vec![])); // Verify the block payload signatures - block_payload_store.verify_payload_signatures(&epoch_state); + let verified_rounds = block_payload_store.verify_payload_signatures(&epoch_state); // Verify the unverified payloads were moved to the verified store assert!(block_payload_store.all_payloads_exist(&unverified_blocks)); @@ -829,6 +833,13 @@ mod test { num_future_blocks ); + // Check the rounds of the newly verified payloads + let expected_verified_rounds = unverified_blocks + .iter() + .map(|block| block.round()) + .collect::>(); + assert_eq!(verified_rounds, expected_verified_rounds); + // Clear the verified blocks and check the verified blocks are empty block_payload_store.remove_committed_blocks(&unverified_blocks); assert_eq!(get_num_verified_payloads(&block_payload_store), 0); @@ -837,7 +848,7 @@ mod test { let epoch_state = EpochState::new(future_epoch, ValidatorVerifier::new(vec![])); // Verify the block payload signatures for a future epoch - block_payload_store.verify_payload_signatures(&epoch_state); + let verified_rounds = block_payload_store.verify_payload_signatures(&epoch_state); // Verify the future unverified payloads were moved to the verified store assert!(block_payload_store.all_payloads_exist(&future_unverified_blocks)); @@ -846,6 +857,59 @@ mod test { num_future_blocks ); assert_eq!(get_num_unverified_payloads(&block_payload_store), 0); + + // Check the rounds of the newly verified payloads + let expected_verified_rounds = future_unverified_blocks + .iter() + .map(|block| block.round()) + .collect::>(); + assert_eq!(verified_rounds, expected_verified_rounds); + } + + #[test] + fn test_verify_payloads_against_ordered_block() { + // Create a new block payload store + let consensus_observer_config = ConsensusObserverConfig::default(); + let mut block_payload_store = BlockPayloadStore::new(consensus_observer_config); + + // Add some verified blocks for the current epoch + let current_epoch = 0; + let num_verified_blocks = 10; + let verified_blocks = create_and_add_blocks_to_store( + block_payload_store.clone(), + num_verified_blocks, + current_epoch, + true, + ); + + // Create an ordered block using the verified blocks + let ordered_block = OrderedBlock::new( + verified_blocks.clone(), + create_empty_ledger_info(current_epoch), + ); + + // Verify the ordered block and ensure it passes + block_payload_store + .verify_payloads_against_ordered_block(&ordered_block) + .unwrap(); + + // Mark the first block payload as unverified + mark_payload_as_unverified(block_payload_store.clone(), &verified_blocks[0]); + + // Verify the ordered block and ensure it fails (since the payloads are unverified) + let error = block_payload_store + .verify_payloads_against_ordered_block(&ordered_block) + .unwrap_err(); + assert_matches!(error, Error::InvalidMessageError(_)); + + // Clear the block payload store + block_payload_store.clear_all_payloads(); + + // Verify the ordered block and ensure it fails (since the payloads are missing) + let error = block_payload_store + .verify_payloads_against_ordered_block(&ordered_block) + .unwrap_err(); + assert_matches!(error, Error::InvalidMessageError(_)); } #[test] @@ -956,7 +1020,7 @@ mod test { } let block_transaction_payload = BlockTransactionPayload::new_quorum_store_inline_hybrid( vec![], - proofs_of_store, + proofs_of_store.clone(), None, vec![], ); @@ -965,13 +1029,25 @@ mod test { let block_payload = BlockPayload::new(block_info.clone(), block_transaction_payload); block_payload_store.insert_block_payload(block_payload, verified_payload_signatures); + // Create the block type + let payload = Payload::InQuorumStore(ProofWithData::new(proofs_of_store)); + let block_type = BlockType::DAGBlock { + author: Author::random(), + failed_authors: vec![], + validator_txns: vec![], + payload, + node_digests: vec![], + parent_block_id: HashValue::random(), + parents_bitvec: BitVec::with_num_bits(0), + }; + // Create the equivalent pipelined block let block_data = BlockData::new_for_testing( block_info.epoch(), block_info.round(), block_info.timestamp_usecs(), QuorumCert::dummy(), - BlockType::Genesis, + block_type, ); let block = Block::new_for_testing(block_info.id(), block_data, None); let pipelined_block = Arc::new(PipelinedBlock::new_ordered(block)); @@ -1001,6 +1077,14 @@ mod test { assert_eq!(num_payloads, expected_num_payloads); } + /// Creates and returns a new ledger info with an empty signature set + fn create_empty_ledger_info(epoch: u64) -> LedgerInfoWithSignatures { + LedgerInfoWithSignatures::new( + LedgerInfo::new(BlockInfo::random_with_epoch(epoch, 0), HashValue::random()), + AggregateSignature::empty(), + ) + } + /// Generates and returns a random number (u64) pub fn get_random_u64() -> u64 { OsRng.gen()