diff --git a/crates/shared/src/event_handling.rs b/crates/shared/src/event_handling.rs index f696ad9766..0570d5b64e 100644 --- a/crates/shared/src/event_handling.rs +++ b/crates/shared/src/event_handling.rs @@ -204,6 +204,31 @@ where }); } + // Special case where multiple new blocks were added and no reorg happened. + // Because we need to fetch the full block range we only do this if the number + // of new blocks is sufficiently small. + if let Ok(block_range) = + RangeInclusive::try_new(last_handled_block_number, current_block_number) + { + if block_range.end() - block_range.start() <= MAX_REORG_BLOCK_COUNT { + let mut new_blocks = self.block_retriever.blocks(block_range).await?; + if new_blocks.first().map(|b| b.1) == Some(last_handled_block_hash) { + // first block is not actually new and was only fetched to detect a reorg + new_blocks.remove(0); + tracing::debug!( + first_new=?new_blocks.first(), + last_new=?new_blocks.last(), + "multiple new blocks without reorg" + ); + return Ok(EventRange { + history_range: None, + latest_blocks: new_blocks, + is_reorg: false, + }); + } + } + } + // full range of blocks which are considered for event update let block_range = RangeInclusive::try_new( last_handled_block_number.saturating_sub(MAX_REORG_BLOCK_COUNT), @@ -811,6 +836,40 @@ mod tests { // add logs to event handler and observe } + #[tokio::test] + #[ignore] + async fn multiple_new_blocks_but_no_reorg_test() { + tracing_subscriber::fmt::init(); + let transport = create_env_test_transport(); + let web3 = Web3::new(transport); + let contract = GPv2Settlement::deployed(&web3).await.unwrap(); + let storage = EventStorage { events: vec![] }; + let current_block = web3.eth().block_number().await.unwrap(); + + const NUMBER_OF_BLOCKS: u64 = 300; + + //get block in history (current_block - NUMBER_OF_BLOCKS) + let block = web3 + .eth() + .block( + BlockNumber::Number(current_block.saturating_sub(NUMBER_OF_BLOCKS.into())).into(), + ) + .await + .unwrap() + .unwrap(); + let block = (block.number.unwrap().as_u64(), block.hash.unwrap()); + let mut event_handler = EventHandler::new( + Arc::new(web3), + GPv2SettlementContract(contract), + storage, + Some(block), + ); + let _result = event_handler.update_events().await; + tracing::info!("wait for at least 2 blocks to see if we hit the new code path"); + tokio::time::sleep(tokio::time::Duration::from_millis(26_000)).await; + let _result = event_handler.update_events().await; + } + #[tokio::test] #[ignore] async fn optional_block_skipping() {