4 Commits

Author SHA1 Message Date
81e81c551a Merge pull request #22 from hl-archive-node/fix/highest-precompile-address-nb
feat: Support highest_precompile_address
2025-07-21 00:16:04 -04:00
209a806c83 chore: lint 2025-07-21 04:15:29 +00:00
736e0da620 remove: stale comments 2025-07-21 04:15:29 +00:00
b3becf9c7b feat: Support highest_precompile_address 2025-07-21 04:15:29 +00:00
13 changed files with 120 additions and 82 deletions

View File

@ -219,7 +219,8 @@ fn not_from_system_tx<Eth: EthWrapper>(log: &Log, provider: &Eth::Provider) -> b
!transactions !transactions
.iter() .iter()
.filter(|tx| tx.is_system_transaction()) .filter(|tx| tx.is_system_transaction())
.map(|tx| *tx.tx_hash()).any(|tx_hash| tx_hash == log.transaction_hash.unwrap()) .map(|tx| *tx.tx_hash())
.any(|tx_hash| tx_hash == log.transaction_hash.unwrap())
} }
/// Helper to convert a serde error into an [`ErrorObject`] /// Helper to convert a serde error into an [`ErrorObject`]

View File

@ -1,3 +1,4 @@
pub mod call_forwarder;
pub mod chainspec; pub mod chainspec;
pub mod consensus; pub mod consensus;
mod evm; mod evm;
@ -6,6 +7,5 @@ pub mod hl_node_compliance;
pub mod node; pub mod node;
pub mod pseudo_peer; pub mod pseudo_peer;
pub mod tx_forwarder; pub mod tx_forwarder;
pub mod call_forwarder;
pub use node::primitives::{HlBlock, HlBlockBody, HlPrimitives}; pub use node::primitives::{HlBlock, HlBlockBody, HlPrimitives};

View File

@ -6,7 +6,7 @@ use crate::{
node::{ node::{
evm::{executor::is_system_transaction, receipt_builder::RethReceiptBuilder}, evm::{executor::is_system_transaction, receipt_builder::RethReceiptBuilder},
primitives::{BlockBody, TransactionSigned}, primitives::{BlockBody, TransactionSigned},
types::ReadPrecompileMap, types::HlExtras,
}, },
HlBlock, HlBlockBody, HlPrimitives, HlBlock, HlBlockBody, HlPrimitives,
}; };
@ -137,7 +137,8 @@ where
body: HlBlockBody { body: HlBlockBody {
inner: BlockBody { transactions, ommers: Default::default(), withdrawals }, inner: BlockBody { transactions, ommers: Default::default(), withdrawals },
sidecars: None, sidecars: None,
read_precompile_calls: Some(ctx.read_precompile_calls.clone().into()), read_precompile_calls: ctx.extras.read_precompile_calls.clone(),
highest_precompile_address: ctx.extras.highest_precompile_address,
}, },
}) })
} }
@ -226,7 +227,7 @@ impl<R, Spec, EvmFactory> HlBlockExecutorFactory<R, Spec, EvmFactory> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct HlBlockExecutionCtx<'a> { pub struct HlBlockExecutionCtx<'a> {
ctx: EthBlockExecutionCtx<'a>, ctx: EthBlockExecutionCtx<'a>,
pub read_precompile_calls: ReadPrecompileMap, pub extras: HlExtras,
} }
impl<R, Spec, EvmF> BlockExecutorFactory for HlBlockExecutorFactory<R, Spec, EvmF> impl<R, Spec, EvmF> BlockExecutorFactory for HlBlockExecutorFactory<R, Spec, EvmF>
@ -372,6 +373,11 @@ where
&self, &self,
block: &'a SealedBlock<BlockTy<Self::Primitives>>, block: &'a SealedBlock<BlockTy<Self::Primitives>>,
) -> ExecutionCtxFor<'a, Self> { ) -> ExecutionCtxFor<'a, Self> {
let block_body = block.body();
let extras = HlExtras {
read_precompile_calls: block_body.read_precompile_calls.clone(),
highest_precompile_address: block_body.highest_precompile_address,
};
HlBlockExecutionCtx { HlBlockExecutionCtx {
ctx: EthBlockExecutionCtx { ctx: EthBlockExecutionCtx {
parent_hash: block.header().parent_hash, parent_hash: block.header().parent_hash,
@ -379,11 +385,7 @@ where
ommers: &block.body().ommers, ommers: &block.body().ommers,
withdrawals: block.body().withdrawals.as_ref().map(Cow::Borrowed), withdrawals: block.body().withdrawals.as_ref().map(Cow::Borrowed),
}, },
read_precompile_calls: block extras,
.body()
.read_precompile_calls
.clone()
.map_or(ReadPrecompileMap::default(), |calls| calls.into()),
} }
} }
@ -400,7 +402,7 @@ where
withdrawals: attributes.withdrawals.map(Cow::Owned), withdrawals: attributes.withdrawals.map(Cow::Owned),
}, },
// TODO: hacky, double check if this is correct // TODO: hacky, double check if this is correct
read_precompile_calls: ReadPrecompileMap::default(), extras: HlExtras::default(),
} }
} }
} }

