Skip to content

Commit 4797b6a

Browse files
committed
feat: add L3 support
1 parent 3653337 commit 4797b6a

File tree

7 files changed

+122
-80
lines changed

7 files changed

+122
-80
lines changed

bin/client/justfile

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ default:
55
@just --list
66

77
# Run the client program on asterisc with the host in detached server mode.
8-
run-client-asterisc block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc verbosity='':
8+
run-client-asterisc block_number l1_rpc l2_rpc rollup_node_rpc verbosity='' l1_beacon_rpc='':
99
#!/usr/bin/env bash
1010

1111
L1_NODE_ADDRESS="{{l1_rpc}}"
@@ -64,7 +64,7 @@ run-client-asterisc block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc ver
6464
{{verbosity}}
6565

6666
# Run the client program natively with the host program attached.
67-
run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollup_config_path='' verbosity='':
67+
run-client-native block_number l1_rpc l2_rpc rollup_node_rpc rollup_config_path='' verbosity='' l1_beacon_rpc='':
6868
#!/usr/bin/env bash
6969
set -o errexit -o nounset -o pipefail
7070

@@ -80,6 +80,13 @@ run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollu
8080
CHAIN_ID_OR_ROLLUP_CONFIG_ARG="--rollup-config-path $(realpath {{rollup_config_path}})"
8181
fi
8282

83+
# Set up beacon address argument only if provided
84+
if [ -n "$L1_BEACON_ADDRESS" ]; then
85+
BEACON_ADDRESS_ARG="--l1-beacon-address $L1_BEACON_ADDRESS"
86+
else
87+
BEACON_ADDRESS_ARG=""
88+
fi
89+
8390
CLAIMED_L2_BLOCK_NUMBER={{block_number}}
8491
echo "Fetching configuration for block #$CLAIMED_L2_BLOCK_NUMBER..."
8592

@@ -96,15 +103,15 @@ run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollu
96103
cd $(git rev-parse --show-toplevel)
97104

98105
echo "Running host program with native client program..."
99-
cargo r --bin kona-host --release -- \
106+
RUST_LOG=debug cargo r --bin kona-host --release -- \
100107
single \
101108
--l1-head $L1_HEAD \
102109
--agreed-l2-head-hash $AGREED_L2_HEAD_HASH \
103110
--claimed-l2-output-root $CLAIMED_L2_OUTPUT_ROOT \
104111
--agreed-l2-output-root $AGREED_L2_OUTPUT_ROOT \
105112
--claimed-l2-block-number $CLAIMED_L2_BLOCK_NUMBER \
106113
--l1-node-address $L1_NODE_ADDRESS \
107-
--l1-beacon-address $L1_BEACON_ADDRESS \
114+
$BEACON_ADDRESS_ARG \
108115
--l2-node-address $L2_NODE_ADDRESS \
109116
--native \
110117
--data-dir ./data \
@@ -184,7 +191,7 @@ run-client-asterisc-offline block_number l2_claim l2_output_root l2_head l1_head
184191
{{verbosity}}
185192

186193
# Run the client program on cannon with the host in detached server mode.
187-
run-client-cannon block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc verbosity='':
194+
run-client-cannon block_number l1_rpc l2_rpc rollup_node_rpc verbosity='' l1_beacon_rpc='':
188195
#!/usr/bin/env bash
189196

190197
L1_NODE_ADDRESS="{{l1_rpc}}"

