Skip to content

Commit

Permalink
some cleanup & add usage in README
Browse files Browse the repository at this point in the history
  • Loading branch information
eshaan7 committed Feb 18, 2025
1 parent 85488e7 commit 3b5d425
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 50 deletions.
61 changes: 30 additions & 31 deletions core/src/execution/verified_client/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,23 +193,30 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>, A: VerifiableApi<N>> VerifiableMethodsA
logs: &[Log],
receipt_proofs: HashMap<B256, TransactionReceiptResponse<N>>,
) -> Result<()> {
// Map of tx_hash -> encoded receipt logs to avoid encoding multiple times
let mut txhash_encodedlogs_map: HashMap<B256, Vec<Vec<u8>>> = HashMap::new();

// Verify each log entry exists in the corresponding receipt logs
for log in logs {
let tx_hash = log.transaction_hash.unwrap();
let log_encoded = rlp::encode(&log.inner);

if !txhash_encodedlogs_map.contains_key(&tx_hash) {

Check failure on line 204 in core/src/execution/verified_client/api.rs

View workflow job for this annotation

GitHub Actions / clippy

usage of `contains_key` followed by `insert` on a `HashMap`
let TransactionReceiptResponse {
receipt,
receipt_proof: _,
} = receipt_proofs
.get(&tx_hash)
.ok_or(ExecutionError::NoReceiptForTransaction(tx_hash))?;
let encoded_logs = N::receipt_logs(receipt)
.iter()
.map(|l| rlp::encode(&l.inner))
.collect::<Vec<_>>();
txhash_encodedlogs_map.insert(tx_hash, encoded_logs);
}
let receipt_logs_encoded = txhash_encodedlogs_map.get(&tx_hash).unwrap();

let TransactionReceiptResponse {
receipt,
receipt_proof: _,
} = receipt_proofs
.get(&tx_hash)
.ok_or(ExecutionError::NoReceiptForTransaction(tx_hash))?;

let encoded_log = rlp::encode(&log.inner);

if !N::receipt_logs(receipt)
.into_iter()
.map(|l| rlp::encode(&l.inner))
.any(|el| el == encoded_log)
{
if !receipt_logs_encoded.contains(&log_encoded) {
return Err(ExecutionError::MissingLog(
tx_hash,
U256::from(log.log_index.unwrap()),
Expand All @@ -218,6 +225,7 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>, A: VerifiableApi<N>> VerifiableMethodsA
}
}

// Verify all receipts
self.verify_receipt_proofs(&receipt_proofs.values().collect::<Vec<_>>())
.await?;

Expand All @@ -228,28 +236,19 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>, A: VerifiableApi<N>> VerifiableMethodsA
&self,
receipt_proofs: &[&TransactionReceiptResponse<N>],
) -> Result<()> {
let mut blocks: HashMap<u64, N::BlockResponse> = HashMap::new();

for TransactionReceiptResponse {
receipt,
receipt_proof,
} in receipt_proofs
{
let block_num = receipt.block_number().unwrap();
let block = if let Some(block) = blocks.get(&block_num) {
block.clone()
} else {
let tag = BlockTag::Number(block_num);
let block = self
.state
.get_block(tag)
.await
.ok_or(ExecutionError::BlockNotFound(tag))?;
blocks.insert(block_num, block.clone());
block
};

verify_receipt_proof::<N>(receipt, block.header().receipts_root(), receipt_proof)
let tag = BlockTag::Number(receipt.block_number().unwrap());
let receipts_root = self
.state
.get_receipts_root(tag)
.await
.ok_or(ExecutionError::BlockNotFound(tag))?;

verify_receipt_proof::<N>(receipt, receipts_root, receipt_proof)
.map_err(|_| ExecutionError::ReceiptRootMismatch(receipt.transaction_hash()))?;
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/execution/verified_client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub enum VerifiableMethodsClient<N: NetworkSpec, R: ExecutionRpc<N>, A: Verifiab
}

impl<N: NetworkSpec, R: ExecutionRpc<N>, A: VerifiableApi<N>> VerifiableMethodsClient<N, R, A> {
// Manual dispatch
// manual dynamic dispatch
pub fn client(&self) -> &dyn VerifiableMethods<N, R> {
match self {
VerifiableMethodsClient::Api(client) => client,
Expand Down
3 changes: 1 addition & 2 deletions core/src/execution/verified_client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>> VerifiableMethods<N, R> for VerifiableM
let mut account_map = HashMap::new();
for chunk in list.chunks(PARALLEL_QUERY_BATCH_SIZE) {
let account_chunk_futs = chunk.iter().map(|account| {
// ToDo(@eshaan7): block is fetched from state each iteration, can be optimized
let account_fut =
self.get_account(account.address, Some(account.storage_keys.as_slice()), tag);
async move { (account.address, account_fut.await) }
Expand Down Expand Up @@ -246,7 +245,7 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>> VerifiableMethodsRpc<N, R> {
.iter()
.map(|log| {
log.block_number
.ok_or_else(|| eyre::eyre!("block num not found in log"))
.ok_or_else(|| eyre::eyre!("block number not found in log"))
})
.collect::<Result<HashSet<_>, _>>()?;

Expand Down
25 changes: 25 additions & 0 deletions verifiable-api/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# helios-verifiable-api

## Usage

```bash
$ cargo run -- --help
Usage: server [OPTIONS] --execution-rpc <EXECUTION_RPC>

Options:
-s, --server-address <SERVER_ADDRESS> [default: 127.0.0.1:4000]
-n, --network <NETWORK> [default: ethereum]
-e, --execution-rpc <EXECUTION_RPC>
-h, --help Print help
```

#### Ethereum

```bash
$ cargo run -- --network ethereum --execution-rpc https://ethereum-rpc.publicnode.com
```

#### OP Stack (Base)

```bash
$ cargo run -- --network opstack --execution-rpc https://base-rpc.publicnode.com
```

## JSON-RPC to REST API map

| Ethereum JSON-RPC Method | Helios Verifiable API Endpoint |
Expand Down
2 changes: 1 addition & 1 deletion verifiable-api/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use helios_verifiable_api_types::*;
pub use helios_verifiable_api_types as types;

#[async_trait]
pub trait VerifiableApi<N: NetworkSpec>: Send + Clone + Sync {
pub trait VerifiableApi<N: NetworkSpec>: Clone + Send + Sync {
fn new(base_url: &str) -> Self
where
Self: Sized;
Expand Down
16 changes: 2 additions & 14 deletions verifiable-api/server/bin/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,7 @@ pub async fn get_account<N: NetworkSpec, R: ExecutionRpc<N>>(
.get_block_by_number(tag, BlockTransactionsKind::Hashes)
.await
.map_err(map_server_err)?
.ok_or_else(|| {
(
StatusCode::INTERNAL_SERVER_ERROR,
json_err("Block not found"),
)
})
.ok_or_else(|| (StatusCode::BAD_REQUEST, json_err("Block not found")))
.map(|block| block.header().number()),
},
BlockId::Hash(hash) => rpc
Expand Down Expand Up @@ -312,12 +307,7 @@ pub async fn create_access_list<N: NetworkSpec, R: ExecutionRpc<N>>(
.get_block_by_number(number_or_tag, BlockTransactionsKind::Hashes)
.await
.map_err(map_server_err)?
.ok_or_else(|| {
(
StatusCode::INTERNAL_SERVER_ERROR,
json_err("Block not found"),
)
}),
.ok_or_else(|| (StatusCode::BAD_REQUEST, json_err("Block not found"))),
BlockId::Hash(hash) => rpc.get_block(hash.into()).await.map_err(map_server_err),
}?;
let block_id = BlockId::Number(block.header().number().into());
Expand Down Expand Up @@ -387,8 +377,6 @@ async fn create_receipt_proofs_for_logs<N: NetworkSpec, R: ExecutionRpc<N>>(
rpc: Arc<R>,
) -> Result<HashMap<B256, TransactionReceiptResponse<N>>> {
// Collect all (unique) block numbers
// ToDo(@eshaan7): Might need to put a max limit on the number of blocks
// otherwise this could make too many requests and slow down the server
let block_nums = logs
.iter()
.map(|log| log.block_number.ok_or_eyre("block_number not found in log"))
Expand Down
2 changes: 1 addition & 1 deletion verifiable-api/server/bin/server.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use std::{net::SocketAddr, str::FromStr};

use clap::Parser;
use router::build_router;
use tracing_subscriber::{EnvFilter, FmtSubscriber};
use url::Url;

use helios_core::execution::rpc::http_rpc::HttpRpc;
use helios_ethereum::spec::Ethereum as EthereumSpec;
use helios_opstack::spec::OpStack as OpStackSpec;

use crate::router::build_router;
use crate::state::ApiState;

mod handlers;
Expand Down

0 comments on commit 3b5d425

Please sign in to comment.