Skip to content

Commit baaf89e

Browse files
committed
feat(host): Support multiple entrypoints
1 parent f2d7447 commit baaf89e

15 files changed

+561
-458
lines changed

bin/client/justfile

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ run-client-asterisc block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc ver
4949
--input $STATE_PATH \
5050
-- \
5151
$HOST_BIN_PATH \
52+
single \
5253
--l1-head $L1_HEAD \
5354
--agreed-l2-head-hash $AGREED_L2_HEAD_HASH \
5455
--claimed-l2-output-root $CLAIMED_L2_OUTPUT_ROOT \
@@ -96,6 +97,7 @@ run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollu
9697

9798
echo "Running host program with native client program..."
9899
cargo r --bin kona-host --release -- \
100+
single \
99101
--l1-head $L1_HEAD \
100102
--agreed-l2-head-hash $AGREED_L2_HEAD_HASH \
101103
--claimed-l2-output-root $CLAIMED_L2_OUTPUT_ROOT \
@@ -125,6 +127,7 @@ run-client-native-offline block_number l2_claim l2_output_root l2_head l1_head l
125127

126128
echo "Running host program with native client program..."
127129
cargo r --bin kona-host --release -- \
130+
single \
128131
--l1-head $L1_HEAD \
129132
--agreed-l2-head-hash $AGREED_L2_HEAD_HASH \
130133
--claimed-l2-output-root $CLAIMED_L2_OUTPUT_ROOT \
@@ -169,6 +172,7 @@ run-client-asterisc-offline block_number l2_claim l2_output_root l2_head l1_head
169172
--input $STATE_PATH \
170173
-- \
171174
$HOST_BIN_PATH \
175+
single \
172176
--l1-head $L1_HEAD \
173177
--agreed-l2-head-hash $AGREED_L2_HEAD_HASH \
174178
--claimed-l2-output-root $CLAIMED_L2_OUTPUT_ROOT \

bin/host/src/cli/mod.rs

+11-234
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
11
//! This module contains all CLI-specific code for the host binary.
22
3-
use crate::{
4-
blobs::OnlineBlobProvider,
5-
kv::{
6-
DiskKeyValueStore, LocalKeyValueStore, MemoryKeyValueStore, SharedKeyValueStore,
7-
SplitKeyValueStore,
8-
},
9-
};
10-
use alloy_primitives::B256;
11-
use alloy_provider::ReqwestProvider;
12-
use alloy_rpc_client::RpcClient;
13-
use alloy_transport_http::Http;
14-
use anyhow::{anyhow, Result};
3+
use crate::single::SingleChainHostCli;
154
use clap::{
165
builder::styling::{AnsiColor, Color, Style},
17-
ArgAction, Parser,
6+
ArgAction, Parser, Subcommand,
187
};
19-
use op_alloy_genesis::RollupConfig;
20-
use reqwest::Client;
218
use serde::Serialize;
22-
use std::{path::PathBuf, sync::Arc};
23-
use tokio::sync::RwLock;
249

2510
mod parser;
2611
pub(crate) use parser::parse_b256;
@@ -37,164 +22,22 @@ primary thread.
3722
";
3823

