Skip to content

Commit ebae794

Browse files
authored
chore(flashblocks): modularize types (#254)
1 parent c810ad2 commit ebae794

File tree

16 files changed

+94
-78
lines changed

16 files changed

+94
-78
lines changed

crates/flashblocks/src/blocks.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//! Contains the [`Flashblock`] and [`Metadata`] types used in Flashblocks.
2+
3+
use alloy_primitives::{Address, B256, U256, map::foldhash::HashMap};
4+
use alloy_rpc_types_engine::PayloadId;
5+
use reth_optimism_primitives::OpReceipt;
6+
use rollup_boost::{ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1};
7+
use serde::{Deserialize, Serialize};
8+
9+
/// Metadata associated with a flashblock.
10+
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
11+
pub struct Metadata {
12+
/// Transaction receipts indexed by hash.
13+
pub receipts: HashMap<B256, OpReceipt>,
14+
/// Updated account balances.
15+
pub new_account_balances: HashMap<Address, U256>,
16+
/// Block number this flashblock belongs to.
17+
pub block_number: u64,
18+
}
19+
20+
/// A flashblock containing partial block data.
21+
#[derive(Debug, Clone)]
22+
pub struct Flashblock {
23+
/// Unique payload identifier.
24+
pub payload_id: PayloadId,
25+
/// Index of this flashblock within the block.
26+
pub index: u64,
27+
/// Base payload data (only present on first flashblock).
28+
pub base: Option<ExecutionPayloadBaseV1>,
29+
/// Delta containing transactions and state changes.
30+
pub diff: ExecutionPayloadFlashblockDeltaV1,
31+
/// Associated metadata.
32+
pub metadata: Metadata,
33+
}

crates/flashblocks/src/lib.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@
44
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
55

66
mod metrics;
7-
pub(crate) use metrics::Metrics;
7+
pub use metrics::Metrics;
88

99
mod pending_blocks;
10+
pub use pending_blocks::{PendingBlocks, PendingBlocksBuilder};
1011

11-
pub mod state;
12+
mod state;
13+
pub use state::FlashblocksState;
1214

13-
pub mod subscription;
14-
pub mod traits;
15+
mod subscription;
16+
pub use subscription::{FlashblocksReceiver, FlashblocksSubscriber};
1517

16-
pub use pending_blocks::PendingBlocks;
18+
mod traits;
19+
pub use traits::{FlashblocksAPI, PendingBlocksAPI};
20+
21+
mod blocks;
22+
pub use blocks::{Flashblock, Metadata};

crates/flashblocks/src/metrics.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,59 @@
1+
//! Metrics for flashblocks.
2+
13
use metrics::{Counter, Gauge, Histogram};
24
use metrics_derive::Metrics;
5+
36
/// Metrics for the `reth_flashblocks` component.
47
/// Conventions:
58
/// - Durations are recorded in seconds (histograms).
69
/// - Counters are monotonic event counts.
710
/// - Gauges reflect the current value/state.
811
#[derive(Metrics, Clone)]
912
#[metrics(scope = "reth_flashblocks")]
10-
pub(crate) struct Metrics {
13+
pub struct Metrics {
14+
/// Count of times upstream receiver was closed/errored.
1115
#[metric(describe = "Count of times upstream receiver was closed/errored")]
1216
pub upstream_errors: Counter,
1317

18+
/// Count of messages received from the upstream source.
1419
#[metric(describe = "Count of messages received from the upstream source")]
1520
pub upstream_messages: Counter,
1621

22+
/// Time taken to process a message.
1723
#[metric(describe = "Time taken to process a message")]
1824
pub block_processing_duration: Histogram,
1925

26+
/// Number of Flashblocks that arrive in an unexpected order.
2027
#[metric(describe = "Number of Flashblocks that arrive in an unexpected order")]
2128
pub unexpected_block_order: Counter,
2229

30+
/// Number of flashblocks contained within a single block.
2331
#[metric(describe = "Number of flashblocks in a block")]
2432
pub flashblocks_in_block: Histogram,
2533

34+
/// Count of times flashblocks are unable to be converted to blocks.
2635
#[metric(describe = "Count of times flashblocks are unable to be converted to blocks")]
2736
pub block_processing_error: Counter,
2837

38+
/// Count of times pending snapshot was cleared because canonical caught up.
2939
#[metric(
3040
describe = "Number of times pending snapshot was cleared because canonical caught up"
3141
)]
3242
pub pending_clear_catchup: Counter,
3343

44+
/// Number of times pending snapshot was cleared because of reorg.
3445
#[metric(describe = "Number of times pending snapshot was cleared because of reorg")]
3546
pub pending_clear_reorg: Counter,
3647

48+
/// Pending snapshot flashblock index (current).
3749
#[metric(describe = "Pending snapshot flashblock index (current)")]
3850
pub pending_snapshot_fb_index: Gauge,
3951

52+
/// Pending snapshot block number (current).
4053
#[metric(describe = "Pending snapshot block number (current)")]
4154
pub pending_snapshot_height: Gauge,
4255

56+
/// Total number of WebSocket reconnection attempts.
4357
#[metric(describe = "Total number of WebSocket reconnection attempts")]
4458
pub reconnect_attempts: Counter,
4559
}

