diff --git a/bin/client/justfile b/bin/client/justfile index faf049f4e2..de7b5aba34 100644 --- a/bin/client/justfile +++ b/bin/client/justfile @@ -5,7 +5,7 @@ default: @just --list # Run the client program on asterisc with the host in detached server mode. -run-client-asterisc block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc verbosity='': +run-client-asterisc block_number l1_rpc l2_rpc rollup_node_rpc verbosity='' l1_beacon_rpc='': #!/usr/bin/env bash 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 {{verbosity}} # Run the client program natively with the host program attached. -run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollup_config_path='' verbosity='': +run-client-native block_number l1_rpc l2_rpc rollup_node_rpc rollup_config_path='' verbosity='' l1_beacon_rpc='': #!/usr/bin/env bash set -o errexit -o nounset -o pipefail @@ -80,6 +80,13 @@ run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollu CHAIN_ID_OR_ROLLUP_CONFIG_ARG="--rollup-config-path $(realpath {{rollup_config_path}})" fi + # Set up beacon address argument only if provided + if [ -n "$L1_BEACON_ADDRESS" ]; then + BEACON_ADDRESS_ARG="--l1-beacon-address $L1_BEACON_ADDRESS" + else + BEACON_ADDRESS_ARG="" + fi + CLAIMED_L2_BLOCK_NUMBER={{block_number}} echo "Fetching configuration for block #$CLAIMED_L2_BLOCK_NUMBER..." @@ -96,7 +103,7 @@ run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollu cd $(git rev-parse --show-toplevel) echo "Running host program with native client program..." - cargo r --bin kona-host --release -- \ + RUST_LOG=debug cargo r --bin kona-host --release -- \ single \ --l1-head $L1_HEAD \ --agreed-l2-head-hash $AGREED_L2_HEAD_HASH \ @@ -104,7 +111,7 @@ run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollu --agreed-l2-output-root $AGREED_L2_OUTPUT_ROOT \ --claimed-l2-block-number $CLAIMED_L2_BLOCK_NUMBER \ --l1-node-address $L1_NODE_ADDRESS \ - --l1-beacon-address $L1_BEACON_ADDRESS \ + $BEACON_ADDRESS_ARG \ --l2-node-address $L2_NODE_ADDRESS \ --native \ --data-dir ./data \ @@ -184,7 +191,7 @@ run-client-asterisc-offline block_number l2_claim l2_output_root l2_head l1_head {{verbosity}} # Run the client program on cannon with the host in detached server mode. -run-client-cannon block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc verbosity='': +run-client-cannon block_number l1_rpc l2_rpc rollup_node_rpc verbosity='' l1_beacon_rpc='': #!/usr/bin/env bash L1_NODE_ADDRESS="{{l1_rpc}}" diff --git a/bin/client/kona.log b/bin/client/kona.log new file mode 100644 index 0000000000..0ffcfbc5ca --- /dev/null +++ b/bin/client/kona.log @@ -0,0 +1,7 @@ +Fetching configuration for block #2434489... +Running host program with native client program... + Finished `release` profile [optimized] target(s) in 0.31s + 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` +2025-03-30T13:25:45.569438Z  INFO host-server: Starting oracle server +2025-03-30T13:25:45.569437Z  INFO host-server: Starting hint router +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! diff --git a/bin/client/rollup.json b/bin/client/rollup.json new file mode 100644 index 0000000000..7aed9b531c --- /dev/null +++ b/bin/client/rollup.json @@ -0,0 +1,48 @@ +{ + "alt_da": { + "da_challenge_contract_address": "0x0000000000000000000000000000000000000000", + "da_challenge_window": 300, + "da_commitment_type": "GenericCommitment", + "da_resolve_window": 300 + }, + "batch_inbox_address": "0x1046467b29c56355f3611c81432bd76918b40521", + "block_time": 2, + "canyon_time": 0, + "chain_op_config": { + "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, + "eip1559Elasticity": 6 + }, + "channel_timeout": 300, + "delta_time": 0, + "deposit_contract_address": "0x6f24b15366390998b36ad6497eb39a3b46a37bc4", + "ecotone_time": 0, + "fjord_time": 0, + "genesis": { + "l1": { + "hash": "0x5123c1419c414204ed6293b9a30076e2d7d62f9f188bb808378d8d0817d2851f", + "number": 7618221 + }, + "l2": { + "hash": "0x29283ff0c581582b84b4e1564a1afe4b7b7f84708700054d8b5ab170c783ddef", + "number": 0 + }, + "l2_time": 1738424688, + "system_config": { + "batcherAddr": "0x05dbef8f18097cf23c415c03f308bdb7b3e936e6", + "eip1559Params": "0x0000000000000000", + "gasLimit": 30000000, + "operatorFeeParams": "0x0000000000000000000000000000000000000000000000000000000000000000", + "overhead": "0x00000000000000000000000000000000000000000000000000000000000000bc", + "scalar": "0x0000000000000000000000000000000000000000000000000000000000010b30" + } + }, + "l1_chain_id": 11155111, + "l1_system_config_address": "0x3592a865cd0a2fadedbedc1f6a07694793fa7ec1", + "l2_chain_id": 91578, + "max_sequencer_drift": 600, + "pectra_blob_schedule_time": 1742486400, + "protocol_versions_address": "0x0000000000000000000000000000000000000000", + "regolith_time": 0, + "seq_window_size": 3600 +} \ No newline at end of file diff --git a/bin/host/src/interop/cfg.rs b/bin/host/src/interop/cfg.rs index 7b39d87041..a21c4822fb 100644 --- a/bin/host/src/interop/cfg.rs +++ b/bin/host/src/interop/cfg.rs @@ -45,32 +45,13 @@ pub struct InteropHost { #[arg(long, visible_alias = "l2-timestamp", env)] pub claimed_l2_timestamp: u64, /// Addresses of L2 JSON-RPC endpoints to use (eth and debug namespace required). - #[arg( - long, - visible_alias = "l2s", - requires = "l1_node_address", - requires = "l1_beacon_address", - value_delimiter = ',', - env - )] + #[arg(long, visible_alias = "l2s", requires = "l1_node_address", value_delimiter = ',', env)] pub l2_node_addresses: Option>, /// Address of L1 JSON-RPC endpoint to use (eth and debug namespace required) - #[arg( - long, - visible_alias = "l1", - requires = "l2_node_addresses", - requires = "l1_beacon_address", - env - )] + #[arg(long, visible_alias = "l1", requires = "l2_node_addresses", env)] pub l1_node_address: Option, /// Address of the L1 Beacon API endpoint to use. - #[arg( - long, - visible_alias = "beacon", - requires = "l1_node_address", - requires = "l2_node_addresses", - env - )] + #[arg(long, visible_alias = "beacon", requires = "l1_node_address", env)] pub l1_beacon_address: Option, /// The Data Directory for preimage data storage. Optional if running in online mode, /// required if running in offline mode. @@ -201,10 +182,10 @@ impl InteropHost { /// Returns `true` if the host is running in offline mode. pub const fn is_offline(&self) -> bool { - self.l1_node_address.is_none() && - self.l2_node_addresses.is_none() && - self.l1_beacon_address.is_none() && - self.data_dir.is_some() + self.l1_node_address.is_none() + && self.l2_node_addresses.is_none() + && self.l1_beacon_address.is_none() + && self.data_dir.is_some() } /// Reads the [RollupConfig]s from the file system and returns a map of L2 chain ID -> @@ -251,12 +232,14 @@ impl InteropHost { self.l1_node_address.as_ref().ok_or(InteropHostError::Other("Provider must be set"))?, ); - let blob_provider = OnlineBlobProvider::init(OnlineBeaconClient::new_http( - self.l1_beacon_address - .clone() - .ok_or(InteropHostError::Other("Beacon API URL must be set"))?, - )) - .await; + let blob_provider = if let Some(beacon_address) = &self.l1_beacon_address { + Some( + OnlineBlobProvider::init(OnlineBeaconClient::new_http(beacon_address.clone())) + .await, + ) + } else { + None + }; // Resolve all chain IDs to their corresponding providers. let l2_node_addresses = self @@ -285,7 +268,7 @@ pub struct InteropProviders { /// The L1 EL provider. pub l1: RootProvider, /// The L1 beacon node provider. - pub blobs: OnlineBlobProvider, + pub blobs: Option>, /// The L2 EL providers, keyed by chain ID. pub l2s: HashMap>, } diff --git a/bin/host/src/interop/handler.rs b/bin/host/src/interop/handler.rs index eca23f3203..b15df18f87 100644 --- a/bin/host/src/interop/handler.rs +++ b/bin/host/src/interop/handler.rs @@ -103,11 +103,16 @@ impl HintHandler for InteropHintHandler { let indexed_hash = IndexedBlobHash { index, hash }; // Fetch the blob sidecar from the blob provider. - let mut sidecars = providers - .blobs - .fetch_filtered_sidecars(&partial_block_ref, &[indexed_hash]) - .await - .map_err(|e| anyhow!("Failed to fetch blob sidecars: {e}"))?; + let mut sidecars = if let Some(blobs) = &providers.blobs { + blobs + .fetch_filtered_sidecars(&partial_block_ref, &[indexed_hash]) + .await + .map_err(|e| anyhow!("Failed to fetch blob sidecars: {e}"))? + } else { + return Err( + anyhow!("Beacon API URL not provided, cannot fetch blob sidecars").into() + ); + }; if sidecars.len() != 1 { anyhow::bail!("Expected 1 sidecar, got {}", sidecars.len()); } diff --git a/bin/host/src/single/cfg.rs b/bin/host/src/single/cfg.rs index 5f8c613cde..a7f16584cb 100644 --- a/bin/host/src/single/cfg.rs +++ b/bin/host/src/single/cfg.rs @@ -46,31 +46,13 @@ pub struct SingleChainHost { #[arg(long, visible_alias = "l2-block-number", env)] pub claimed_l2_block_number: u64, /// Address of L2 JSON-RPC endpoint to use (eth and debug namespace required). - #[arg( - long, - visible_alias = "l2", - requires = "l1_node_address", - requires = "l1_beacon_address", - env - )] + #[arg(long, visible_alias = "l2", requires = "l1_node_address", env)] pub l2_node_address: Option, /// Address of L1 JSON-RPC endpoint to use (eth and debug namespace required) - #[arg( - long, - visible_alias = "l1", - requires = "l2_node_address", - requires = "l1_beacon_address", - env - )] + #[arg(long, visible_alias = "l1", requires = "l2_node_address", env)] pub l1_node_address: Option, /// Address of the L1 Beacon API endpoint to use. - #[arg( - long, - visible_alias = "beacon", - requires = "l1_node_address", - requires = "l2_node_address", - env - )] + #[arg(long, visible_alias = "beacon", requires = "l1_node_address", env)] pub l1_beacon_address: Option, /// The Data Directory for preimage data storage. Optional if running in online mode, /// required if running in offline mode. @@ -211,10 +193,10 @@ impl SingleChainHost { /// Returns `true` if the host is running in offline mode. pub const fn is_offline(&self) -> bool { - self.l1_node_address.is_none() && - self.l2_node_address.is_none() && - self.l1_beacon_address.is_none() && - self.data_dir.is_some() + self.l1_node_address.is_none() + && self.l2_node_address.is_none() + && self.l1_beacon_address.is_none() + && self.data_dir.is_some() } /// Reads the [RollupConfig] from the file system and returns it as a string. @@ -256,12 +238,16 @@ impl SingleChainHost { .as_ref() .ok_or(SingleChainHostError::Other("Provider must be set"))?, ); - let blob_provider = OnlineBlobProvider::init(OnlineBeaconClient::new_http( - self.l1_beacon_address - .clone() - .ok_or(SingleChainHostError::Other("Beacon API URL must be set"))?, - )) - .await; + + let blob_provider = if let Some(beacon_address) = &self.l1_beacon_address { + Some( + OnlineBlobProvider::init(OnlineBeaconClient::new_http(beacon_address.clone())) + .await, + ) + } else { + None + }; + let l2_provider = http_provider::( self.l2_node_address .as_ref() @@ -283,7 +269,7 @@ pub struct SingleChainProviders { /// The L1 EL provider. pub l1: RootProvider, /// The L1 beacon node provider. - pub blobs: OnlineBlobProvider, + pub blobs: Option>, /// The L2 EL provider. pub l2: RootProvider, } diff --git a/bin/host/src/single/handler.rs b/bin/host/src/single/handler.rs index a988197e6e..53f7807bcf 100644 --- a/bin/host/src/single/handler.rs +++ b/bin/host/src/single/handler.rs @@ -87,11 +87,17 @@ impl HintHandler for SingleChainHintHandler { let indexed_hash = IndexedBlobHash { index, hash }; // Fetch the blob sidecar from the blob provider. - let mut sidecars = providers - .blobs - .fetch_filtered_sidecars(&partial_block_ref, &[indexed_hash]) - .await - .map_err(|e| anyhow!("Failed to fetch blob sidecars: {e}"))?; + let mut sidecars = if let Some(blobs) = &providers.blobs { + blobs + .fetch_filtered_sidecars(&partial_block_ref, &[indexed_hash]) + .await + .map_err(|e| anyhow!("Failed to fetch blob sidecars: {e}"))? + } else { + return Err( + anyhow!("Beacon API URL not provided, cannot fetch blob sidecars").into() + ); + }; + if sidecars.len() != 1 { anyhow::bail!("Expected 1 sidecar, got {}", sidecars.len()); }