diff --git a/crates/flashblocks-rpc/src/pending_blocks.rs b/crates/flashblocks-rpc/src/pending_blocks.rs index c6c1422..dba4a1b 100644 --- a/crates/flashblocks-rpc/src/pending_blocks.rs +++ b/crates/flashblocks-rpc/src/pending_blocks.rs @@ -1,4 +1,5 @@ use alloy_consensus::{Header, Sealed}; +use alloy_eips::BlockNumberOrTag; use alloy_primitives::{ map::foldhash::{HashMap, HashMapExt}, Address, BlockNumber, TxHash, B256, U256, @@ -151,6 +152,10 @@ impl PendingBlocks { self.headers.last().unwrap().number } + pub fn canonical_block_number(&self) -> BlockNumberOrTag { + BlockNumberOrTag::Number(self.headers.first().unwrap().number - 1) + } + pub fn latest_flashblock_index(&self) -> u64 { self.flashblocks.last().unwrap().index } diff --git a/crates/flashblocks-rpc/src/rpc.rs b/crates/flashblocks-rpc/src/rpc.rs index 1586f14..85be61a 100644 --- a/crates/flashblocks-rpc/src/rpc.rs +++ b/crates/flashblocks-rpc/src/rpc.rs @@ -2,12 +2,14 @@ use std::sync::Arc; use std::time::Duration; use crate::metrics::Metrics; +use crate::pending_blocks::PendingBlocks; use crate::subscription::Flashblock; use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::{Address, TxHash, U256}; use alloy_rpc_types::simulate::{SimBlock, SimulatePayload, SimulatedBlock}; use alloy_rpc_types::state::{EvmOverrides, StateOverride, StateOverridesBuilder}; use alloy_rpc_types::BlockOverrides; +use arc_swap::Guard; use jsonrpsee::{ core::{async_trait, RpcResult}, proc_macros::rpc, @@ -35,24 +37,32 @@ pub const MAX_TIMEOUT_SEND_RAW_TX_SYNC_MS: u64 = 6_000; /// Core API for accessing flashblock state and data. pub trait FlashblocksAPI { + /// Retrieves the pending blocks. + fn get_pending_blocks(&self) -> Guard>>; + + fn subscribe_to_flashblocks(&self) -> broadcast::Receiver; +} + +pub trait PendingBlocksAPI { + /// Get the canonical block number on top of which all pending state is built + fn get_canonical_block_number(&self) -> BlockNumberOrTag; + + /// Get the pending transactions count for an address + fn get_transaction_count(&self, address: Address) -> U256; + /// Retrieves the current block. If `full` is true, includes full transaction details. fn get_block(&self, full: bool) -> Option>; /// Gets transaction receipt by hash. fn get_transaction_receipt(&self, tx_hash: TxHash) -> Option>; - /// Gets transaction count (nonce) for an address. - fn get_transaction_count(&self, address: Address) -> U256; - /// Gets transaction details by hash. fn get_transaction_by_hash(&self, tx_hash: TxHash) -> Option>; /// Gets balance for an address. Returns None if address not updated in flashblocks. fn get_balance(&self, address: Address) -> Option; - /// Creates a subscription to receive flashblock updates. - fn subscribe_to_flashblocks(&self) -> broadcast::Receiver; - + /// Gets the state overrides for the pending blocks fn get_state_overrides(&self) -> Option; } @@ -157,7 +167,8 @@ where if number.is_pending() { self.metrics.get_block_by_number.increment(1); - Ok(self.flashblocks_state.get_block(full)) + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + Ok(pending_blocks.get_block(full)) } else { EthBlocks::rpc_block(&self.eth_api, number.into(), full) .await @@ -174,7 +185,8 @@ where tx_hash = %tx_hash ); - if let Some(fb_receipt) = self.flashblocks_state.get_transaction_receipt(tx_hash) { + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + if let Some(fb_receipt) = pending_blocks.get_transaction_receipt(tx_hash) { self.metrics.get_transaction_receipt.increment(1); return Ok(Some(fb_receipt)); } @@ -196,7 +208,8 @@ where let block_id = block_number.unwrap_or_default(); if block_id.is_pending() { self.metrics.get_balance.increment(1); - if let Some(balance) = self.flashblocks_state.get_balance(address) { + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + if let Some(balance) = pending_blocks.get_balance(address) { return Ok(balance); } } @@ -219,16 +232,16 @@ where let block_id = block_number.unwrap_or_default(); if block_id.is_pending() { self.metrics.get_transaction_count.increment(1); - let latest_count = EthState::transaction_count( - &self.eth_api, - address, - Some(BlockId::Number(BlockNumberOrTag::Latest)), - ) - .await - .map_err(Into::into)?; + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + let canon_block = pending_blocks.get_canonical_block_number(); + let fb_count = pending_blocks.get_transaction_count(address); + + let canon_count = + EthState::transaction_count(&self.eth_api, address, Some(canon_block.into())) + .await + .map_err(Into::into)?; - let fb_count = self.flashblocks_state.get_transaction_count(address); - return Ok(latest_count + fb_count); + return Ok(canon_count + fb_count); } EthState::transaction_count(&self.eth_api, address, block_number) @@ -245,7 +258,9 @@ where tx_hash = %tx_hash ); - if let Some(fb_transaction) = self.flashblocks_state.get_transaction_by_hash(tx_hash) { + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + + if let Some(fb_transaction) = pending_blocks.get_transaction_by_hash(tx_hash) { self.metrics.get_transaction_receipt.increment(1); return Ok(Some(fb_transaction)); } @@ -329,12 +344,14 @@ where block_overrides = ?block_overrides, ); - let block_id = block_number.unwrap_or_default(); + let mut block_id = block_number.unwrap_or_default(); let mut pending_overrides = EvmOverrides::default(); // If the call is to pending block use cached override (if they exist) if block_id.is_pending() { self.metrics.call.increment(1); - pending_overrides.state = self.flashblocks_state.get_state_overrides(); + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + block_id = pending_blocks.get_canonical_block_number().into(); + pending_overrides.state = pending_blocks.get_state_overrides(); } // Apply user's overrides on top @@ -348,7 +365,7 @@ where EthCall::call( &self.eth_api, transaction, - block_number, + Some(block_id), EvmOverrides::new(Some(final_overrides), block_overrides), ) .await @@ -368,12 +385,14 @@ where overrides = ?overrides, ); - let block_id = block_number.unwrap_or_default(); + let mut block_id = block_number.unwrap_or_default(); let mut pending_overrides = EvmOverrides::default(); // If the call is to pending block use cached override (if they exist) if block_id.is_pending() { self.metrics.estimate_gas.increment(1); - pending_overrides.state = self.flashblocks_state.get_state_overrides(); + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + block_id = pending_blocks.get_canonical_block_number().into(); + pending_overrides.state = pending_blocks.get_state_overrides(); } let mut state_overrides_builder = @@ -396,13 +415,15 @@ where block_number = ?block_number, ); - let block_id = block_number.unwrap_or_default(); + let mut block_id = block_number.unwrap_or_default(); let mut pending_overrides = EvmOverrides::default(); // If the call is to pending block use cached override (if they exist) if block_id.is_pending() { self.metrics.simulate_v1.increment(1); - pending_overrides.state = self.flashblocks_state.get_state_overrides(); + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + block_id = pending_blocks.get_canonical_block_number().into(); + pending_overrides.state = pending_blocks.get_state_overrides(); } // Prepend flashblocks pending overrides to the block state calls @@ -444,7 +465,8 @@ where match receiver.recv().await { Ok(flashblock) if flashblock.metadata.receipts.contains_key(&tx_hash) => { debug!(message = "found receipt in flashblock", tx_hash = %tx_hash); - return self.flashblocks_state.get_transaction_receipt(tx_hash); + let pending_blocks = self.flashblocks_state.get_pending_blocks(); + return pending_blocks.get_transaction_receipt(tx_hash); } Ok(_) => { trace!(message = "flashblock does not contain receipt", tx_hash = %tx_hash); diff --git a/crates/flashblocks-rpc/src/state.rs b/crates/flashblocks-rpc/src/state.rs index 6c1bf5c..b00d5e0 100644 --- a/crates/flashblocks-rpc/src/state.rs +++ b/crates/flashblocks-rpc/src/state.rs @@ -1,21 +1,20 @@ use crate::metrics::Metrics; use crate::pending_blocks::{PendingBlocks, PendingBlocksBuilder}; -use crate::rpc::FlashblocksAPI; +use crate::rpc::{FlashblocksAPI, PendingBlocksAPI}; use crate::subscription::{Flashblock, FlashblocksReceiver}; use alloy_consensus::transaction::{Recovered, SignerRecoverable, TransactionMeta}; use alloy_consensus::{Header, TxReceipt}; use alloy_eips::BlockNumberOrTag; use alloy_primitives::map::foldhash::HashMap; use alloy_primitives::map::B256HashMap; -use alloy_primitives::{Address, BlockNumber, Bytes, Sealable, TxHash, B256, U256}; -use alloy_rpc_types::{TransactionTrait, Withdrawal}; +use alloy_primitives::{Address, BlockNumber, Bytes, Sealable, B256, U256}; +use alloy_rpc_types::{state::StateOverride, TransactionTrait, Withdrawal}; use alloy_rpc_types_engine::{ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3}; -use alloy_rpc_types_eth::state::{AccountOverride, StateOverride, StateOverridesBuilder}; -use arc_swap::ArcSwapOption; +use alloy_rpc_types_eth::state::{AccountOverride, StateOverridesBuilder}; +use arc_swap::{ArcSwapOption, Guard}; use eyre::eyre; use op_alloy_consensus::OpTxEnvelope; -use op_alloy_network::Optimism; -use op_alloy_network::TransactionResponse; +use op_alloy_network::{Optimism, TransactionResponse}; use op_alloy_rpc_types::Transaction; use reth::chainspec::{ChainSpecProvider, EthChainSpec}; use reth::providers::{BlockReaderIdExt, StateProviderFactory}; @@ -29,8 +28,7 @@ use reth_optimism_evm::{OpEvmConfig, OpNextBlockEnvAttributes}; use reth_optimism_primitives::{DepositReceipt, OpBlock, OpPrimitives}; use reth_optimism_rpc::OpReceiptBuilder; use reth_primitives::RecoveredBlock; -use reth_rpc_convert::transaction::ConvertReceiptInput; -use reth_rpc_convert::RpcTransaction; +use reth_rpc_convert::{transaction::ConvertReceiptInput, RpcTransaction}; use reth_rpc_eth_api::{RpcBlock, RpcReceipt}; use std::collections::{BTreeMap, HashSet}; use std::sync::Arc; @@ -120,51 +118,55 @@ impl FlashblocksReceiver for FlashblocksState { } impl FlashblocksAPI for FlashblocksState { - fn get_block(&self, full: bool) -> Option> { - self.pending_blocks - .load() - .as_ref() - .map(|pb| pb.get_latest_block(full)) + fn get_pending_blocks(&self) -> Guard>> { + self.pending_blocks.load() } - fn get_transaction_receipt(&self, tx_hash: TxHash) -> Option> { - self.pending_blocks - .load() - .as_ref() - .and_then(|pb| pb.get_receipt(tx_hash)) + fn subscribe_to_flashblocks(&self) -> tokio::sync::broadcast::Receiver { + self.flashblock_sender.subscribe() + } +} + +impl PendingBlocksAPI for Guard>> { + fn get_canonical_block_number(&self) -> BlockNumberOrTag { + self.as_ref() + .map(|pb| pb.canonical_block_number()) + .unwrap_or(BlockNumberOrTag::Latest) } fn get_transaction_count(&self, address: Address) -> U256 { - self.pending_blocks - .load() - .as_ref() + self.as_ref() .map(|pb| pb.get_transaction_count(address)) .unwrap_or_else(|| U256::from(0)) } - fn get_transaction_by_hash(&self, tx_hash: TxHash) -> Option> { - self.pending_blocks - .load() - .as_ref() - .and_then(|pb| pb.get_transaction_by_hash(tx_hash)) + fn get_block(&self, full: bool) -> Option> { + self.as_ref().map(|pb| pb.get_latest_block(full)) } - fn get_balance(&self, address: Address) -> Option { - self.pending_blocks - .load() - .as_ref() - .and_then(|pb| pb.get_balance(address)) + fn get_transaction_receipt( + &self, + tx_hash: alloy_primitives::TxHash, + ) -> Option> { + self.as_ref().and_then(|pb| pb.get_receipt(tx_hash)) } - fn subscribe_to_flashblocks(&self) -> tokio::sync::broadcast::Receiver { - self.flashblock_sender.subscribe() + fn get_transaction_by_hash( + &self, + tx_hash: alloy_primitives::TxHash, + ) -> Option> { + self.as_ref() + .and_then(|pb| pb.get_transaction_by_hash(tx_hash)) + } + + fn get_balance(&self, address: Address) -> Option { + self.as_ref().and_then(|pb| pb.get_balance(address)) } fn get_state_overrides(&self) -> Option { - self.pending_blocks - .load() - .as_ref() - .and_then(|pb| pb.get_state_overrides()) + self.as_ref() + .map(|pb| pb.get_state_overrides()) + .unwrap_or_default() } } diff --git a/crates/flashblocks-rpc/src/tests/state.rs b/crates/flashblocks-rpc/src/tests/state.rs index 99f6954..cb1ae12 100644 --- a/crates/flashblocks-rpc/src/tests/state.rs +++ b/crates/flashblocks-rpc/src/tests/state.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod tests { - use crate::rpc::FlashblocksAPI; + use crate::rpc::{FlashblocksAPI, PendingBlocksAPI}; use crate::state::FlashblocksState; use crate::subscription::{Flashblock, FlashblocksReceiver, Metadata}; use crate::tests::utils::create_test_provider_factory; @@ -31,12 +31,12 @@ mod tests { use reth_provider::providers::BlockchainProvider; use reth_provider::{ BlockWriter, ChainSpecProvider, ExecutionOutcome, LatestStateProviderRef, ProviderFactory, + StateProviderFactory, }; use rollup_boost::{ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1}; use std::sync::Arc; use std::time::Duration; use tokio::time::sleep; - // The amount of time to wait (in milliseconds) after sending a new flashblock or canonical block // so it can be processed by the state processor const SLEEP_TIME: u64 = 10; @@ -93,15 +93,17 @@ mod tests { let nonce = self .flashblocks + .get_pending_blocks() .get_transaction_count(self.address(u)) .to::(); let balance = self .flashblocks + .get_pending_blocks() .get_balance(self.address(u)) .unwrap_or(basic_account.balance); Account { - nonce, + nonce: nonce + basic_account.nonce, balance, bytecode_hash: basic_account.bytecode_hash, } @@ -157,7 +159,10 @@ mod tests { sleep(Duration::from_millis(SLEEP_TIME)).await; } - async fn new_canonical_block(&mut self, mut user_transactions: Vec) { + async fn new_canonical_block_without_processing( + &mut self, + mut user_transactions: Vec, + ) -> RecoveredBlock { let current_tip = self.current_canonical_block(); let deposit_transaction = @@ -214,6 +219,13 @@ mod tests { .unwrap(); provider_rw.commit().unwrap(); + block + } + + async fn new_canonical_block(&mut self, user_transactions: Vec) { + let block = self + .new_canonical_block_without_processing(user_transactions) + .await; self.flashblocks.on_canonical_block_received(&block); sleep(Duration::from_millis(SLEEP_TIME)).await; } @@ -422,6 +434,7 @@ mod tests { .await; assert_eq!( test.flashblocks + .get_pending_blocks() .get_block(true) .expect("block is built") .transactions @@ -429,9 +442,14 @@ mod tests { 1 ); - assert!(test.flashblocks.get_state_overrides().is_some()); + assert!(test + .flashblocks + .get_pending_blocks() + .get_state_overrides() + .is_some()); assert!(!test .flashblocks + .get_pending_blocks() .get_state_overrides() .unwrap() .contains_key(&test.address(User::Alice))); @@ -447,13 +465,14 @@ mod tests { ) .await; - let pending = test.flashblocks.get_block(true); + let pending = test.flashblocks.get_pending_blocks().get_block(true); assert!(pending.is_some()); let pending = pending.unwrap(); assert_eq!(pending.transactions.len(), 2); let overrides = test .flashblocks + .get_pending_blocks() .get_state_overrides() .expect("should be set from txn execution"); @@ -472,6 +491,7 @@ mod tests { let overrides = test .flashblocks + .get_pending_blocks() .get_state_overrides() .expect("should be set from txn execution in flashblock index 1"); @@ -496,6 +516,7 @@ mod tests { test.send_flashblock(initial_base).await; assert_eq!( test.flashblocks + .get_pending_blocks() .get_block(true) .expect("block is built") .transactions @@ -503,9 +524,14 @@ mod tests { 1 ); - assert!(test.flashblocks.get_state_overrides().is_some()); + assert!(test + .flashblocks + .get_pending_blocks() + .get_state_overrides() + .is_some()); assert!(!test .flashblocks + .get_pending_blocks() .get_state_overrides() .unwrap() .contains_key(&test.address(User::Alice))); @@ -521,13 +547,14 @@ mod tests { ) .await; - let pending = test.flashblocks.get_block(true); + let pending = test.flashblocks.get_pending_blocks().get_block(true); assert!(pending.is_some()); let pending = pending.unwrap(); assert_eq!(pending.transactions.len(), 2); let overrides = test .flashblocks + .get_pending_blocks() .get_state_overrides() .expect("should be set from txn execution"); @@ -550,6 +577,7 @@ mod tests { assert_eq!( test.flashblocks + .get_pending_blocks() .get_block(true) .expect("block is built") .transactions @@ -558,6 +586,7 @@ mod tests { ); assert_eq!( test.flashblocks + .get_pending_blocks() .get_block(true) .expect("block is built") .header @@ -565,9 +594,14 @@ mod tests { initial_block_number + 1 ); - assert!(test.flashblocks.get_state_overrides().is_some()); assert!(test .flashblocks + .get_pending_blocks() + .get_state_overrides() + .is_some()); + assert!(test + .flashblocks + .get_pending_blocks() .get_state_overrides() .unwrap() .contains_key(&test.address(User::Alice))); @@ -586,6 +620,7 @@ mod tests { let overrides = test .flashblocks + .get_pending_blocks() .get_state_overrides() .expect("should be set from txn execution"); @@ -609,15 +644,21 @@ mod tests { .await; assert_eq!( test.flashblocks + .get_pending_blocks() .get_block(true) .expect("block is built") .transactions .len(), 1 ); - assert!(test.flashblocks.get_state_overrides().is_some()); + assert!(test + .flashblocks + .get_pending_blocks() + .get_state_overrides() + .is_some()); assert!(!test .flashblocks + .get_pending_blocks() .get_state_overrides() .unwrap() .contains_key(&test.address(User::Alice))); @@ -632,13 +673,14 @@ mod tests { .build(), ) .await; - let pending = test.flashblocks.get_block(true); + let pending = test.flashblocks.get_pending_blocks().get_block(true); assert!(pending.is_some()); let pending = pending.unwrap(); assert_eq!(pending.transactions.len(), 2); let overrides = test .flashblocks + .get_pending_blocks() .get_state_overrides() .expect("should be set from txn execution"); @@ -669,13 +711,14 @@ mod tests { .build(), ) .await; - let pending = test.flashblocks.get_block(true); + let pending = test.flashblocks.get_pending_blocks().get_block(true); assert!(pending.is_some()); let pending = pending.unwrap(); assert_eq!(pending.transactions.len(), 2); let overrides = test .flashblocks + .get_pending_blocks() .get_state_overrides() .expect("should be set from txn execution"); @@ -697,13 +740,14 @@ mod tests { )]) .await; - let pending = test.flashblocks.get_block(true); + let pending = test.flashblocks.get_pending_blocks().get_block(true); assert!(pending.is_some()); let pending = pending.unwrap(); assert_eq!(pending.transactions.len(), 2); let overrides = test .flashblocks + .get_pending_blocks() .get_state_overrides() .expect("should be set from txn execution"); @@ -718,6 +762,89 @@ mod tests { ); } + #[tokio::test] + async fn test_nonce_uses_pending_canon_block_instead_of_latest() { + // Test for race condition when a canon block comes in but user + // requests their nonce prior to the StateProcessor processing the canon block + // causing it to return an n+1 nonce instead of n + // because underlying reth node `latest` block is already updated, but + // relevant pending state has not been cleared yet + reth_tracing::init_test_tracing(); + let mut test = TestHarness::new(); + + test.send_flashblock(FlashblockBuilder::new_base(&test).build()) + .await; + test.send_flashblock( + FlashblockBuilder::new(&test, 1) + .with_transactions(vec![test.build_transaction_to_send_eth( + User::Alice, + User::Bob, + 100, + )]) + .build(), + ) + .await; + + let pending_nonce = test + .provider + .basic_account(&test.address(User::Alice)) + .unwrap() + .unwrap() + .nonce + + test + .flashblocks + .get_pending_blocks() + .get_transaction_count(test.address(User::Alice)) + .to::(); + assert_eq!(pending_nonce, 1); + + test.new_canonical_block_without_processing(vec![ + test.build_transaction_to_send_eth_with_nonce(User::Alice, User::Bob, 100, 0) + ]) + .await; + + let pending_nonce = test + .provider + .basic_account(&test.address(User::Alice)) + .unwrap() + .unwrap() + .nonce + + test + .flashblocks + .get_pending_blocks() + .get_transaction_count(test.address(User::Alice)) + .to::(); + + // This is 2, because canon block has reached the underlying chain + // but the StateProcessor hasn't processed it + // so pending nonce is effectively double-counting the same transaction, leading to a nonce of 2 + assert_eq!(pending_nonce, 2); + + // On the RPC level, we correctly return 1 because we + // use the pending canon block instead of the latest block when fetching + // onchain nonce count to compute + // pending_nonce = onchain_nonce + pending_txn_count + let canon_block = test + .flashblocks + .get_pending_blocks() + .get_canonical_block_number(); + let canon_state_provider = test + .provider + .state_by_block_number_or_tag(canon_block) + .unwrap(); + let canon_nonce = canon_state_provider + .account_nonce(&test.address(User::Alice)) + .unwrap() + .unwrap(); + let pending_nonce = canon_nonce + + test + .flashblocks + .get_pending_blocks() + .get_transaction_count(test.address(User::Alice)) + .to::(); + assert_eq!(pending_nonce, 1); + } + #[tokio::test] async fn test_missing_receipts_will_not_process() { reth_tracing::init_test_tracing(); @@ -726,7 +853,7 @@ mod tests { test.send_flashblock(FlashblockBuilder::new_base(&test).build()) .await; - let current_block = test.flashblocks.get_block(true); + let current_block = test.flashblocks.get_pending_blocks().get_block(true); test.send_flashblock( FlashblockBuilder::new(&test, 1) @@ -740,7 +867,7 @@ mod tests { ) .await; - let pending_block = test.flashblocks.get_block(true); + let pending_block = test.flashblocks.get_pending_blocks().get_block(true); // When the flashblock is invalid, the chain doesn't progress assert_eq!(pending_block.unwrap().hash(), current_block.unwrap().hash()); @@ -754,7 +881,11 @@ mod tests { test.send_flashblock(FlashblockBuilder::new_base(&test).build()) .await; - let current_block = test.flashblocks.get_block(true).expect("should be a block"); + let current_block = test + .flashblocks + .get_pending_blocks() + .get_block(true) + .expect("should be a block"); assert_eq!(current_block.header().number, 1); assert_eq!(current_block.transactions.len(), 1); @@ -766,7 +897,7 @@ mod tests { ) .await; - let current_block = test.flashblocks.get_block(true); + let current_block = test.flashblocks.get_pending_blocks().get_block(true); assert!(current_block.is_none()); } @@ -778,7 +909,11 @@ mod tests { test.send_flashblock(FlashblockBuilder::new_base(&test).build()) .await; - let current_block = test.flashblocks.get_block(true).expect("should be a block"); + let current_block = test + .flashblocks + .get_pending_blocks() + .get_block(true) + .expect("should be a block"); assert_eq!(current_block.header().number, 1); assert_eq!(current_block.transactions.len(), 1); @@ -790,7 +925,11 @@ mod tests { ) .await; - let current_block = test.flashblocks.get_block(true).expect("should be a block"); + let current_block = test + .flashblocks + .get_pending_blocks() + .get_block(true) + .expect("should be a block"); assert_eq!(current_block.header().number, 2); assert_eq!(current_block.transactions.len(), 1); @@ -801,7 +940,11 @@ mod tests { reth_tracing::init_test_tracing(); let test = TestHarness::new(); - assert!(test.flashblocks.get_block(true).is_none()); + assert!(test + .flashblocks + .get_pending_blocks() + .get_block(true) + .is_none()); test.send_flashblock(FlashblockBuilder::new_base(&test).build()) .await; @@ -809,6 +952,7 @@ mod tests { // Just the block info transaction assert_eq!( test.flashblocks + .get_pending_blocks() .get_block(true) .expect("should be set") .transactions @@ -831,6 +975,7 @@ mod tests { // missing a Flashblock assert_eq!( test.flashblocks + .get_pending_blocks() .get_block(true) .expect("should be set") .transactions @@ -856,10 +1001,10 @@ mod tests { .build(); test.send_flashblock(fb.clone()).await; - let block = test.flashblocks.get_block(true); + let block = test.flashblocks.get_pending_blocks().get_block(true); test.send_flashblock(fb.clone()).await; - let block_two = test.flashblocks.get_block(true); + let block_two = test.flashblocks.get_pending_blocks().get_block(true); assert_eq!(block, block_two); } @@ -872,7 +1017,11 @@ mod tests { let genesis_block = test.current_canonical_block(); assert_eq!(genesis_block.number, 0); assert_eq!(genesis_block.transaction_count(), 0); - assert!(test.flashblocks.get_block(true).is_none()); + assert!(test + .flashblocks + .get_pending_blocks() + .get_block(true) + .is_none()); test.new_canonical_block(vec![test.build_transaction_to_send_eth( User::Alice, @@ -884,7 +1033,11 @@ mod tests { let block_one = test.current_canonical_block(); assert_eq!(block_one.number, 1); assert_eq!(block_one.transaction_count(), 2); - assert!(test.flashblocks.get_block(true).is_none()); + assert!(test + .flashblocks + .get_pending_blocks() + .get_block(true) + .is_none()); test.new_canonical_block(vec![ test.build_transaction_to_send_eth(User::Bob, User::Charlie, 100), @@ -895,6 +1048,10 @@ mod tests { let block_two = test.current_canonical_block(); assert_eq!(block_two.number, 2); assert_eq!(block_two.transaction_count(), 3); - assert!(test.flashblocks.get_block(true).is_none()); + assert!(test + .flashblocks + .get_pending_blocks() + .get_block(true) + .is_none()); } }