Skip to content

Commit aa078ea

Browse files
authored
Merge branch 'main' into dependabot/cargo/arbitrary-1.4.2
2 parents a2465f3 + 69ae488 commit aa078ea

File tree

10 files changed

+148
-118
lines changed

10 files changed

+148
-118
lines changed

.github/workflows/build-and-test.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ jobs:
8686
- name: Run lint
8787
run: just lint
8888
build-docker:
89-
needs: build
9089
runs-on: ubuntu-latest
9190
steps:
9291
- uses: actions/checkout@v4
@@ -159,5 +158,5 @@ jobs:
159158
run: just run_demo -s /tmp/stamp --ignore-stamp -k test-configs/local-2.json --rounds 10000 --yapper --nitro
160159
- name: Verify sequencer blocks
161160
run: |
162-
just verify_blocks
161+
RUST_LOG=info just verify_blocks
163162

Cargo.lock

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ members = [
1717
"timeboost-types",
1818
"timeboost-utils",
1919
"yapper",
20+
"tests/block-verifier"
2021
]
2122
resolver = "2"
2223

justfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ mkconfig_docker_full NUM_NODES RPC_URL PARENT_CHAIN_ID PARENT_INBOX_ADDRESS *ARG
109109
--parent-ibox-contr-addr {{PARENT_INBOX_ADDRESS}} \
110110
--mode "increment-address" {{ARGS}} | jq
111111

112-
verify_blocks:
113-
./scripts/verify-blocks
112+
verify_blocks *ARGS:
113+
cargo run --release --bin block_verifier {{ARGS}}
114114

115115
####################
116116
####TEST COMMANDS###

scripts/verify-blocks

Lines changed: 0 additions & 89 deletions
This file was deleted.

tests/block-verifier/Cargo.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "block_verifier"
3+
version.workspace = true
4+
edition.workspace = true
5+
rust-version.workspace = true
6+
7+
[dependencies]
8+
alloy = { workspace = true }
9+
anyhow = { workspace = true }
10+
clap = { workspace = true }
11+
futures = { workspace = true }
12+
timeboost-utils = { path = "../../timeboost-utils" }
13+
tokio = { workspace = true }
14+
tracing = { workspace = true }

tests/block-verifier/src/main.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use alloy::{
2+
eips::BlockNumberOrTag,
3+
network::{Ethereum, Network},
4+
providers::{Provider, RootProvider},
5+
rpc::types::Block,
6+
};
7+
use anyhow::{Context, Result};
8+
use clap::Parser;
9+
use futures::future::join_all;
10+
use timeboost_utils::types::logging::init_logging;
11+
use tracing::{error, info};
12+
13+
/// Max. Difference between l2 block heights for potential race conditions when heights are fetched
14+
/// from the sequencers
15+
const MAX_BLOCK_HEIGHT_DIFF: u64 = 2;
16+
17+
#[derive(Parser, Debug)]
18+
struct Cli {
19+
/// Nitro node URLs use to check state for different sequencers to ensure consistency
20+
#[clap(
21+
long,
22+
default_value = "http://localhost:8547,http://localhost:8647",
23+
use_value_delimiter = true,
24+
value_delimiter = ','
25+
)]
26+
nitro_urls: Vec<String>,
27+
}
28+
29+
async fn connect_to_nitro<N: Network>(urls: &[String]) -> Result<Vec<RootProvider<N>>> {
30+
let mut p = Vec::new();
31+
for url in urls {
32+
p.push(RootProvider::<N>::connect(url).await?)
33+
}
34+
Ok(p)
35+
}
36+
37+
#[tokio::main]
38+
async fn main() -> Result<()> {
39+
init_logging();
40+
let cli = Cli::parse();
41+
42+
let providers = connect_to_nitro::<Ethereum>(&cli.nitro_urls).await?;
43+
44+
let block_numbers = join_all(providers.iter().map(|p| async {
45+
p.get_block_number()
46+
.await
47+
.context("provider request failed")
48+
}))
49+
.await
50+
.into_iter()
51+
.collect::<Result<Vec<u64>>>()?;
52+
53+
let min = *block_numbers.iter().min().context("no blocks received")?;
54+
let max = *block_numbers.iter().max().context("no blocks received")?;
55+
let diff = max - min;
56+
57+
// ensure the max - min is within MAX_BLOCK_HEIGHT_DIFF
58+
info!(
59+
max_height = %max,
60+
min_height = %min,
61+
height_diff = %diff,
62+
provider_count = %providers.len(),
63+
"block height verification"
64+
);
65+
if diff > MAX_BLOCK_HEIGHT_DIFF {
66+
error!(%max, %min, %diff, max_diff = %MAX_BLOCK_HEIGHT_DIFF, "❌ block numbers too far apart");
67+
anyhow::bail!(
68+
"block numbers too far apart (min: {}, max: {}, diff: {})",
69+
min,
70+
max,
71+
diff
72+
);
73+
}
74+
75+
// use minimum block in to avoid race conditions
76+
for i in 0..=min {
77+
let blocks = join_all(providers.iter().map(|p| async {
78+
p.get_block_by_number(BlockNumberOrTag::Number(i))
79+
.await
80+
.context("provider request failed")
81+
}))
82+
.await
83+
.into_iter()
84+
.collect::<Result<Vec<Option<Block>>>>()?;
85+
let first_block = blocks
86+
.first()
87+
.and_then(|b| b.as_ref())
88+
.ok_or_else(|| anyhow::anyhow!("no blocks received from any provider"))?;
89+
for (i, block) in blocks.iter().enumerate().skip(1) {
90+
let b = block
91+
.as_ref()
92+
.ok_or_else(|| anyhow::anyhow!("provider returned no block"))?;
93+
if b != first_block {
94+
error!(
95+
num = %b.number(),
96+
block_a = ?b,
97+
block_b = ?first_block,
98+
"❌ block mismatch between state"
99+
);
100+
anyhow::bail!(
101+
"block mismatch between blocks: left: {:?}, right: {:?}",
102+
b,
103+
first_block
104+
);
105+
}
106+
if i == blocks.len() - 1 {
107+
info!(num = %b.number(), block_hash = %b.hash(), txns = ?b.transactions, "✅ verified block");
108+
}
109+
}
110+
}
111+
112+
Ok(())
113+
}