3924
/// The host binary CLI application arguments.
40-
#[derive(Default, Parser, Serialize, Clone, Debug)]
25+
#[derive(Parser, Serialize, Clone, Debug)]
4126
#[command(about = ABOUT, version, styles = cli_styles())]
4227
pub struct HostCli {
4328
/// Verbosity level (0-2)
4429
#[arg(long, short, action = ArgAction::Count)]
4530
pub v: u8,
46-
/// Hash of the L1 head block. Derivation stops after this block is processed.
47-
#[clap(long, value_parser = parse_b256, env)]
48-
pub l1_head: B256,
49-
/// Hash of the agreed upon safe L2 block committed to by `--agreed-l2-output-root`.
50-
#[clap(long, visible_alias = "l2-head", value_parser = parse_b256, env)]
51-
pub agreed_l2_head_hash: B256,
52-
/// Agreed safe L2 Output Root to start derivation from.
53-
#[clap(long, visible_alias = "l2-output-root", value_parser = parse_b256, env)]
54-
pub agreed_l2_output_root: B256,
55-
/// Claimed L2 output root at block # `--claimed-l2-block-number` to validate.
56-
#[clap(long, visible_alias = "l2-claim", value_parser = parse_b256, env)]
57-
pub claimed_l2_output_root: B256,
58-
/// Number of the L2 block that the claimed output root commits to.
59-
#[clap(long, visible_alias = "l2-block-number", env)]
60-
pub claimed_l2_block_number: u64,
61-
/// Address of L2 JSON-RPC endpoint to use (eth and debug namespace required).
62-
#[clap(
63-
long,
64-
visible_alias = "l2",
65-
requires = "l1_node_address",
66-
requires = "l1_beacon_address",
67-
env
68-
)]
69-
pub l2_node_address: Option<String>,
70-
/// Address of L1 JSON-RPC endpoint to use (eth and debug namespace required)
71-
#[clap(
72-
long,
73-
visible_alias = "l1",
74-
requires = "l2_node_address",
75-
requires = "l1_beacon_address",
76-
env
77-
)]
78-
pub l1_node_address: Option<String>,
79-
/// Address of the L1 Beacon API endpoint to use.
80-
#[clap(
81-
long,
82-
visible_alias = "beacon",
83-
requires = "l1_node_address",
84-
requires = "l2_node_address",
85-
env
86-
)]
87-
pub l1_beacon_address: Option<String>,
88-
/// The Data Directory for preimage data storage. Optional if running in online mode,
89-
/// required if running in offline mode.
90-
#[clap(
91-
long,
92-
visible_alias = "db",
93-
required_unless_present_all = ["l2_node_address", "l1_node_address", "l1_beacon_address"],
94-
env
95-
)]
96-
pub data_dir: Option<PathBuf>,
97-
/// Run the client program natively.
98-
#[clap(long, conflicts_with = "server", required_unless_present = "server")]
99-
pub native: bool,
100-
/// Run in pre-image server mode without executing any client program. If not provided, the
101-
/// host will run the client program in the host process.
102-
#[clap(long, conflicts_with = "native", required_unless_present = "native")]
103-
pub server: bool,
104-
/// The L2 chain ID of a supported chain. If provided, the host will look for the corresponding
105-
/// rollup config in the superchain registry.
106-
#[clap(
107-
long,
108-
conflicts_with = "rollup_config_path",
109-
required_unless_present = "rollup_config_path",
110-
env
111-
)]
112-
pub l2_chain_id: Option<u64>,
113-
/// Path to rollup config. If provided, the host will use this config instead of attempting to
114-
/// look up the config in the superchain registry.
115-
#[clap(
116-
long,
117-
alias = "rollup-cfg",
118-
conflicts_with = "l2_chain_id",
119-
required_unless_present = "l2_chain_id",
120-
env
121-
)]
122-
pub rollup_config_path: Option<PathBuf>,
31+
/// Host mode
32+
#[clap(subcommand)]
33+
pub mode: HostMode,
12334
}
12435

