Skip to content

Commit

Permalink
refactor: migrate to alloy block types (alloy) (#492)
Browse files Browse the repository at this point in the history
* chore: Block type migrated to BlockResponse from Network trait (alloy)

* chore: new hash_block method added on network trait + ethreum and opstack crate updated

* chore: hash_block replaced with is_hash_valid in network spec to implement extra checks on the block
  • Loading branch information
Dhruv-2003 authored Jan 22, 2025
1 parent f2a90ba commit 552bc95
Show file tree
Hide file tree
Showing 20 changed files with 371 additions and 347 deletions.
8 changes: 2 additions & 6 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,14 @@ fn enable_tracer() {
tracing::subscriber::set_global_default(subscriber).expect("subscriber set failed");
}

async fn start_client<N: NetworkSpec, C: Consensus<N::TransactionResponse>>(
client: &mut Client<N, C>,
) {
async fn start_client<N: NetworkSpec, C: Consensus<N::BlockResponse>>(client: &mut Client<N, C>) {
if let Err(err) = client.start().await {
error!(target: "helios::runner", error = %err);
exit(1);
}
}

fn register_shutdown_handler<N: NetworkSpec, C: Consensus<N::TransactionResponse>>(
client: Client<N, C>,
) {
fn register_shutdown_handler<N: NetworkSpec, C: Consensus<N::BlockResponse>>(client: Client<N, C>) {
let client = Arc::new(client);
let shutdown_counter = Arc::new(Mutex::new(0));

Expand Down
10 changes: 5 additions & 5 deletions core/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ use crate::client::rpc::Rpc;
use crate::consensus::Consensus;
use crate::network_spec::NetworkSpec;
use crate::time::interval;
use crate::types::{Block, BlockTag};
use crate::types::BlockTag;

pub mod node;
#[cfg(not(target_arch = "wasm32"))]
pub mod rpc;

pub struct Client<N: NetworkSpec, C: Consensus<N::TransactionResponse>> {
pub struct Client<N: NetworkSpec, C: Consensus<N::BlockResponse>> {
node: Arc<Node<N, C>>,
#[cfg(not(target_arch = "wasm32"))]
rpc: Option<Rpc<N, C>>,
}

impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Client<N, C> {
impl<N: NetworkSpec, C: Consensus<N::BlockResponse>> Client<N, C> {
pub fn new(
execution_rpc: &str,
consensus: C,
Expand Down Expand Up @@ -179,15 +179,15 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Client<N, C> {
&self,
block: BlockTag,
full_tx: bool,
) -> Result<Option<Block<N::TransactionResponse>>> {
) -> Result<Option<N::BlockResponse>> {
self.node.get_block_by_number(block, full_tx).await
}

pub async fn get_block_by_hash(
&self,
hash: B256,
full_tx: bool,
) -> Result<Option<Block<N::TransactionResponse>>> {
) -> Result<Option<N::BlockResponse>> {
self.node.get_block_by_hash(hash, full_tx).await
}

Expand Down
30 changes: 16 additions & 14 deletions core/src/client/node.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::sync::Arc;

use alloy::consensus::BlockHeader;
use alloy::network::BlockResponse;
use alloy::primitives::{Address, Bytes, B256, U256};
use alloy::rpc::types::{Filter, FilterChanges, Log, SyncInfo, SyncStatus};
use eyre::{eyre, Result};
Expand All @@ -12,15 +14,15 @@ use crate::execution::state::State;
use crate::execution::ExecutionClient;
use crate::network_spec::NetworkSpec;
use crate::time::{SystemTime, UNIX_EPOCH};
use crate::types::{Block, BlockTag};
use crate::types::BlockTag;

pub struct Node<N: NetworkSpec, C: Consensus<N::TransactionResponse>> {
pub struct Node<N: NetworkSpec, C: Consensus<N::BlockResponse>> {
pub consensus: C,
pub execution: Arc<ExecutionClient<N, HttpRpc<N>>>,
pub history_size: usize,
}

impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Node<N, C> {
impl<N: NetworkSpec, C: Consensus<N::BlockResponse>> Node<N, C> {
pub fn new(execution_rpc: &str, mut consensus: C) -> Result<Self, ClientError> {
let block_recv = consensus.block_recv().take().unwrap();
let finalized_block_recv = consensus.finalized_block_recv().take().unwrap();
Expand Down Expand Up @@ -72,15 +74,15 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Node<N, C> {

pub async fn get_block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<u64>> {
let block = self.execution.get_block_by_hash(hash, false).await;
Ok(block.map(|block| block.transactions.hashes().len() as u64))
Ok(block.map(|block| block.transactions().hashes().len() as u64))
}

pub async fn get_block_transaction_count_by_number(
&self,
tag: BlockTag,
) -> Result<Option<u64>> {
let block = self.execution.get_block(tag, false).await;
Ok(block.map(|block| block.transactions.hashes().len() as u64))
Ok(block.map(|block| block.transactions().hashes().len() as u64))
}

pub async fn get_code(&self, address: Address, tag: BlockTag) -> Result<Bytes> {
Expand Down Expand Up @@ -199,9 +201,9 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Node<N, C> {
.get_block(BlockTag::Latest, false)
.await
.ok_or(eyre!(ClientError::BlockNotFound(BlockTag::Latest)))?;
let base_fee = block.base_fee_per_gas;
let tip = U256::from(10_u64.pow(9));
Ok(base_fee + tip)
let base_fee = block.header().base_fee_per_gas().unwrap_or(0_u64);
let tip = 10_u64.pow(9);
Ok(U256::from(base_fee + tip))
}

pub async fn blob_base_fee(&self, block: BlockTag) -> Result<U256> {
Expand All @@ -222,14 +224,14 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Node<N, C> {
.get_block(BlockTag::Latest, false)
.await
.ok_or(eyre!(ClientError::BlockNotFound(BlockTag::Latest)))?;
Ok(block.number.to())
Ok(U256::from(block.header().number()))
}

pub async fn get_block_by_number(
&self,
tag: BlockTag,
full_tx: bool,
) -> Result<Option<Block<N::TransactionResponse>>> {
) -> Result<Option<N::BlockResponse>> {
self.check_blocktag_age(&tag).await?;

let block = self.execution.get_block(tag, full_tx).await;
Expand All @@ -240,7 +242,7 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Node<N, C> {
&self,
hash: B256,
full_tx: bool,
) -> Result<Option<Block<N::TransactionResponse>>> {
) -> Result<Option<N::BlockResponse>> {
let block = self.execution.get_block_by_hash(hash, full_tx).await;
Ok(block)
}
Expand Down Expand Up @@ -274,7 +276,7 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Node<N, C> {
.await
.ok_or(eyre!(ClientError::BlockNotFound(BlockTag::Latest)))?;

Ok(block.miner)
Ok(block.header().beneficiary())
}

async fn check_head_age(&self) -> Result<(), ClientError> {
Expand All @@ -288,8 +290,8 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Node<N, C> {
.get_block(BlockTag::Latest, false)
.await
.ok_or_else(|| ClientError::OutOfSync(timestamp))?
.timestamp
.to();
.header()
.timestamp();

let delay = timestamp.checked_sub(block_timestamp).unwrap_or_default();
if delay > 60 {
Expand Down
44 changes: 27 additions & 17 deletions core/src/client/rpc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{fmt::Display, net::SocketAddr, sync::Arc};

use alloy::network::{ReceiptResponse, TransactionResponse};
use alloy::network::{BlockResponse, ReceiptResponse, TransactionResponse};
use alloy::primitives::{Address, Bytes, B256, U256, U64};
use alloy::rpc::json_rpc::RpcObject;
use alloy::rpc::types::{Filter, FilterChanges, Log, SyncStatus};
Expand All @@ -16,15 +16,15 @@ use tracing::info;
use crate::client::node::Node;
use crate::consensus::Consensus;
use crate::network_spec::NetworkSpec;
use crate::types::{Block, BlockTag};
use crate::types::BlockTag;

pub struct Rpc<N: NetworkSpec, C: Consensus<N::TransactionResponse>> {
pub struct Rpc<N: NetworkSpec, C: Consensus<N::BlockResponse>> {
node: Arc<Node<N, C>>,
handle: Option<ServerHandle>,
address: SocketAddr,
}

impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Rpc<N, C> {
impl<N: NetworkSpec, C: Consensus<N::BlockResponse>> Rpc<N, C> {
pub fn new(node: Arc<Node<N, C>>, address: SocketAddr) -> Self {
Rpc {
node,
Expand All @@ -49,7 +49,13 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Rpc<N, C> {
}

#[rpc(server, namespace = "eth")]
trait EthRpc<TX: TransactionResponse + RpcObject, TXR: RpcObject, R: ReceiptResponse + RpcObject> {
trait EthRpc<
TX: TransactionResponse + RpcObject,
TXR: RpcObject,
R: ReceiptResponse + RpcObject,
B: BlockResponse + RpcObject,
>
{
#[method(name = "getBalance")]
async fn get_balance(
&self,
Expand Down Expand Up @@ -93,13 +99,13 @@ trait EthRpc<TX: TransactionResponse + RpcObject, TXR: RpcObject, R: ReceiptResp
&self,
block: BlockTag,
full_tx: bool,
) -> Result<Option<Block<TX>>, ErrorObjectOwned>;
) -> Result<Option<B>, ErrorObjectOwned>;
#[method(name = "getBlockByHash")]
async fn get_block_by_hash(
&self,
hash: B256,
full_tx: bool,
) -> Result<Option<Block<TX>>, ErrorObjectOwned>;
) -> Result<Option<B>, ErrorObjectOwned>;
#[method(name = "sendRawTransaction")]
async fn send_raw_transaction(&self, bytes: Bytes) -> Result<B256, ErrorObjectOwned>;
#[method(name = "getTransactionReceipt")]
Expand Down Expand Up @@ -160,12 +166,12 @@ trait Web3Rpc {
async fn client_version(&self) -> Result<String, ErrorObjectOwned>;
}

struct RpcInner<N: NetworkSpec, C: Consensus<N::TransactionResponse>> {
struct RpcInner<N: NetworkSpec, C: Consensus<N::BlockResponse>> {
node: Arc<Node<N, C>>,
address: SocketAddr,
}

impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Clone for RpcInner<N, C> {
impl<N: NetworkSpec, C: Consensus<N::BlockResponse>> Clone for RpcInner<N, C> {
fn clone(&self) -> Self {
Self {
node: self.node.clone(),
Expand All @@ -175,9 +181,13 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Clone for RpcInner<N,
}

#[async_trait]
impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>>
EthRpcServer<N::TransactionResponse, N::TransactionRequest, N::ReceiptResponse>
for RpcInner<N, C>
impl<N: NetworkSpec, C: Consensus<N::BlockResponse>>
EthRpcServer<
N::TransactionResponse,
N::TransactionRequest,
N::ReceiptResponse,
N::BlockResponse,
> for RpcInner<N, C>
{
async fn get_balance(
&self,
Expand Down Expand Up @@ -261,15 +271,15 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>>
&self,
block: BlockTag,
full_tx: bool,
) -> Result<Option<Block<N::TransactionResponse>>, ErrorObjectOwned> {
) -> Result<Option<N::BlockResponse>, ErrorObjectOwned> {
convert_err(self.node.get_block_by_number(block, full_tx).await)
}

async fn get_block_by_hash(
&self,
hash: B256,
full_tx: bool,
) -> Result<Option<Block<N::TransactionResponse>>, ErrorObjectOwned> {
) -> Result<Option<N::BlockResponse>, ErrorObjectOwned> {
convert_err(self.node.get_block_by_hash(hash, full_tx).await)
}

Expand Down Expand Up @@ -368,20 +378,20 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>>
}

#[async_trait]
impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> NetRpcServer for RpcInner<N, C> {
impl<N: NetworkSpec, C: Consensus<N::BlockResponse>> NetRpcServer for RpcInner<N, C> {
async fn version(&self) -> Result<u64, ErrorObjectOwned> {
Ok(self.node.chain_id())
}
}

#[async_trait]
impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Web3RpcServer for RpcInner<N, C> {
impl<N: NetworkSpec, C: Consensus<N::BlockResponse>> Web3RpcServer for RpcInner<N, C> {
async fn client_version(&self) -> Result<String, ErrorObjectOwned> {
Ok(self.node.client_version().await)
}
}

async fn start<N: NetworkSpec, C: Consensus<N::TransactionResponse>>(
async fn start<N: NetworkSpec, C: Consensus<N::BlockResponse>>(
rpc: RpcInner<N, C>,
) -> Result<(ServerHandle, SocketAddr)> {
let server = ServerBuilder::default().build(rpc.address).await?;
Expand Down
13 changes: 7 additions & 6 deletions core/src/consensus.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use alloy::network::TransactionResponse;
use alloy::network::{primitives::HeaderResponse, BlockResponse, TransactionResponse};
use eyre::Result;
use serde::Serialize;
use tokio::sync::{mpsc, watch};

use crate::types::Block;

pub trait Consensus<T: TransactionResponse + Serialize>: Sync + Send + 'static {
fn block_recv(&mut self) -> Option<mpsc::Receiver<Block<T>>>;
fn finalized_block_recv(&mut self) -> Option<watch::Receiver<Option<Block<T>>>>;
pub trait Consensus<
B: BlockResponse<Transaction: TransactionResponse, Header: HeaderResponse> + Serialize,
>: Sync + Send + 'static
{
fn block_recv(&mut self) -> Option<mpsc::Receiver<B>>;
fn finalized_block_recv(&mut self) -> Option<watch::Receiver<Option<B>>>;
fn expected_highest_block(&self) -> u64;
fn chain_id(&self) -> u64;
fn shutdown(&self) -> Result<()>;
Expand Down
10 changes: 7 additions & 3 deletions core/src/execution/evm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::{borrow::BorrowMut, collections::HashMap, sync::Arc};

use alloy::network::TransactionBuilder;
use alloy::{
consensus::BlockHeader,
network::{primitives::HeaderResponse, BlockResponse, TransactionBuilder},
};
use eyre::{Report, Result};
use futures::future::join_all;
use revm::{
Expand Down Expand Up @@ -184,7 +187,7 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>> EvmState<N, R> {
.await
.ok_or(ExecutionError::BlockNotFound(tag))?;

self.block_hash.insert(*number, block.hash);
self.block_hash.insert(*number, block.header().hash());
}
}
}
Expand Down Expand Up @@ -248,7 +251,8 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>> EvmState<N, R> {
.get_block(self.block, false)
.await
.ok_or(ExecutionError::BlockNotFound(self.block))?
.miner;
.header()
.beneficiary();
let producer_access_entry = AccessListItem {
address: coinbase,
storage_keys: Vec::default(),
Expand Down
Loading

0 comments on commit 552bc95

Please sign in to comment.