crates/flashblocks/src/pending_blocks.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ use reth::revm::{db::Cache, state::EvmState};
1717
use reth_rpc_convert::RpcTransaction;
1818
use reth_rpc_eth_api::{RpcBlock, RpcReceipt};
1919

20-
use crate::{subscription::Flashblock, traits::PendingBlocksAPI};
20+
use crate::{Flashblock, PendingBlocksAPI};
2121

22-
pub(crate) struct PendingBlocksBuilder {
22+
/// Builder for [`PendingBlocks`].
23+
#[derive(Debug)]
24+
pub struct PendingBlocksBuilder {
2325
flashblocks: Vec<Flashblock>,
2426
headers: Vec<Sealed<Header>>,
2527

crates/flashblocks/src/state.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,7 @@ use tokio::sync::{
4343
use tracing::{debug, error, info, warn};
4444

4545
use crate::{
46-
PendingBlocks,
47-
metrics::Metrics,
48-
pending_blocks::PendingBlocksBuilder,
49-
subscription::{Flashblock, FlashblocksReceiver},
50-
traits::FlashblocksAPI,
46+
Flashblock, FlashblocksAPI, FlashblocksReceiver, Metrics, PendingBlocks, PendingBlocksBuilder,
5147
};
5248

5349
// Buffer 4s of flashblocks for flashblock_sender

crates/flashblocks/src/subscription.rs

Lines changed: 20 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,21 @@
22
33
use std::{io::Read, sync::Arc, time::Duration};
44

5-
use alloy_primitives::{Address, B256, U256, map::foldhash::HashMap};
6-
use alloy_rpc_types_engine::PayloadId;
75
use futures_util::{SinkExt as _, StreamExt};
8-
use reth_optimism_primitives::OpReceipt;
9-
use rollup_boost::{
10-
ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1, FlashblocksPayloadV1,
11-
};
12-
use serde::{Deserialize, Serialize};
6+
use rollup_boost::FlashblocksPayloadV1;
137
use tokio::{sync::mpsc, time::interval};
148
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
159
use tracing::{error, info, trace, warn};
1610
use url::Url;
1711

18-
use crate::Metrics;
19-
20-
/// Interval of liveness check of upstream, in milliseconds.
21-
pub const PING_INTERVAL_MS: u64 = 500;
22-
23-
/// Max duration of backoff before reconnecting to upstream.
24-
pub const MAX_BACKOFF: Duration = Duration::from_secs(10);
12+
use crate::{Flashblock, Metadata, Metrics};
2513

2614
/// Trait for receiving flashblock updates.
2715
pub trait FlashblocksReceiver {
2816
/// Called when a new flashblock is received.
2917
fn on_flashblock_received(&self, flashblock: Flashblock);
3018
}
3119

32-
/// Metadata associated with a flashblock.
33-
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
34-
pub struct Metadata {
35-
/// Transaction receipts indexed by hash.
36-
pub receipts: HashMap<B256, OpReceipt>,
37-
/// Updated account balances.
38-
pub new_account_balances: HashMap<Address, U256>,
39-
/// Block number this flashblock belongs to.
40-
pub block_number: u64,
41-
}
42-
43-
/// A flashblock containing partial block data.
44-
#[derive(Debug, Clone)]
45-
pub struct Flashblock {
46-
/// Unique payload identifier.
47-
pub payload_id: PayloadId,
48-
/// Index of this flashblock within the block.
49-
pub index: u64,
50-
/// Base payload data (only present on first flashblock).
51-
pub base: Option<ExecutionPayloadBaseV1>,
52-
/// Delta containing transactions and state changes.
53-
pub diff: ExecutionPayloadFlashblockDeltaV1,
54-
/// Associated metadata.
55-
pub metadata: Metadata,
56-
}
57-
5820
// Simplify actor messages to just handle shutdown
5921
#[derive(Debug)]
6022
enum ActorMessage {
@@ -73,6 +35,12 @@ impl<Receiver> FlashblocksSubscriber<Receiver>
7335
where
7436
Receiver: FlashblocksReceiver + Send + Sync + 'static,
7537
{
38+
/// Interval of liveness check of upstream, in milliseconds.
39+
pub const PING_INTERVAL_MS: u64 = 500;
40+
41+
/// Max duration of backoff before reconnecting to upstream.
42+
pub const MAX_BACKOFF: Duration = Duration::from_secs(10);
43+
7644
/// Creates a new flashblocks subscriber.
7745
pub fn new(flashblocks_state: Arc<Receiver>, ws_url: Url) -> Self {
7846
Self { ws_url, flashblocks_state, metrics: Metrics::default() }
@@ -98,7 +66,8 @@ where
9866
Ok((ws_stream, _)) => {
9967
info!(message = "WebSocket connection established");
10068

101-
let mut ping_interval = interval(Duration::from_millis(PING_INTERVAL_MS));
69+
let mut ping_interval =
70+
interval(Duration::from_millis(Self::PING_INTERVAL_MS));
10271
let mut awaiting_pong_resp = false;
10372

10473
let (mut write, mut read) = ws_stream.split();
@@ -152,11 +121,11 @@ where
152121
warn!(
153122
target: "flashblocks_rpc::subscription",
154123
?backoff,
155-
timeout_ms = PING_INTERVAL_MS,
124+
timeout_ms = Self::PING_INTERVAL_MS,
156125
"No pong response from upstream, reconnecting",
157126
);
158127

159-
backoff = sleep(&metrics, backoff).await;
128+
backoff = Self::sleep(&metrics, backoff).await;
160129
break 'conn;
161130
}
162131

@@ -172,7 +141,7 @@ where
172141
"WebSocket connection lost, reconnecting",
173142
);
174143

175-
backoff = sleep(&metrics, backoff).await;
144+
backoff = Self::sleep(&metrics, backoff).await;
176145
break 'conn;
177146
}
178147
awaiting_pong_resp = true
@@ -187,7 +156,7 @@ where
187156
error = %e
188157
);
189158

190-
backoff = sleep(&metrics, backoff).await;
159+
backoff = Self::sleep(&metrics, backoff).await;
191160
continue;
192161
}
193162
}
@@ -205,13 +174,13 @@ where
205174
}
206175
});
207176
}
208-
}
209177

