From eb851fbe7f0b107f44c9722ddfdb2873e34acb4e Mon Sep 17 00:00:00 2001 From: Oliver Nordbjerg Date: Fri, 15 Dec 2023 16:28:37 +0200 Subject: [PATCH] chore: use new aquamarine macro --- Cargo.lock | 6 +- Cargo.toml | 2 +- crates/blockchain-tree/src/blockchain_tree.rs | 51 ++++------- crates/net/network/src/fetch/client.rs | 37 +------- crates/net/network/src/manager.rs | 32 ++----- crates/net/network/src/swarm.rs | 43 +++------- crates/stages/src/pipeline/mod.rs | 48 ++--------- crates/transaction-pool/src/pool/txpool.rs | 85 ++++++------------- docs/mermaid/fetch-client.mmd | 31 +++++++ docs/mermaid/network-manager.mmd | 20 +++++ docs/mermaid/pipeline.mmd | 31 +++++++ docs/mermaid/swarm.mmd | 15 ++++ docs/mermaid/tree.mmd | 21 +++++ docs/mermaid/txpool.mmd | 32 +++++++ 14 files changed, 229 insertions(+), 225 deletions(-) create mode 100644 docs/mermaid/fetch-client.mmd create mode 100644 docs/mermaid/network-manager.mmd create mode 100644 docs/mermaid/pipeline.mmd create mode 100644 docs/mermaid/swarm.mmd create mode 100644 docs/mermaid/tree.mmd create mode 100644 docs/mermaid/txpool.mmd diff --git a/Cargo.lock b/Cargo.lock index 9d897c45332d..58b4c51730cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -332,16 +332,16 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "aquamarine" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df752953c49ce90719c7bf1fc587bc8227aed04732ea0c0f85e5397d7fdbd1a1" +checksum = "074b80d14d0240b6ce94d68f059a2d26a5d77280ae142662365a21ef6e2594ef" dependencies = [ "include_dir", "itertools 0.10.5", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.39", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c88763520ff7..cc048a6df522 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -157,7 +157,7 @@ boa_engine = "0.17" boa_gc = "0.17" # misc -aquamarine = "0.3" +aquamarine = "0.4" bytes = "1.5" bitflags = "2.4" clap = "4" diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 3b956fe2b1f6..20d878399f5b 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -37,40 +37,25 @@ use tracing::{debug, error, info, instrument, trace, warn}; #[cfg_attr(doc, aquamarine::aquamarine)] /// A Tree of chains. /// -/// Mermaid flowchart represents all the states a block can have inside the blockchaintree. -/// Green blocks belong to canonical chain and are saved inside then database, they are our main -/// chain. Pending blocks and sidechains are found in memory inside [`BlockchainTree`]. -/// Both pending and sidechains have same mechanisms only difference is when they get committed to -/// the database. For pending it is an append operation but for sidechains they need to move current -/// canonical blocks to BlockchainTree and commit the sidechain to the database to become canonical -/// chain (reorg). ```mermaid -/// flowchart BT -/// subgraph canonical chain -/// CanonState:::state -/// block0canon:::canon -->block1canon:::canon -->block2canon:::canon -->block3canon:::canon --> -/// block4canon:::canon --> block5canon:::canon end -/// block5canon --> block6pending1:::pending -/// block5canon --> block6pending2:::pending -/// subgraph sidechain2 -/// S2State:::state -/// block3canon --> block4s2:::sidechain --> block5s2:::sidechain -/// end -/// subgraph sidechain1 -/// S1State:::state -/// block2canon --> block3s1:::sidechain --> block4s1:::sidechain --> block5s1:::sidechain --> -/// block6s1:::sidechain end -/// classDef state fill:#1882C4 -/// classDef canon fill:#8AC926 -/// classDef pending fill:#FFCA3A -/// classDef sidechain fill:#FF595E -/// ``` -/// +/// The flowchart represents all the states a block can have inside the tree. /// -/// main functions: -/// * [BlockchainTree::insert_block]: Connect block to chain, execute it and if valid insert block -/// into the tree. -/// * [BlockchainTree::finalize_block]: Remove chains that are branch off the now finalized block. -/// * [BlockchainTree::make_canonical]: Check if we have the hash of block that is the current +/// - Green blocks belong to the canonical chain and are saved inside the database. +/// - Pending blocks and sidechains are found in-memory inside [`BlockchainTree`]. +/// +/// Both pending chains and sidechains have the same mechanisms, the only difference is when they +/// get committed to the database. +/// +/// For pending, it is an append operation, but for sidechains they need to move the current +/// canonical blocks to the tree (by removing them from the database), and commit the sidechain +/// blocks to the database to become the canonical chain (reorg). +/// +/// include_mmd!("docs/mermaid/tree.mmd") +/// +/// # Main functions +/// * [BlockchainTree::insert_block]: Connect a block to a chain, execute it, and if valid, insert +/// the block into the tree. +/// * [BlockchainTree::finalize_block]: Remove chains that branch off of the now finalized block. +/// * [BlockchainTree::make_canonical]: Check if we have the hash of a block that is the current /// canonical head and commit it to db. #[derive(Debug)] pub struct BlockchainTree { diff --git a/crates/net/network/src/fetch/client.rs b/crates/net/network/src/fetch/client.rs index a9febae7ec9d..eab4745065ea 100644 --- a/crates/net/network/src/fetch/client.rs +++ b/crates/net/network/src/fetch/client.rs @@ -18,44 +18,13 @@ use std::sync::{ }; use tokio::sync::{mpsc::UnboundedSender, oneshot}; +#[cfg_attr(doc, aquamarine::aquamarine)] /// Front-end API for fetching data from the network. /// /// Following diagram illustrates how a request, See [`HeadersClient::get_headers`] and /// [`BodiesClient::get_block_bodies`] is handled internally. -#[cfg_attr(doc, aquamarine::aquamarine)] -/// ```mermaid -/// sequenceDiagram -// participant Client as FetchClient -// participant Fetcher as StateFetcher -// participant State as NetworkState -// participant Session as Active Peer Session -// participant Peers as PeerManager -// loop Send Request, retry if retriable and remaining retries -// Client->>Fetcher: DownloadRequest{GetHeaders, GetBodies} -// Note over Client,Fetcher: Request and oneshot Sender sent via `request_tx` channel -// loop Process buffered requests -// State->>Fetcher: poll action -// Fetcher->>Fetcher: Select Available Peer -// Note over Fetcher: Peer is available if it's currently idle, no inflight requests -// Fetcher->>State: FetchAction::BlockDownloadRequest -// State->>Session: Delegate Request -// Note over State,Session: Request and oneshot Sender sent via `to_session_tx` channel -// end -// Session->>Session: Send Request to remote -// Session->>Session: Enforce Request timeout -// Session-->>State: Send Response Result via channel -// State->>Fetcher: Delegate Response -// Fetcher-->>Client: Send Response via channel -// opt Bad Response -// Client->>Peers: Penalize Peer -// end -// Peers->>Peers: Apply Reputation Change -// opt reputation dropped below threshold -// Peers->>State: Disconnect Session -// State->>Session: Delegate Disconnect -// end -// end -/// ``` +/// +/// include_mmd!("docs/mermaid/fetch-client.mmd") #[derive(Debug, Clone)] pub struct FetchClient { /// Sender half of the request channel. diff --git a/crates/net/network/src/manager.rs b/crates/net/network/src/manager.rs index 4441c2e51336..88cb8bdcbcdf 100644 --- a/crates/net/network/src/manager.rs +++ b/crates/net/network/src/manager.rs @@ -60,34 +60,14 @@ use tokio::sync::mpsc::{self, error::TrySendError}; use tokio_stream::wrappers::UnboundedReceiverStream; use tracing::{debug, error, trace, warn}; +#[cfg_attr(doc, aquamarine::aquamarine)] /// Manages the _entire_ state of the network. /// /// This is an endless [`Future`] that consistently drives the state of the entire network forward. /// /// The [`NetworkManager`] is the container type for all parts involved with advancing the network. -#[cfg_attr(doc, aquamarine::aquamarine)] -/// ```mermaid -/// graph TB -/// handle(NetworkHandle) -/// events(NetworkEvents) -/// transactions(Transactions Task) -/// ethrequest(ETH Request Task) -/// discovery(Discovery Task) -/// subgraph NetworkManager -/// direction LR -/// subgraph Swarm -/// direction TB -/// B1[(Session Manager)] -/// B2[(Connection Lister)] -/// B3[(Network State)] -/// end -/// end -/// handle <--> |request response channel| NetworkManager -/// NetworkManager --> |Network events| events -/// transactions <--> |transactions| NetworkManager -/// ethrequest <--> |ETH request handing| NetworkManager -/// discovery --> |Discovered peers| NetworkManager -/// ``` +/// +/// include_mmd!("docs/mermaid/network-manager.mmd") #[derive(Debug)] #[must_use = "The NetworkManager does nothing unless polled"] pub struct NetworkManager { @@ -543,7 +523,7 @@ where if self.handle.mode().is_stake() { // See [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#devp2p) warn!(target: "net", "Peer performed block propagation, but it is not supported in proof of stake (EIP-3675)"); - return + return; } let msg = NewBlockMessage { hash, block: Arc::new(block) }; self.swarm.state_mut().announce_new_block(msg); @@ -638,7 +618,7 @@ where // This is only possible if the channel was deliberately closed since we always // have an instance of `NetworkHandle` error!("Network message channel closed."); - return Poll::Ready(()) + return Poll::Ready(()); } Poll::Ready(Some(msg)) => this.on_handle_message(msg), }; @@ -909,7 +889,7 @@ where if budget == 0 { // make sure we're woken up again cx.waker().wake_by_ref(); - break + break; } } diff --git a/crates/net/network/src/swarm.rs b/crates/net/network/src/swarm.rs index ce647fe181e8..690a37b4b650 100644 --- a/crates/net/network/src/swarm.rs +++ b/crates/net/network/src/swarm.rs @@ -23,6 +23,7 @@ use std::{ }; use tracing::trace; +#[cfg_attr(doc, aquamarine::aquamarine)] /// Contains the connectivity related state of the network. /// /// A swarm emits [`SwarmEvent`]s when polled. @@ -44,24 +45,8 @@ use tracing::trace; /// request channel for the created session and sends requests it receives from the /// [`StateFetcher`], which receives request objects from the client interfaces responsible for /// downloading headers and bodies. -#[cfg_attr(doc, aquamarine::aquamarine)] -/// ```mermaid -/// graph TB -/// connections(TCP Listener) -/// Discovery[(Discovery)] -/// fetchRequest(Client Interfaces) -/// Sessions[(SessionManager)] -/// SessionTask[(Peer Session)] -/// State[(State)] -/// StateFetch[(State Fetcher)] -/// connections --> |incoming| Sessions -/// State --> |initiate outgoing| Sessions -/// Discovery --> |update peers| State -/// Sessions --> |spawns| SessionTask -/// SessionTask <--> |handle state requests| State -/// fetchRequest --> |request Headers, Bodies| StateFetch -/// State --> |poll pending requests| StateFetch -/// ``` +/// +/// include_mmd!("docs/mermaid/swarm.mmd") #[derive(Debug)] #[must_use = "Swarm does nothing unless polled"] pub(crate) struct Swarm { @@ -207,7 +192,7 @@ where ListenerEvent::Incoming { stream, remote_addr } => { // Reject incoming connection if node is shutting down. if self.is_shutting_down() { - return None + return None; } // ensure we can handle an incoming connection from this address if let Err(err) = @@ -225,13 +210,13 @@ where ); } } - return None + return None; } match self.sessions.on_incoming(stream, remote_addr) { Ok(session_id) => { trace!(target: "net", ?remote_addr, "Incoming connection"); - return Some(SwarmEvent::IncomingTcpConnection { session_id, remote_addr }) + return Some(SwarmEvent::IncomingTcpConnection { session_id, remote_addr }); } Err(err) => { trace!(target: "net", ?err, "Incoming connection rejected, capacity already reached."); @@ -250,7 +235,7 @@ where match event { StateAction::Connect { remote_addr, peer_id } => { self.dial_outbound(remote_addr, peer_id); - return Some(SwarmEvent::OutgoingTcpConnection { remote_addr, peer_id }) + return Some(SwarmEvent::OutgoingTcpConnection { remote_addr, peer_id }); } StateAction::Disconnect { peer_id, reason } => { self.sessions.disconnect(peer_id, reason); @@ -268,7 +253,7 @@ where StateAction::DiscoveredNode { peer_id, socket_addr, fork_id } => { // Don't try to connect to peer if node is shutting down if self.is_shutting_down() { - return None + return None; } // Insert peer only if no fork id or a valid fork id if fork_id.map_or_else(|| true, |f| self.sessions.is_valid_fork_id(f)) { @@ -317,7 +302,7 @@ where loop { while let Poll::Ready(action) = this.state.poll(cx) { if let Some(event) = this.on_state_action(action) { - return Poll::Ready(Some(event)) + return Poll::Ready(Some(event)); } } @@ -326,9 +311,9 @@ where Poll::Pending => {} Poll::Ready(event) => { if let Some(event) = this.on_session_event(event) { - return Poll::Ready(Some(event)) + return Poll::Ready(Some(event)); } - continue + continue; } } @@ -337,13 +322,13 @@ where Poll::Pending => {} Poll::Ready(event) => { if let Some(event) = this.on_connection(event) { - return Poll::Ready(Some(event)) + return Poll::Ready(Some(event)); } - continue + continue; } } - return Poll::Pending + return Poll::Pending; } } } diff --git a/crates/stages/src/pipeline/mod.rs b/crates/stages/src/pipeline/mod.rs index 344510b23332..2d416db5c9c7 100644 --- a/crates/stages/src/pipeline/mod.rs +++ b/crates/stages/src/pipeline/mod.rs @@ -49,39 +49,7 @@ pub type PipelineWithResult = (Pipeline, Result RunLoop --> NextStage -/// NextStage --> |No stages left| LoopDone -/// NextStage --> |Next stage| Execute -/// Execute --> |Not done| Execute -/// Execute --> |Unwind requested| StartUnwind -/// Execute --> |Done| NextStage -/// Execute --> |Error| Error -/// StartUnwind --> NextStageToUnwind -/// NextStageToUnwind --> |Next stage| UnwindStage -/// NextStageToUnwind --> |No stages left| RunLoop -/// UnwindStage --> |Error| Error -/// UnwindStage --> |Unwound| NextStageToUnwind -/// LoopDone --> |Target block reached| Done -/// LoopDone --> |Target block not reached| RunLoop -/// ``` +/// include_mmd!("docs/mermaid/pipeline.mmd") /// /// # Unwinding /// @@ -193,7 +161,7 @@ where max_block = ?self.max_block, "Terminating pipeline." ); - return Ok(()) + return Ok(()); } } } @@ -229,7 +197,7 @@ where ControlFlow::Continue { block_number } => self.progress.update(block_number), ControlFlow::Unwind { target, bad_block } => { self.unwind(target, Some(bad_block.number))?; - return Ok(ControlFlow::Unwind { target, bad_block }) + return Ok(ControlFlow::Unwind { target, bad_block }); } } @@ -272,7 +240,7 @@ where "Unwind point too far for stage" ); self.listeners.notify(PipelineEvent::Skipped { stage_id }); - continue + continue; } debug!( @@ -317,7 +285,7 @@ where } Err(err) => { self.listeners.notify(PipelineEvent::Error { stage_id }); - return Err(PipelineError::Stage(StageError::Fatal(Box::new(err)))) + return Err(PipelineError::Stage(StageError::Fatal(Box::new(err)))); } } } @@ -357,7 +325,7 @@ where // We reached the maximum block, so we skip the stage return Ok(ControlFlow::NoProgress { block_number: prev_checkpoint.map(|progress| progress.block_number), - }) + }); } let exec_input = ExecInput { target, checkpoint: prev_checkpoint }; @@ -412,7 +380,7 @@ where ControlFlow::Continue { block_number } } else { ControlFlow::NoProgress { block_number: Some(block_number) } - }) + }); } } Err(err) => { @@ -421,7 +389,7 @@ where if let Some(ctrl) = on_stage_error(&self.provider_factory, stage_id, prev_checkpoint, err)? { - return Ok(ctrl) + return Ok(ctrl); } } } diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index bcebb4d69507..617cdaa94c93 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -32,45 +32,12 @@ use std::{ sync::Arc, }; +#[cfg_attr(doc, aquamarine::aquamarine)] /// A pool that manages transactions. /// /// This pool maintains the state of all transactions and stores them accordingly. - -#[cfg_attr(doc, aquamarine::aquamarine)] -/// ```mermaid -/// graph TB -/// subgraph TxPool -/// direction TB -/// pool[(All Transactions)] -/// subgraph Subpools -/// direction TB -/// B3[(Queued)] -/// B1[(Pending)] -/// B2[(Basefee)] -/// B4[(Blob)] -/// end -/// end -/// discard([discard]) -/// production([Block Production]) -/// new([New Block]) -/// A[Incoming Tx] --> B[Validation] -->|insert| pool -/// pool --> |if ready + blobfee too low| B4 -/// pool --> |if ready| B1 -/// pool --> |if ready + basfee too low| B2 -/// pool --> |nonce gap or lack of funds| B3 -/// pool --> |update| pool -/// B1 --> |best| production -/// B2 --> |worst| discard -/// B3 --> |worst| discard -/// B4 --> |worst| discard -/// B1 --> |increased blob fee| B4 -/// B4 --> |decreased blob fee| B1 -/// B1 --> |increased base fee| B2 -/// B2 --> |decreased base fee| B1 -/// B3 --> |promote| B1 -/// B3 --> |promote| B2 -/// new --> |apply state changes| pool -/// ``` +/// +/// include_mmd!("docs/mermaid/txpool.mmd") pub struct TxPool { /// Contains the currently known information about the senders. sender_info: FnvHashMap, @@ -509,7 +476,7 @@ impl TxPool { on_chain_nonce: u64, ) -> PoolResult> { if self.contains(tx.hash()) { - return Err(PoolError::new(*tx.hash(), PoolErrorKind::AlreadyImported)) + return Err(PoolError::new(*tx.hash(), PoolErrorKind::AlreadyImported)); } // Update sender info with balance and nonce @@ -737,7 +704,7 @@ impl TxPool { } id = descendant; } else { - return + return; } } } @@ -964,7 +931,7 @@ impl AllTransactions { let count = entry.get_mut(); if *count == 1 { entry.remove(); - return + return; } *count -= 1; } @@ -1024,7 +991,7 @@ impl AllTransactions { ($iter:ident) => { 'this: while let Some((peek, _)) = iter.peek() { if peek.sender != id.sender { - break 'this + break 'this; } iter.next(); } @@ -1043,7 +1010,7 @@ impl AllTransactions { current: tx.subpool, destination: Destination::Discard, }); - continue 'transactions + continue 'transactions; } let ancestor = TransactionId::ancestor(id.nonce, info.state_nonce, id.sender); @@ -1066,7 +1033,7 @@ impl AllTransactions { // If there's a nonce gap, we can shortcircuit, because there's nothing to update yet. if tx.state.has_nonce_gap() { next_sender!(iter); - continue 'transactions + continue 'transactions; } // Since this is the first transaction of the sender, it has no parked ancestors @@ -1086,13 +1053,13 @@ impl AllTransactions { while let Some((peek, ref mut tx)) = iter.peek_mut() { if peek.sender != id.sender { // Found the next sender - continue 'transactions + continue 'transactions; } // can short circuit if tx.state.has_nonce_gap() { next_sender!(iter); - continue 'transactions + continue 'transactions; } // update cumulative cost @@ -1254,7 +1221,7 @@ impl AllTransactions { fn contains_conflicting_transaction(&self, tx: &ValidPoolTransaction) -> bool { let mut iter = self.txs_iter(tx.transaction_id.sender); if let Some((_, existing)) = iter.next() { - return tx.tx_type_conflicts_with(&existing.transaction) + return tx.tx_type_conflicts_with(&existing.transaction); } // no existing transaction for this sender false @@ -1278,7 +1245,7 @@ impl AllTransactions { if current_txs >= self.max_account_slots { return Err(InsertErr::ExceededSenderTransactionsCapacity { transaction: Arc::new(transaction), - }) + }); } } if transaction.gas_limit() > self.block_gas_limit { @@ -1286,12 +1253,12 @@ impl AllTransactions { block_gas_limit: self.block_gas_limit, tx_gas_limit: transaction.gas_limit(), transaction: Arc::new(transaction), - }) + }); } if self.contains_conflicting_transaction(&transaction) { // blob vs non blob transactions are mutually exclusive for the same sender - return Err(InsertErr::TxTypeConflict { transaction: Arc::new(transaction) }) + return Err(InsertErr::TxTypeConflict { transaction: Arc::new(transaction) }); } Ok(transaction) @@ -1311,12 +1278,12 @@ impl AllTransactions { if let Some(ancestor) = ancestor { let Some(ancestor_tx) = self.txs.get(&ancestor) else { // ancestor tx is missing, so we can't insert the new blob - return Err(InsertErr::BlobTxHasNonceGap { transaction: Arc::new(new_blob_tx) }) + return Err(InsertErr::BlobTxHasNonceGap { transaction: Arc::new(new_blob_tx) }); }; if ancestor_tx.state.has_nonce_gap() { // the ancestor transaction already has a nonce gap, so we can't insert the new // blob - return Err(InsertErr::BlobTxHasNonceGap { transaction: Arc::new(new_blob_tx) }) + return Err(InsertErr::BlobTxHasNonceGap { transaction: Arc::new(new_blob_tx) }); } // the max cost executing this transaction requires @@ -1325,7 +1292,7 @@ impl AllTransactions { // check if the new blob would go into overdraft if cumulative_cost > on_chain_balance { // the transaction would go into overdraft - return Err(InsertErr::Overdraft { transaction: Arc::new(new_blob_tx) }) + return Err(InsertErr::Overdraft { transaction: Arc::new(new_blob_tx) }); } // ensure that a replacement would not shift already propagated blob transactions into @@ -1342,14 +1309,14 @@ impl AllTransactions { cumulative_cost += tx.transaction.cost(); if tx.transaction.is_eip4844() && cumulative_cost > on_chain_balance { // the transaction would shift - return Err(InsertErr::Overdraft { transaction: Arc::new(new_blob_tx) }) + return Err(InsertErr::Overdraft { transaction: Arc::new(new_blob_tx) }); } } } } } else if new_blob_tx.cost() > on_chain_balance { // the transaction would go into overdraft - return Err(InsertErr::Overdraft { transaction: Arc::new(new_blob_tx) }) + return Err(InsertErr::Overdraft { transaction: Arc::new(new_blob_tx) }); } Ok(new_blob_tx) @@ -1369,7 +1336,7 @@ impl AllTransactions { if maybe_replacement.max_fee_per_gas() <= existing_transaction.max_fee_per_gas() * price_bump_multiplier { - return true + return true; } let existing_max_priority_fee_per_gas = @@ -1382,7 +1349,7 @@ impl AllTransactions { existing_max_priority_fee_per_gas != 0 && replacement_max_priority_fee_per_gas != 0 { - return true + return true; } // check max blob fee per gas @@ -1395,7 +1362,7 @@ impl AllTransactions { if replacement_max_blob_fee_per_gas <= existing_max_blob_fee_per_gas * price_bump_multiplier { - return true + return true; } } @@ -1484,7 +1451,7 @@ impl AllTransactions { let fee_cap = transaction.max_fee_per_gas(); if fee_cap < self.minimal_protocol_basefee as u128 { - return Err(InsertErr::FeeCapBelowMinimumProtocolFeeCap { transaction, fee_cap }) + return Err(InsertErr::FeeCapBelowMinimumProtocolFeeCap { transaction, fee_cap }); } if fee_cap >= self.pending_fees.base_fee as u128 { state.insert(TxState::ENOUGH_FEE_CAP_BLOCK); @@ -1523,7 +1490,7 @@ impl AllTransactions { return Err(InsertErr::Underpriced { transaction: pool_tx.transaction, existing: *entry.get().transaction.hash(), - }) + }); } let new_hash = *pool_tx.transaction.hash(); let new_transaction = pool_tx.transaction.clone(); @@ -1566,7 +1533,7 @@ impl AllTransactions { // If there's a nonce gap, we can shortcircuit if next_nonce != id.nonce { - break + break; } // close the nonce gap diff --git a/docs/mermaid/fetch-client.mmd b/docs/mermaid/fetch-client.mmd new file mode 100644 index 000000000000..28c89aaf9f7f --- /dev/null +++ b/docs/mermaid/fetch-client.mmd @@ -0,0 +1,31 @@ +sequenceDiagram + participant Client as FetchClient + participant Fetcher as StateFetcher + participant State as NetworkState + participant Session as Active Peer Session + participant Peers as PeerManager + loop Send Request, retry if retriable and remaining retries + Client->>Fetcher: DownloadRequest{GetHeaders, GetBodies} + Note over Client,Fetcher: Request and oneshot Sender sent via `request_tx` channel + loop Process buffered requests + State->>Fetcher: poll action + Fetcher->>Fetcher: Select Available Peer + Note over Fetcher: Peer is available if it's currently idle, no inflight requests + Fetcher->>State: FetchAction::BlockDownloadRequest + State->>Session: Delegate Request + Note over State,Session: Request and oneshot Sender sent via `to_session_tx` channel + end + Session->>Session: Send Request to remote + Session->>Session: Enforce Request timeout + Session-->>State: Send Response Result via channel + State->>Fetcher: Delegate Response + Fetcher-->>Client: Send Response via channel + opt Bad Response + Client->>Peers: Penalize Peer + end + Peers->>Peers: Apply Reputation Change + opt reputation dropped below threshold + Peers->>State: Disconnect Session + State->>Session: Delegate Disconnect + end + end diff --git a/docs/mermaid/network-manager.mmd b/docs/mermaid/network-manager.mmd new file mode 100644 index 000000000000..e34dbb177772 --- /dev/null +++ b/docs/mermaid/network-manager.mmd @@ -0,0 +1,20 @@ +graph TB + handle(NetworkHandle) + events(NetworkEvents) + transactions(Transactions Task) + ethrequest(ETH Request Task) + discovery(Discovery Task) + subgraph NetworkManager + direction LR + subgraph Swarm + direction TB + B1[(Session Manager)] + B2[(Connection Lister)] + B3[(Network State)] + end + end + handle <--> |request response channel| NetworkManager + NetworkManager --> |Network events| events + transactions <--> |transactions| NetworkManager + ethrequest <--> |ETH request handing| NetworkManager + discovery --> |Discovered peers| NetworkManager diff --git a/docs/mermaid/pipeline.mmd b/docs/mermaid/pipeline.mmd new file mode 100644 index 000000000000..23ff0fcafb97 --- /dev/null +++ b/docs/mermaid/pipeline.mmd @@ -0,0 +1,31 @@ +graph TB + Start[Start] + Done[Done] + Error[Error] + subgraph Unwind + StartUnwind(Unwind in reverse order of execution) + UnwindStage(Unwind stage) + NextStageToUnwind(Next stage) + end + subgraph Single loop + RunLoop(Run loop) + NextStage(Next stage) + LoopDone(Loop done) + subgraph Stage Execution + Execute(Execute stage) + end + end + Start --> RunLoop --> NextStage + NextStage --> |No stages left| LoopDone + NextStage --> |Next stage| Execute + Execute --> |Not done| Execute + Execute --> |Unwind requested| StartUnwind + Execute --> |Done| NextStage + Execute --> |Error| Error + StartUnwind --> NextStageToUnwind + NextStageToUnwind --> |Next stage| UnwindStage + NextStageToUnwind --> |No stages left| RunLoop + UnwindStage --> |Error| Error + UnwindStage --> |Unwound| NextStageToUnwind + LoopDone --> |Target block reached| Done + LoopDone --> |Target block not reached| RunLoop diff --git a/docs/mermaid/swarm.mmd b/docs/mermaid/swarm.mmd new file mode 100644 index 000000000000..afc17454f030 --- /dev/null +++ b/docs/mermaid/swarm.mmd @@ -0,0 +1,15 @@ +graph TB + connections(TCP Listener) + Discovery[(Discovery)] + fetchRequest(Client Interfaces) + Sessions[(SessionManager)] + SessionTask[(Peer Session)] + State[(State)] + StateFetch[(State Fetcher)] + connections --> |incoming| Sessions + State --> |initiate outgoing| Sessions + Discovery --> |update peers| State + Sessions --> |spawns| SessionTask + SessionTask <--> |handle state requests| State + fetchRequest --> |request Headers, Bodies| StateFetch + State --> |poll pending requests| StateFetch diff --git a/docs/mermaid/tree.mmd b/docs/mermaid/tree.mmd new file mode 100644 index 000000000000..c9b41b857b17 --- /dev/null +++ b/docs/mermaid/tree.mmd @@ -0,0 +1,21 @@ +flowchart BT + subgraph canonical chain + CanonState:::state + block0canon:::canon -->block1canon:::canon -->block2canon:::canon -->block3canon:::canon --> + block4canon:::canon --> block5canon:::canon + end + block5canon --> block6pending1:::pending + block5canon --> block6pending2:::pending + subgraph sidechain2 + S2State:::state + block3canon --> block4s2:::sidechain --> block5s2:::sidechain + end + subgraph sidechain1 + S1State:::state + block2canon --> block3s1:::sidechain --> block4s1:::sidechain --> block5s1:::sidechain --> + block6s1:::sidechain + end + classDef state fill:#1882C4 + classDef canon fill:#8AC926 + classDef pending fill:#FFCA3A + classDef sidechain fill:#FF595E diff --git a/docs/mermaid/txpool.mmd b/docs/mermaid/txpool.mmd new file mode 100644 index 000000000000..2f0e740bb766 --- /dev/null +++ b/docs/mermaid/txpool.mmd @@ -0,0 +1,32 @@ +graph TB + subgraph TxPool + direction TB + pool[(All Transactions)] + subgraph Subpools + direction TB + B3[(Queued)] + B1[(Pending)] + B2[(Basefee)] + B4[(Blob)] + end + end + discard([discard]) + production([Block Production]) + new([New Block]) + A[Incoming Tx] --> B[Validation] -->|insert| pool + pool --> |if ready + blobfee too low| B4 + pool --> |if ready| B1 + pool --> |if ready + basfee too low| B2 + pool --> |nonce gap or lack of funds| B3 + pool --> |update| pool + B1 --> |best| production + B2 --> |worst| discard + B3 --> |worst| discard + B4 --> |worst| discard + B1 --> |increased blob fee| B4 + B4 --> |decreased blob fee| B1 + B1 --> |increased base fee| B2 + B2 --> |decreased base fee| B1 + B3 --> |promote| B1 + B3 --> |promote| B2 + new --> |apply state changes| pool