Skip to content

Commit

Permalink
feat(client): Derivation integration (#257)
Browse files Browse the repository at this point in the history
* feat(client): Derivation integration

Adds the `DerivationDriver` to the client program.

* andreas review
  • Loading branch information
clabby authored Jun 16, 2024
1 parent d1a3f08 commit 49a9d9c
Show file tree
Hide file tree
Showing 20 changed files with 470 additions and 69 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 21 additions & 10 deletions bin/host/src/fetcher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use kona_derive::{
use kona_preimage::{PreimageKey, PreimageKeyType};
use std::sync::Arc;
use tokio::sync::RwLock;
use tracing::debug;
use tracing::trace;

mod precompiles;

Expand Down Expand Up @@ -58,13 +58,13 @@ where

/// Set the last hint to be received.
pub fn hint(&mut self, hint: &str) {
debug!(target: "fetcher", "Received hint: {hint}");
trace!(target: "fetcher", "Received hint: {hint}");
self.last_hint = Some(hint.to_string());
}

/// Get the preimage for the given key.
pub async fn get_preimage(&self, key: B256) -> Result<Vec<u8>> {
debug!(target: "fetcher", "Pre-image requested. Key: {key}");
trace!(target: "fetcher", "Pre-image requested. Key: {key}");

// Acquire a read lock on the key-value store.
let kv_lock = self.kv_store.read().await;
Expand All @@ -88,7 +88,7 @@ where
/// Fetch the preimage for the given hint and insert it into the key-value store.
async fn prefetch(&self, hint: &str) -> Result<()> {
let (hint_type, hint_data) = util::parse_hint(hint)?;
debug!(target: "fetcher", "Fetching hint: {hint_type} {hint_data}");
trace!(target: "fetcher", "Fetching hint: {hint_type} {hint_data}");

match hint_type {
HintType::L1BlockHeader => {
Expand Down Expand Up @@ -349,14 +349,15 @@ where
};

let mut kv_write_lock = self.kv_store.write().await;
kv_write_lock.set(hash, code.into());
kv_write_lock
.set(PreimageKey::new(*hash, PreimageKeyType::Keccak256).into(), code.into());
}
HintType::StartingL2Output => {
const OUTPUT_ROOT_VERSION: u8 = 0;
const L2_TO_L1_MESSAGE_PASSER_ADDRESS: Address =
address!("4200000000000000000000000000000000000016");

if !hint_data.is_empty() {
if hint_data.len() != 32 {
anyhow::bail!("Invalid hint data length: {}", hint_data.len());
}

Expand Down Expand Up @@ -388,8 +389,15 @@ where
raw_output[96..128].copy_from_slice(self.l2_head.as_ref());
let output_root = keccak256(raw_output);

if output_root.as_slice() != hint_data.as_ref() {
anyhow::bail!("Output root does not match L2 head.");
}

let mut kv_write_lock = self.kv_store.write().await;
kv_write_lock.set(output_root, raw_output.into());
kv_write_lock.set(
PreimageKey::new(*output_root, PreimageKeyType::Keccak256).into(),
raw_output.into(),
);
}
HintType::L2StateNode => {
if hint_data.len() != 32 {
Expand All @@ -410,7 +418,10 @@ where
.map_err(|e| anyhow!("Failed to fetch preimage: {e}"))?;

let mut kv_write_lock = self.kv_store.write().await;
kv_write_lock.set(hash, preimage.into());
kv_write_lock.set(
PreimageKey::new(*hash, PreimageKeyType::Keccak256).into(),
preimage.into(),
);
}
HintType::L2AccountProof => {
if hint_data.len() != 8 + 20 {
Expand All @@ -422,7 +433,7 @@ where
.try_into()
.map_err(|e| anyhow!("Error converting hint data to u64: {e}"))?,
);
let address = Address::from_slice(&hint_data.as_ref()[8..]);
let address = Address::from_slice(&hint_data.as_ref()[8..28]);

let proof_response = self
.l2_provider
Expand All @@ -449,7 +460,7 @@ where
.try_into()
.map_err(|e| anyhow!("Error converting hint data to u64: {e}"))?,
);
let address = Address::from_slice(&hint_data.as_ref()[8..]);
let address = Address::from_slice(&hint_data.as_ref()[8..28]);
let slot = B256::from_slice(&hint_data.as_ref()[28..]);

let mut proof_response = self
Expand Down
2 changes: 1 addition & 1 deletion bin/host/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ mod server;
mod types;
mod util;

#[tokio::main]
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> {
let cfg = HostCli::parse();
init_tracing_subscriber(cfg.v)?;
Expand Down
11 changes: 7 additions & 4 deletions bin/host/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use anyhow::{anyhow, Result};
use kona_preimage::{HintReaderServer, PreimageKey, PreimageOracleServer};
use std::{future::Future, pin::Pin, sync::Arc};
use tokio::sync::RwLock;
use tracing::debug;
use tracing::trace;

/// The [PreimageServer] is responsible for waiting for incoming preimage requests and
/// serving them to the client.
Expand Down Expand Up @@ -47,8 +47,11 @@ where
/// Starts the [PreimageServer] and waits for incoming requests.
pub async fn start(self) -> Result<()> {
// Create the futures for the oracle server and hint router.
let server_fut =
Self::start_oracle_server(self.kv_store, self.fetcher.clone(), self.oracle_server);
let server_fut = Self::start_oracle_server(
self.kv_store.clone(),
self.fetcher.clone(),
self.oracle_server,
);
let hinter_fut = Self::start_hint_router(self.hint_reader, self.fetcher);

// Spawn tasks for the futures and wait for them to complete.
Expand Down Expand Up @@ -110,7 +113,7 @@ where
})
} else {
Box::pin(async move {
debug!(target: "preimage_server", "Received hint in offline mode: {}", &hint);
trace!(target: "preimage_server", "Received hint in offline mode: {}", &hint);
Ok(())
})
}
Expand Down
6 changes: 4 additions & 2 deletions bin/host/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use kona_common::FileDescriptor;
use kona_preimage::PipeHandle;
use reqwest::Client;
use std::{fs::File, os::fd::AsRawFd};
use tempfile::tempfile;
use tokio::task::JoinHandle;

/// Parses a hint from a string.
Expand All @@ -34,7 +33,10 @@ pub(crate) fn parse_hint(s: &str) -> Result<(HintType, Bytes)> {

/// Creates two temporary files that are connected by a pipe.
pub(crate) fn create_temp_files() -> Result<(File, File)> {
let (read, write) = (tempfile().map_err(|e| anyhow!(e))?, tempfile().map_err(|e| anyhow!(e))?);
let (read, write) = (
tempfile::tempfile().map_err(|e| anyhow!(e))?,
tempfile::tempfile().map_err(|e| anyhow!(e))?,
);
Ok((read, write))
}

Expand Down
8 changes: 7 additions & 1 deletion bin/programs/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,21 @@ revm = { workspace = true, features = ["optimism"] }
lru.workspace = true
spin.workspace = true
async-trait.workspace = true
tracing.workspace = true

# local
kona-common = { path = "../../../crates/common", version = "0.0.1" }
kona-common-proc = { path = "../../../crates/common-proc", version = "0.0.1" }
kona-preimage = { path = "../../../crates/preimage", version = "0.0.1" }
kona-primitives = { path = "../../../crates/primitives", version = "0.0.1" }
kona-mpt = { path = "../../../crates/mpt", version = "0.0.1" }
kona-derive = { path = "../../../crates/derive", version = "0.0.1" }
kona-derive = { path = "../../../crates/derive", default-features = false, version = "0.0.1" }

tracing-subscriber = { version = "0.3.18", optional = true }

[dev-dependencies]
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.117"

[features]
tracing-subscriber = ["dep:tracing-subscriber"]
4 changes: 2 additions & 2 deletions bin/programs/client/src/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub enum HintType {
impl HintType {
/// Encodes the hint type as a string.
pub fn encode_with(&self, data: &[&[u8]]) -> String {
let concatenated = data.iter().map(hex::encode).collect::<Vec<_>>().join(" ");
let concatenated = hex::encode(data.iter().copied().flatten().copied().collect::<Vec<_>>());
alloc::format!("{} {}", self, concatenated)
}
}
Expand All @@ -55,7 +55,7 @@ impl TryFrom<&str> for HintType {
"l2-block-header" => Ok(HintType::L2BlockHeader),
"l2-transactions" => Ok(HintType::L2Transactions),
"l2-code" => Ok(HintType::L2Code),
"l2-output" => Ok(HintType::StartingL2Output),
"starting-l2-output" => Ok(HintType::StartingL2Output),
"l2-state-node" => Ok(HintType::L2StateNode),
"l2-account-proof" => Ok(HintType::L2AccountProof),
"l2-account-storage-proof" => Ok(HintType::L2AccountStorageProof),
Expand Down
4 changes: 3 additions & 1 deletion bin/programs/client/src/l1/blob_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use kona_preimage::{HintWriterClient, PreimageKey, PreimageKeyType, PreimageOrac
use kona_primitives::BlockInfo;

/// An oracle-backed blob provider.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct OracleBlobProvider {
oracle: Arc<CachingOracle>,
}
Expand Down Expand Up @@ -70,6 +70,8 @@ impl OracleBlobProvider {
blob[(i as usize) << 5..(i as usize + 1) << 5].copy_from_slice(field_element.as_ref());
}

tracing::info!(target: "client_oracle", "Retrieved blob {blob_hash:?} from the oracle.");

Ok(blob)
}
}
Expand Down
2 changes: 1 addition & 1 deletion bin/programs/client/src/l1/chain_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use kona_preimage::{HintWriterClient, PreimageKey, PreimageKeyType, PreimageOrac
use kona_primitives::BlockInfo;

/// The oracle-backed L1 chain provider for the client program.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct OracleL1ChainProvider {
/// The boot information
boot_info: Arc<BootInfo>,
Expand Down
Loading

0 comments on commit 49a9d9c

Please sign in to comment.