bin/client/kona.log

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Fetching configuration for block #2434489...
2+
Running host program with native client program...
3+
Finished `release` profile [optimized] target(s) in 0.31s
4+
Running `target/release/kona-host single --l1-head 0xdd0546ce8a22379393e9049932316056d4331deacf6849d554602db9c5c3b086 --agreed-l2-head-hash 0x38fb154677237edda3e830ea83d2316e0c264f6b1af544d4aae41af16d87a99d --claimed-l2-output-root 0x830a27941e4409736793db708dbf7bccd642fa66f32ad131544405d524b36f63 --agreed-l2-output-root 0x38c77a18a13f4c4c32c4cbbdce9189d411ec77f7320ea4d7133157d30ee89417 --claimed-l2-block-number 2434489 --l1-node-address 'https://eth-sepolia.g.alchemy.com/v2/hIxcf_hqT9It2hS8iCFeHKklL8tNyXNF' --l1-beacon-address 'https://restless-dimensional-lake.ethereum-sepolia.quiknode.pro/dbf58bd128200c47196a7dbeb84a42905f219959' --l2-node-address 'https://rpc-wolf-mammoth-plepjtp7jw.t.conduit.xyz/' --native --data-dir ./data --l2-chain-id 91578`
5+
2025-03-30T13:25:45.569438Z  INFO host-server: Starting oracle server
6+
2025-03-30T13:25:45.569437Z  INFO host-server: Starting hint router
7+
2025-03-30T13:25:45.570135Z  WARN boot-loader: No rollup config found for chain ID 91578, falling back to preimage oracle. This is insecure in production without additional validation!

bin/client/rollup.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"alt_da": {
3+
"da_challenge_contract_address": "0x0000000000000000000000000000000000000000",
4+
"da_challenge_window": 300,
5+
"da_commitment_type": "GenericCommitment",
6+
"da_resolve_window": 300
7+
},
8+
"batch_inbox_address": "0x1046467b29c56355f3611c81432bd76918b40521",
9+
"block_time": 2,
10+
"canyon_time": 0,
11+
"chain_op_config": {
12+
"eip1559Denominator": 50,
13+
"eip1559DenominatorCanyon": 250,
14+
"eip1559Elasticity": 6
15+
},
16+
"channel_timeout": 300,
17+
"delta_time": 0,
18+
"deposit_contract_address": "0x6f24b15366390998b36ad6497eb39a3b46a37bc4",
19+
"ecotone_time": 0,
20+
"fjord_time": 0,
21+
"genesis": {
22+
"l1": {
23+
"hash": "0x5123c1419c414204ed6293b9a30076e2d7d62f9f188bb808378d8d0817d2851f",
24+
"number": 7618221
25+
},
26+
"l2": {
27+
"hash": "0x29283ff0c581582b84b4e1564a1afe4b7b7f84708700054d8b5ab170c783ddef",
28+
"number": 0
29+
},
30+
"l2_time": 1738424688,
31+
"system_config": {
32+
"batcherAddr": "0x05dbef8f18097cf23c415c03f308bdb7b3e936e6",
33+
"eip1559Params": "0x0000000000000000",
34+
"gasLimit": 30000000,
35+
"operatorFeeParams": "0x0000000000000000000000000000000000000000000000000000000000000000",
36+
"overhead": "0x00000000000000000000000000000000000000000000000000000000000000bc",
37+
"scalar": "0x0000000000000000000000000000000000000000000000000000000000010b30"
38+
}
39+
},
40+
"l1_chain_id": 11155111,
41+
"l1_system_config_address": "0x3592a865cd0a2fadedbedc1f6a07694793fa7ec1",
42+
"l2_chain_id": 91578,
43+
"max_sequencer_drift": 600,
44+
"pectra_blob_schedule_time": 1742486400,
45+
"protocol_versions_address": "0x0000000000000000000000000000000000000000",
46+
"regolith_time": 0,
47+
"seq_window_size": 3600
48+
}

