Skip to content

Commit

Permalink
feat(raiko): read & merge chain spec from a optional config file (#206)
Browse files Browse the repository at this point in the history
* Read & merge chain spec from file

Signed-off-by: smtmfft <smtm@taiko.xyz>

* make chain_spec path optional

Signed-off-by: smtmfft <smtm@taiko.xyz>

* fix test build

Signed-off-by: smtmfft <smtm@taiko.xyz>

* update prove-block.sh

* remove useless fn

Signed-off-by: smtmfft <smtm@taiko.xyz>

* code refine: rename fn

Signed-off-by: smtmfft <smtm@taiko.xyz>

* fix review comments

Signed-off-by: smtmfft <smtm@taiko.xyz>

* move rpc & beacon rpc into chain spec

* use inclue_str to compile in the default support chains

* code refine: re-org the genesis into the right chain spec.

* do not check tx_list in non-taiko chain

* tiny config update

* Fix compile & test

* fix fmt

Signed-off-by: smtmfft <smtm@taiko.xyz>

* Fix CI

* Fix CI

* remove warning & fix CI

* fix fmt again

---------

Signed-off-by: smtmfft <smtm@taiko.xyz>
  • Loading branch information
smtmfft authored May 17, 2024
1 parent 72e8a57 commit 4c76667
Show file tree
Hide file tree
Showing 11 changed files with 367 additions and 248 deletions.
90 changes: 90 additions & 0 deletions host/config/chain_spec_list_default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
[
{
"name": "ethereum",
"chain_id": 1,
"max_spec_id": "CANCUN",
"hard_forks": {
"FRONTIER": {
"Block": 0
},
"MERGE": {
"Block": 15537394
},
"SHANGHAI": {
"Block": 17034870
},
"CANCUN": {
"Timestamp": 1710338135
}
},
"eip_1559_constants": {
"base_fee_change_denominator": "0x8",
"base_fee_max_increase_denominator": "0x8",
"base_fee_max_decrease_denominator": "0x8",
"elasticity_multiplier": "0x2"
},
"l1_contract": null,
"l2_contract": null,
"rpc": "https://rpc.ankr.com/eth",
"beacon_rpc": "https://ethereum-beacon-api.publicnode.com",
"sgx_verifier_address": null,
"genesis_time": 1606824023,
"seconds_per_slot": 12,
"is_taiko": false
},
{
"name": "holesky",
"chain_id": 17000,
"max_spec_id": "CANCUN",
"hard_forks": {
"FRONTIER": {
"Block": 0
},
"SHANGHAI": {
"Timestamp": 1696000704
},
"CANCUN": {
"Timestamp": 1707305664
}
},
"eip_1559_constants": {
"base_fee_change_denominator": "0x8",
"base_fee_max_increase_denominator": "0x8",
"base_fee_max_decrease_denominator": "0x8",
"elasticity_multiplier": "0x2"
},
"l1_contract": null,
"l2_contract": null,
"rpc": "https://ethereum-holesky-rpc.publicnode.com",
"beacon_rpc": "https://api.holesky.blobscan.com",
"sgx_verifier_address": null,
"genesis_time": 1695902400,
"seconds_per_slot": 12,
"is_taiko": false
},
{
"name": "taiko_a7",
"chain_id": 167009,
"max_spec_id": "SHANGHAI",
"hard_forks": {
"SHANGHAI": {
"Block": 0
},
"CANCUN": "TBD"
},
"eip_1559_constants": {
"base_fee_change_denominator": "0x8",
"base_fee_max_increase_denominator": "0x8",
"base_fee_max_decrease_denominator": "0x8",
"elasticity_multiplier": "0x2"
},
"l1_contract": "0x79c9109b764609df928d16fc4a91e9081f7e87db",
"l2_contract": "0x1670090000000000000000000000000000010001",
"rpc": "https://rpc.hekla.taiko.xyz",
"beacon_rpc": null,
"sgx_verifier_address": "0x532efbf6d62720d0b2a2bb9d11066e8588cae6d9",
"genesis_time": 0,
"seconds_per_slot": 1,
"is_taiko": true
}
]
37 changes: 3 additions & 34 deletions host/src/interfaces/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::{path::Path, str::FromStr};
use alloy_primitives::{Address, B256};
use clap::{Args, ValueEnum};
use raiko_lib::{
consts::Network,
input::{GuestInput, GuestOutput},
protocol_instance::ProtocolInstance,
prover::{Proof, Prover},
Expand Down Expand Up @@ -140,15 +139,8 @@ impl ProofType {
pub struct ProofRequest {
/// The block number for the block to generate a proof for.
pub block_number: u64,
/// RPC URL for retrieving block by block number.
pub rpc: String,
/// The L1 node URL for signal root verify and get txlist info from proposed
/// transaction.
pub l1_rpc: String,
/// The beacon node URL for retrieving data blobs.
pub beacon_rpc: String,
/// The network to generate the proof for.
pub network: Network,
pub network: String,
/// The L1 network to grnerate the proof for.
pub l1_network: String,
/// Graffiti.
Expand All @@ -171,16 +163,6 @@ pub struct ProofRequestOpt {
/// The block number for the block to generate a proof for.
pub block_number: Option<u64>,
#[arg(long, require_equals = true)]
/// RPC URL for retrieving block by block number.
pub rpc: Option<String>,
#[arg(long, require_equals = true)]
/// The L1 node URL for signal root verify and get txlist info from proposed
/// transaction.
pub l1_rpc: Option<String>,
#[arg(long, require_equals = true)]
/// The beacon node URL for retrieving data blobs.
pub beacon_rpc: Option<String>,
#[arg(long, require_equals = true)]
/// The network to generate the proof for.
pub network: Option<String>,
#[arg(long, require_equals = true)]
Expand Down Expand Up @@ -258,22 +240,9 @@ impl TryFrom<ProofRequestOpt> for ProofRequest {
block_number: value.block_number.ok_or(HostError::InvalidRequestConfig(
"Missing block number".to_string(),
))?,
rpc: value
.rpc
.ok_or(HostError::InvalidRequestConfig("Missing rpc".to_string()))?,
l1_rpc: value.l1_rpc.ok_or(HostError::InvalidRequestConfig(
"Missing l1_rpc".to_string(),
))?,
beacon_rpc: value.beacon_rpc.ok_or(HostError::InvalidRequestConfig(
"Missing beacon_rpc".to_string(),
network: value.network.ok_or(HostError::InvalidRequestConfig(
"Missing network".to_string(),
))?,
network: value
.network
.ok_or(HostError::InvalidRequestConfig(
"Missing network".to_string(),
))?
.parse()
.map_err(|_| HostError::InvalidRequestConfig("Invalid network".to_string()))?,
l1_network: value.l1_network.ok_or(HostError::InvalidRequestConfig(
"Missing l1_network".to_string(),
))?,
Expand Down
22 changes: 19 additions & 3 deletions host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ pub mod server;

use std::{alloc, collections::HashMap, path::PathBuf};

use crate::interfaces::{error::HostResult, request::ProofRequestOpt};
use alloy_primitives::Address;
use alloy_rpc_types::EIP1186AccountProofResponse;
use anyhow::Context;
use cap::Cap;
use clap::Parser;
use raiko_lib::consts::SupportedChainSpecs;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::interfaces::{error::HostResult, request::ProofRequestOpt};
use tracing::info;

type MerkleProof = HashMap<Address, EIP1186AccountProofResponse>;

Expand Down Expand Up @@ -88,6 +89,10 @@ pub struct Cli {
/// a proof of specified type. Curl json-rpc overrides its contents
config_path: PathBuf,

#[arg(long, require_equals = true)]
/// Path to a chain spec file that includes supported chain list
chain_spec_path: Option<PathBuf>,

#[arg(long, require_equals = true)]
/// Use a local directory as a cache for input. Accepts a custom directory.
cache_path: Option<PathBuf>,
Expand All @@ -111,6 +116,7 @@ impl Cli {
let mut config: Value = serde_json::from_reader(reader)?;
let this = serde_json::to_value(&self)?;
merge(&mut config, &this);

*self = serde_json::from_value(config)?;
Ok(())
}
Expand All @@ -133,6 +139,7 @@ fn merge(a: &mut Value, b: &Value) {
#[derive(Debug, Clone)]
pub struct ProverState {
pub opts: Cli,
pub chain_specs: SupportedChainSpecs,
}

impl ProverState {
Expand All @@ -142,14 +149,23 @@ impl ProverState {
// Read the config file.
opts.merge_from_file()?;

let chain_specs = if let Some(cs_path) = &opts.chain_spec_path {
let chain_specs = SupportedChainSpecs::merge_from_file(cs_path.clone())
.unwrap_or(SupportedChainSpecs::default());
info!("Supported chains: {:?}", chain_specs.supported_networks());
chain_specs
} else {
SupportedChainSpecs::default()
};

// Check if the cache path exists and create it if it doesn't.
if let Some(cache_path) = &opts.cache_path {
if !cache_path.exists() {
std::fs::create_dir_all(cache_path).context("Could not create cache dir")?;
}
}

Ok(Self { opts })
Ok(Self { opts, chain_specs })
}
}

Expand Down
49 changes: 25 additions & 24 deletions host/src/preflight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ use crate::{
pub async fn preflight<BDP: BlockDataProvider>(
provider: BDP,
block_number: u64,
chain_spec: ChainSpec,
l1_chain_spec: ChainSpec,
taiko_chain_spec: ChainSpec,
prover_data: TaikoProverData,
l1_rpc_url: Option<String>,
beacon_rpc_url: Option<String>,
) -> HostResult<GuestInput> {
let measurement = Measurement::start("Fetching block data...", false);

Expand All @@ -65,13 +64,12 @@ pub async fn preflight<BDP: BlockDataProvider>(
info!("block gas used: {:?}", block.header.gas_used);
info!("block transactions: {:?}", block.transactions.len());

let taiko_guest_input = if chain_spec.is_taiko() {
let taiko_guest_input = if taiko_chain_spec.is_taiko() {
prepare_taiko_chain_input(
&chain_spec,
&l1_chain_spec,
&taiko_chain_spec,
block_number,
block,
l1_rpc_url,
beacon_rpc_url,
prover_data,
)
.await?
Expand All @@ -87,7 +85,7 @@ pub async fn preflight<BDP: BlockDataProvider>(

let input =
GuestInput {
chain_spec: chain_spec.clone(),
chain_spec: taiko_chain_spec.clone(),
block_number,
gas_used: block.header.gas_used.try_into().map_err(|_| {
HostError::Conversion("Failed converting gas used to u64".to_string())
Expand Down Expand Up @@ -150,7 +148,7 @@ pub async fn preflight<BDP: BlockDataProvider>(
// Create the block builder, run the transactions and extract the DB
let provider_db = ProviderDb::new(
provider,
chain_spec,
taiko_chain_spec,
if let Some(parent_block_number) = parent_block.header.number {
parent_block_number
} else {
Expand Down Expand Up @@ -225,17 +223,13 @@ pub async fn preflight<BDP: BlockDataProvider>(

/// Prepare the input for a Taiko chain
async fn prepare_taiko_chain_input(
chain_spec: &ChainSpec,
l1_chain_spec: &ChainSpec,
taiko_chain_spec: &ChainSpec,
block_number: u64,
block: &Block,
l1_rpc_url: Option<String>,
beacon_rpc_url: Option<String>,
prover_data: TaikoProverData,
) -> HostResult<TaikoGuestInput> {
let l1_rpc_url = l1_rpc_url.ok_or_else(|| {
HostError::Preflight("L1 RPC URL is required for Taiko chains".to_owned())
})?;
let provider_l1 = RpcBlockDataProvider::new(&l1_rpc_url, block_number)?;
let provider_l1 = RpcBlockDataProvider::new(&l1_chain_spec.rpc, block_number)?;

// Decode the anchor tx to find out which L1 blocks we need to fetch
let anchor_tx = match &block.transactions {
Expand Down Expand Up @@ -273,7 +267,7 @@ async fn prepare_taiko_chain_input(
// Get the block proposal data
let (proposal_tx, proposal_event) = get_block_proposed_event(
provider_l1.provider(),
chain_spec.clone(),
taiko_chain_spec.clone(),
l1_inclusion_block_hash,
block_number,
)
Expand All @@ -290,10 +284,10 @@ async fn prepare_taiko_chain_input(
// Get the blob data for this block
let slot_id = block_time_to_block_slot(
l1_inclusion_block.header.timestamp,
chain_spec.genesis_time,
chain_spec.seconds_per_slot,
l1_chain_spec.genesis_time,
l1_chain_spec.seconds_per_slot,
)?;
let beacon_rpc_url = beacon_rpc_url.ok_or_else(|| {
let beacon_rpc_url: String = l1_chain_spec.beacon_rpc.clone().ok_or_else(|| {
HostError::Preflight("Beacon RPC URL is required for Taiko chains".to_owned())
})?;
let blob = get_blob_data(&beacon_rpc_url, slot_id, blob_hash).await?;
Expand All @@ -307,7 +301,7 @@ async fn prepare_taiko_chain_input(

// Create the transactions from the proposed tx list
let transactions = generate_transactions(
chain_spec,
&taiko_chain_spec,
proposal_event.meta.blobUsed,
&tx_data,
Some(anchor_tx.clone()),
Expand Down Expand Up @@ -336,7 +330,11 @@ fn block_time_to_block_slot(
genesis_time: u64,
block_per_slot: u64,
) -> HostResult<u64> {
if block_time < genesis_time {
if genesis_time == 0u64 {
Err(HostError::Anyhow(anyhow!(
"genesis time is 0, please check chain spec"
)))
} else if block_time < genesis_time {
Err(HostError::Anyhow(anyhow!(
"provided block_time precedes genesis time",
)))
Expand Down Expand Up @@ -408,6 +406,7 @@ async fn get_blob_data_beacon(
"{}/eth/v1/beacon/blob_sidecars/{block_id}",
beacon_rpc_url.trim_end_matches('/'),
);
info!("Retrieve blob from {url}.");
let response = reqwest::get(url.clone()).await?;
if response.status().is_success() {
let blobs: GetBlobsResponse = response.json().await?;
Expand Down Expand Up @@ -623,7 +622,7 @@ fn from_block_tx(tx: &AlloyRpcTransaction) -> HostResult<TxEnvelope> {
mod test {
use ethers_core::types::Transaction;
use raiko_lib::{
consts::{get_network_spec, Network},
consts::{Network, SupportedChainSpecs},
utils::decode_transactions,
};
use raiko_primitives::{eip4844::parse_kzg_trusted_setup, kzg::KzgSettings};
Expand Down Expand Up @@ -864,7 +863,9 @@ mod test {
#[ignore]
#[test]
fn test_slot_block_num_mapping() {
let chain_spec = get_network_spec(Network::TaikoA7);
let chain_spec = SupportedChainSpecs::default()
.get_chain_spec(&Network::TaikoA7.to_string())
.unwrap();
let expected_slot = 1000u64;
let second_per_slot = 12u64;
let block_time = chain_spec.genesis_time + expected_slot * second_per_slot;
Expand Down
Loading

0 comments on commit 4c76667

Please sign in to comment.