From a629f63519d804624b840d0f872969c1a2e95ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Mon, 27 May 2024 11:31:08 +0200 Subject: [PATCH] refactor: move out core into separate crate (#247) * refactor: Move out core into separate crate Make host only responsible for running server and docs creation * fix: Update imports * fix: Unignore core directory for docker * chore(repo): merge updates from main * refactor(lib): cleanup unwrap for chain specs struct * chore(repo): rebase main into core-extract --- .dockerignore | 3 +- Cargo.lock | 38 ++++++ Cargo.toml | 2 + core/Cargo.toml | 65 ++++++++++ .../request.rs => core/src/interfaces.rs | 109 ++++++++++++---- host/src/raiko.rs => core/src/lib.rs | 121 +++++++----------- {host => core}/src/preflight.rs | 65 +++++----- core/src/prover.rs | 36 ++++++ {host => core}/src/provider/db.rs | 28 ++-- {host => core}/src/provider/mod.rs | 10 +- {host => core}/src/provider/rpc.rs | 57 +++++---- host/Cargo.toml | 7 +- host/src/bin/main.rs | 2 +- .../{interfaces/error.rs => interfaces.rs} | 33 ++--- host/src/interfaces/mod.rs | 2 - host/src/lib.rs | 29 +---- host/src/metrics.rs | 3 +- host/src/server/api/v1/metrics.rs | 2 +- host/src/server/api/v1/mod.rs | 9 +- host/src/server/api/v1/proof.rs | 18 +-- host/src/server/mod.rs | 2 +- lib/src/consts.rs | 24 ++-- lib/src/protocol_instance.rs | 7 +- 23 files changed, 399 insertions(+), 273 deletions(-) create mode 100644 core/Cargo.toml rename host/src/interfaces/request.rs => core/src/interfaces.rs (67%) rename host/src/raiko.rs => core/src/lib.rs (78%) rename {host => core}/src/preflight.rs (94%) create mode 100644 core/src/prover.rs rename {host => core}/src/provider/db.rs (92%) rename {host => core}/src/provider/mod.rs (69%) rename {host => core}/src/provider/rpc.rs (83%) rename host/src/{interfaces/error.rs => interfaces.rs} (79%) delete mode 100644 host/src/interfaces/mod.rs diff --git a/.dockerignore b/.dockerignore index f08b58e0d..febdaead5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -16,4 +16,5 @@ !/taiko.toml !/tests !/provers/sgx/setup -!/kzg_settings_raw.bin \ No newline at end of file +!/kzg_settings_raw.bin +!/core diff --git a/Cargo.lock b/Cargo.lock index 65bd5b06f..5c4003e9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4948,6 +4948,43 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "raiko-core" +version = "0.1.0" +dependencies = [ + "alloy-consensus 0.1.0 (git+https://github.com/brechtpd/alloy?branch=175_4e22b9e)", + "alloy-network 0.1.0 (git+https://github.com/brechtpd/alloy?branch=175_4e22b9e)", + "alloy-primitives", + "alloy-provider 0.1.0 (git+https://github.com/brechtpd/alloy?branch=175_4e22b9e)", + "alloy-rlp", + "alloy-rlp-derive", + "alloy-rpc-client 0.1.0 (git+https://github.com/brechtpd/alloy?branch=175_4e22b9e)", + "alloy-rpc-types 0.1.0 (git+https://github.com/brechtpd/alloy?branch=175_4e22b9e)", + "alloy-sol-types", + "alloy-transport-http 0.1.0 (git+https://github.com/brechtpd/alloy?branch=175_4e22b9e)", + "anyhow", + "assert_cmd", + "c-kzg-taiko", + "clap 4.5.4", + "ethers-core", + "raiko-lib", + "raiko-primitives", + "reqwest 0.11.27", + "reqwest 0.12.4", + "revm", + "risc0-driver", + "rstest", + "serde", + "serde_json", + "serde_with", + "sgx-prover", + "sp1-driver", + "thiserror", + "tokio", + "tracing", + "utoipa", +] + [[package]] name = "raiko-host" version = "0.1.0" @@ -4980,6 +5017,7 @@ dependencies = [ "once_cell", "prometheus", "proptest", + "raiko-core", "raiko-lib", "raiko-primitives", "reqwest 0.11.27", diff --git a/Cargo.toml b/Cargo.toml index e317b0537..4e103ce1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "provers/sgx/guest", "provers/sgx/setup", "pipeline", + "core", ] # Always optimize; building and running the guest takes much longer without optimization. @@ -33,6 +34,7 @@ opt-level = 3 # raiko raiko-lib = { path = "./lib", features = ["std"] } raiko-primitives = { path = "./primitives" } +raiko-core = { path = "./core" } # revm revm-primitives = { git = "https://github.com/taikoxyz/revm.git", branch = "v35_taiko_v2", default-features = false } diff --git a/core/Cargo.toml b/core/Cargo.toml new file mode 100644 index 000000000..4b652b1f9 --- /dev/null +++ b/core/Cargo.toml @@ -0,0 +1,65 @@ +[package] +name = "raiko-core" +version = "0.1.0" +edition = "2021" + +[dependencies] + +# provers +sp1-driver = { path = "../provers/sp1/driver", optional = true } +risc0-driver = { path = "../provers/risc0/driver", optional = true } +sgx-prover = { path = "../provers/sgx/prover", optional = true } + +# raiko +raiko-lib = { workspace = true } +raiko-primitives = { workspace = true, features = ["c-kzg"] } + +# alloy +alloy-rlp = { workspace = true } +alloy-rlp-derive = { workspace = true } +alloy-sol-types = { workspace = true } +alloy-primitives = { workspace = true } +alloy-rpc-types = { workspace = true } +alloy-provider = { workspace = true } +alloy-transport-http = { workspace = true } +alloy-consensus = { workspace = true } +alloy-network = { workspace = true } +alloy-rpc-client = { workspace = true } +revm = { workspace = true } + +# tracing and logging +tracing = { workspace = true } + +# errors +anyhow = { workspace = true } +thiserror = { workspace = true } + +# serde +serde = { workspace = true } +serde_json = { workspace = true } +serde_with = { workspace = true } + +# c-kzg +c-kzg = { workspace = true } + +# async +tokio = { workspace = true } +reqwest = { workspace = true } +reqwest_alloy = { workspace = true } + +# docs +utoipa = { workspace = true } + +# cli +clap = { workspace = true } + +[dev-dependencies] +assert_cmd = { workspace = true } +rstest = { workspace = true } +ethers-core = { workspace = true } + +[features] +# powdr = ["dep:powdr"] +sp1 = ["dep:sp1-driver", "sp1-driver/enable"] +risc0 = ["dep:risc0-driver", "risc0-driver/enable"] +sgx = ["dep:sgx-prover", "sgx-prover/enable"] diff --git a/host/src/interfaces/request.rs b/core/src/interfaces.rs similarity index 67% rename from host/src/interfaces/request.rs rename to core/src/interfaces.rs index 06e0fe3bc..d609c6d6e 100644 --- a/host/src/interfaces/request.rs +++ b/core/src/interfaces.rs @@ -1,23 +1,78 @@ -use core::fmt::Debug; -use std::collections::HashMap; -use std::{path::Path, str::FromStr}; +use std::{collections::HashMap, path::Path, str::FromStr}; use alloy_primitives::{Address, B256}; use clap::{Args, ValueEnum}; use raiko_lib::{ input::{GuestInput, GuestOutput}, - prover::{Proof, Prover}, + prover::{Proof, Prover, ProverError}, }; use serde::{Deserialize, Serialize}; use serde_json::Value; use serde_with::{serde_as, DisplayFromStr}; use utoipa::ToSchema; -use crate::{ - interfaces::error::{HostError, HostResult}, - merge, - raiko::NativeProver, -}; +use crate::{merge, prover::NativeProver}; + +#[derive(Debug, thiserror::Error, ToSchema)] +pub enum RaikoError { + /// For invalid proof type generation request. + #[error("Unknown proof type: {0}")] + InvalidProofType(String), + + /// For invalid proof request configuration. + #[error("Invalid proof request: {0}")] + InvalidRequestConfig(String), + + /// For requesting a proof of a type that is not supported. + #[error("Feature not supported: {0}")] + #[schema(value_type = Value)] + FeatureNotSupportedError(ProofType), + + /// For invalid type conversion. + #[error("Invalid conversion: {0}")] + Conversion(String), + + /// For RPC errors. + #[error("There was an error with the RPC provider: {0}")] + RPC(String), + + /// For preflight errors. + #[error("There was an error running the preflight: {0}")] + Preflight(String), + + /// For errors produced by the guest provers. + #[error("There was an error with a guest prover: {0}")] + #[schema(value_type = Value)] + Guest(#[from] ProverError), + + /// For db errors. + #[error("There was an error with the db: {0}")] + #[schema(value_type = Value)] + Db(raiko_lib::mem_db::DbError), + + /// For I/O errors. + #[error("There was a I/O error: {0}")] + #[schema(value_type = Value)] + Io(#[from] std::io::Error), + + /// For Serde errors. + #[error("There was a deserialization error: {0}")] + #[schema(value_type = Value)] + Serde(#[from] serde_json::Error), + + /// A catch-all error for any other error type. + #[error("There was an unexpected error: {0}")] + #[schema(value_type = Value)] + Anyhow(#[from] anyhow::Error), +} + +impl From for RaikoError { + fn from(e: raiko_lib::mem_db::DbError) -> Self { + RaikoError::Db(e) + } +} + +pub type RaikoResult = Result; #[derive( PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Deserialize, Serialize, ToSchema, Hash, ValueEnum, @@ -54,7 +109,7 @@ impl std::fmt::Display for ProofType { } impl FromStr for ProofType { - type Err = HostError; + type Err = RaikoError; fn from_str(s: &str) -> Result { match s.trim().to_lowercase().as_str() { @@ -62,7 +117,7 @@ impl FromStr for ProofType { "sp1" => Ok(ProofType::Sp1), "sgx" => Ok(ProofType::Sgx), "risc0" => Ok(ProofType::Risc0), - _ => Err(HostError::InvalidProofType(s.to_string())), + _ => Err(RaikoError::InvalidProofType(s.to_string())), } } } @@ -74,7 +129,7 @@ impl ProofType { input: GuestInput, output: &GuestOutput, config: &Value, - ) -> HostResult { + ) -> RaikoResult { match self { ProofType::Native => NativeProver::run(input, output, config) .await @@ -85,7 +140,7 @@ impl ProofType { .await .map_err(|e| e.into()); - Err(HostError::FeatureNotSupportedError(self.clone())) + Err(RaikoError::FeatureNotSupportedError(self.clone())) } ProofType::Risc0 => { #[cfg(feature = "risc0")] @@ -93,7 +148,7 @@ impl ProofType { .await .map_err(|e| e.into()); - Err(HostError::FeatureNotSupportedError(self.clone())) + Err(RaikoError::FeatureNotSupportedError(self.clone())) } ProofType::Sgx => { #[cfg(feature = "sgx")] @@ -101,7 +156,7 @@ impl ProofType { .await .map_err(|e| e.into()); - Err(HostError::FeatureNotSupportedError(self.clone())) + Err(RaikoError::FeatureNotSupportedError(self.clone())) } } } @@ -187,7 +242,7 @@ impl From(path: T) -> HostResult + pub fn from_file(path: T) -> RaikoResult where T: AsRef, { @@ -198,7 +253,7 @@ impl ProofRequestOpt { } /// Merge a partial proof request into current one. - pub fn merge(&mut self, other: &Value) -> HostResult<()> { + pub fn merge(&mut self, other: &Value) -> RaikoResult<()> { let mut this = serde_json::to_value(&self)?; merge(&mut this, other); *self = serde_json::from_value(this)?; @@ -207,40 +262,40 @@ impl ProofRequestOpt { } impl TryFrom for ProofRequest { - type Error = HostError; + type Error = RaikoError; fn try_from(value: ProofRequestOpt) -> Result { Ok(Self { - block_number: value.block_number.ok_or(HostError::InvalidRequestConfig( + block_number: value.block_number.ok_or(RaikoError::InvalidRequestConfig( "Missing block number".to_string(), ))?, - network: value.network.ok_or(HostError::InvalidRequestConfig( + network: value.network.ok_or(RaikoError::InvalidRequestConfig( "Missing network".to_string(), ))?, - l1_network: value.l1_network.ok_or(HostError::InvalidRequestConfig( + l1_network: value.l1_network.ok_or(RaikoError::InvalidRequestConfig( "Missing l1_network".to_string(), ))?, graffiti: value .graffiti - .ok_or(HostError::InvalidRequestConfig( + .ok_or(RaikoError::InvalidRequestConfig( "Missing graffiti".to_string(), ))? .parse() - .map_err(|_| HostError::InvalidRequestConfig("Invalid graffiti".to_string()))?, + .map_err(|_| RaikoError::InvalidRequestConfig("Invalid graffiti".to_string()))?, prover: value .prover - .ok_or(HostError::InvalidRequestConfig( + .ok_or(RaikoError::InvalidRequestConfig( "Missing prover".to_string(), ))? .parse() - .map_err(|_| HostError::InvalidRequestConfig("Invalid prover".to_string()))?, + .map_err(|_| RaikoError::InvalidRequestConfig("Invalid prover".to_string()))?, proof_type: value .proof_type - .ok_or(HostError::InvalidRequestConfig( + .ok_or(RaikoError::InvalidRequestConfig( "Missing proof_type".to_string(), ))? .parse() - .map_err(|_| HostError::InvalidRequestConfig("Invalid proof_type".to_string()))?, + .map_err(|_| RaikoError::InvalidRequestConfig("Invalid proof_type".to_string()))?, prover_args: value.prover_args.into(), }) } diff --git a/host/src/raiko.rs b/core/src/lib.rs similarity index 78% rename from host/src/raiko.rs rename to core/src/lib.rs index 1d6993867..e58d39a19 100644 --- a/host/src/raiko.rs +++ b/core/src/lib.rs @@ -1,23 +1,31 @@ -use alloy_primitives::FixedBytes; -use raiko_lib::builder::{BlockBuilderStrategy, TaikoStrategy}; -use raiko_lib::consts::{ChainSpec, VerifierType}; -use raiko_lib::input::{GuestInput, GuestOutput, TaikoProverData}; -use raiko_lib::protocol_instance::ProtocolInstance; -use raiko_lib::prover::{to_proof, Proof, Prover, ProverError, ProverResult}; -use raiko_lib::utils::HeaderHasher; -use serde::{Deserialize, Serialize}; -use serde_with::serde_as; -use tracing::{error, info, trace, warn}; +use std::collections::HashMap; + +use alloy_primitives::{Address, FixedBytes}; +use alloy_rpc_types::EIP1186AccountProofResponse; +use raiko_lib::{ + builder::{BlockBuilderStrategy, TaikoStrategy}, + consts::{ChainSpec, VerifierType}, + input::{GuestInput, GuestOutput, TaikoProverData}, + protocol_instance::ProtocolInstance, + prover::Proof, + utils::HeaderHasher, +}; +use serde_json::Value; +use tracing::{error, info, warn}; + +pub mod interfaces; +pub mod preflight; +pub mod prover; +pub mod provider; -use crate::preflight::preflight; use crate::{ - interfaces::{ - error::{self, HostError, HostResult}, - request::ProofRequest, - }, + interfaces::{ProofRequest, RaikoError, RaikoResult}, + preflight::preflight, provider::BlockDataProvider, }; +pub type MerkleProof = HashMap; + pub struct Raiko { l1_chain_spec: ChainSpec, taiko_chain_spec: ChainSpec, @@ -40,7 +48,7 @@ impl Raiko { pub async fn generate_input( &self, provider: BDP, - ) -> HostResult { + ) -> RaikoResult { preflight( provider, self.request.block_number, @@ -52,10 +60,10 @@ impl Raiko { }, ) .await - .map_err(Into::::into) + .map_err(Into::::into) } - pub fn get_output(&self, input: &GuestInput) -> HostResult { + pub fn get_output(&self, input: &GuestInput) -> RaikoResult { match TaikoStrategy::build_from(input) { Ok((header, _mpt_node)) => { info!("Verifying final state using provider data ..."); @@ -123,14 +131,14 @@ impl Raiko { } Err(e) => { warn!("Proving bad block construction!"); - Err(HostError::Guest( + Err(RaikoError::Guest( raiko_lib::prover::ProverError::GuestError(e.to_string()), )) } } } - pub async fn prove(&self, input: GuestInput, output: &GuestOutput) -> HostResult { + pub async fn prove(&self, input: GuestInput, output: &GuestOutput) -> RaikoResult { self.request .proof_type .run_prover( @@ -142,62 +150,32 @@ impl Raiko { } } -pub struct NativeProver; - -#[serde_as] -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct NativeParam { - pub save_test_input: bool, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct NativeResponse { - pub output: GuestOutput, -} - -impl Prover for NativeProver { - async fn run( - input: GuestInput, - output: &GuestOutput, - request: &serde_json::Value, - ) -> ProverResult { - trace!("Running the native prover for input {input:?}"); - // Write the input. - let param = NativeParam::deserialize(request.get("native").unwrap()).unwrap(); - if param.save_test_input { - seriailize_input(&input, "./provers/sp1/contracts/src/fixtures/input.json"); - } - - let GuestOutput::Success { header, .. } = output.clone() else { - return Err(ProverError::GuestError("Unexpected output".to_owned())); - }; - - ProtocolInstance::new(&input, &header, VerifierType::None) - .map_err(|e| ProverError::GuestError(e.to_string()))?; - - to_proof(Ok(NativeResponse { - output: output.clone(), - })) - } -} - -fn seriailize_input(input: &GuestInput, path: &str) { - let input = serde_json::to_string(&input).expect("Sp1: serializing input failed"); - std::fs::write(path, input).expect("failed to write input"); -} - fn check_eq(expected: &T, actual: &T, message: &str) { if expected != actual { error!("Assertion failed: {message} - Expected: {expected:?}, Found: {actual:?}"); } } +/// Merges two json's together, overwriting `a` with the values of `b` +pub fn merge(a: &mut Value, b: &Value) { + match (a, b) { + (Value::Object(a), Value::Object(b)) => { + for (k, v) in b { + merge(a.entry(k.clone()).or_insert(Value::Null), v); + } + } + (a, b) if !b.is_null() => *a = b.clone(), + // If b is null, just keep a (which means do nothing). + _ => {} + } +} + #[cfg(test)] mod tests { use crate::{ - interfaces::request::{ProofRequest, ProofType}, + interfaces::{ProofRequest, ProofType}, provider::rpc::RpcBlockDataProvider, - raiko::{ChainSpec, Raiko}, + ChainSpec, Raiko, }; use alloy_primitives::Address; use clap::ValueEnum; @@ -240,17 +218,6 @@ mod tests { } }, ); - prover_args.insert( - "sp1".to_string(), - json! { - { - "recursion": "core", - "prover": "mock", - "save_test_input": false, - - } - }, - ); prover_args } diff --git a/host/src/preflight.rs b/core/src/preflight.rs similarity index 94% rename from host/src/preflight.rs rename to core/src/preflight.rs index fd7112f67..7ccf5bcb0 100644 --- a/host/src/preflight.rs +++ b/core/src/preflight.rs @@ -28,7 +28,7 @@ use std::{collections::HashSet, sync::Arc}; use tracing::{info, warn}; use crate::{ - interfaces::error::{HostError, HostResult}, + interfaces::{RaikoError, RaikoResult}, provider::{db::ProviderDb, rpc::RpcBlockDataProvider, BlockDataProvider}, }; @@ -38,7 +38,7 @@ pub async fn preflight( l1_chain_spec: ChainSpec, taiko_chain_spec: ChainSpec, prover_data: TaikoProverData, -) -> HostResult { +) -> RaikoResult { let measurement = Measurement::start("Fetching block data...", false); // Get the block and the parent block @@ -47,17 +47,16 @@ pub async fn preflight( .await?; let (block, parent_block) = ( blocks.first().ok_or_else(|| { - HostError::Preflight("No block data for the requested block".to_owned()) + RaikoError::Preflight("No block data for the requested block".to_owned()) })?, &blocks.get(1).ok_or_else(|| { - HostError::Preflight("No parent block data for the requested block".to_owned()) + RaikoError::Preflight("No parent block data for the requested block".to_owned()) })?, ); - let hash = block - .header - .hash - .ok_or_else(|| HostError::Preflight("No block hash for the requested block".to_string()))?; + let hash = block.header.hash.ok_or_else(|| { + RaikoError::Preflight("No block hash for the requested block".to_string()) + })?; info!("\nblock.hash: {hash:?}"); info!("block.parent_hash: {:?}", block.header.parent_hash); @@ -89,17 +88,15 @@ pub async fn preflight( block_hash_reference: hash, block_header_reference: to_header(&block.header), beneficiary: block.header.miner, - gas_limit: block - .header - .gas_limit - .try_into() - .map_err(|_| HostError::Conversion("Failed converting gas limit to u64".to_string()))?, + gas_limit: block.header.gas_limit.try_into().map_err(|_| { + RaikoError::Conversion("Failed converting gas limit to u64".to_string()) + })?, timestamp: block.header.timestamp, extra_data: block.header.extra_data.clone(), mix_hash: if let Some(mix_hash) = block.header.mix_hash { mix_hash } else { - return Err(HostError::Preflight( + return Err(RaikoError::Preflight( "No mix hash for the requested block".to_owned(), )); }, @@ -111,29 +108,29 @@ pub async fn preflight( ancestor_headers: Default::default(), base_fee_per_gas: block.header.base_fee_per_gas.map_or_else( || { - Err(HostError::Preflight( + Err(RaikoError::Preflight( "No base fee per gas for the requested block".to_owned(), )) }, |base_fee_per_gas| { base_fee_per_gas.try_into().map_err(|_| { - HostError::Conversion("Failed converting base fee per gas to u64".to_owned()) + RaikoError::Conversion("Failed converting base fee per gas to u64".to_owned()) }) }, )?, blob_gas_used: block.header.blob_gas_used.map_or_else( || Ok(None), - |b: u128| -> HostResult> { + |b: u128| -> RaikoResult> { b.try_into().map(Some).map_err(|_| { - HostError::Conversion("Failed converting blob gas used to u64".to_owned()) + RaikoError::Conversion("Failed converting blob gas used to u64".to_owned()) }) }, )?, excess_blob_gas: block.header.excess_blob_gas.map_or_else( || Ok(None), - |b: u128| -> HostResult> { + |b: u128| -> RaikoResult> { b.try_into().map(Some).map_err(|_| { - HostError::Conversion("Failed converting excess blob gas to u64".to_owned()) + RaikoError::Conversion("Failed converting excess blob gas to u64".to_owned()) }) }, )?, @@ -148,7 +145,7 @@ pub async fn preflight( if let Some(parent_block_number) = parent_block.header.number { parent_block_number } else { - return Err(HostError::Preflight( + return Err(RaikoError::Preflight( "No parent block number for the requested block".to_owned(), )); }, @@ -223,7 +220,7 @@ async fn prepare_taiko_chain_input( block_number: u64, block: &Block, prover_data: TaikoProverData, -) -> HostResult { +) -> RaikoResult { 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 @@ -250,13 +247,13 @@ async fn prepare_taiko_chain_input( let (l1_inclusion_block, l1_state_block) = (&l1_blocks[0], &l1_blocks[1]); let l1_state_block_hash = l1_state_block.header.hash.ok_or_else(|| { - HostError::Preflight("No L1 state block hash for the requested block".to_owned()) + RaikoError::Preflight("No L1 state block hash for the requested block".to_owned()) })?; info!("l1_state_root_block hash: {l1_state_block_hash:?}"); let l1_inclusion_block_hash = l1_inclusion_block.header.hash.ok_or_else(|| { - HostError::Preflight("No L1 inclusion block hash for the requested block".to_owned()) + RaikoError::Preflight("No L1 inclusion block hash for the requested block".to_owned()) })?; // Get the block proposal data @@ -283,14 +280,14 @@ async fn prepare_taiko_chain_input( l1_chain_spec.seconds_per_slot, )?; 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()) + RaikoError::Preflight("Beacon RPC URL is required for Taiko chains".to_owned()) })?; let blob = get_blob_data(&beacon_rpc_url, slot_id, blob_hash).await?; (blob, Some(blob_hash)) } else { // Get the tx list data directly from the propose transaction data let proposal_call = proposeBlockCall::abi_decode(&proposal_tx.input, false) - .map_err(|_| HostError::Preflight("Could not decode proposeBlockCall".to_owned()))?; + .map_err(|_| RaikoError::Preflight("Could not decode proposeBlockCall".to_owned()))?; (proposal_call.txList.as_ref().to_owned(), None) }; @@ -311,7 +308,7 @@ async fn prepare_taiko_chain_input( Ok(TaikoGuestInput { l1_header: to_header(&l1_state_block.header), tx_data, - anchor_tx: serde_json::to_string(&anchor_tx).map_err(HostError::Serde)?, + anchor_tx: serde_json::to_string(&anchor_tx).map_err(RaikoError::Serde)?, tx_blob_hash, block_proposed: proposal_event, prover_data, @@ -324,13 +321,13 @@ fn block_time_to_block_slot( block_time: u64, genesis_time: u64, block_per_slot: u64, -) -> HostResult { +) -> RaikoResult { if genesis_time == 0u64 { - Err(HostError::Anyhow(anyhow!( + Err(RaikoError::Anyhow(anyhow!( "genesis time is 0, please check chain spec" ))) } else if block_time < genesis_time { - Err(HostError::Anyhow(anyhow!( + Err(RaikoError::Anyhow(anyhow!( "provided block_time precedes genesis time", ))) } else { @@ -490,7 +487,7 @@ async fn get_block_proposed_event( bail!("Could not create log") }; let event = BlockProposed::decode_log(&log_struct, false) - .map_err(|_| HostError::Anyhow(anyhow!("Could not decode log")))?; + .map_err(|_| RaikoError::Anyhow(anyhow!("Could not decode log")))?; if event.blockId == raiko_primitives::U256::from(l2_block_number) { let Some(log_tx_hash) = log.transaction_hash else { bail!("No transaction hash in the log") @@ -505,7 +502,7 @@ async fn get_block_proposed_event( bail!("No BlockProposed event found for block {l2_block_number}"); } -fn get_transactions_from_block(block: &Block) -> HostResult> { +fn get_transactions_from_block(block: &Block) -> RaikoResult> { let mut transactions: Vec = Vec::new(); if !block.transactions.is_empty() { match &block.transactions { @@ -524,13 +521,13 @@ fn get_transactions_from_block(block: &Block) -> HostResult> { Ok(transactions) } -fn from_block_tx(tx: &AlloyRpcTransaction) -> HostResult { +fn from_block_tx(tx: &AlloyRpcTransaction) -> RaikoResult { let Some(signature) = tx.signature else { panic!("Transaction has no signature"); }; let signature = Signature::from_rs_and_parity(signature.r, signature.s, signature.v.as_limbs()[0]) - .map_err(|_| HostError::Anyhow(anyhow!("Could not create signature")))?; + .map_err(|_| RaikoError::Anyhow(anyhow!("Could not create signature")))?; Ok(match tx.transaction_type.unwrap_or_default() { 0 => TxEnvelope::Legacy( TxLegacy { diff --git a/core/src/prover.rs b/core/src/prover.rs new file mode 100644 index 000000000..75a133a3c --- /dev/null +++ b/core/src/prover.rs @@ -0,0 +1,36 @@ +use raiko_lib::{ + consts::VerifierType, + input::{GuestInput, GuestOutput}, + protocol_instance::ProtocolInstance, + prover::{to_proof, Proof, Prover, ProverError, ProverResult}, +}; +use serde::{Deserialize, Serialize}; +use tracing::trace; + +pub struct NativeProver; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct NativeResponse { + pub output: GuestOutput, +} + +impl Prover for NativeProver { + async fn run( + input: GuestInput, + output: &GuestOutput, + _request: &serde_json::Value, + ) -> ProverResult { + trace!("Running the native prover for input {input:?}"); + + let GuestOutput::Success { header, .. } = output.clone() else { + return Err(ProverError::GuestError("Unexpected output".to_owned())); + }; + + ProtocolInstance::new(&input, &header, VerifierType::None) + .map_err(|e| ProverError::GuestError(e.to_string()))?; + + to_proof(Ok(NativeResponse { + output: output.clone(), + })) + } +} diff --git a/host/src/provider/db.rs b/core/src/provider/db.rs similarity index 92% rename from host/src/provider/db.rs rename to core/src/provider/db.rs index 780102a37..8897fe74a 100644 --- a/host/src/provider/db.rs +++ b/core/src/provider/db.rs @@ -24,7 +24,7 @@ use revm::{ use tokio::runtime::Handle; use crate::{ - interfaces::error::{HostError, HostResult}, + interfaces::{RaikoError, RaikoResult}, provider::BlockDataProvider, MerkleProof, }; @@ -45,11 +45,11 @@ pub struct ProviderDb { } impl ProviderDb { - pub async fn new(provider: BDP, chain_spec: ChainSpec, block_number: u64) -> HostResult { + pub async fn new(provider: BDP, chain_spec: ChainSpec, block_number: u64) -> RaikoResult { let mut provider_db = ProviderDb { provider, block_number, - async_executor: tokio::runtime::Handle::current(), + async_executor: Handle::current(), // defaults optimistic: false, staging_db: Default::default(), @@ -72,11 +72,11 @@ impl ProviderDb { let block_number: u64 = block .header .number - .ok_or_else(|| HostError::RPC("No block number".to_owned()))?; + .ok_or_else(|| RaikoError::RPC("No block number".to_owned()))?; let block_hash = block .header .hash - .ok_or_else(|| HostError::RPC("No block hash".to_owned()))?; + .ok_or_else(|| RaikoError::RPC("No block hash".to_owned()))?; provider_db .initial_db .insert_block_hash(block_number, block_hash); @@ -88,7 +88,7 @@ impl ProviderDb { Ok(provider_db) } - pub async fn get_proofs(&mut self) -> HostResult<(MerkleProof, MerkleProof, usize)> { + pub async fn get_proofs(&mut self) -> RaikoResult<(MerkleProof, MerkleProof, usize)> { // Latest proof keys let mut storage_keys = self.initial_db.storage_keys(); for (address, mut indices) in self.current_db.storage_keys() { @@ -133,7 +133,7 @@ impl ProviderDb { Ok((initial_proofs, latest_proofs, num_storage_proofs)) } - pub async fn get_ancestor_headers(&mut self) -> HostResult> { + pub async fn get_ancestor_headers(&mut self) -> RaikoResult> { let earliest_block = self .initial_db .block_hashes @@ -143,7 +143,7 @@ impl ProviderDb { let mut headers = Vec::with_capacity( usize::try_from(self.block_number - *earliest_block) - .map_err(|_| HostError::Conversion("Could not convert u64 to usize".to_owned()))?, + .map_err(|_| RaikoError::Conversion("Could not convert u64 to usize".to_owned()))?, ); for block_number in (*earliest_block..self.block_number).rev() { if let std::collections::hash_map::Entry::Vacant(e) = @@ -170,7 +170,7 @@ impl ProviderDb { } impl Database for ProviderDb { - type Error = HostError; + type Error = RaikoError; fn basic(&mut self, address: Address) -> Result, Self::Error> { // Check if the account is in the current database. @@ -209,7 +209,7 @@ impl Database for ProviderDb { })? .first() .cloned() - .ok_or(HostError::RPC("No account".to_owned()))?; + .ok_or(RaikoError::RPC("No account".to_owned()))?; // Insert the account into the initial database. self.initial_db @@ -250,7 +250,7 @@ impl Database for ProviderDb { })? .first() .copied() - .ok_or(HostError::RPC("No storage value".to_owned()))?; + .ok_or(RaikoError::RPC("No storage value".to_owned()))?; self.initial_db .insert_account_storage(&address, index, value); Ok(value) @@ -259,7 +259,7 @@ impl Database for ProviderDb { fn block_hash(&mut self, number: U256) -> Result { let block_number: u64 = number .try_into() - .map_err(|_| HostError::Conversion("Could not convert U256 to u64".to_owned()))?; + .map_err(|_| RaikoError::Conversion("Could not convert U256 to u64".to_owned()))?; // Check if the block hash is in the current database. if let Ok(block_hash) = self.initial_db.block_hash(number) { @@ -284,10 +284,10 @@ impl Database for ProviderDb { .block_on(self.provider.get_blocks(&[(block_number, false)])) })? .first() - .ok_or(HostError::RPC("No block".to_owned()))? + .ok_or(RaikoError::RPC("No block".to_owned()))? .header .hash - .ok_or_else(|| HostError::RPC("No block hash".to_owned()))? + .ok_or_else(|| RaikoError::RPC("No block hash".to_owned()))? .0 .into(); self.initial_db.insert_block_hash(block_number, block_hash); diff --git a/host/src/provider/mod.rs b/core/src/provider/mod.rs similarity index 69% rename from host/src/provider/mod.rs rename to core/src/provider/mod.rs index d0f3a2c4c..7f9e974eb 100644 --- a/host/src/provider/mod.rs +++ b/core/src/provider/mod.rs @@ -3,18 +3,18 @@ use alloy_rpc_types::Block; use revm::primitives::AccountInfo; use std::collections::HashMap; -use crate::{interfaces::error::HostResult, MerkleProof}; +use crate::{interfaces::RaikoResult, MerkleProof}; pub mod db; pub mod rpc; #[allow(async_fn_in_trait)] pub trait BlockDataProvider { - async fn get_blocks(&self, blocks_to_fetch: &[(u64, bool)]) -> HostResult>; + async fn get_blocks(&self, blocks_to_fetch: &[(u64, bool)]) -> RaikoResult>; - async fn get_accounts(&self, accounts: &[Address]) -> HostResult>; + async fn get_accounts(&self, accounts: &[Address]) -> RaikoResult>; - async fn get_storage_values(&self, accounts: &[(Address, U256)]) -> HostResult>; + async fn get_storage_values(&self, accounts: &[(Address, U256)]) -> RaikoResult>; async fn get_merkle_proofs( &self, @@ -22,5 +22,5 @@ pub trait BlockDataProvider { accounts: HashMap>, offset: usize, num_storage_proofs: usize, - ) -> HostResult; + ) -> RaikoResult; } diff --git a/host/src/provider/rpc.rs b/core/src/provider/rpc.rs similarity index 83% rename from host/src/provider/rpc.rs rename to core/src/provider/rpc.rs index 002b586e3..593dee08a 100644 --- a/host/src/provider/rpc.rs +++ b/core/src/provider/rpc.rs @@ -1,4 +1,6 @@ -pub use alloy_primitives::*; +use std::collections::HashMap; + +use alloy_primitives::{Address, Bytes, StorageKey, Uint, U256}; use alloy_provider::{ProviderBuilder, ReqwestProvider, RootProvider}; use alloy_rpc_client::{ClientBuilder, RpcClient}; use alloy_rpc_types::{Block, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse}; @@ -6,10 +8,9 @@ use alloy_transport_http::Http; use raiko_lib::{clear_line, inplace_print}; use reqwest_alloy::Client; use revm::primitives::{AccountInfo, Bytecode}; -use std::collections::HashMap; use crate::{ - interfaces::error::{HostError, HostResult}, + interfaces::{RaikoError, RaikoResult}, provider::BlockDataProvider, MerkleProof, }; @@ -21,9 +22,9 @@ pub struct RpcBlockDataProvider { } impl RpcBlockDataProvider { - pub fn new(url: &str, block_number: u64) -> HostResult { + pub fn new(url: &str, block_number: u64) -> RaikoResult { let url = - reqwest::Url::parse(url).map_err(|_| HostError::RPC("Invalid RPC URL".to_owned()))?; + reqwest::Url::parse(url).map_err(|_| RaikoError::RPC("Invalid RPC URL".to_owned()))?; Ok(Self { provider: ProviderBuilder::new().on_provider(RootProvider::new_http(url.clone())), client: ClientBuilder::default().http(url), @@ -37,7 +38,7 @@ impl RpcBlockDataProvider { } impl BlockDataProvider for RpcBlockDataProvider { - async fn get_blocks(&self, blocks_to_fetch: &[(u64, bool)]) -> HostResult> { + async fn get_blocks(&self, blocks_to_fetch: &[(u64, bool)]) -> RaikoResult> { let mut all_blocks = Vec::with_capacity(blocks_to_fetch.len()); let max_batch_size = 32; @@ -53,7 +54,7 @@ impl BlockDataProvider for RpcBlockDataProvider { &(BlockNumberOrTag::from(*block_number), full), ) .map_err(|_| { - HostError::RPC( + RaikoError::RPC( "Failed adding eth_getBlockByNumber call to batch".to_owned(), ) })?, @@ -63,7 +64,7 @@ impl BlockDataProvider for RpcBlockDataProvider { batch .send() .await - .map_err(|_| HostError::RPC("Error sending batch request".to_owned()))?; + .map_err(|_| RaikoError::RPC("Error sending batch request".to_owned()))?; let mut blocks = Vec::with_capacity(max_batch_size); // Collect the data from the batch @@ -71,7 +72,7 @@ impl BlockDataProvider for RpcBlockDataProvider { blocks.push( request .await - .map_err(|_| HostError::RPC("Error collecting request data".to_owned()))?, + .map_err(|_| RaikoError::RPC("Error collecting request data".to_owned()))?, ); } @@ -81,7 +82,7 @@ impl BlockDataProvider for RpcBlockDataProvider { Ok(all_blocks) } - async fn get_accounts(&self, accounts: &[Address]) -> HostResult> { + async fn get_accounts(&self, accounts: &[Address]) -> RaikoResult> { let mut all_accounts = Vec::with_capacity(accounts.len()); let max_batch_size = 250; @@ -100,7 +101,7 @@ impl BlockDataProvider for RpcBlockDataProvider { &(address, Some(BlockId::from(self.block_number))), ) .map_err(|_| { - HostError::RPC( + RaikoError::RPC( "Failed adding eth_getTransactionCount call to batch".to_owned(), ) })?, @@ -112,7 +113,7 @@ impl BlockDataProvider for RpcBlockDataProvider { &(address, Some(BlockId::from(self.block_number))), ) .map_err(|_| { - HostError::RPC("Failed adding eth_getBalance call to batch".to_owned()) + RaikoError::RPC("Failed adding eth_getBalance call to batch".to_owned()) })?, )); code_requests.push(Box::pin( @@ -122,7 +123,7 @@ impl BlockDataProvider for RpcBlockDataProvider { &(address, Some(BlockId::from(self.block_number))), ) .map_err(|_| { - HostError::RPC("Failed adding eth_getCode call to batch".to_owned()) + RaikoError::RPC("Failed adding eth_getCode call to batch".to_owned()) })?, )); } @@ -130,7 +131,7 @@ impl BlockDataProvider for RpcBlockDataProvider { batch .send() .await - .map_err(|_| HostError::RPC("Error sending batch request".to_owned()))?; + .map_err(|_| RaikoError::RPC("Error sending batch request".to_owned()))?; let mut accounts = vec![]; // Collect the data from the batch @@ -141,18 +142,18 @@ impl BlockDataProvider for RpcBlockDataProvider { { let (nonce, balance, code) = ( nonce_request.await.map_err(|_| { - HostError::RPC("Failed to collect nonce request".to_owned()) + RaikoError::RPC("Failed to collect nonce request".to_owned()) })?, balance_request.await.map_err(|_| { - HostError::RPC("Failed to collect balance request".to_owned()) + RaikoError::RPC("Failed to collect balance request".to_owned()) + })?, + code_request.await.map_err(|_| { + RaikoError::RPC("Failed to collect code request".to_owned()) })?, - code_request - .await - .map_err(|_| HostError::RPC("Failed to collect code request".to_owned()))?, ); let nonce = nonce.try_into().map_err(|_| { - HostError::Conversion("Failed to convert nonce to u64".to_owned()) + RaikoError::Conversion("Failed to convert nonce to u64".to_owned()) })?; let bytecode = Bytecode::new_raw(code); @@ -168,7 +169,7 @@ impl BlockDataProvider for RpcBlockDataProvider { Ok(all_accounts) } - async fn get_storage_values(&self, accounts: &[(Address, U256)]) -> HostResult> { + async fn get_storage_values(&self, accounts: &[(Address, U256)]) -> RaikoResult> { let mut all_values = Vec::with_capacity(accounts.len()); let max_batch_size = 1000; @@ -185,7 +186,7 @@ impl BlockDataProvider for RpcBlockDataProvider { &(address, key, Some(BlockId::from(self.block_number))), ) .map_err(|_| { - HostError::RPC( + RaikoError::RPC( "Failed adding eth_getStorageAt call to batch".to_owned(), ) })?, @@ -195,7 +196,7 @@ impl BlockDataProvider for RpcBlockDataProvider { batch .send() .await - .map_err(|_| HostError::RPC("Error sending batch request".to_owned()))?; + .map_err(|_| RaikoError::RPC("Error sending batch request".to_owned()))?; let mut values = Vec::with_capacity(max_batch_size); // Collect the data from the batch @@ -203,7 +204,7 @@ impl BlockDataProvider for RpcBlockDataProvider { values.push( request .await - .map_err(|_| HostError::RPC("Error collecting request data".to_owned()))?, + .map_err(|_| RaikoError::RPC("Error collecting request data".to_owned()))?, ); } @@ -219,7 +220,7 @@ impl BlockDataProvider for RpcBlockDataProvider { accounts: HashMap>, offset: usize, num_storage_proofs: usize, - ) -> HostResult { + ) -> RaikoResult { let mut storage_proofs: MerkleProof = HashMap::new(); let mut idx = offset; @@ -272,7 +273,7 @@ impl BlockDataProvider for RpcBlockDataProvider { ), ) .map_err(|_| { - HostError::RPC( + RaikoError::RPC( "Failed adding eth_getProof call to batch".to_owned(), ) })?, @@ -293,13 +294,13 @@ impl BlockDataProvider for RpcBlockDataProvider { batch .send() .await - .map_err(|_| HostError::RPC("Error sending batch request".to_owned()))?; + .map_err(|_| RaikoError::RPC("Error sending batch request".to_owned()))?; // Collect the data from the batch for request in requests { let mut proof = request .await - .map_err(|_| HostError::RPC("Error collecting request data".to_owned()))?; + .map_err(|_| RaikoError::RPC("Error collecting request data".to_owned()))?; idx += proof.storage_proof.len(); if let Some(map_proof) = storage_proofs.get_mut(&proof.address) { map_proof.storage_proof.append(&mut proof.storage_proof); diff --git a/host/Cargo.toml b/host/Cargo.toml index fe1d8b130..ec2c20a6a 100644 --- a/host/Cargo.toml +++ b/host/Cargo.toml @@ -14,6 +14,7 @@ sgx-prover = { path = "../provers/sgx/prover", optional = true } # raiko raiko-lib = { workspace = true } raiko-primitives = { workspace = true, features = ["c-kzg"] } +raiko-core = { workspace = true } # alloy alloy-rlp = { workspace = true } @@ -73,9 +74,9 @@ ethers-core = { workspace = true } [features] # powdr = ["dep:powdr"] -sp1 = ["dep:sp1-driver", "sp1-driver/enable"] -risc0 = ["dep:risc0-driver", "risc0-driver/enable"] -sgx = ["dep:sgx-prover", "sgx-prover/enable"] +sp1 = ["raiko-core/sp1"] +risc0 = ["raiko-core/risc0"] +sgx = ["raiko-core/sgx"] [[bin]] name = "raiko-host" diff --git a/host/src/bin/main.rs b/host/src/bin/main.rs index 4acb30101..335bf79f4 100644 --- a/host/src/bin/main.rs +++ b/host/src/bin/main.rs @@ -1,7 +1,7 @@ #![allow(incomplete_features)] use std::path::PathBuf; -use raiko_host::{interfaces::error::HostResult, server::serve, ProverState}; +use raiko_host::{interfaces::HostResult, server::serve, ProverState}; use tracing::info; use tracing_appender::{ non_blocking::WorkerGuard, diff --git a/host/src/interfaces/error.rs b/host/src/interfaces.rs similarity index 79% rename from host/src/interfaces/error.rs rename to host/src/interfaces.rs index 46cea8ea9..f9d2b9696 100644 --- a/host/src/interfaces/error.rs +++ b/host/src/interfaces.rs @@ -1,33 +1,24 @@ use axum::response::IntoResponse; +use raiko_core::interfaces::ProofType; use raiko_lib::prover::ProverError; use utoipa::ToSchema; -use crate::interfaces::request::ProofType; - /// The standardized error returned by the Raiko host. #[derive(thiserror::Error, Debug, ToSchema)] pub enum HostError { - /// For invalid proof type generation request. - #[error("Unknown proof type: {0}")] - InvalidProofType(String), + /// For invalid address. + #[error("Invalid address: {0}")] + InvalidAddress(String), /// For invalid proof request configuration. #[error("Invalid proof request: {0}")] InvalidRequestConfig(String), - /// For invalid address. - #[error("Invalid address: {0}")] - InvalidAddress(String), - /// For I/O errors. #[error("There was a I/O error: {0}")] #[schema(value_type = Value)] Io(#[from] std::io::Error), - /// For preflight errors. - #[error("There was an error running the preflight: {0}")] - Preflight(String), - /// For invalid type conversion. #[error("Invalid conversion: {0}")] Conversion(String), @@ -51,10 +42,10 @@ pub enum HostError { #[schema(value_type = Value)] Guest(#[from] ProverError), - /// For db errors. - #[error("There was an error with the db: {0}")] + /// For errors from the core of Raiko. + #[error("There was an error with the core: {0}")] #[schema(value_type = Value)] - Db(raiko_lib::mem_db::DbError), + Core(#[from] raiko_core::interfaces::RaikoError), /// For requesting a proof of a type that is not supported. #[error("Feature not supported: {0}")] @@ -67,26 +58,18 @@ pub enum HostError { Anyhow(#[from] anyhow::Error), } -impl From for HostError { - fn from(e: raiko_lib::mem_db::DbError) -> Self { - HostError::Db(e) - } -} - impl IntoResponse for HostError { fn into_response(self) -> axum::response::Response { let (error, message) = match self { - HostError::InvalidProofType(e) => ("invalid_proof_type".to_string(), e), HostError::InvalidRequestConfig(e) => ("invalid_request_config".to_string(), e), HostError::InvalidAddress(e) => ("invalid_address".to_string(), e), HostError::Io(e) => ("io_error".to_string(), e.to_string()), - HostError::Preflight(e) => ("preflight_error".to_string(), e), HostError::Conversion(e) => ("conversion_error".to_string(), e), HostError::RPC(e) => ("rpc_error".to_string(), e), HostError::Serde(e) => ("serde_error".to_string(), e.to_string()), HostError::JoinHandle(e) => ("join_handle_error".to_string(), e.to_string()), HostError::Guest(e) => ("guest_error".to_string(), e.to_string()), - HostError::Db(e) => ("db_error".to_string(), e.to_string()), + HostError::Core(e) => ("core_error".to_string(), e.to_string()), HostError::FeatureNotSupportedError(t) => { ("feature_not_supported_error".to_string(), t.to_string()) } diff --git a/host/src/interfaces/mod.rs b/host/src/interfaces/mod.rs deleted file mode 100644 index bc12622b5..000000000 --- a/host/src/interfaces/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod error; -pub mod request; diff --git a/host/src/lib.rs b/host/src/lib.rs index 24a07861f..45d80e131 100644 --- a/host/src/lib.rs +++ b/host/src/lib.rs @@ -14,24 +14,19 @@ pub mod interfaces; pub mod metrics; -pub mod preflight; -pub mod provider; -pub mod raiko; pub mod server; -use std::{alloc, collections::HashMap, path::PathBuf}; +use std::{alloc, 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_core::{interfaces::ProofRequestOpt, merge}; use raiko_lib::consts::SupportedChainSpecs; use serde::{Deserialize, Serialize}; use serde_json::Value; -type MerkleProof = HashMap; +use crate::interfaces::HostResult; #[global_allocator] static ALLOCATOR: Cap = Cap::new(alloc::System, usize::MAX); @@ -125,20 +120,6 @@ impl Cli { } } -/// Merges two json's together, overwriting `a` with the values of `b` -fn merge(a: &mut Value, b: &Value) { - match (a, b) { - (Value::Object(a), Value::Object(b)) => { - for (k, v) in b { - merge(a.entry(k.clone()).or_insert(Value::Null), v); - } - } - (a, b) if !b.is_null() => *a = b.clone(), - // If b is null, just keep a (which means do nothing). - _ => {} - } -} - #[derive(Debug, Clone)] pub struct ProverState { pub opts: Cli, @@ -153,9 +134,7 @@ impl ProverState { 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()); - chain_specs + SupportedChainSpecs::merge_from_file(cs_path.clone()).unwrap_or_default() } else { SupportedChainSpecs::default() }; diff --git a/host/src/metrics.rs b/host/src/metrics.rs index 5e1006bbb..307a1992f 100644 --- a/host/src/metrics.rs +++ b/host/src/metrics.rs @@ -5,8 +5,7 @@ use prometheus::{ labels, register_histogram_vec, register_int_counter_vec, register_int_gauge, HistogramVec, IntCounterVec, IntGauge, }; - -use crate::interfaces::request::ProofType; +use raiko_core::interfaces::ProofType; lazy_static! { pub static ref HOST_REQ_COUNT: IntCounterVec = register_int_counter_vec!( diff --git a/host/src/server/api/v1/metrics.rs b/host/src/server/api/v1/metrics.rs index 1cb996c92..ad45cbcdc 100644 --- a/host/src/server/api/v1/metrics.rs +++ b/host/src/server/api/v1/metrics.rs @@ -2,7 +2,7 @@ use axum::{body::Body, debug_handler, http::header, response::Response, routing: use prometheus::{Encoder, TextEncoder}; use utoipa::OpenApi; -use crate::{interfaces::error::HostResult, ProverState}; +use crate::{interfaces::HostResult, ProverState}; #[utoipa::path( get, diff --git a/host/src/server/api/v1/mod.rs b/host/src/server/api/v1/mod.rs index 417ac7d6c..f9ba17a1f 100644 --- a/host/src/server/api/v1/mod.rs +++ b/host/src/server/api/v1/mod.rs @@ -1,4 +1,3 @@ -use crate::interfaces::error::HostError; use axum::{response::IntoResponse, Router}; use raiko_lib::input::GuestOutput; use serde::{Deserialize, Serialize}; @@ -8,7 +7,7 @@ use utoipa::{OpenApi, ToSchema}; use utoipa_scalar::{Scalar, Servable}; use utoipa_swagger_ui::SwaggerUi; -use crate::ProverState; +use crate::{interfaces::HostError, ProverState}; mod health; mod metrics; @@ -32,9 +31,9 @@ mod proof; ), components( schemas( - crate::interfaces::request::ProofRequestOpt, - crate::interfaces::request::ProverSpecificOpts, - crate::interfaces::error::HostError, + raiko_core::interfaces::ProofRequestOpt, + raiko_core::interfaces::ProverSpecificOpts, + crate::interfaces::HostError, GuestOutputDoc, ProofResponse, Status, diff --git a/host/src/server/api/v1/proof.rs b/host/src/server/api/v1/proof.rs index 81bb5f1a2..41fa22027 100644 --- a/host/src/server/api/v1/proof.rs +++ b/host/src/server/api/v1/proof.rs @@ -1,6 +1,11 @@ use std::{fs::File, path::PathBuf}; use axum::{debug_handler, extract::State, routing::post, Json, Router}; +use raiko_core::{ + interfaces::{ProofRequest, RaikoError}, + provider::rpc::RpcBlockDataProvider, + Raiko, +}; use raiko_lib::{ input::{get_input_path, GuestInput}, Measurement, @@ -10,18 +15,13 @@ use tracing::{debug, info}; use utoipa::OpenApi; use crate::{ - interfaces::{ - error::{HostError, HostResult}, - request::ProofRequest, - }, + interfaces::{HostError, HostResult}, memory, metrics::{ dec_current_req, inc_current_req, inc_guest_error, inc_guest_req_count, inc_guest_success, inc_host_error, inc_host_req_count, observe_guest_time, observe_prepare_input_time, observe_total_time, }, - provider::rpc::RpcBlockDataProvider, - raiko::Raiko, server::api::v1::ProofResponse, ProverState, }; @@ -130,13 +130,13 @@ async fn handle_proof( let total_time = total_time.stop_with("====> Proof generation failed"); observe_total_time(proof_request.block_number, total_time, false); match e { - HostError::Guest(e) => { + RaikoError::Guest(e) => { inc_guest_error(&proof_request.proof_type, proof_request.block_number); - HostError::Guest(e) + HostError::Core(e.into()) } e => { inc_host_error(proof_request.block_number); - e + e.into() } } })?; diff --git a/host/src/server/mod.rs b/host/src/server/mod.rs index 7844f7079..a604f6914 100644 --- a/host/src/server/mod.rs +++ b/host/src/server/mod.rs @@ -4,7 +4,7 @@ use anyhow::Context; use tokio::net::TcpListener; use tracing::debug; -use crate::{interfaces::error::HostError, server::api::create_router, ProverState}; +use crate::{interfaces::HostError, server::api::create_router, ProverState}; pub mod api; diff --git a/lib/src/consts.rs b/lib/src/consts.rs index 2f80433eb..afcc14ee2 100644 --- a/lib/src/consts.rs +++ b/lib/src/consts.rs @@ -18,7 +18,7 @@ extern crate alloc; use alloc::collections::BTreeMap; use alloy_primitives::Address; -use anyhow::{bail, Result}; +use anyhow::{anyhow, bail, Result}; use raiko_primitives::{uint, BlockNumber, ChainId, U256}; use revm::primitives::SpecId; use serde::{Deserialize, Serialize}; @@ -49,16 +49,19 @@ const DEFAULT_CHAIN_SPECS: &str = include_str!("../../host/config/chain_spec_lis #[derive(Clone, Debug)] pub struct SupportedChainSpecs(HashMap); -impl SupportedChainSpecs { - pub fn default() -> Self { - let deserialized: Vec = serde_json::from_str(DEFAULT_CHAIN_SPECS).unwrap(); +impl Default for SupportedChainSpecs { + fn default() -> Self { + let deserialized: Vec = + serde_json::from_str(DEFAULT_CHAIN_SPECS).unwrap_or_default(); let chain_spec_list = deserialized - .iter() - .map(|cs| (cs.name.clone(), cs.clone())) + .into_iter() + .map(|cs| (cs.name.clone(), cs)) .collect::>(); SupportedChainSpecs(chain_spec_list) } +} +impl SupportedChainSpecs { #[cfg(feature = "std")] pub fn merge_from_file(file_path: PathBuf) -> Result { let mut known_chain_specs = SupportedChainSpecs::default(); @@ -67,8 +70,8 @@ impl SupportedChainSpecs { let config: Value = serde_json::from_reader(reader)?; let chain_spec_list: Vec = serde_json::from_value(config)?; let new_chain_specs = chain_spec_list - .iter() - .map(|cs| (cs.name.clone(), cs.clone())) + .into_iter() + .map(|cs| (cs.name.clone(), cs)) .collect::>(); // override known specs @@ -187,10 +190,12 @@ impl ChainSpec { is_taiko, } } + /// Returns the network chain ID. pub fn chain_id(&self) -> ChainId { self.chain_id } + /// Returns the [SpecId] for a given block number and timestamp or an error if not /// supported. pub fn active_fork(&self, block_no: BlockNumber, timestamp: u64) -> Result { @@ -201,9 +206,10 @@ impl ChainSpec { } Ok(spec_id) } - None => bail!("no supported fork for block {block_no}"), + None => Err(anyhow!("no supported fork for block {block_no}")), } } + /// Returns the Eip1559 constants pub fn gas_constants(&self) -> &Eip1559Constants { &self.eip_1559_constants diff --git a/lib/src/protocol_instance.rs b/lib/src/protocol_instance.rs index ce8c3f8e6..ffc9f3b82 100644 --- a/lib/src/protocol_instance.rs +++ b/lib/src/protocol_instance.rs @@ -102,13 +102,12 @@ impl ProtocolInstance { .collect::>(); let gas_limit: u64 = header.gas_limit.try_into().unwrap(); - let verifier_address = input + let verifier_address = (*input .chain_spec .verifier_address .get(&proof_type) - .unwrap_or(&None) - .clone() - .unwrap_or_default(); + .unwrap_or(&None)) + .unwrap_or_default(); let pi = ProtocolInstance { transition: Transition {