Skip to content

Commit

Permalink
refactor host Taiko API
Browse files Browse the repository at this point in the history
  • Loading branch information
CeciliaZ030 committed Feb 9, 2024
1 parent ef4172f commit f87ffd7
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 11 deletions.
3 changes: 2 additions & 1 deletion lib/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ pub static TKO_MAINNET_CHAIN_SPEC: Lazy<ChainSpec> = Lazy::new(|| {
}
});


#[cfg(feature = "taiko")]
pub use crate::taiko::consts::testnet::*;

/// The Optimism mainnet specification.
#[cfg(feature = "optimism")]
Expand Down
37 changes: 37 additions & 0 deletions lib/src/host/provider/cached_rpc_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,41 @@ impl Provider for CachedRpcProvider {

Ok(out)
}

#[cfg(feature = "taiko")]
fn get_logs(&mut self, query: &LogsQuery) -> Result<Vec<Log>> {
let cache_out = self.cache.get_logs(query);
if cache_out.is_ok() {
return cache_out;
}

let out = self.rpc.get_logs(query)?;
self.cache.insert_logs(query.clone(), out);

Ok(out)
}

#[cfg(feature = "taiko")]
fn get_transaction(&mut self, query: &super::TxQuery) -> Result<Transaction> {
let mut cache_out = self.cache.get_transaction(query);
if cache_out.is_ok() {
return cache_out;
}

// Search cached block for target Tx
let cache_block_out = self.cache
.get_full_block(&BlockQuery {block_no: query.block_no})
.map(|b| b.transactions.iter().filter(|tx| tx.hash == query.tx_hash).collect::<Vec<_>>())
.map(|txs| txs.pop());
if let Ok(tx_op) = cache_block_out {
if let Some(tx) = tx_op {
return Ok(tx)
}
}

let out = self.rpc.get_transaction(query)?;
self.cache.insert_transaction(query.clone(), out);

Ok(out)
}
}
46 changes: 44 additions & 2 deletions lib/src/host/provider/file_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ use std::{
path::{Path, PathBuf},
};

use ethers_core::types::Log;
use anyhow::{anyhow, Result};
use ethers_core::types::{
use ethers_core::{abi::Hash, types::{
Block, Bytes, EIP1186ProofResponse, Transaction, TransactionReceipt, H256, U256,
};
}};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;

use super::{AccountQuery, BlockQuery, MutProvider, ProofQuery, Provider, StorageQuery};
#[cfg(feature = "taiko")]
use super::{LogsQuery, TxQuery};

#[serde_as]
#[derive(Deserialize, Serialize)]
Expand All @@ -52,6 +55,13 @@ pub struct FileProvider {
code: HashMap<AccountQuery, Bytes>,
#[serde_as(as = "Vec<(_, _)>")]
storage: HashMap<StorageQuery, H256>,

#[cfg(feature = "taiko")]
#[serde_as(as = "Vec<(_, _)>")]
logs: HashMap<LogsQuery, Vec<Log>>,
#[cfg(feature = "taiko")]
#[serde_as(as = "Vec<(_, _)>")]
transactions: HashMap<TxQuery, Transaction>,
}

impl FileProvider {
Expand All @@ -67,6 +77,10 @@ impl FileProvider {
balance: HashMap::new(),
code: HashMap::new(),
storage: HashMap::new(),
#[cfg(feature = "taiko")]
logs: HashMap::new(),
#[cfg(feature = "taiko")]
transactions: HashMap::new(),
}
}

Expand Down Expand Up @@ -156,6 +170,22 @@ impl Provider for FileProvider {
None => Err(anyhow!("No data for {:?}", query)),
}
}

#[cfg(feature = "taiko")]
fn get_logs(&mut self, query: &LogsQuery) -> Result<Vec<Log>> {
match self.logs.get(query) {
Some(val) => Ok(val.clone()),
None => Err(anyhow!("No data for {:?}", query)),
}
}

#[cfg(feature = "taiko")]
fn get_transaction(&mut self, query: &TxQuery) -> Result<Transaction> {
match self.transactions.get(query) {
Some(val) => Ok(val.clone()),
None => Err(anyhow!("No data for {:?}", query)),
}
}
}

