mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 02:49:55 +00:00
feat(breaking): Use HlHeader for HlPrimitives
This commit is contained in:
@ -23,7 +23,7 @@ use jsonrpsee::{PendingSubscriptionSink, SubscriptionMessage, SubscriptionSink,
|
|||||||
use jsonrpsee_core::{RpcResult, async_trait};
|
use jsonrpsee_core::{RpcResult, async_trait};
|
||||||
use jsonrpsee_types::{ErrorObject, error::INTERNAL_ERROR_CODE};
|
use jsonrpsee_types::{ErrorObject, error::INTERNAL_ERROR_CODE};
|
||||||
use reth::{api::FullNodeComponents, builder::rpc::RpcContext, tasks::TaskSpawner};
|
use reth::{api::FullNodeComponents, builder::rpc::RpcContext, tasks::TaskSpawner};
|
||||||
use reth_primitives_traits::{BlockBody as _, SignedTransaction};
|
use reth_primitives_traits::SignedTransaction;
|
||||||
use reth_provider::{BlockIdReader, BlockReader, BlockReaderIdExt, ReceiptProvider};
|
use reth_provider::{BlockIdReader, BlockReader, BlockReaderIdExt, ReceiptProvider};
|
||||||
use reth_rpc::{EthFilter, EthPubSub, RpcTypes, eth::pubsub::SubscriptionSerializeError};
|
use reth_rpc::{EthFilter, EthPubSub, RpcTypes, eth::pubsub::SubscriptionSerializeError};
|
||||||
use reth_rpc_eth_api::{
|
use reth_rpc_eth_api::{
|
||||||
@ -579,9 +579,9 @@ async fn adjust_transaction_receipt<Eth: EthWrapper>(
|
|||||||
// This function assumes that `block_id` is already validated by the caller.
|
// This function assumes that `block_id` is already validated by the caller.
|
||||||
fn system_tx_count_for_block<Eth: EthWrapper>(eth_api: &Eth, block_id: BlockId) -> usize {
|
fn system_tx_count_for_block<Eth: EthWrapper>(eth_api: &Eth, block_id: BlockId) -> usize {
|
||||||
let provider = eth_api.provider();
|
let provider = eth_api.provider();
|
||||||
let block = provider.block_by_id(block_id).unwrap().unwrap();
|
let header = provider.header_by_id(block_id).unwrap().unwrap();
|
||||||
|
|
||||||
block.body.transactions().iter().filter(|tx| tx.is_system_transaction()).count()
|
header.extras.system_tx_count.try_into().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
pub mod hl;
|
pub mod hl;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
||||||
use crate::{hardforks::HlHardforks, node::primitives::HlHeader};
|
use crate::{hardforks::HlHardforks, node::primitives::{header::HlHeaderExtras, HlHeader}};
|
||||||
use alloy_eips::eip7840::BlobParams;
|
use alloy_eips::eip7840::BlobParams;
|
||||||
use alloy_genesis::Genesis;
|
use alloy_genesis::Genesis;
|
||||||
use alloy_primitives::{Address, B256, U256};
|
use alloy_primitives::{Address, B256, U256};
|
||||||
@ -129,12 +129,8 @@ impl HlChainSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new(inner: ChainSpec) -> Self {
|
fn new(inner: ChainSpec) -> Self {
|
||||||
let genesis_header = HlHeader {
|
let genesis_header =
|
||||||
inner: inner.genesis_header().clone(),
|
HlHeader { inner: inner.genesis_header().clone(), extras: HlHeaderExtras::default() };
|
||||||
logs_bloom_with_system_txs: Default::default(),
|
|
||||||
system_tx_count: 0,
|
|
||||||
read_precompile_calls: Default::default(),
|
|
||||||
};
|
|
||||||
Self { inner, genesis_header }
|
Self { inner, genesis_header }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,36 +7,12 @@ use alloy_primitives::keccak256;
|
|||||||
use revm::{
|
use revm::{
|
||||||
context::Host,
|
context::Host,
|
||||||
interpreter::{
|
interpreter::{
|
||||||
InstructionContext, InterpreterTypes, as_u64_saturated, interpreter_types::StackTr,
|
_count, InstructionContext, InterpreterTypes, as_u64_saturated, interpreter_types::StackTr,
|
||||||
popn_top,
|
popn_top,
|
||||||
},
|
},
|
||||||
primitives::{BLOCK_HASH_HISTORY, U256},
|
primitives::{BLOCK_HASH_HISTORY, U256},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export]
|
|
||||||
#[collapse_debuginfo(yes)]
|
|
||||||
macro_rules! _count {
|
|
||||||
(@count) => { 0 };
|
|
||||||
(@count $head:tt $($tail:tt)*) => { 1 + _count!(@count $($tail)*) };
|
|
||||||
($($arg:tt)*) => { _count!(@count $($arg)*) };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pops n values from the stack and returns the top value. Fails the instruction if n values can't
|
|
||||||
/// be popped.
|
|
||||||
#[macro_export]
|
|
||||||
#[collapse_debuginfo(yes)]
|
|
||||||
macro_rules! popn_top {
|
|
||||||
([ $($x:ident),* ], $top:ident, $interpreter:expr $(,$ret:expr)? ) => {
|
|
||||||
// Workaround for https://github.com/rust-lang/rust/issues/144329.
|
|
||||||
if $interpreter.stack.len() < (1 + $crate::_count!($($x)*)) {
|
|
||||||
$interpreter.halt_underflow();
|
|
||||||
return $($ret)?;
|
|
||||||
}
|
|
||||||
let ([$( $x ),*], $top) = unsafe { $interpreter.stack.popn_top().unwrap_unchecked() };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implements the BLOCKHASH instruction.
|
/// Implements the BLOCKHASH instruction.
|
||||||
///
|
///
|
||||||
/// Gets the hash of one of the 256 most recent complete blocks.
|
/// Gets the hash of one of the 256 most recent complete blocks.
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
//! Copy of reth codebase.
|
//! Copy of reth codebase.
|
||||||
|
|
||||||
|
use crate::HlBlock;
|
||||||
use alloy_consensus::{BlockHeader, TxReceipt, proofs::calculate_receipt_root};
|
use alloy_consensus::{BlockHeader, TxReceipt, proofs::calculate_receipt_root};
|
||||||
use alloy_eips::eip7685::Requests;
|
use alloy_eips::eip7685::Requests;
|
||||||
use alloy_primitives::{B256, Bloom};
|
use alloy_primitives::{B256, Bloom};
|
||||||
use reth::consensus::ConsensusError;
|
use reth::consensus::ConsensusError;
|
||||||
use reth_chainspec::EthereumHardforks;
|
use reth_chainspec::EthereumHardforks;
|
||||||
use reth_primitives::{GotExpected, RecoveredBlock, gas_spent_by_transactions};
|
use reth_primitives::{GotExpected, RecoveredBlock, gas_spent_by_transactions};
|
||||||
use reth_primitives_traits::{Block, Receipt as ReceiptTrait};
|
use reth_primitives_traits::Receipt as ReceiptTrait;
|
||||||
|
|
||||||
pub fn validate_block_post_execution<B, R, ChainSpec>(
|
pub fn validate_block_post_execution<R, ChainSpec>(
|
||||||
block: &RecoveredBlock<B>,
|
block: &RecoveredBlock<HlBlock>,
|
||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
receipts: &[R],
|
receipts: &[R],
|
||||||
requests: &Requests,
|
requests: &Requests,
|
||||||
) -> Result<(), ConsensusError>
|
) -> Result<(), ConsensusError>
|
||||||
where
|
where
|
||||||
B: Block,
|
|
||||||
R: ReceiptTrait,
|
R: ReceiptTrait,
|
||||||
ChainSpec: EthereumHardforks,
|
ChainSpec: EthereumHardforks,
|
||||||
{
|
{
|
||||||
@ -42,7 +42,7 @@ where
|
|||||||
receipts.iter().filter(|&r| r.cumulative_gas_used() != 0).cloned().collect::<Vec<_>>();
|
receipts.iter().filter(|&r| r.cumulative_gas_used() != 0).cloned().collect::<Vec<_>>();
|
||||||
if let Err(error) = verify_receipts(
|
if let Err(error) = verify_receipts(
|
||||||
block.header().receipts_root(),
|
block.header().receipts_root(),
|
||||||
block.header().logs_bloom(),
|
block.header().inner.logs_bloom(),
|
||||||
&receipts_for_root,
|
&receipts_for_root,
|
||||||
) {
|
) {
|
||||||
tracing::debug!(%error, ?receipts, "receipts verification failed");
|
tracing::debug!(%error, ?receipts, "receipts verification failed");
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
use super::{executor::HlBlockExecutor, factory::HlEvmFactory};
|
use super::{executor::HlBlockExecutor, factory::HlEvmFactory};
|
||||||
use crate::{
|
use crate::{
|
||||||
chainspec::HlChainSpec, evm::{spec::HlSpecId, transaction::HlTxEnv}, hardforks::HlHardforks, node::{
|
HlBlock, HlBlockBody, HlHeader, HlPrimitives,
|
||||||
|
chainspec::HlChainSpec,
|
||||||
|
evm::{spec::HlSpecId, transaction::HlTxEnv},
|
||||||
|
hardforks::HlHardforks,
|
||||||
|
node::{
|
||||||
evm::{executor::is_system_transaction, receipt_builder::RethReceiptBuilder},
|
evm::{executor::is_system_transaction, receipt_builder::RethReceiptBuilder},
|
||||||
primitives::{BlockBody, TransactionSigned},
|
primitives::{BlockBody, TransactionSigned},
|
||||||
rpc::engine_api::validator::HlExecutionData,
|
rpc::engine_api::validator::HlExecutionData,
|
||||||
types::HlExtras,
|
types::HlExtras,
|
||||||
}, HlBlock, HlBlockBody, HlHeader, HlPrimitives
|
},
|
||||||
};
|
};
|
||||||
use alloy_consensus::{BlockHeader, EMPTY_OMMER_ROOT_HASH, Header, Transaction as _, TxReceipt};
|
use alloy_consensus::{BlockHeader, EMPTY_OMMER_ROOT_HASH, Header, Transaction as _, TxReceipt};
|
||||||
use alloy_eips::{Encodable2718, merge::BEACON_NONCE};
|
use alloy_eips::{Encodable2718, merge::BEACON_NONCE};
|
||||||
@ -132,7 +136,9 @@ where
|
|||||||
excess_blob_gas,
|
excess_blob_gas,
|
||||||
requests_hash,
|
requests_hash,
|
||||||
};
|
};
|
||||||
let header = HlHeader::from_ethereum_header(header, receipts);
|
let system_tx_count =
|
||||||
|
transactions.iter().filter(|t| is_system_transaction(t)).count() as u64;
|
||||||
|
let header = HlHeader::from_ethereum_header(header, receipts, system_tx_count);
|
||||||
|
|
||||||
Ok(Self::Block {
|
Ok(Self::Block {
|
||||||
header,
|
header,
|
||||||
|
|||||||
@ -9,8 +9,6 @@ use reth_primitives_traits::{BlockHeader, InMemorySize, serde_bincode_compat::Rl
|
|||||||
use reth_rpc_convert::transaction::FromConsensusHeader;
|
use reth_rpc_convert::transaction::FromConsensusHeader;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::node::types::HlExtras;
|
|
||||||
|
|
||||||
/// The header type of this node
|
/// The header type of this node
|
||||||
///
|
///
|
||||||
/// This type extends the regular ethereum header with an extension.
|
/// This type extends the regular ethereum header with an extension.
|
||||||
@ -33,22 +31,25 @@ pub struct HlHeader {
|
|||||||
/// The regular eth header
|
/// The regular eth header
|
||||||
#[as_ref]
|
#[as_ref]
|
||||||
#[deref]
|
#[deref]
|
||||||
#[serde(flatten)]
|
|
||||||
pub inner: Header,
|
pub inner: Header,
|
||||||
/// The extended header fields that is not part of the block hash
|
/// The extended header fields that is not part of the block hash
|
||||||
|
pub extras: HlHeaderExtras,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, RlpEncodable, RlpDecodable, Hash,
|
||||||
|
)]
|
||||||
|
pub struct HlHeaderExtras {
|
||||||
pub logs_bloom_with_system_txs: Bloom,
|
pub logs_bloom_with_system_txs: Bloom,
|
||||||
pub system_tx_count: u64,
|
pub system_tx_count: u64,
|
||||||
pub read_precompile_calls: HlExtras,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HlHeader {
|
impl HlHeader {
|
||||||
pub(crate) fn from_ethereum_header(header: Header, receipts: &[EthereumReceipt]) -> HlHeader {
|
pub(crate) fn from_ethereum_header(header: Header, receipts: &[EthereumReceipt], system_tx_count: u64) -> HlHeader {
|
||||||
let logs_bloom = logs_bloom(receipts.iter().flat_map(|r| &r.logs));
|
let logs_bloom = logs_bloom(receipts.iter().flat_map(|r| &r.logs));
|
||||||
let system_tx_count = receipts.iter().filter(|r| r.cumulative_gas_used == 0).count() as u64;
|
|
||||||
HlHeader {
|
HlHeader {
|
||||||
inner: header,
|
inner: header,
|
||||||
logs_bloom_with_system_txs: logs_bloom,
|
extras: HlHeaderExtras { logs_bloom_with_system_txs: logs_bloom, system_tx_count },
|
||||||
system_tx_count,
|
|
||||||
read_precompile_calls: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,7 +102,7 @@ impl alloy_consensus::BlockHeader for HlHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn logs_bloom(&self) -> Bloom {
|
fn logs_bloom(&self) -> Bloom {
|
||||||
self.inner.logs_bloom()
|
self.extras.logs_bloom_with_system_txs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn difficulty(&self) -> U256 {
|
fn difficulty(&self) -> U256 {
|
||||||
@ -155,14 +156,21 @@ impl alloy_consensus::BlockHeader for HlHeader {
|
|||||||
fn extra_data(&self) -> &Bytes {
|
fn extra_data(&self) -> &Bytes {
|
||||||
self.inner.extra_data()
|
self.inner.extra_data()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.extras.system_tx_count == 0 && self.inner.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InMemorySize for HlHeader {
|
impl InMemorySize for HlHeader {
|
||||||
fn size(&self) -> usize {
|
fn size(&self) -> usize {
|
||||||
self.inner.size()
|
self.inner.size() + self.extras.size()
|
||||||
+ self.logs_bloom_with_system_txs.data().len()
|
}
|
||||||
+ self.system_tx_count.size()
|
}
|
||||||
+ self.read_precompile_calls.size()
|
|
||||||
|
impl InMemorySize for HlHeaderExtras {
|
||||||
|
fn size(&self) -> usize {
|
||||||
|
self.logs_bloom_with_system_txs.data().len() + self.system_tx_count.size()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,15 +179,20 @@ impl reth_codecs::Compact for HlHeader {
|
|||||||
where
|
where
|
||||||
B: alloy_rlp::bytes::BufMut + AsMut<[u8]>,
|
B: alloy_rlp::bytes::BufMut + AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
// It's too tedious to implement to_compact for every field, so use rmp_serde to serialize
|
// Because Header ends with extra_data which is `Bytes`, we can't use to_compact for extras,
|
||||||
// This also helps the struct to be upgradable in future thanks to serde's flexibility.
|
// because Compact trait requires the Bytes field to be placed at the end of the struct.
|
||||||
|
// Bytes::from_compact just reads all trailing data as the Bytes field.
|
||||||
|
//
|
||||||
|
// Hence we need to use other form of serialization, since extra headers are not Compact-compatible.
|
||||||
|
// We just treat all header fields as rmp-serialized one `Bytes` field.
|
||||||
let result: Bytes = rmp_serde::to_vec(&self).unwrap().into();
|
let result: Bytes = rmp_serde::to_vec(&self).unwrap().into();
|
||||||
result.to_compact(buf)
|
result.to_compact(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_compact(buf: &[u8], identifier: usize) -> (Self, &[u8]) {
|
fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
|
||||||
let header: HlHeader = rmp_serde::from_slice(&buf[identifier..]).unwrap();
|
let (bytes, remaining) = Bytes::from_compact(buf, len);
|
||||||
(header, &buf[identifier + buf.len()..])
|
let header: HlHeader = rmp_serde::from_slice(&bytes).unwrap();
|
||||||
|
(header, remaining)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -120,6 +120,11 @@ impl SealedBlock {
|
|||||||
let mut merged_txs = vec![];
|
let mut merged_txs = vec![];
|
||||||
merged_txs.extend(system_txs.iter().map(|tx| system_tx_to_reth_transaction(tx, chain_id)));
|
merged_txs.extend(system_txs.iter().map(|tx| system_tx_to_reth_transaction(tx, chain_id)));
|
||||||
merged_txs.extend(self.body.transactions.iter().map(|tx| tx.to_reth_transaction()));
|
merged_txs.extend(self.body.transactions.iter().map(|tx| tx.to_reth_transaction()));
|
||||||
|
|
||||||
|
let mut merged_receipts = vec![];
|
||||||
|
merged_receipts.extend(system_txs.iter().map(|tx| tx.receipt.clone().unwrap().into()));
|
||||||
|
merged_receipts.extend(receipts.into_iter().map(From::from));
|
||||||
|
|
||||||
let block_body = HlBlockBody {
|
let block_body = HlBlockBody {
|
||||||
inner: reth_primitives::BlockBody {
|
inner: reth_primitives::BlockBody {
|
||||||
transactions: merged_txs,
|
transactions: merged_txs,
|
||||||
@ -131,10 +136,12 @@ impl SealedBlock {
|
|||||||
highest_precompile_address,
|
highest_precompile_address,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let system_tx_count = system_txs.len() as u64;
|
||||||
HlBlock {
|
HlBlock {
|
||||||
header: HlHeader::from_ethereum_header(
|
header: HlHeader::from_ethereum_header(
|
||||||
self.header.header.clone(),
|
self.header.header.clone(),
|
||||||
&receipts.into_iter().map(From::from).collect::<Vec<_>>(),
|
&merged_receipts,
|
||||||
|
system_tx_count,
|
||||||
),
|
),
|
||||||
body: block_body,
|
body: block_body,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user