View File

@ -26,6 +26,7 @@ use revm::{
result::{ExecutionResult, ResultAndState}, result::{ExecutionResult, ResultAndState},
TxEnv, TxEnv,
}, },
interpreter::instructions::utility::IntoU256,
precompile::{PrecompileError, PrecompileOutput, PrecompileResult}, precompile::{PrecompileError, PrecompileOutput, PrecompileResult},
primitives::HashMap, primitives::HashMap,
state::Bytecode, state::Bytecode,
@ -254,30 +255,43 @@ where
precompiles_mut.apply_precompile(&address, |_| None); precompiles_mut.apply_precompile(&address, |_| None);
} }
} }
for (address, precompile) in ctx.read_precompile_calls.iter() { for (address, precompile) in
ctx.extras.read_precompile_calls.clone().unwrap_or_default().0.iter()
{
let precompile = precompile.clone(); let precompile = precompile.clone();
precompiles_mut.apply_precompile(address, |_| { precompiles_mut.apply_precompile(address, |_| {
let precompiles_map: HashMap<ReadPrecompileInput, ReadPrecompileResult> =
precompile.iter().map(|(input, result)| (input.clone(), result.clone())).collect();
Some(DynPrecompile::from(move |input: PrecompileInput| -> PrecompileResult { Some(DynPrecompile::from(move |input: PrecompileInput| -> PrecompileResult {
run_precompile(&precompile, input.data, input.gas) run_precompile(&precompiles_map, input.data, input.gas)
})) }))
}); });
} }
// NOTE: Hotfix for the precompile issue (#17). Remove this once the issue is fixed. // NOTE: This is adapted from hyperliquid-dex/hyper-evm-sync#5
if block_number >= U256::from(7000000) { const WARM_PRECOMPILES_BLOCK_NUMBER: u64 = 8_197_684;
if block_number >= U256::from(WARM_PRECOMPILES_BLOCK_NUMBER) {
fill_all_precompiles(ctx, precompiles_mut); fill_all_precompiles(ctx, precompiles_mut);
} }
} }
fn address_to_u64(address: Address) -> u64 {
address.into_u256().try_into().unwrap()
}
fn fill_all_precompiles<'a>(ctx: &HlBlockExecutionCtx<'a>, precompiles_mut: &mut PrecompilesMap) { fn fill_all_precompiles<'a>(ctx: &HlBlockExecutionCtx<'a>, precompiles_mut: &mut PrecompilesMap) {
for address in 0x800..=0x80D { let lowest_address = 0x800;
let highest_address = ctx.extras.highest_precompile_address.map_or(0x80D, address_to_u64);
for address in lowest_address..=highest_address {
let address = Address::from(U160::from(address)); let address = Address::from(U160::from(address));
if !ctx.read_precompile_calls.contains_key(&address) { precompiles_mut.apply_precompile(&address, |f| {
precompiles_mut.apply_precompile(&address, |_| { if let Some(precompile) = f {
Some(DynPrecompile::from(move |_: PrecompileInput| -> PrecompileResult { return Some(precompile);
Err(PrecompileError::OutOfGas) }
}))
}); Some(DynPrecompile::from(move |_: PrecompileInput| -> PrecompileResult {
} Err(PrecompileError::OutOfGas)
}))
});
} }
} }

