chain-state: add unit test for set_pending_block (#10363)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Thomas Coratger
2024-08-20 01:27:10 -07:00
committed by GitHub
parent 3aaa284a5e
commit 5530fb0680

View File

@ -112,7 +112,7 @@ impl InMemoryState {
/// Returns the pending state corresponding to the current head plus one, /// Returns the pending state corresponding to the current head plus one,
/// from the payload received in newPayload that does not have a FCU yet. /// from the payload received in newPayload that does not have a FCU yet.
pub(crate) fn pending_state(&self) -> Option<Arc<BlockState>> { pub(crate) fn pending_state(&self) -> Option<Arc<BlockState>> {
self.pending.borrow().as_ref().map(|state| Arc::new(BlockState::new(state.block.clone()))) self.pending.borrow().as_ref().map(|state| Arc::new(state.clone()))
} }
#[cfg(test)] #[cfg(test)]
@ -159,8 +159,8 @@ pub struct CanonicalInMemoryState {
} }
impl CanonicalInMemoryState { impl CanonicalInMemoryState {
/// Create a new in memory state with the given blocks, numbers, pending state and finalized /// Create a new in-memory state with the given blocks, numbers, pending state, and optional
/// header if it exists. /// finalized header.
pub fn new( pub fn new(
blocks: HashMap<B256, Arc<BlockState>>, blocks: HashMap<B256, Arc<BlockState>>,
numbers: BTreeMap<u64, B256>, numbers: BTreeMap<u64, B256>,
@ -168,21 +168,20 @@ impl CanonicalInMemoryState {
finalized: Option<SealedHeader>, finalized: Option<SealedHeader>,
) -> Self { ) -> Self {
let in_memory_state = InMemoryState::new(blocks, numbers, pending); let in_memory_state = InMemoryState::new(blocks, numbers, pending);
let head_state = in_memory_state.head_state(); let header = in_memory_state
let header = .head_state()
head_state.map(|state| state.block().block().header.clone()).unwrap_or_default(); .map_or_else(SealedHeader::default, |state| state.block().block().header.clone());
let chain_info_tracker = ChainInfoTracker::new(header, finalized); let chain_info_tracker = ChainInfoTracker::new(header, finalized);
let (canon_state_notification_sender, _) = let (canon_state_notification_sender, _) =
broadcast::channel(CANON_STATE_NOTIFICATION_CHANNEL_SIZE); broadcast::channel(CANON_STATE_NOTIFICATION_CHANNEL_SIZE);
let inner = CanonicalInMemoryStateInner { Self {
chain_info_tracker, inner: Arc::new(CanonicalInMemoryStateInner {
in_memory_state, chain_info_tracker,
canon_state_notification_sender, in_memory_state,
}; canon_state_notification_sender,
}),
Self { inner: Arc::new(inner) } }
} }
/// Create an empty state. /// Create an empty state.
@ -1108,6 +1107,58 @@ mod tests {
assert_eq!(state.inner.in_memory_state.block_count(), 1); assert_eq!(state.inner.in_memory_state.block_count(), 1);
} }
#[test]
fn test_in_memory_state_set_pending_block() {
let state = CanonicalInMemoryState::empty();
let mut test_block_builder = TestBlockBuilder::default();
// First random block
let block1 = test_block_builder.get_executed_block_with_number(0, B256::random());
// Second block with parent hash of the first block
let block2 = test_block_builder.get_executed_block_with_number(1, block1.block().hash());
// Commit the two blocks
let chain = NewCanonicalChain::Commit { new: vec![block1.clone(), block2.clone()] };
state.update_chain(chain);
// Assert that the pending state is None before setting it
assert!(state.pending_state().is_none());
// Set the pending block
state.set_pending_block(block2.clone());
// Check the pending state
assert_eq!(
state.pending_state().unwrap(),
Arc::new(BlockState::with_parent(block2.clone(), Some(BlockState::new(block1))))
);
// Check the pending block
assert_eq!(state.pending_block().unwrap(), block2.block().clone());
// Check the pending block number and hash
assert_eq!(
state.pending_block_num_hash().unwrap(),
BlockNumHash { number: 1, hash: block2.block().hash() }
);
// Check the pending header
assert_eq!(state.pending_header().unwrap(), block2.block().header.header().clone());
// Check the pending sealed header
assert_eq!(state.pending_sealed_header().unwrap(), block2.block().header.clone());
// Check the pending block with senders
assert_eq!(
state.pending_block_with_senders().unwrap(),
block2.block().clone().seal_with_senders().unwrap()
);
// Check the pending block and receipts
assert_eq!(state.pending_block_and_receipts().unwrap(), (block2.block().clone(), vec![]));
}
#[test] #[test]
fn test_canonical_in_memory_state_state_provider() { fn test_canonical_in_memory_state_state_provider() {
let mut test_block_builder = TestBlockBuilder::default(); let mut test_block_builder = TestBlockBuilder::default();