impl MutProvider for FileProvider {
Expand Down Expand Up @@ -198,4 +228,16 @@ impl MutProvider for FileProvider {
self.storage.insert(query, val);
self.dirty = true;
}

#[cfg(feature = "taiko")]
fn insert_logs(&mut self, query: LogsQuery, val: Vec<Log>) {
self.storage.insert(query, val);
self.dirty = true;
}

#[cfg(feature = "taiko")]
fn insert_transaction(&mut self, query: super::TxQuery, val: Transaction) {
self.transaction.insert(query, val);
self.dirty = true;
}
}
78 changes: 77 additions & 1 deletion lib/src/host/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@

use std::{collections::BTreeSet, path::PathBuf};

use alloy_primitives::TxHash;
use ethers_core::types::{Log, H256};
use alloy_sol_types::{sol_data::Uint, SolEvent};
use anyhow::{anyhow, Context, Result};
use ethers_core::types::{
Block, Bytes, EIP1186ProofResponse, Transaction, TransactionReceipt, H160, H256, U256,
Block, Bytes, EIP1186ProofResponse, Transaction, TransactionReceipt, H160, U256,
};
use serde::{Deserialize, Serialize};
#[cfg(feature = "taiko")]
use crate::taiko::BlockProposed;

pub mod cached_rpc_provider;
pub mod file_provider;
Expand Down Expand Up @@ -49,6 +54,21 @@ pub struct StorageQuery {
pub index: H256,
}

#[cfg(feature = "taiko")]
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct LogsQuery {
pub address: H160,
pub from_block: u64,
pub to_block: u64,
}

#[cfg(feature = "taiko")]
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct TxQuery {
pub tx_hash: H256,
pub block_no: Option<u64>,
}