View File

@ -112,7 +112,8 @@ where
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> { ) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
// NOTE: This is used for block traces. // NOTE: This is used for block traces.
// Per hyper-evm-sync, HyperEVM doesn't seem to call this method, so // Per hyper-evm-sync, HyperEVM doesn't seem to call this method, so
// - we just return a success result with no changes, which gives the same semantics as HyperEVM. // - we just return a success result with no changes, which gives the same semantics as
// HyperEVM.
// - In a long term (ideally), consider implementing SystemCaller. // - In a long term (ideally), consider implementing SystemCaller.
Ok(ResultAndState::new( Ok(ResultAndState::new(
ExecutionResult::Success { ExecutionResult::Success {

View File

@ -160,6 +160,7 @@ where
}, },
sidecars: None, sidecars: None,
read_precompile_calls: None, read_precompile_calls: None,
highest_precompile_address: None,
}, },
} }
} }

View File

@ -401,6 +401,7 @@ mod tests {
}, },
sidecars: None, sidecars: None,
read_precompile_calls: None, read_precompile_calls: None,
highest_precompile_address: None,
}, },
}; };
let new_block = HlNewBlock(NewBlock { block, td: U128::from(1) }); let new_block = HlNewBlock(NewBlock { block, td: U128::from(1) });

View File

