-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Begins the client program, adding the `BootInfo` prologue phase implementation (sans the `RollupConfig` / `ChainConfig`, waiting on #193 for these)
- Loading branch information
Showing
17 changed files
with
298 additions
and
19 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
set fallback := true | ||
|
||
# default recipe to display help information | ||
default: | ||
@just --list | ||
|
||
# Run the client program natively with the hos | ||
run-client-native l1_rpc l1_beacon_rpc l2_rpc verbosity: | ||
#!/usr/bin/env bash | ||
ROLLUP_CONFIG_PATH="x" | ||
L2_GENESIS_PATH="x" | ||
L1_HEAD=$(cast 2b 0) | ||
L2_HEAD=$(cast 2b 0) | ||
L2_OUTPUT_ROOT=$(cast 2b 0) | ||
L2_CLAIM=$(cast 2b 0) | ||
L2_BLOCK_NUMBER=0 | ||
|
||
L1_NODE_ADDRESS="{{l1_rpc}}" | ||
L1_BEACON_ADDRESS="{{l1_beacon_rpc}}" | ||
L2_NODE_ADDRESS="{{l2_rpc}}" | ||
|
||
CLIENT_BIN_PATH="./target/release-client-lto/kona-client" | ||
|
||
echo "Building client program..." | ||
cargo build --bin kona-client --profile release-client-lto | ||
echo "Running host program with native client program..." | ||
(cd ../../.. && cargo r --bin kona-host --release -- \ | ||
--rollup-config $ROLLUP_CONFIG_PATH \ | ||
--network optimism \ | ||
--l2-genesis-path $L2_GENESIS_PATH \ | ||
--l1-head $L1_HEAD \ | ||
--l2-head $L2_HEAD \ | ||
--l2-claim $L2_CLAIM \ | ||
--l2-output-root $L2_OUTPUT_ROOT \ | ||
--l2-block-number $L2_BLOCK_NUMBER \ | ||
--l1-node-address $L1_NODE_ADDRESS \ | ||
--l1-beacon-address $L1_BEACON_ADDRESS \ | ||
--l2-node-address $L2_NODE_ADDRESS \ | ||
--exec $CLIENT_BIN_PATH \ | ||
{{verbosity}}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
//! This module contains the prologue phase of the client program, pulling in the boot information | ||
//! through the `PreimageOracle` ABI as local keys. | ||
use alloy_primitives::{B256, U256}; | ||
use anyhow::{anyhow, Result}; | ||
use kona_preimage::{PreimageKey, PreimageOracleClient}; | ||
|
||
/// The local key ident for the L1 head hash. | ||
pub const L1_HEAD_KEY: U256 = U256::from_be_slice(&[1]); | ||
|
||
/// The local key ident for the L2 output root. | ||
pub const L2_OUTPUT_ROOT_KEY: U256 = U256::from_be_slice(&[2]); | ||
|
||
/// The local key ident for the L2 output root claim. | ||
pub const L2_CLAIM_KEY: U256 = U256::from_be_slice(&[3]); | ||
|
||
/// The local key ident for the L2 claim block number. | ||
pub const L2_CLAIM_BLOCK_NUMBER_KEY: U256 = U256::from_be_slice(&[4]); | ||
|
||
/// The local key ident for the L2 chain ID. | ||
pub const L2_CHAIN_ID_KEY: U256 = U256::from_be_slice(&[5]); | ||
|
||
/// The local key ident for the L2 chain config. | ||
pub const L2_CHAIN_CONFIG_KEY: U256 = U256::from_be_slice(&[6]); | ||
|
||
/// The local key ident for the L2 rollup config. | ||
pub const L2_ROLLUP_CONFIG_KEY: U256 = U256::from_be_slice(&[7]); | ||
|
||
/// The boot information for the client program. | ||
/// | ||
/// **Verified inputs:** | ||
/// - `l1_head`: The L1 head hash containing the safe L2 chain data that may reproduce the L2 head | ||
/// hash. | ||
/// - `l2_output_root`: The latest finalized L2 output root. | ||
/// - `chain_id`: The L2 chain ID. | ||
/// | ||
/// **User submitted inputs:** | ||
/// - `l2_claim`: The L2 output root claim. | ||
/// - `l2_claim_block`: The L2 claim block number. | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct BootInfo { | ||
/// The L1 head hash containing the safe L2 chain data that may reproduce the L2 head hash. | ||
pub l1_head: B256, | ||
/// The latest finalized L2 output root. | ||
pub l2_output_root: B256, | ||
/// The L2 output root claim. | ||
pub l2_claim: B256, | ||
/// The L2 claim block number. | ||
pub l2_claim_block: u64, | ||
/// The L2 chain ID. | ||
pub chain_id: u64, | ||
} | ||
|
||
impl BootInfo { | ||
/// Load the boot information from the preimage oracle. | ||
/// | ||
/// ## Takes | ||
/// - `ORACLE_READER`: The preimage oracle reader. | ||
/// | ||
/// ## Returns | ||
/// - `Ok(BootInfo)`: The boot information. | ||
/// - `Err(_)`: Failed to load the boot information. | ||
pub async fn load<O>(oracle: &O) -> Result<Self> | ||
where | ||
O: PreimageOracleClient + Send, | ||
{ | ||
let mut l1_head: B256 = B256::ZERO; | ||
oracle.get_exact(PreimageKey::new_local(L1_HEAD_KEY.to()), l1_head.as_mut()).await?; | ||
|
||
let mut l2_output_root: B256 = B256::ZERO; | ||
oracle | ||
.get_exact(PreimageKey::new_local(L2_OUTPUT_ROOT_KEY.to()), l2_output_root.as_mut()) | ||
.await?; | ||
|
||
let mut l2_claim: B256 = B256::ZERO; | ||
oracle.get_exact(PreimageKey::new_local(L2_CLAIM_KEY.to()), l2_claim.as_mut()).await?; | ||
|
||
let l2_claim_block = u64::from_be_bytes( | ||
oracle | ||
.get(PreimageKey::new_local(L2_CLAIM_BLOCK_NUMBER_KEY.to())) | ||
.await? | ||
.try_into() | ||
.map_err(|_| anyhow!("Failed to convert L2 claim block number to u64"))?, | ||
); | ||
let chain_id = u64::from_be_bytes( | ||
oracle | ||
.get(PreimageKey::new_local(L2_CHAIN_ID_KEY.to())) | ||
.await? | ||
.try_into() | ||
.map_err(|_| anyhow!("Failed to convert L2 chain ID to u64"))?, | ||
); | ||
|
||
Ok(Self { l1_head, l2_output_root, l2_claim, l2_claim_block, chain_id }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
//! Contains the [CachingOracle], which is a wrapper around an [OracleReader] that stores a | ||
//! configurable number of responses in an [LruCache] for quick retrieval. | ||
//! | ||
//! [OracleReader]: kona_preimage::OracleReader | ||
use crate::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 lru::LruCache; | ||
use spin::Mutex; | ||
|
||
/// A wrapper around an [OracleReader] that stores a configurable number of responses in an | ||
/// [LruCache] for quick retrieval. | ||
/// | ||
/// [OracleReader]: kona_preimage::OracleReader | ||
#[derive(Debug, Clone)] | ||
pub struct CachingOracle<const N: usize> { | ||
/// The spin-locked cache that stores the responses from the oracle. | ||
cache: Arc<Mutex<LruCache<PreimageKey, Vec<u8>>>>, | ||
} | ||
|
||
impl<const N: usize> CachingOracle<N> { | ||
/// Creates a new [CachingOracle] that wraps the given [OracleReader] and stores up to `N` | ||
/// responses in the cache. | ||
/// | ||
/// [OracleReader]: kona_preimage::OracleReader | ||
pub fn new() -> Self { | ||
Self { | ||
cache: Arc::new(Mutex::new(LruCache::new( | ||
NonZeroUsize::new(N).expect("N must be greater than 0"), | ||
))), | ||
} | ||
} | ||
} | ||
|
||
impl<const N: usize> Default for CachingOracle<N> { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl<const N: usize> PreimageOracleClient for CachingOracle<N> { | ||
async fn get(&self, key: PreimageKey) -> Result<Vec<u8>> { | ||
let mut cache_lock = self.cache.lock(); | ||
if let Some(value) = cache_lock.get(&key) { | ||
Ok(value.clone()) | ||
} else { | ||
let value = ORACLE_READER.get(key).await?; | ||
cache_lock.put(key, value.clone()); | ||
Ok(value) | ||
} | ||
} | ||
|
||
async fn get_exact(&self, key: PreimageKey, buf: &mut [u8]) -> Result<()> { | ||
let mut cache_lock = self.cache.lock(); | ||
if let Some(value) = cache_lock.get(&key) { | ||
// SAFETY: The value never enters the cache unless the preimage length matches the | ||
// buffer length, due to the checks in the OracleReader. | ||
buf.copy_from_slice(value.as_slice()); | ||
Ok(()) | ||
} else { | ||
ORACLE_READER.get_exact(key, buf).await?; | ||
cache_lock.put(key, buf.to_vec()); | ||
Ok(()) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//! Contains the host <-> client communication utilities. | ||
use kona_common::FileDescriptor; | ||
use kona_preimage::{HintWriter, OracleReader, PipeHandle}; | ||
|
||
mod caching_oracle; | ||
pub use caching_oracle::CachingOracle; | ||
|
||
/// The global preimage oracle reader pipe. | ||
static ORACLE_READER_PIPE: PipeHandle = | ||
PipeHandle::new(FileDescriptor::PreimageRead, FileDescriptor::PreimageWrite); | ||
|
||
/// The global hint writer pipe. | ||
static HINT_WRITER_PIPE: PipeHandle = | ||
PipeHandle::new(FileDescriptor::HintRead, FileDescriptor::HintWrite); | ||
|
||
/// The global preimage oracle reader. | ||
pub static ORACLE_READER: OracleReader = OracleReader::new(ORACLE_READER_PIPE); | ||
|
||
/// The global hint writer. | ||
pub static HINT_WRITER: HintWriter = HintWriter::new(HINT_WRITER_PIPE); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
//! Contains the EVM executor and its associated types. | ||
// TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#![doc = include_str!("../README.md")] | ||
#![warn(missing_debug_implementations, missing_docs, unreachable_pub, rustdoc::all)] | ||
#![deny(unused_must_use, rust_2018_idioms)] | ||
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] | ||
#![no_std] | ||
|
||
extern crate alloc; | ||
|
||
mod executor; | ||
|
||
mod comms; | ||
pub use comms::{CachingOracle, HINT_WRITER, ORACLE_READER}; | ||
|
||
mod boot; | ||
pub use boot::{ | ||
BootInfo, L1_HEAD_KEY, L2_CHAIN_CONFIG_KEY, L2_CHAIN_ID_KEY, L2_CLAIM_BLOCK_NUMBER_KEY, | ||
L2_CLAIM_KEY, L2_OUTPUT_ROOT_KEY, L2_ROLLUP_CONFIG_KEY, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,22 @@ | ||
#![doc = include_str!("../README.md")] | ||
#![warn(missing_debug_implementations, missing_docs, unreachable_pub, rustdoc::all)] | ||
#![deny(unused_must_use, rust_2018_idioms)] | ||
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] | ||
#![no_std] | ||
#![cfg_attr(any(target_arch = "mips", target_arch = "riscv64"), no_main)] | ||
|
||
use kona_client::{BootInfo, CachingOracle}; | ||
use kona_common::io; | ||
use kona_common_proc::client_entry; | ||
|
||
extern crate alloc; | ||
|
||
#[client_entry(0x77359400)] | ||
fn main() { | ||
io::print("Hello, world!\n"); | ||
fn main() -> Result<()> { | ||
kona_common::block_on(async move { | ||
let caching_oracle = CachingOracle::<16>::new(); | ||
let boot = BootInfo::load(&caching_oracle).await?; | ||
io::print(&alloc::format!("{:?}\n", boot)); | ||
Ok(()) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.