210-
/// Sleeps for given backoff duration. Returns incremented backoff duration, capped at [`MAX_BACKOFF`].
211-
async fn sleep(metrics: &Metrics, backoff: Duration) -> Duration {
212-
metrics.reconnect_attempts.increment(1);
213-
tokio::time::sleep(backoff).await;
214-
std::cmp::min(backoff * 2, MAX_BACKOFF)
178+
/// Sleeps for given backoff duration. Returns incremented backoff duration, capped at [`MAX_BACKOFF`].
179+
async fn sleep(metrics: &Metrics, backoff: Duration) -> Duration {
180+
metrics.reconnect_attempts.increment(1);
181+
tokio::time::sleep(backoff).await;
182+
std::cmp::min(backoff * 2, Self::MAX_BACKOFF)
183+
}
215184
}
216185

217186
fn try_decode_message(bytes: &[u8]) -> eyre::Result<Flashblock> {

crates/flashblocks/tests/state.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ use alloy_eips::{BlockHashOrNumber, Encodable2718};
99
use alloy_primitives::{Address, B256, BlockNumber, Bytes, U256, hex, map::foldhash::HashMap};
1010
use alloy_rpc_types_engine::PayloadId;
1111
use base_reth_flashblocks::{
12-
state::FlashblocksState,
13-
subscription::{Flashblock, Metadata},
14-
traits::{FlashblocksAPI, PendingBlocksAPI},
12+
Flashblock, FlashblocksAPI, FlashblocksState, Metadata, PendingBlocksAPI,
1513
};
1614
use base_reth_test_utils::{
1715
accounts::TestAccounts, flashblocks_harness::FlashblocksHarness, node::LocalNodeProvider,

crates/rpc/src/base/pubsub.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::sync::Arc;
44

5-
use base_reth_flashblocks::traits::FlashblocksAPI;
5+
use base_reth_flashblocks::FlashblocksAPI;
66
use jsonrpsee::{
77
PendingSubscriptionSink, SubscriptionSink,
88
core::{SubscriptionResult, async_trait},

crates/rpc/src/eth/rpc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use alloy_rpc_types::{
1313
state::{EvmOverrides, StateOverride, StateOverridesBuilder},
1414
};
1515
use alloy_rpc_types_eth::{Filter, Log};
16-
use base_reth_flashblocks::traits::{FlashblocksAPI, PendingBlocksAPI};
16+
use base_reth_flashblocks::{FlashblocksAPI, PendingBlocksAPI};
1717
use jsonrpsee::{
1818
core::{RpcResult, async_trait},
1919
proc_macros::rpc,

crates/rpc/tests/flashblocks_rpc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use alloy_rpc_client::RpcClient;
1414
use alloy_rpc_types::simulate::{SimBlock, SimulatePayload};
1515
use alloy_rpc_types_engine::PayloadId;
1616
use alloy_rpc_types_eth::{TransactionInput, error::EthRpcErrorCode};
17-
use base_reth_flashblocks::subscription::{Flashblock, Metadata};
17+
use base_reth_flashblocks::{Flashblock, Metadata};
1818
use base_reth_test_utils::flashblocks_harness::FlashblocksHarness;
1919
use common::{BLOCK_INFO_TXN, BLOCK_INFO_TXN_HASH};
2020
use eyre::Result;

0 commit comments

Comments
 (0)