@ -42,7 +42,7 @@ mod rlp {
HlBlockBody, HlBlockBody,
}; };
use alloy_consensus::{BlobTransactionSidecar, Header}; use alloy_consensus::{BlobTransactionSidecar, Header};
use alloy_primitives::U128; use alloy_primitives::{Address, U128};
use alloy_rlp::{RlpDecodable, RlpEncodable}; use alloy_rlp::{RlpDecodable, RlpEncodable};
use alloy_rpc_types::Withdrawals; use alloy_rpc_types::Withdrawals;
use std::borrow::Cow; use std::borrow::Cow;
@ -63,6 +63,7 @@ mod rlp {
td: U128, td: U128,
sidecars: Option<Cow<'a, Vec<BlobTransactionSidecar>>>, sidecars: Option<Cow<'a, Vec<BlobTransactionSidecar>>>,
read_precompile_calls: Option<Cow<'a, ReadPrecompileCalls>>, read_precompile_calls: Option<Cow<'a, ReadPrecompileCalls>>,
highest_precompile_address: Option<Cow<'a, Address>>,
} }
impl<'a> From<&'a HlNewBlock> for HlNewBlockHelper<'a> { impl<'a> From<&'a HlNewBlock> for HlNewBlockHelper<'a> {
@ -76,6 +77,7 @@ mod rlp {
inner: BlockBody { transactions, ommers, withdrawals }, inner: BlockBody { transactions, ommers, withdrawals },
sidecars, sidecars,
read_precompile_calls, read_precompile_calls,
highest_precompile_address,
}, },
}, },
td, td,
@ -91,6 +93,7 @@ mod rlp {
td: *td, td: *td,
sidecars: sidecars.as_ref().map(Cow::Borrowed), sidecars: sidecars.as_ref().map(Cow::Borrowed),
read_precompile_calls: read_precompile_calls.as_ref().map(Cow::Borrowed), read_precompile_calls: read_precompile_calls.as_ref().map(Cow::Borrowed),
highest_precompile_address: highest_precompile_address.as_ref().map(Cow::Borrowed),
} }
} }
} }
@ -112,6 +115,7 @@ mod rlp {
td, td,
sidecars, sidecars,
read_precompile_calls, read_precompile_calls,
highest_precompile_address,
} = HlNewBlockHelper::decode(buf)?; } = HlNewBlockHelper::decode(buf)?;
Ok(HlNewBlock(NewBlock { Ok(HlNewBlock(NewBlock {
@ -125,6 +129,8 @@ mod rlp {
}, },
sidecars: sidecars.map(|s| s.into_owned()), sidecars: sidecars.map(|s| s.into_owned()),
read_precompile_calls: read_precompile_calls.map(|s| s.into_owned()), read_precompile_calls: read_precompile_calls.map(|s| s.into_owned()),
highest_precompile_address: highest_precompile_address
.map(|s| s.into_owned()),
}, },
}, },
td, td,
@ -231,13 +237,9 @@ where
ctx.task_executor().spawn_critical("pseudo peer", async move { ctx.task_executor().spawn_critical("pseudo peer", async move {
let block_source = block_source_config.create_cached_block_source().await; let block_source = block_source_config.create_cached_block_source().await;
start_pseudo_peer( start_pseudo_peer(chain_spec, local_node_record.to_string(), block_source)
chain_spec, .await
local_node_record.to_string(), .unwrap();
block_source,
)
.await
.unwrap();
}); });
Ok(handle) Ok(handle)

View File

@ -1,5 +1,6 @@
#![allow(clippy::owned_cow)] #![allow(clippy::owned_cow)]
use alloy_consensus::{BlobTransactionSidecar, Header}; use alloy_consensus::{BlobTransactionSidecar, Header};
use alloy_primitives::Address;
use alloy_rlp::{Encodable, RlpDecodable, RlpEncodable}; use alloy_rlp::{Encodable, RlpDecodable, RlpEncodable};
use reth_ethereum_primitives::Receipt; use reth_ethereum_primitives::Receipt;
use reth_primitives::NodePrimitives; use reth_primitives::NodePrimitives;
@ -45,6 +46,7 @@ pub struct HlBlockBody {
pub inner: BlockBody, pub inner: BlockBody,
pub sidecars: Option<Vec<BlobTransactionSidecar>>, pub sidecars: Option<Vec<BlobTransactionSidecar>>,
pub read_precompile_calls: Option<ReadPrecompileCalls>, pub read_precompile_calls: Option<ReadPrecompileCalls>,
pub highest_precompile_address: Option<Address>,
} }
impl InMemorySize for HlBlockBody { impl InMemorySize for HlBlockBody {
@ -135,6 +137,7 @@ impl Block for HlBlock {
withdrawals: body.inner.withdrawals.as_ref().map(Cow::Borrowed), withdrawals: body.inner.withdrawals.as_ref().map(Cow::Borrowed),
sidecars: body.sidecars.as_ref().map(Cow::Borrowed), sidecars: body.sidecars.as_ref().map(Cow::Borrowed),
read_precompile_calls: body.read_precompile_calls.as_ref().map(Cow::Borrowed), read_precompile_calls: body.read_precompile_calls.as_ref().map(Cow::Borrowed),
highest_precompile_address: body.highest_precompile_address.as_ref().map(Cow::Borrowed),
} }
.length() .length()
} }
@ -153,6 +156,7 @@ mod rlp {
withdrawals: Option<Cow<'a, Withdrawals>>, withdrawals: Option<Cow<'a, Withdrawals>>,
sidecars: Option<Cow<'a, Vec<BlobTransactionSidecar>>>, sidecars: Option<Cow<'a, Vec<BlobTransactionSidecar>>>,
read_precompile_calls: Option<Cow<'a, ReadPrecompileCalls>>, read_precompile_calls: Option<Cow<'a, ReadPrecompileCalls>>,
highest_precompile_address: Option<Cow<'a, Address>>,
} }
#[derive(RlpEncodable, RlpDecodable)] #[derive(RlpEncodable, RlpDecodable)]
@ -164,6 +168,7 @@ mod rlp {
pub(crate) withdrawals: Option<Cow<'a, Withdrawals>>, pub(crate) withdrawals: Option<Cow<'a, Withdrawals>>,
pub(crate) sidecars: Option<Cow<'a, Vec<BlobTransactionSidecar>>>, pub(crate) sidecars: Option<Cow<'a, Vec<BlobTransactionSidecar>>>,
pub(crate) read_precompile_calls: Option<Cow<'a, ReadPrecompileCalls>>, pub(crate) read_precompile_calls: Option<Cow<'a, ReadPrecompileCalls>>,
pub(crate) highest_precompile_address: Option<Cow<'a, Address>>,
} }
impl<'a> From<&'a HlBlockBody> for BlockBodyHelper<'a> { impl<'a> From<&'a HlBlockBody> for BlockBodyHelper<'a> {
@ -172,6 +177,7 @@ mod rlp {
inner: BlockBody { transactions, ommers, withdrawals }, inner: BlockBody { transactions, ommers, withdrawals },
sidecars, sidecars,
read_precompile_calls, read_precompile_calls,
highest_precompile_address,
} = value; } = value;
Self { Self {
@ -180,6 +186,7 @@ mod rlp {
withdrawals: withdrawals.as_ref().map(Cow::Borrowed), withdrawals: withdrawals.as_ref().map(Cow::Borrowed),
sidecars: sidecars.as_ref().map(Cow::Borrowed), sidecars: sidecars.as_ref().map(Cow::Borrowed),
read_precompile_calls: read_precompile_calls.as_ref().map(Cow::Borrowed), read_precompile_calls: read_precompile_calls.as_ref().map(Cow::Borrowed),
highest_precompile_address: highest_precompile_address.as_ref().map(Cow::Borrowed),
} }
} }
} }
@ -193,6 +200,7 @@ mod rlp {
inner: BlockBody { transactions, ommers, withdrawals }, inner: BlockBody { transactions, ommers, withdrawals },
sidecars, sidecars,
read_precompile_calls, read_precompile_calls,
highest_precompile_address,
}, },
} = value; } = value;
@ -203,6 +211,7 @@ mod rlp {
withdrawals: withdrawals.as_ref().map(Cow::Borrowed), withdrawals: withdrawals.as_ref().map(Cow::Borrowed),
sidecars: sidecars.as_ref().map(Cow::Borrowed), sidecars: sidecars.as_ref().map(Cow::Borrowed),
read_precompile_calls: read_precompile_calls.as_ref().map(Cow::Borrowed), read_precompile_calls: read_precompile_calls.as_ref().map(Cow::Borrowed),
highest_precompile_address: highest_precompile_address.as_ref().map(Cow::Borrowed),
} }
} }
} }
@ -225,6 +234,7 @@ mod rlp {
withdrawals, withdrawals,
sidecars, sidecars,
read_precompile_calls, read_precompile_calls,
highest_precompile_address,
} = BlockBodyHelper::decode(buf)?; } = BlockBodyHelper::decode(buf)?;
Ok(Self { Ok(Self {
inner: BlockBody { inner: BlockBody {
@ -234,6 +244,7 @@ mod rlp {
}, },
sidecars: sidecars.map(|s| s.into_owned()), sidecars: sidecars.map(|s| s.into_owned()),
read_precompile_calls: read_precompile_calls.map(|s| s.into_owned()), read_precompile_calls: read_precompile_calls.map(|s| s.into_owned()),
highest_precompile_address: highest_precompile_address.map(|s| s.into_owned()),
}) })
} }
} }
@ -257,6 +268,7 @@ mod rlp {
withdrawals, withdrawals,
sidecars, sidecars,
read_precompile_calls, read_precompile_calls,
highest_precompile_address,
} = BlockHelper::decode(buf)?; } = BlockHelper::decode(buf)?;
Ok(Self { Ok(Self {
header: header.into_owned(), header: header.into_owned(),
@ -268,6 +280,7 @@ mod rlp {
}, },
sidecars: sidecars.map(|s| s.into_owned()), sidecars: sidecars.map(|s| s.into_owned()),
read_precompile_calls: read_precompile_calls.map(|s| s.into_owned()), read_precompile_calls: read_precompile_calls.map(|s| s.into_owned()),
highest_precompile_address: highest_precompile_address.map(|s| s.into_owned()),
}, },
}) })
} }
@ -283,6 +296,7 @@ pub mod serde_bincode_compat {
inner: BincodeReprFor<'a, BlockBody>, inner: BincodeReprFor<'a, BlockBody>,
sidecars: Option<Cow<'a, Vec<BlobTransactionSidecar>>>, sidecars: Option<Cow<'a, Vec<BlobTransactionSidecar>>>,
read_precompile_calls: Option<Cow<'a, ReadPrecompileCalls>>, read_precompile_calls: Option<Cow<'a, ReadPrecompileCalls>>,
highest_precompile_address: Option<Cow<'a, Address>>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -299,15 +313,25 @@ pub mod serde_bincode_compat {
inner: self.inner.as_repr(), inner: self.inner.as_repr(),
sidecars: self.sidecars.as_ref().map(Cow::Borrowed), sidecars: self.sidecars.as_ref().map(Cow::Borrowed),
read_precompile_calls: self.read_precompile_calls.as_ref().map(Cow::Borrowed), read_precompile_calls: self.read_precompile_calls.as_ref().map(Cow::Borrowed),
highest_precompile_address: self
.highest_precompile_address
.as_ref()
.map(Cow::Borrowed),
} }
} }
fn from_repr(repr: Self::BincodeRepr<'_>) -> Self { fn from_repr(repr: Self::BincodeRepr<'_>) -> Self {
let HlBlockBodyBincode { inner, sidecars, read_precompile_calls } = repr; let HlBlockBodyBincode {
inner,
sidecars,
read_precompile_calls,
highest_precompile_address,
} = repr;
Self { Self {
inner: BlockBody::from_repr(inner), inner: BlockBody::from_repr(inner),
sidecars: sidecars.map(|s| s.into_owned()), sidecars: sidecars.map(|s| s.into_owned()),
read_precompile_calls: read_precompile_calls.map(|s| s.into_owned()), read_precompile_calls: read_precompile_calls.map(|s| s.into_owned()),
highest_precompile_address: highest_precompile_address.map(|s| s.into_owned()),
} }
} }
} }

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
node::{ node::{
primitives::tx_wrapper::{convert_to_eth_block_body, convert_to_hl_block_body}, primitives::tx_wrapper::{convert_to_eth_block_body, convert_to_hl_block_body},
types::ReadPrecompileCalls, types::HlExtras,
}, },
HlBlock, HlBlockBody, HlPrimitives, HlBlock, HlBlockBody, HlPrimitives,
}; };
@ -29,23 +29,20 @@ impl HlStorage {
fn write_precompile_calls<Provider>( fn write_precompile_calls<Provider>(
&self, &self,
provider: &Provider, provider: &Provider,
inputs: Vec<(u64, Option<ReadPrecompileCalls>)>, inputs: Vec<(u64, HlExtras)>,
) -> ProviderResult<()> ) -> ProviderResult<()>
where where
Provider: DBProvider<Tx: DbTxMut>, Provider: DBProvider<Tx: DbTxMut>,
{ {
let mut precompile_calls_cursor = let mut precompile_calls_cursor: <<Provider as DBProvider>::Tx as DbTxMut>::CursorMut<
provider.tx_ref().cursor_write::<tables::BlockReadPrecompileCalls>()?; tables::BlockReadPrecompileCalls,
> = provider.tx_ref().cursor_write::<tables::BlockReadPrecompileCalls>()?;
for (block_number, read_precompile_calls) in inputs { for (block_number, extras) in inputs {
let Some(read_precompile_calls) = read_precompile_calls else {
continue;
};
precompile_calls_cursor.append( precompile_calls_cursor.append(
block_number, block_number,
&Bytes::copy_from_slice( &Bytes::copy_from_slice(
&rmp_serde::to_vec(&read_precompile_calls) &rmp_serde::to_vec(&extras).expect("Failed to serialize read precompile calls"),
.expect("Failed to serialize read precompile calls"),
), ),
)?; )?;
} }
@ -57,11 +54,11 @@ impl HlStorage {
&self, &self,
provider: &Provider, provider: &Provider,
inputs: &[ReadBodyInput<'_, HlBlock>], inputs: &[ReadBodyInput<'_, HlBlock>],
) -> ProviderResult<Vec<Option<ReadPrecompileCalls>>> ) -> ProviderResult<Vec<HlExtras>>
where where
Provider: DBProvider<Tx: DbTx>, Provider: DBProvider<Tx: DbTx>,
{ {
let mut read_precompile_calls = Vec::with_capacity(inputs.len()); let mut extras: Vec<HlExtras> = Vec::with_capacity(inputs.len());
let mut precompile_calls_cursor = let mut precompile_calls_cursor =
provider.tx_ref().cursor_read::<tables::BlockReadPrecompileCalls>()?; provider.tx_ref().cursor_read::<tables::BlockReadPrecompileCalls>()?;
@ -69,11 +66,12 @@ impl HlStorage {
let precompile_calls = precompile_calls_cursor let precompile_calls = precompile_calls_cursor
.seek_exact(header.number())? .seek_exact(header.number())?
.map(|(_, calls)| calls) .map(|(_, calls)| calls)
.map(|calls| rmp_serde::from_slice(&calls).unwrap()); .map(|calls| rmp_serde::from_slice(&calls).unwrap())
read_precompile_calls.push(precompile_calls); .unwrap_or_default();
extras.push(precompile_calls);
} }
Ok(read_precompile_calls) Ok(extras)
} }
} }
@ -92,13 +90,27 @@ where
for (block_number, body) in bodies { for (block_number, body) in bodies {
match body { match body {
Some(HlBlockBody { inner, sidecars: _, read_precompile_calls: rpc }) => { Some(HlBlockBody {
inner,
sidecars: _,
read_precompile_calls: rpc,
highest_precompile_address,
}) => {
eth_bodies.push((block_number, Some(convert_to_eth_block_body(inner)))); eth_bodies.push((block_number, Some(convert_to_eth_block_body(inner))));
read_precompile_calls.push((block_number, rpc)); read_precompile_calls.push((
block_number,
HlExtras { read_precompile_calls: rpc, highest_precompile_address },
));
} }
None => { None => {
eth_bodies.push((block_number, None)); eth_bodies.push((block_number, None));
read_precompile_calls.push((block_number, None)); read_precompile_calls.push((
block_number,
HlExtras {
read_precompile_calls: Default::default(),
highest_precompile_address: None,
},
));
} }
} }
} }
@ -148,10 +160,11 @@ where
Ok(eth_bodies Ok(eth_bodies
.into_iter() .into_iter()
.zip(read_precompile_calls) .zip(read_precompile_calls)
.map(|(inner, read_precompile_calls)| HlBlockBody { .map(|(inner, extra)| HlBlockBody {
inner: convert_to_hl_block_body(inner), inner: convert_to_hl_block_body(inner),
sidecars: None, sidecars: None,
read_precompile_calls, read_precompile_calls: extra.read_precompile_calls,
highest_precompile_address: extra.highest_precompile_address,
}) })
.collect()) .collect())
} }