pub trait Provider: Send {
fn save(&self) -> Result<()>;

Expand All @@ -60,6 +80,10 @@ pub trait Provider: Send {
fn get_balance(&mut self, query: &AccountQuery) -> Result<U256>;
fn get_code(&mut self, query: &AccountQuery) -> Result<Bytes>;
fn get_storage(&mut self, query: &StorageQuery) -> Result<H256>;
#[cfg(feature = "taiko")]
fn get_logs(&mut self, query: &LogsQuery) -> Result<Vec<Log>>;
#[cfg(feature = "taiko")]
fn get_transaction(&mut self, query: &TxQuery) -> Result<Transaction>;
}

pub trait MutProvider: Provider {
Expand All @@ -71,6 +95,10 @@ pub trait MutProvider: Provider {
fn insert_balance(&mut self, query: AccountQuery, val: U256);
fn insert_code(&mut self, query: AccountQuery, val: Bytes);
fn insert_storage(&mut self, query: StorageQuery, val: H256);
#[cfg(feature = "taiko")]
fn insert_logs(&mut self, query: LogsQuery, val: Vec<Log>);
#[cfg(feature = "taiko")]
fn insert_transaction(&mut self, query: TxQuery, val: Transaction);
}

pub fn new_file_provider(file_path: PathBuf) -> Result<Box<dyn Provider>> {
Expand Down Expand Up @@ -103,3 +131,51 @@ pub fn new_provider(
(None, None) => Err(anyhow!("No cache_path or rpc_url given")),
}
}


use alloy_sol_types::{TopicList};
use zeth_primitives::ethers::from_ethers_h256;

#[cfg(feature = "taiko")]
impl dyn Provider {
fn filter_block_proposal(
&mut self,
l1_contract: H160,
l1_block_no: u64,
l2_block_no: u64,
) -> Result<(Transaction, BlockProposed)>{
let logs = self.get_logs(
&LogsQuery {
address: l1_contract,
from_block: l1_block_no,
to_block: l1_block_no,
}
)?;
let res = logs
.iter()
.filter(|log| log.topics().len() == <<BlockProposed as SolEvent>::TopicList as TopicList>::COUNT)
.filter(|log| from_ethers_h256(log.topics()[0]) == BlockProposed::SIGNATURE_HASH)
.map(|log| {
let block_proposed = <BlockProposed as SolEvent>::decode_log(
alloy_primitives::Log {address: log.address, data: log.data },
true
)
.with_context(|| anyhow!("Decode log failed for l1_block_no {}", l1_block_no))?;
(log.block_number, log.transaction_hash, block_proposed)
})
.filter(|(block_no, tx_hash, event)| event.blockId == revm::primitives::U256::from(l2_block_no))
.collect::<Vec<_>>();

let (block_no, tx_hash, event) = res.pop()
.with_context(|| anyhow!("Cannot find BlockProposed event for {}" l2_block_no))?;

let tx = self
.get_transaction(& TxQuery {
tx_hash: tx_hash.unwrap(),
block_no: block_no.map(|b| b.as_u64())
})
.with_context(|| anyhow!("Cannot find BlockProposed Tx {:?}", tx_hash))?;

Ok((tx, event.data))
}
}
27 changes: 26 additions & 1 deletion lib/src/host/provider/rpc_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use anyhow::{anyhow, Result};
use ethers_core::types::{
Block, Bytes, EIP1186ProofResponse, Transaction, TransactionReceipt, H256, U256,
Block, Bytes, EIP1186ProofResponse, Filter, Transaction, TransactionReceipt, H256, U256
};
use ethers_providers::{Http, Middleware, RetryClient};
use log::info;
Expand Down Expand Up @@ -143,4 +143,29 @@ impl Provider for RpcProvider {

Ok(out)
}

#[cfg(feature = "taiko")]
fn get_logs(&mut self, query: &LogsQuery) -> Result<Vec<Log>> {
info!("Querying RPC for logs: {:?}", query);

let out = self.tokio_handle.block_on(async {
self.http_client
.get_logs(&Filter::new().address(query.l1_contract).from_block(query.l1_block_no).to_block(query.l1_block_no))
.await
})?;

Ok(out)
}

#[cfg(feature = "taiko")]
fn get_transaction(&mut self, query: &super::TxQuery) -> Result<Transaction> {
info!("Querying RPC for tx: {:?}", query);
let out = self.tokio_handle.block_on(async {
self.http_client
.get_transaction(query.tx_hash)
.await
})?;

Ok(out)
}
}
2 changes: 2 additions & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub mod consts;
pub mod input;
pub mod mem_db;
pub mod optimism;

#[cfg(feature = "taiko")]
pub mod taiko;

mod utils;
Expand Down
12 changes: 6 additions & 6 deletions lib/src/taiko/protocol_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use alloy_sol_types::SolValue;
use anyhow::{Result, anyhow};
use alloy_primitives::{Address, TxHash, B256};
use revm::primitives::SpecId;
use serde_json::to_string;
use zeth_primitives::{block::Header, ethers::{from_ethers_h256, from_ethers_u256}, keccak::keccak, transactions::EthereumTransaction};
use crate::consts::TKO_MAINNET_CHAIN_SPEC;

Expand Down Expand Up @@ -105,7 +106,7 @@ pub fn assemble_protocol_instance(sys: &TaikoSystemInfo, header: &Header) -> Res
},
prover: sys.prover,
};
verify(header, &mut pi, sys)?;
verify(sys, header, &mut pi)?;
Ok(pi)
}

Expand All @@ -119,8 +120,7 @@ pub fn verify(sys: &TaikoSystemInfo, header: &Header, pi: &mut ProtocolInstance)
pi.block_metadata
));
}
// println!("Protocol instance Transition: {:?}", pi.transition);
// check the block hash
// Check the block hash
if Some(header.hash()) != sys.l2_fini_block.hash.map(from_ethers_h256) {
let txs: Vec<EthereumTransaction> = sys
.l2_fini_block
Expand All @@ -129,9 +129,9 @@ pub fn verify(sys: &TaikoSystemInfo, header: &Header, pi: &mut ProtocolInstance)
.filter_map(|tx| tx.clone().try_into().ok())
.collect();
return Err(anyhow!(
"block hash mismatch, expected: {}, got: {}",
to_string(&txs).unwrap_or_default(),
to_string(&header.transactions).unwrap_or_default(),
"block hash mismatch, expected: {}, got: {}",
header.hash(),
sys.l2_fini_block.hash.map(from_ethers_h256).unwrap()
));
}

Expand Down
2 changes: 2 additions & 0 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,7 @@ hex-literal = "0.4"
serde_json = "1.0"

[features]
default = ["taiko"]
taiko = []
ethers = ["dep:ethers-core"]
revm = ["dep:revm-primitives"]

0 comments on commit f87ffd7

Please sign in to comment.