yapper/src/config.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ pub(crate) struct YapperConfig {
1111
pub(crate) nitro_integration: bool,
1212
/// URL of nitro chain that is configured
1313
pub(crate) nitro_url: String,
14-
/// Limit on the number of transactions we want to send
15-
pub(crate) txn_limit: u64,
1614
/// Chain id for l2 chain
1715
pub(crate) chain_id: u64,
1816
}

yapper/src/main.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ struct Cli {
4545
#[clap(long, default_value_t = false)]
4646
nitro_integration: bool,
4747

48-
/// How many txns to send before terminating yapper
49-
#[clap(long, default_value_t = 20)]
50-
nitro_txn_limit: u64,
51-
5248
/// Chain id for l2 chain
5349
/// default: https://docs.arbitrum.io/run-arbitrum-node/run-local-full-chain-simulation#default-endpoints-and-addresses
5450
#[clap(long, default_value_t = 412346)]
@@ -85,7 +81,6 @@ async fn main() -> Result<()> {
8581
.addresses(addresses)
8682
.nitro_integration(cli.nitro_integration)
8783
.tps(cli.tps)
88-
.txn_limit(cli.nitro_txn_limit)
8984
.nitro_url(cli.nitro_url)
9085
.chain_id(cli.chain_id)
9186
.build();

yapper/src/yapper.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ pub(crate) struct Yapper {
4141
interval: Duration,
4242
chain_id: u64,
4343
provider: Option<RootProvider>,
44-
txn_limit: Option<u64>,
4544
}
4645

4746
impl Yapper {
@@ -63,23 +62,16 @@ impl Yapper {
6362
});
6463
}
6564
let client = Client::builder().timeout(Duration::from_secs(1)).build()?;
66-
let (provider, interval, txn_limit) = if cfg.nitro_integration {
67-
(
68-
Some(RootProvider::<Ethereum>::connect(&cfg.nitro_url).await?),
69-
Duration::from_secs(1),
70-
// For nitro running in ci, avoid race conditions with block height by setting txn
71-
// limit
72-
Some(cfg.txn_limit),
73-
)
65+
let provider = if cfg.nitro_integration {
66+
Some(RootProvider::<Ethereum>::connect(&cfg.nitro_url).await?)
7467
} else {
75-
(None, Duration::from_millis(tps_to_millis(cfg.tps)), None)
68+
None
7669
};
7770
Ok(Self {
7871
urls,
79-
interval,
72+
interval: Duration::from_millis(tps_to_millis(cfg.tps)),
8073
client,
8174
provider,
82-
txn_limit,
8375
chain_id: cfg.chain_id,
8476
})
8577
}
@@ -93,7 +85,6 @@ impl Yapper {
9385
self.urls.iter().map(|url| url.enckey_url.clone()),
9486
);
9587

96-
let mut txn_sent = 0;
9788
loop {
9889
let b = if let Some(ref p) = self.provider {
9990
// For testing just send from the dev account to the validator address
@@ -133,11 +124,6 @@ impl Yapper {
133124
.await
134125
}))
135126
.await;
136-
txn_sent += 1;
137-
if self.txn_limit == Some(txn_sent) {
138-
warn!("hit txn limit, terminating yapper");
139-
return Ok(());
140-
}
141127

142128
interval.tick().await;
143129
}

0 commit comments

Comments
 (0)