View File

@ -1,16 +1,3 @@
//! Tables and data models.
//!
//! # Overview
//!
//! This module defines the tables in reth, as well as some table-related abstractions:
//!
//! - [`codecs`] integrates different codecs into [`Encode`] and [`Decode`]
//! - [`models`](crate::models) defines the values written to tables
//!
//! # Database Tour
//!
//! TODO(onbjerg): Find appropriate format for this...
use alloy_primitives::{BlockNumber, Bytes}; use alloy_primitives::{BlockNumber, Bytes};
use reth_db::{table::TableInfo, tables, TableSet, TableType, TableViewer}; use reth_db::{table::TableInfo, tables, TableSet, TableType, TableViewer};
use std::fmt; use std::fmt;

View File

@ -5,7 +5,6 @@
use alloy_primitives::{Address, Bytes, Log, B256}; use alloy_primitives::{Address, Bytes, Log, B256};
use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable};
use bytes::BufMut; use bytes::BufMut;
use revm::primitives::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{node::spot_meta::MAINNET_CHAIN_ID, HlBlock}; use crate::{node::spot_meta::MAINNET_CHAIN_ID, HlBlock};
@ -14,24 +13,13 @@ pub type ReadPrecompileCall = (Address, Vec<(ReadPrecompileInput, ReadPrecompile
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Default)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Default)]
pub struct ReadPrecompileCalls(pub Vec<ReadPrecompileCall>); pub struct ReadPrecompileCalls(pub Vec<ReadPrecompileCall>);
pub type ReadPrecompileMap = HashMap<Address, HashMap<ReadPrecompileInput, ReadPrecompileResult>>;
mod reth_compat; mod reth_compat;
impl From<ReadPrecompileCalls> for ReadPrecompileMap { #[derive(Debug, Clone, Serialize, Deserialize, Default)]
fn from(calls: ReadPrecompileCalls) -> Self { pub struct HlExtras {
calls.0.into_iter().map(|(address, calls)| (address, calls.into_iter().collect())).collect() pub read_precompile_calls: Option<ReadPrecompileCalls>,
} pub highest_precompile_address: Option<Address>,
}
impl From<ReadPrecompileMap> for ReadPrecompileCalls {
fn from(map: ReadPrecompileMap) -> Self {
Self(
map.into_iter()
.map(|(address, calls)| (address, calls.into_iter().collect()))
.collect(),
)
}
} }
impl Encodable for ReadPrecompileCalls { impl Encodable for ReadPrecompileCalls {
@ -58,6 +46,7 @@ pub struct BlockAndReceipts {
pub system_txs: Vec<SystemTx>, pub system_txs: Vec<SystemTx>,
#[serde(default)] #[serde(default)]
pub read_precompile_calls: ReadPrecompileCalls, pub read_precompile_calls: ReadPrecompileCalls,
pub highest_precompile_address: Option<Address>,
} }
impl BlockAndReceipts { impl BlockAndReceipts {
@ -65,6 +54,7 @@ impl BlockAndReceipts {
let EvmBlock::Reth115(block) = self.block; let EvmBlock::Reth115(block) = self.block;
block.to_reth_block( block.to_reth_block(
self.read_precompile_calls.clone(), self.read_precompile_calls.clone(),
self.highest_precompile_address,
self.system_txs.clone(), self.system_txs.clone(),
MAINNET_CHAIN_ID, MAINNET_CHAIN_ID,
) )

View File

@ -112,6 +112,7 @@ impl SealedBlock {
pub fn to_reth_block( pub fn to_reth_block(
&self, &self,
read_precompile_calls: ReadPrecompileCalls, read_precompile_calls: ReadPrecompileCalls,
highest_precompile_address: Option<Address>,
system_txs: Vec<super::SystemTx>, system_txs: Vec<super::SystemTx>,
chain_id: u64, chain_id: u64,
) -> HlBlock { ) -> HlBlock {
@ -126,6 +127,7 @@ impl SealedBlock {
}, },
sidecars: None, sidecars: None,
read_precompile_calls: Some(read_precompile_calls), read_precompile_calls: Some(read_precompile_calls),
highest_precompile_address,
}; };
HlBlock { header: self.header.header.clone(), body: block_body } HlBlock { header: self.header.header.clone(), body: block_body }