bin/host/src/interop/cfg.rs

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -45,32 +45,13 @@ pub struct InteropHost {
4545
#[arg(long, visible_alias = "l2-timestamp", env)]
4646
pub claimed_l2_timestamp: u64,
4747
/// Addresses of L2 JSON-RPC endpoints to use (eth and debug namespace required).
48-
#[arg(
49-
long,
50-
visible_alias = "l2s",
51-
requires = "l1_node_address",
52-
requires = "l1_beacon_address",
53-
value_delimiter = ',',
54-
env
55-
)]
48+
#[arg(long, visible_alias = "l2s", requires = "l1_node_address", value_delimiter = ',', env)]
5649
pub l2_node_addresses: Option<Vec<String>>,
5750
/// Address of L1 JSON-RPC endpoint to use (eth and debug namespace required)
58-
#[arg(
59-
long,
60-
visible_alias = "l1",
61-
requires = "l2_node_addresses",
62-
requires = "l1_beacon_address",
63-
env
64-
)]
51+
#[arg(long, visible_alias = "l1", requires = "l2_node_addresses", env)]
6552
pub l1_node_address: Option<String>,
6653
/// Address of the L1 Beacon API endpoint to use.
67-
#[arg(
68-
long,
69-
visible_alias = "beacon",
70-
requires = "l1_node_address",
71-
requires = "l2_node_addresses",
72-
env
73-
)]
54+
#[arg(long, visible_alias = "beacon", requires = "l1_node_address", env)]
7455
pub l1_beacon_address: Option<String>,
7556
/// The Data Directory for preimage data storage. Optional if running in online mode,
7657
/// required if running in offline mode.
@@ -201,10 +182,10 @@ impl InteropHost {
201182

202183
/// Returns `true` if the host is running in offline mode.
203184
pub const fn is_offline(&self) -> bool {
204-
self.l1_node_address.is_none() &&
205-
self.l2_node_addresses.is_none() &&
206-
self.l1_beacon_address.is_none() &&
207-
self.data_dir.is_some()
185+
self.l1_node_address.is_none()
186+
&& self.l2_node_addresses.is_none()
187+
&& self.l1_beacon_address.is_none()
188+
&& self.data_dir.is_some()
208189
}
209190

210191
/// Reads the [RollupConfig]s from the file system and returns a map of L2 chain ID ->
@@ -251,12 +232,14 @@ impl InteropHost {
251232
self.l1_node_address.as_ref().ok_or(InteropHostError::Other("Provider must be set"))?,
252233
);
253234

254-
let blob_provider = OnlineBlobProvider::init(OnlineBeaconClient::new_http(
255-
self.l1_beacon_address
256-
.clone()
257-
.ok_or(InteropHostError::Other("Beacon API URL must be set"))?,
258-
))
259-
.await;
235+
let blob_provider = if let Some(beacon_address) = &self.l1_beacon_address {
236+
Some(
237+
OnlineBlobProvider::init(OnlineBeaconClient::new_http(beacon_address.clone()))
238+
.await,
239+
)
240+
} else {
241+
None
242+
};
260243

261244
// Resolve all chain IDs to their corresponding providers.
262245
let l2_node_addresses = self
@@ -285,7 +268,7 @@ pub struct InteropProviders {
285268
/// The L1 EL provider.
286269
pub l1: RootProvider,
287270
/// The L1 beacon node provider.
288-
pub blobs: OnlineBlobProvider<OnlineBeaconClient>,
271+
pub blobs: Option<OnlineBlobProvider<OnlineBeaconClient>>,
289272
/// The L2 EL providers, keyed by chain ID.
290273
pub l2s: HashMap<u64, RootProvider<Optimism>>,
291274
}

bin/host/src/interop/handler.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,16 @@ impl HintHandler for InteropHintHandler {
103103
let indexed_hash = IndexedBlobHash { index, hash };
104104

105105
// Fetch the blob sidecar from the blob provider.
106-
let mut sidecars = providers
107-
.blobs
108-
.fetch_filtered_sidecars(&partial_block_ref, &[indexed_hash])
109-
.await
110-
.map_err(|e| anyhow!("Failed to fetch blob sidecars: {e}"))?;
106+
let mut sidecars = if let Some(blobs) = &providers.blobs {
107+
blobs
108+
.fetch_filtered_sidecars(&partial_block_ref, &[indexed_hash])
109+
.await
110+
.map_err(|e| anyhow!("Failed to fetch blob sidecars: {e}"))?
111+
} else {
112+
return Err(
113+
anyhow!("Beacon API URL not provided, cannot fetch blob sidecars").into()
114+
);
115+
};
111116
if sidecars.len() != 1 {
112117
anyhow::bail!("Expected 1 sidecar, got {}", sidecars.len());
113118
}

bin/host/src/single/cfg.rs

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -46,31 +46,13 @@ pub struct SingleChainHost {
4646
#[arg(long, visible_alias = "l2-block-number", env)]
4747
pub claimed_l2_block_number: u64,
4848
/// Address of L2 JSON-RPC endpoint to use (eth and debug namespace required).
49-
#[arg(
50-
long,
51-
visible_alias = "l2",
52-
requires = "l1_node_address",
53-
requires = "l1_beacon_address",
54-
env
55-
)]
49+
#[arg(long, visible_alias = "l2", requires = "l1_node_address", env)]
5650
pub l2_node_address: Option<String>,
5751
/// Address of L1 JSON-RPC endpoint to use (eth and debug namespace required)
58-
#[arg(
59-
long,
60-
visible_alias = "l1",
61-
requires = "l2_node_address",
62-
requires = "l1_beacon_address",
63-
env
64-
)]
52+
#[arg(long, visible_alias = "l1", requires = "l2_node_address", env)]
6553
pub l1_node_address: Option<String>,
6654
/// Address of the L1 Beacon API endpoint to use.
67-
#[arg(
68-
long,
69-
visible_alias = "beacon",
70-
requires = "l1_node_address",
71-
requires = "l2_node_address",
72-
env
73-
)]
55+
#[arg(long, visible_alias = "beacon", requires = "l1_node_address", env)]
7456
pub l1_beacon_address: Option<String>,
7557
/// The Data Directory for preimage data storage. Optional if running in online mode,
7658
/// required if running in offline mode.
@@ -211,10 +193,10 @@ impl SingleChainHost {
211193

212194
/// Returns `true` if the host is running in offline mode.
213195
pub const fn is_offline(&self) -> bool {
214-
self.l1_node_address.is_none() &&
215-
self.l2_node_address.is_none() &&
216-
self.l1_beacon_address.is_none() &&
217-
self.data_dir.is_some()
196+
self.l1_node_address.is_none()
197+
&& self.l2_node_address.is_none()
198+
&& self.l1_beacon_address.is_none()
199+
&& self.data_dir.is_some()
218200
}
219201

220202
/// Reads the [RollupConfig] from the file system and returns it as a string.
@@ -256,12 +238,16 @@ impl SingleChainHost {
256238
.as_ref()
257239
.ok_or(SingleChainHostError::Other("Provider must be set"))?,
258240
);
259-
let blob_provider = OnlineBlobProvider::init(OnlineBeaconClient::new_http(
260-
self.l1_beacon_address
261-
.clone()
262-
.ok_or(SingleChainHostError::Other("Beacon API URL must be set"))?,
263-
))
264-
.await;
241+
242+
let blob_provider = if let Some(beacon_address) = &self.l1_beacon_address {
243+
Some(
244+
OnlineBlobProvider::init(OnlineBeaconClient::new_http(beacon_address.clone()))
245+
.await,
246+
)
247+
} else {
248+
None
249+
};
250+
265251
let l2_provider = http_provider::<Optimism>(
266252
self.l2_node_address
267253
.as_ref()
@@ -283,7 +269,7 @@ pub struct SingleChainProviders {
283269
/// The L1 EL provider.
284270
pub l1: RootProvider,
285271
/// The L1 beacon node provider.
286-
pub blobs: OnlineBlobProvider<OnlineBeaconClient>,
272+
pub blobs: Option<OnlineBlobProvider<OnlineBeaconClient>>,
287273
/// The L2 EL provider.
288274
pub l2: RootProvider<Optimism>,
289275
}

bin/host/src/single/handler.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,17 @@ impl HintHandler for SingleChainHintHandler {
8787
let indexed_hash = IndexedBlobHash { index, hash };
8888

8989
// Fetch the blob sidecar from the blob provider.
90-
let mut sidecars = providers
91-
.blobs
92-
.fetch_filtered_sidecars(&partial_block_ref, &[indexed_hash])
93-
.await
94-
.map_err(|e| anyhow!("Failed to fetch blob sidecars: {e}"))?;
90+
let mut sidecars = if let Some(blobs) = &providers.blobs {
91+
blobs
92+
.fetch_filtered_sidecars(&partial_block_ref, &[indexed_hash])
93+
.await
94+
.map_err(|e| anyhow!("Failed to fetch blob sidecars: {e}"))?
95+
} else {
96+
return Err(
97+
anyhow!("Beacon API URL not provided, cannot fetch blob sidecars").into()
98+
);
99+
};
100+
95101
if sidecars.len() != 1 {
96102
anyhow::bail!("Expected 1 sidecar, got {}", sidecars.len());
97103
}

0 commit comments

Comments
 (0)