diff --git a/Cargo.lock b/Cargo.lock index cde96ccfc..e395a18d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "ahash" version = "0.8.11" @@ -390,7 +401,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "derive_more", - "hashbrown", + "hashbrown 0.14.5", "nybbles", "smallvec", "tracing", @@ -775,6 +786,28 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -958,7 +991,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1340,13 +1373,22 @@ dependencies = [ "tracing", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] + [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash", + "ahash 0.8.11", "allocator-api2", "serde", ] @@ -1537,7 +1579,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -1677,7 +1719,7 @@ dependencies = [ "async-trait", "brotli", "c-kzg", - "hashbrown", + "hashbrown 0.14.5", "kona-primitives", "lru", "miniz_oxide", @@ -1794,7 +1836,7 @@ dependencies = [ "async-trait", "cfg-if", "kona-common", - "serde", + "rkyv", "tempfile", "tokio", "tracing", @@ -1874,7 +1916,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -2370,6 +2412,26 @@ dependencies = [ "unarray", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -2445,6 +2507,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.12.5" @@ -2543,7 +2614,7 @@ dependencies = [ "derive_more", "dyn-clone", "enumn", - "hashbrown", + "hashbrown 0.14.5", "hex", "once_cell", "serde", @@ -2583,6 +2654,35 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "rkyv" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "rlp" version = "0.5.2" @@ -2745,6 +2845,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "sec1" version = "0.7.3" @@ -2929,6 +3035,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + [[package]] name = "simple-revm" version = "0.1.0" @@ -3049,9 +3161,9 @@ checksum = "0d0208408ba0c3df17ed26eb06992cb1a1268d41b2c0e12e65203fbe3972cee5" [[package]] name = "superchain-primitives" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ce53db1b0ae24593ac759782cceedb03c838a39bb1f2ccd5c0923778acd7871" +checksum = "a88a85697c4aa789e1465c86f855cfaecd8d38553961f1fec77af6ea51d30e8e" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3059,7 +3171,7 @@ dependencies = [ "alloy-primitives", "alloy-sol-types", "anyhow", - "hashbrown", + "hashbrown 0.14.5", "serde", "serde_repr", ] @@ -3489,6 +3601,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" + [[package]] name = "valuable" version = "0.1.0" diff --git a/bin/client/src/comms/caching_oracle.rs b/bin/client/src/comms/caching_oracle.rs index ab3d84df2..8eac4670b 100644 --- a/bin/client/src/comms/caching_oracle.rs +++ b/bin/client/src/comms/caching_oracle.rs @@ -3,12 +3,12 @@ //! //! [OracleReader]: kona_preimage::OracleReader -use crate::ORACLE_READER; +use crate::{HINT_WRITER, ORACLE_READER}; use alloc::{boxed::Box, sync::Arc, vec::Vec}; use anyhow::Result; use async_trait::async_trait; use core::num::NonZeroUsize; -use kona_preimage::{PreimageKey, PreimageOracleClient}; +use kona_preimage::{HintWriterClient, PreimageKey, PreimageOracleClient}; use lru::LruCache; use spin::Mutex; @@ -63,3 +63,10 @@ impl PreimageOracleClient for CachingOracle { } } } + +#[async_trait] +impl HintWriterClient for CachingOracle { + async fn write(&self, hint: &str) -> Result<()> { + HINT_WRITER.write(hint).await + } +} diff --git a/bin/client/src/kona.rs b/bin/client/src/kona.rs index 7d81deb50..8ddc924cb 100644 --- a/bin/client/src/kona.rs +++ b/bin/client/src/kona.rs @@ -9,7 +9,7 @@ use alloc::sync::Arc; use alloy_consensus::Header; use kona_client::{ l1::{DerivationDriver, OracleBlobProvider, OracleL1ChainProvider}, - l2::{OracleL2ChainProvider, TrieDBHintWriter}, + l2::OracleL2ChainProvider, BootInfo, CachingOracle, }; use kona_common_proc::client_entry; @@ -60,8 +60,8 @@ fn main() -> Result<()> { let mut executor = StatelessL2BlockExecutor::new( &boot.rollup_config, driver.take_l2_safe_head_header(), + l2_provider.clone(), l2_provider, - TrieDBHintWriter, ); let Header { number, .. } = *executor.execute_payload(attributes)?; let output_root = executor.compute_output_root()?; diff --git a/bin/client/src/l1/blob_provider.rs b/bin/client/src/l1/blob_provider.rs index 01b7375a2..265fa33db 100644 --- a/bin/client/src/l1/blob_provider.rs +++ b/bin/client/src/l1/blob_provider.rs @@ -1,6 +1,6 @@ //! Contains the concrete implementation of the [BlobProvider] trait for the client program. -use crate::{CachingOracle, HintType, HINT_WRITER}; +use crate::HintType; use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloy_consensus::Blob; use alloy_eips::eip4844::FIELD_ELEMENTS_PER_BLOB; @@ -10,18 +10,18 @@ use kona_derive::{ traits::BlobProvider, types::{BlobProviderError, IndexedBlobHash}, }; -use kona_preimage::{HintWriterClient, PreimageKey, PreimageKeyType, PreimageOracleClient}; +use kona_preimage::{CommsClient, PreimageKey, PreimageKeyType}; use kona_primitives::BlockInfo; /// An oracle-backed blob provider. #[derive(Debug, Clone)] -pub struct OracleBlobProvider { - oracle: Arc, +pub struct OracleBlobProvider { + oracle: Arc, } -impl OracleBlobProvider { +impl OracleBlobProvider { /// Constructs a new `OracleBlobProvider`. - pub fn new(oracle: Arc) -> Self { + pub fn new(oracle: Arc) -> Self { Self { oracle } } @@ -45,7 +45,7 @@ impl OracleBlobProvider { blob_req_meta[40..48].copy_from_slice(block_ref.timestamp.to_be_bytes().as_ref()); // Send a hint for the blob commitment and field elements. - HINT_WRITER.write(&HintType::L1Blob.encode_with(&[blob_req_meta.as_ref()])).await?; + self.oracle.write(&HintType::L1Blob.encode_with(&[blob_req_meta.as_ref()])).await?; // Fetch the blob commitment. let mut commitment = [0u8; 48]; @@ -77,7 +77,7 @@ impl OracleBlobProvider { } #[async_trait] -impl BlobProvider for OracleBlobProvider { +impl BlobProvider for OracleBlobProvider { async fn get_blobs( &mut self, block_ref: &BlockInfo, diff --git a/bin/client/src/l1/chain_provider.rs b/bin/client/src/l1/chain_provider.rs index c6725c9e7..940f905ae 100644 --- a/bin/client/src/l1/chain_provider.rs +++ b/bin/client/src/l1/chain_provider.rs @@ -1,6 +1,6 @@ //! Contains the concrete implementation of the [ChainProvider] trait for the client program. -use crate::{BootInfo, CachingOracle, HintType, HINT_WRITER}; +use crate::{BootInfo, HintType}; use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloy_consensus::{Header, Receipt, ReceiptEnvelope, TxEnvelope}; use alloy_eips::eip2718::Decodable2718; @@ -10,30 +10,30 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use kona_derive::traits::ChainProvider; use kona_mpt::{OrderedListWalker, TrieDBFetcher}; -use kona_preimage::{HintWriterClient, PreimageKey, PreimageKeyType, PreimageOracleClient}; +use kona_preimage::{CommsClient, PreimageKey, PreimageKeyType}; use kona_primitives::BlockInfo; /// The oracle-backed L1 chain provider for the client program. #[derive(Debug, Clone)] -pub struct OracleL1ChainProvider { +pub struct OracleL1ChainProvider { /// The boot information boot_info: Arc, /// The preimage oracle client. - oracle: Arc, + pub oracle: Arc, } -impl OracleL1ChainProvider { +impl OracleL1ChainProvider { /// Creates a new [OracleL1ChainProvider] with the given boot information and oracle client. - pub fn new(boot_info: Arc, oracle: Arc) -> Self { + pub fn new(boot_info: Arc, oracle: Arc) -> Self { Self { boot_info, oracle } } } #[async_trait] -impl ChainProvider for OracleL1ChainProvider { +impl ChainProvider for OracleL1ChainProvider { async fn header_by_hash(&mut self, hash: B256) -> Result
{ // Send a hint for the block header. - HINT_WRITER.write(&HintType::L1BlockHeader.encode_with(&[hash.as_ref()])).await?; + self.oracle.write(&HintType::L1BlockHeader.encode_with(&[hash.as_ref()])).await?; // Fetch the header RLP from the oracle. let header_rlp = @@ -72,7 +72,7 @@ impl ChainProvider for OracleL1ChainProvider { // Send a hint for the block's receipts, and walk through the receipts trie in the header to // verify them. - HINT_WRITER.write(&HintType::L1Receipts.encode_with(&[hash.as_ref()])).await?; + self.oracle.write(&HintType::L1Receipts.encode_with(&[hash.as_ref()])).await?; let trie_walker = OrderedListWalker::try_new_hydrated(header.receipts_root, self)?; // Decode the receipts within the transactions trie. @@ -103,7 +103,7 @@ impl ChainProvider for OracleL1ChainProvider { // Send a hint for the block's transactions, and walk through the transactions trie in the // header to verify them. - HINT_WRITER.write(&HintType::L1Transactions.encode_with(&[hash.as_ref()])).await?; + self.oracle.write(&HintType::L1Transactions.encode_with(&[hash.as_ref()])).await?; let trie_walker = OrderedListWalker::try_new_hydrated(header.transactions_root, self)?; // Decode the transactions within the transactions trie. @@ -119,7 +119,7 @@ impl ChainProvider for OracleL1ChainProvider { } } -impl TrieDBFetcher for OracleL1ChainProvider { +impl TrieDBFetcher for OracleL1ChainProvider { fn trie_node_preimage(&self, key: B256) -> Result { // On L1, trie node preimages are stored as keccak preimage types in the oracle. We assume // that a hint for these preimages has already been sent, prior to this call. diff --git a/bin/client/src/l1/driver.rs b/bin/client/src/l1/driver.rs index 8f5603531..df60d392d 100644 --- a/bin/client/src/l1/driver.rs +++ b/bin/client/src/l1/driver.rs @@ -4,7 +4,7 @@ //! [L2PayloadAttributes]: kona_derive::types::L2PayloadAttributes use super::{OracleBlobProvider, OracleL1ChainProvider}; -use crate::{l2::OracleL2ChainProvider, BootInfo, CachingOracle, HintType, HINT_WRITER}; +use crate::{l2::OracleL2ChainProvider, BootInfo, HintType}; use alloc::sync::Arc; use alloy_consensus::{Header, Sealed}; use anyhow::{anyhow, Result}; @@ -19,31 +19,32 @@ use kona_derive::{ traits::{ChainProvider, L2ChainProvider}, }; use kona_mpt::TrieDBFetcher; -use kona_preimage::{HintWriterClient, PreimageKey, PreimageKeyType, PreimageOracleClient}; +use kona_preimage::{CommsClient, PreimageKey, PreimageKeyType}; use kona_primitives::{BlockInfo, L2AttributesWithParent, L2BlockInfo}; use tracing::{info, warn}; /// An oracle-backed derivation pipeline. -pub type OraclePipeline = - DerivationPipeline, OracleL2ChainProvider>; +pub type OraclePipeline = + DerivationPipeline, O>, OracleL2ChainProvider>; /// An oracle-backed Ethereum data source. -pub type OracleDataProvider = EthereumDataSource; +pub type OracleDataProvider = + EthereumDataSource, OracleBlobProvider>; /// An oracle-backed payload attributes builder for the `AttributesQueue` stage of the derivation /// pipeline. -pub type OracleAttributesBuilder = - StatefulAttributesBuilder; +pub type OracleAttributesBuilder = + StatefulAttributesBuilder, OracleL2ChainProvider>; /// An oracle-backed attributes queue for the derivation pipeline. -pub type OracleAttributesQueue = AttributesQueue< +pub type OracleAttributesQueue = AttributesQueue< BatchQueue< ChannelReader< - ChannelBank>>>, + ChannelBank>>>>, >, - OracleL2ChainProvider, + OracleL2ChainProvider, >, - OracleAttributesBuilder, + OracleAttributesBuilder, >; /// The [DerivationDriver] struct is responsible for handling the [L2PayloadAttributes] derivation @@ -54,16 +55,16 @@ pub type OracleAttributesQueue = AttributesQueue< /// /// [L2PayloadAttributes]: kona_derive::types::L2PayloadAttributes #[derive(Debug)] -pub struct DerivationDriver { +pub struct DerivationDriver { /// The current L2 safe head. l2_safe_head: L2BlockInfo, /// The header of the L2 safe head. l2_safe_head_header: Sealed
, /// The inner pipeline. - pipeline: OraclePipeline, + pipeline: OraclePipeline, } -impl DerivationDriver { +impl DerivationDriver { /// Returns the current L2 safe head [L2BlockInfo]. pub fn l2_safe_head(&self) -> &L2BlockInfo { &self.l2_safe_head @@ -92,10 +93,10 @@ impl DerivationDriver { /// - A new [DerivationDriver] instance. pub async fn new( boot_info: &BootInfo, - caching_oracle: &CachingOracle, - blob_provider: OracleBlobProvider, - mut chain_provider: OracleL1ChainProvider, - mut l2_chain_provider: OracleL2ChainProvider, + caching_oracle: &O, + blob_provider: OracleBlobProvider, + mut chain_provider: OracleL1ChainProvider, + mut l2_chain_provider: OracleL2ChainProvider, ) -> Result { let cfg = Arc::new(boot_info.rollup_config.clone()); @@ -159,13 +160,13 @@ impl DerivationDriver { /// ## Returns /// - A tuple containing the L1 origin block information and the L2 safe head information. async fn find_startup_info( - caching_oracle: &CachingOracle, + caching_oracle: &O, boot_info: &BootInfo, - chain_provider: &mut OracleL1ChainProvider, - l2_chain_provider: &mut OracleL2ChainProvider, + chain_provider: &mut OracleL1ChainProvider, + l2_chain_provider: &mut OracleL2ChainProvider, ) -> Result<(BlockInfo, L2BlockInfo, Sealed
)> { // Find the initial safe head, based off of the starting L2 block number in the boot info. - HINT_WRITER + caching_oracle .write(&HintType::StartingL2Output.encode_with(&[boot_info.l2_output_root.as_ref()])) .await?; let mut output_preimage = [0u8; 128]; diff --git a/bin/client/src/l2/chain_provider.rs b/bin/client/src/l2/chain_provider.rs index 92cf3e90d..f540ae248 100644 --- a/bin/client/src/l2/chain_provider.rs +++ b/bin/client/src/l2/chain_provider.rs @@ -1,16 +1,16 @@ //! Contains the concrete implementation of the [L2ChainProvider] trait for the client program. -use crate::{BootInfo, CachingOracle, HintType, HINT_WRITER}; +use crate::{BootInfo, HintType}; use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloy_consensus::Header; use alloy_eips::eip2718::Decodable2718; -use alloy_primitives::{Bytes, B256}; +use alloy_primitives::{Address, Bytes, B256}; use alloy_rlp::Decodable; use anyhow::{anyhow, Result}; use async_trait::async_trait; use kona_derive::traits::L2ChainProvider; -use kona_mpt::{OrderedListWalker, TrieDBFetcher}; -use kona_preimage::{HintWriterClient, PreimageKey, PreimageKeyType, PreimageOracleClient}; +use kona_mpt::{OrderedListWalker, TrieDBFetcher, TrieDBHinter}; +use kona_preimage::{CommsClient, PreimageKey, PreimageKeyType}; use kona_primitives::{ L2BlockInfo, L2ExecutionPayloadEnvelope, OpBlock, RollupConfig, SystemConfig, }; @@ -18,26 +18,26 @@ use op_alloy_consensus::OpTxEnvelope; /// The oracle-backed L2 chain provider for the client program. #[derive(Debug, Clone)] -pub struct OracleL2ChainProvider { +pub struct OracleL2ChainProvider { /// The boot information boot_info: Arc, /// The preimage oracle client. - oracle: Arc, + oracle: Arc, } -impl OracleL2ChainProvider { +impl OracleL2ChainProvider { /// Creates a new [OracleL2ChainProvider] with the given boot information and oracle client. - pub fn new(boot_info: Arc, oracle: Arc) -> Self { + pub fn new(boot_info: Arc, oracle: Arc) -> Self { Self { boot_info, oracle } } } -impl OracleL2ChainProvider { +impl OracleL2ChainProvider { /// Returns a [Header] corresponding to the given L2 block number, by walking back from the /// L2 safe head. async fn header_by_number(&mut self, block_number: u64) -> Result
{ // Fetch the starting L2 output preimage. - HINT_WRITER + self.oracle .write( &HintType::StartingL2Output.encode_with(&[self.boot_info.l2_output_root.as_ref()]), ) @@ -68,7 +68,7 @@ impl OracleL2ChainProvider { } #[async_trait] -impl L2ChainProvider for OracleL2ChainProvider { +impl L2ChainProvider for OracleL2ChainProvider { async fn l2_block_info_by_number(&mut self, number: u64) -> Result { // Get the payload at the given block number. let payload = self.payload_by_number(number).await?; @@ -84,7 +84,7 @@ impl L2ChainProvider for OracleL2ChainProvider { let header_hash = header.hash_slow(); // Fetch the transactions in the block. - HINT_WRITER.write(&HintType::L2Transactions.encode_with(&[header_hash.as_ref()])).await?; + self.oracle.write(&HintType::L2Transactions.encode_with(&[header_hash.as_ref()])).await?; let trie_walker = OrderedListWalker::try_new_hydrated(transactions_root, self)?; // Decode the transactions within the transactions trie. @@ -118,7 +118,7 @@ impl L2ChainProvider for OracleL2ChainProvider { } } -impl TrieDBFetcher for OracleL2ChainProvider { +impl TrieDBFetcher for OracleL2ChainProvider { fn trie_node_preimage(&self, key: B256) -> Result { // On L2, trie node preimages are stored as keccak preimage types in the oracle. We assume // that a hint for these preimages has already been sent, prior to this call. @@ -133,7 +133,7 @@ impl TrieDBFetcher for OracleL2ChainProvider { fn bytecode_by_hash(&self, hash: B256) -> Result { // Fetch the bytecode preimage from the caching oracle. kona_common::block_on(async move { - HINT_WRITER.write(&HintType::L2Code.encode_with(&[hash.as_ref()])).await?; + self.oracle.write(&HintType::L2Code.encode_with(&[hash.as_ref()])).await?; self.oracle .get(PreimageKey::new(*hash, PreimageKeyType::Keccak256)) @@ -145,7 +145,7 @@ impl TrieDBFetcher for OracleL2ChainProvider { fn header_by_hash(&self, hash: B256) -> Result
{ // Fetch the header from the caching oracle. kona_common::block_on(async move { - HINT_WRITER.write(&HintType::L2BlockHeader.encode_with(&[hash.as_ref()])).await?; + self.oracle.write(&HintType::L2BlockHeader.encode_with(&[hash.as_ref()])).await?; let header_bytes = self.oracle.get(PreimageKey::new(*hash, PreimageKeyType::Keccak256)).await?; @@ -154,3 +154,39 @@ impl TrieDBFetcher for OracleL2ChainProvider { }) } } + +impl TrieDBHinter for OracleL2ChainProvider { + fn hint_trie_node(&self, hash: B256) -> Result<()> { + kona_common::block_on(async move { + self.oracle.write(&HintType::L2StateNode.encode_with(&[hash.as_slice()])).await + }) + } + + fn hint_account_proof(&self, address: Address, block_number: u64) -> Result<()> { + kona_common::block_on(async move { + self.oracle + .write( + &HintType::L2AccountProof + .encode_with(&[block_number.to_be_bytes().as_ref(), address.as_slice()]), + ) + .await + }) + } + + fn hint_storage_proof( + &self, + address: alloy_primitives::Address, + slot: alloy_primitives::U256, + block_number: u64, + ) -> Result<()> { + kona_common::block_on(async move { + self.oracle + .write(&HintType::L2AccountStorageProof.encode_with(&[ + block_number.to_be_bytes().as_ref(), + address.as_slice(), + slot.to_be_bytes::<32>().as_ref(), + ])) + .await + }) + } +} diff --git a/bin/client/src/l2/mod.rs b/bin/client/src/l2/mod.rs index 31ceb9323..459e4dfe8 100644 --- a/bin/client/src/l2/mod.rs +++ b/bin/client/src/l2/mod.rs @@ -1,7 +1,4 @@ //! Contains the L2-specifc contstructs of the client program. -mod trie_hinter; -pub use trie_hinter::TrieDBHintWriter; - mod chain_provider; pub use chain_provider::OracleL2ChainProvider; diff --git a/bin/client/src/l2/trie_hinter.rs b/bin/client/src/l2/trie_hinter.rs deleted file mode 100644 index 53e9ecf7d..000000000 --- a/bin/client/src/l2/trie_hinter.rs +++ /dev/null @@ -1,51 +0,0 @@ -//! Contains the hinter for the [TrieDB]. -//! -//! [TrieDB]: kona_mpt::TrieDB - -use crate::{HintType, HINT_WRITER}; -use alloy_primitives::{Address, B256}; -use anyhow::Result; -use kona_mpt::TrieDBHinter; -use kona_preimage::HintWriterClient; - -/// The [TrieDBHinter] implementation for the block executor's [TrieDB]. -/// -/// [TrieDB]: kona_mpt::TrieDB -#[derive(Debug)] -pub struct TrieDBHintWriter; - -impl TrieDBHinter for TrieDBHintWriter { - fn hint_trie_node(&self, hash: B256) -> Result<()> { - kona_common::block_on(async move { - HINT_WRITER.write(&HintType::L2StateNode.encode_with(&[hash.as_slice()])).await - }) - } - - fn hint_account_proof(&self, address: Address, block_number: u64) -> Result<()> { - kona_common::block_on(async move { - HINT_WRITER - .write( - &HintType::L2AccountProof - .encode_with(&[block_number.to_be_bytes().as_ref(), address.as_slice()]), - ) - .await - }) - } - - fn hint_storage_proof( - &self, - address: alloy_primitives::Address, - slot: alloy_primitives::U256, - block_number: u64, - ) -> Result<()> { - kona_common::block_on(async move { - HINT_WRITER - .write(&HintType::L2AccountStorageProof.encode_with(&[ - block_number.to_be_bytes().as_ref(), - address.as_slice(), - slot.to_be_bytes::<32>().as_ref(), - ])) - .await - }) - } -} diff --git a/crates/common/src/io.rs b/crates/common/src/io.rs index 611540acb..334029820 100644 --- a/crates/common/src/io.rs +++ b/crates/common/src/io.rs @@ -12,6 +12,9 @@ cfg_if! { } else if #[cfg(target_arch = "riscv64")] { #[doc = "Concrete implementation of the [BasicKernelInterface] trait for the `riscv64` target architecture."] pub type ClientIO = crate::asterisc::io::AsteriscIO; + } else if #[cfg(target_os = "zkvm")] { + #[doc = "Concrete implementation of the [BasicKernelInterface] trait for the `zkvm` target architecture."] + pub type ClientIO = crate::zkvm::io::ZkvmIO; } else { #[doc = "Concrete implementation of the [BasicKernelInterface] trait for the `native` target architecture."] pub type ClientIO = native_io::NativeIO; @@ -54,7 +57,7 @@ pub fn exit(code: usize) -> ! { ClientIO::exit(code) } -#[cfg(not(any(target_arch = "mips", target_arch = "riscv64")))] +#[cfg(not(any(target_arch = "mips", target_arch = "riscv64", target_os = "zkvm")))] mod native_io { extern crate std; diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 59945c942..9d54a5dd6 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -25,3 +25,6 @@ pub(crate) mod cannon; #[cfg(target_arch = "riscv64")] pub(crate) mod asterisc; + +#[cfg(target_os = "zkvm")] +pub(crate) mod zkvm; diff --git a/crates/common/src/zkvm/io.rs b/crates/common/src/zkvm/io.rs new file mode 100644 index 000000000..20d107d6c --- /dev/null +++ b/crates/common/src/zkvm/io.rs @@ -0,0 +1,20 @@ +use crate::{BasicKernelInterface, FileDescriptor}; +use anyhow::Result; + +/// Concrete implementation of the [`KernelIO`] trait for the `SP1` target architecture. +#[derive(Debug)] +pub struct ZkvmIO; + +impl BasicKernelInterface for ZkvmIO { + fn write(_fd: FileDescriptor, _buf: &[u8]) -> Result { + unimplemented!(); + } + + fn read(_fd: FileDescriptor, _buf: &mut [u8]) -> Result { + unimplemented!(); + } + + fn exit(_code: usize) -> ! { + unimplemented!(); + } +} diff --git a/crates/common/src/zkvm/mod.rs b/crates/common/src/zkvm/mod.rs new file mode 100644 index 000000000..253dfbcce --- /dev/null +++ b/crates/common/src/zkvm/mod.rs @@ -0,0 +1,4 @@ +//! This module contains raw syscall bindings for the `riscv64gc` target architecture, as well as a +//! high-level implementation of the [crate::BasicKernelInterface] trait for the `asterisc` kernel. + +pub(crate) mod io; diff --git a/crates/executor/src/lib.rs b/crates/executor/src/lib.rs index 77524ca09..a5202d93f 100644 --- a/crates/executor/src/lib.rs +++ b/crates/executor/src/lib.rs @@ -57,6 +57,8 @@ where pub fn new( config: &'a RollupConfig, parent_header: Sealed
, + // TODO: @Clabby - would you rather refactor this to assume Provider implements F + H + // and just pass one argument? fetcher: F, hinter: H, ) -> Self { diff --git a/crates/preimage/Cargo.toml b/crates/preimage/Cargo.toml index 6f38ca540..6d549e88b 100644 --- a/crates/preimage/Cargo.toml +++ b/crates/preimage/Cargo.toml @@ -19,7 +19,8 @@ async-trait.workspace = true # local kona-common = { path = "../common", version = "0.0.2" } -serde = { version = "1.0.203", features = ["derive"], optional = true } +# external +rkyv = { version = "0.7.44", optional = true } [dev-dependencies] tokio = { version = "1.38.0", features = ["full"] } @@ -27,4 +28,4 @@ tempfile = "3.10.1" [features] default = [] -serde = ["dep:serde"] +rkyv = ["dep:rkyv"] diff --git a/crates/preimage/src/key.rs b/crates/preimage/src/key.rs index 99784bb2b..68b99349c 100644 --- a/crates/preimage/src/key.rs +++ b/crates/preimage/src/key.rs @@ -2,13 +2,14 @@ //! the preimage oracle. use alloy_primitives::{B256, U256}; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +#[cfg(feature = "rkyv")] +use rkyv::{Archive, Deserialize, Serialize}; /// -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)] #[repr(u8)] +#[cfg_attr(feature = "rkyv", derive(Archive, Serialize, Deserialize))] +#[cfg_attr(feature = "rkyv", archive_attr(derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)))] pub enum PreimageKeyType { /// Local key types are local to a given instance of a fault-proof and context dependent. /// Commonly these local keys are mapped to bootstrap data for the fault proof program. @@ -56,8 +57,9 @@ impl TryFrom for PreimageKeyType { /// |---------|-------------| /// | [0, 1) | Type byte | /// | [1, 32) | Data | -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)] +#[cfg_attr(feature = "rkyv", derive(Archive, Serialize, Deserialize))] +#[cfg_attr(feature = "rkyv", archive_attr(derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)))] pub struct PreimageKey { data: [u8; 31], key_type: PreimageKeyType, diff --git a/crates/preimage/src/lib.rs b/crates/preimage/src/lib.rs index 61906eb0b..d3db482ce 100644 --- a/crates/preimage/src/lib.rs +++ b/crates/preimage/src/lib.rs @@ -19,4 +19,6 @@ mod pipe; pub use pipe::PipeHandle; mod traits; -pub use traits::{HintReaderServer, HintWriterClient, PreimageOracleClient, PreimageOracleServer}; +pub use traits::{ + CommsClient, HintReaderServer, HintWriterClient, PreimageOracleClient, PreimageOracleServer, +}; diff --git a/crates/preimage/src/traits.rs b/crates/preimage/src/traits.rs index c62d1c5bc..050d6c01b 100644 --- a/crates/preimage/src/traits.rs +++ b/crates/preimage/src/traits.rs @@ -38,6 +38,12 @@ pub trait HintWriterClient { async fn write(&self, hint: &str) -> Result<()>; } +/// A [CommsClient] is a trait that combines the [PreimageOracleClient] and [HintWriterClient] +pub trait CommsClient: PreimageOracleClient + Clone + HintWriterClient {} + +// Implement the super trait for any type that satisfies the bounds +impl CommsClient for T {} + /// A [PreimageOracleServer] is a high-level interface to accept read requests from the client and /// write the preimage data to the client pipe. #[async_trait]