125-
impl HostCli {
126-
/// Returns `true` if the host is running in offline mode.
127-
pub const fn is_offline(&self) -> bool {
128-
self.l1_node_address.is_none() &&
129-
self.l2_node_address.is_none() &&
130-
self.l1_beacon_address.is_none()
131-
}
132-
133-
/// Returns an HTTP provider for the given URL.
134-
fn http_provider(url: &str) -> ReqwestProvider {
135-
let url = url.parse().unwrap();
136-
let http = Http::<Client>::new(url);
137-
ReqwestProvider::new(RpcClient::new(http, true))
138-
}
139-
140-
/// Creates the providers associated with the [HostCli] configuration.
141-
///
142-
/// ## Returns
143-
/// - A [ReqwestProvider] for the L1 node.
144-
/// - An [OnlineBlobProvider] for the L1 beacon node.
145-
/// - A [ReqwestProvider] for the L2 node.
146-
pub async fn create_providers(
147-
&self,
148-
) -> Result<(ReqwestProvider, OnlineBlobProvider, ReqwestProvider)> {
149-
let blob_provider = OnlineBlobProvider::new_http(
150-
self.l1_beacon_address.clone().ok_or(anyhow!("Beacon API URL must be set"))?,
151-
)
152-
.await
153-
.map_err(|e| anyhow!("Failed to load blob provider configuration: {e}"))?;
154-
let l1_provider = Self::http_provider(
155-
self.l1_node_address.as_ref().ok_or(anyhow!("Provider must be set"))?,
156-
);
157-
let l2_provider = Self::http_provider(
158-
self.l2_node_address.as_ref().ok_or(anyhow!("L2 node address must be set"))?,
159-
);
160-
161-
Ok((l1_provider, blob_provider, l2_provider))
162-
}
163-
164-
/// Parses the CLI arguments and returns a new instance of a [SharedKeyValueStore], as it is
165-
/// configured to be created.
166-
pub fn construct_kv_store(&self) -> SharedKeyValueStore {
167-
let local_kv_store = LocalKeyValueStore::new(self.clone());
168-
169-
let kv_store: SharedKeyValueStore = if let Some(ref data_dir) = self.data_dir {
170-
let disk_kv_store = DiskKeyValueStore::new(data_dir.clone());
171-
let split_kv_store = SplitKeyValueStore::new(local_kv_store, disk_kv_store);
172-
Arc::new(RwLock::new(split_kv_store))
173-
} else {
174-
let mem_kv_store = MemoryKeyValueStore::new();
175-
let split_kv_store = SplitKeyValueStore::new(local_kv_store, mem_kv_store);
176-
Arc::new(RwLock::new(split_kv_store))
177-
};
178-
179-
kv_store
180-
}
181-
182-
/// Reads the [RollupConfig] from the file system and returns it as a string.
183-
pub fn read_rollup_config(&self) -> Result<RollupConfig> {
184-
let path = self.rollup_config_path.as_ref().ok_or_else(|| {
185-
anyhow::anyhow!(
186-
"No rollup config path provided. Please provide a path to the rollup config."
187-
)
188-
})?;
189-
190-
// Read the serialized config from the file system.
191-
let ser_config = std::fs::read_to_string(path)
192-
.map_err(|e| anyhow!("Error reading RollupConfig file: {e}"))?;
193-
194-
// Deserialize the config and return it.
195-
serde_json::from_str(&ser_config)
196-
.map_err(|e| anyhow!("Error deserializing RollupConfig: {e}"))
197-
}
36+
/// Operation modes for the host binary.
37+
#[derive(Subcommand, Serialize, Clone, Debug)]
38+
pub enum HostMode {
39+
/// Run the host in single-chain mode.
40+
Single(SingleChainHostCli),
19841
}
19942

20043
/// Styles for the CLI application.
@@ -208,69 +51,3 @@ const fn cli_styles() -> clap::builder::Styles {
20851
.valid(Style::new().bold().underline().fg_color(Some(Color::Ansi(AnsiColor::Green))))
20952
.placeholder(Style::new().fg_color(Some(Color::Ansi(AnsiColor::White))))
21053
}
211-
212-
#[cfg(test)]
213-
mod test {
214-
use crate::HostCli;
215-
use alloy_primitives::B256;
216-
use clap::Parser;
217-
218-
#[test]
219-
fn test_flags() {
220-
let zero_hash_str = &B256::ZERO.to_string();
221-
let default_flags = [
222-
"host",
223-
"--l1-head",
224-
zero_hash_str,
225-
"--l2-head",
226-
zero_hash_str,
227-
"--l2-output-root",
228-
zero_hash_str,
229-
"--l2-claim",
230-
zero_hash_str,
231-
"--l2-block-number",
232-
"0",
233-
];
234-
235-
let cases = [
236-
// valid
237-
(["--server", "--l2-chain-id", "0", "--data-dir", "dummy"].as_slice(), true),
238-
(["--server", "--rollup-config-path", "dummy", "--data-dir", "dummy"].as_slice(), true),
239-
(["--native", "--l2-chain-id", "0", "--data-dir", "dummy"].as_slice(), true),
240-
(["--native", "--rollup-config-path", "dummy", "--data-dir", "dummy"].as_slice(), true),
241-
(
242-
[
243-
"--l1-node-address",
244-
"dummy",
245-
"--l2-node-address",
246-
"dummy",
247-
"--l1-beacon-address",
248-
"dummy",
249-
"--server",
250-
"--l2-chain-id",
251-
"0",
252-
]
253-
.as_slice(),
254-
true,
255-
),
256-
// invalid
257-
(["--server", "--native", "--l2-chain-id", "0"].as_slice(), false),
258-
(["--l2-chain-id", "0", "--rollup-config-path", "dummy", "--server"].as_slice(), false),
259-
(["--server"].as_slice(), false),
260-
(["--native"].as_slice(), false),
261-
(["--rollup-config-path", "dummy"].as_slice(), false),
262-
(["--l2-chain-id", "0"].as_slice(), false),
263-
(["--l1-node-address", "dummy", "--server", "--l2-chain-id", "0"].as_slice(), false),
264-
(["--l2-node-address", "dummy", "--server", "--l2-chain-id", "0"].as_slice(), false),
265-
(["--l1-beacon-address", "dummy", "--server", "--l2-chain-id", "0"].as_slice(), false),
266-
([].as_slice(), false),
267-
];
268-
269-
for (args_ext, valid) in cases.into_iter() {
270-
let args = default_flags.iter().chain(args_ext.iter()).cloned().collect::<Vec<_>>();
271-
272-
let parsed = HostCli::try_parse_from(args);
273-
assert_eq!(parsed.is_ok(), valid);
274-
}
275-
}
276-
}
File renamed without changes.

bin/host/src/eth/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//! Ethereum utilities for the host binary.
2+
3+
mod blobs;
4+
pub use blobs::{
5+
APIConfigResponse, APIGenesisResponse, OnlineBlobProvider, ReducedConfigData,
6+
ReducedGenesisData,
7+
};
8+
9+
mod precompiles;
10+
pub(crate) use precompiles::execute;
File renamed without changes.

bin/host/src/fetcher.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//! Fetcher trait definition.
2+
3+
use kona_preimage::{HintRouter, PreimageFetcher};
4+
5+
/// The Fetcher trait is used to define the interface for fetching data from the preimage oracle,
6+
/// by [PreimageKey], and routing hints.
7+
///
8+
/// [PreimageKey]: kona_preimage::PreimageKey
9+
pub trait Fetcher: PreimageFetcher + HintRouter {}
10+
11+
impl<T> Fetcher for T where T: PreimageFetcher + HintRouter {}

bin/host/src/kv/mod.rs

-3
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ pub use disk::DiskKeyValueStore;
1414
mod split;
1515
pub use split::SplitKeyValueStore;
1616

17-
mod local;
18-
pub use local::LocalKeyValueStore;
19-
2017
/// A type alias for a shared key-value store.
2118
pub type SharedKeyValueStore = Arc<RwLock<dyn KeyValueStore + Send + Sync>>;
2219

0 commit comments

Comments
 (0)