feat: Support highest_precompile_address

This commit is contained in:
sprites0
2025-07-19 21:16:54 +00:00
parent eb7c6b050c
commit b3becf9c7b
9 changed files with 115 additions and 66 deletions

View File

@ -6,7 +6,7 @@ use crate::{
node::{
evm::{executor::is_system_transaction, receipt_builder::RethReceiptBuilder},
primitives::{BlockBody, TransactionSigned},
types::ReadPrecompileMap,
types::HlExtras,
},
HlBlock, HlBlockBody, HlPrimitives,
};
@ -137,7 +137,8 @@ where
body: HlBlockBody {
inner: BlockBody { transactions, ommers: Default::default(), withdrawals },
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)]
pub struct HlBlockExecutionCtx<'a> {
ctx: EthBlockExecutionCtx<'a>,
pub read_precompile_calls: ReadPrecompileMap,
pub extras: HlExtras,
}
impl<R, Spec, EvmF> BlockExecutorFactory for HlBlockExecutorFactory<R, Spec, EvmF>
@ -372,6 +373,11 @@ where
&self,
block: &'a SealedBlock<BlockTy<Self::Primitives>>,
) -> 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 {
ctx: EthBlockExecutionCtx {
parent_hash: block.header().parent_hash,
@ -379,11 +385,7 @@ where
ommers: &block.body().ommers,
withdrawals: block.body().withdrawals.as_ref().map(Cow::Borrowed),
},
read_precompile_calls: block
.body()
.read_precompile_calls
.clone()
.map_or(ReadPrecompileMap::default(), |calls| calls.into()),
extras,
}
}
@ -400,7 +402,7 @@ where
withdrawals: attributes.withdrawals.map(Cow::Owned),
},
// 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},
TxEnv,
},
interpreter::instructions::utility::IntoU256,
precompile::{PrecompileError, PrecompileOutput, PrecompileResult},
primitives::HashMap,
state::Bytecode,
@ -254,30 +255,43 @@ where
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();
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 {
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.
if block_number >= U256::from(7000000) {
// NOTE: This is adapted from hyperliquid-dex/hyper-evm-sync#5
const WARM_PRECOMPILES_BLOCK_NUMBER: u64 = 8_197_684;
if block_number >= U256::from(WARM_PRECOMPILES_BLOCK_NUMBER) {
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) {
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));
if !ctx.read_precompile_calls.contains_key(&address) {
precompiles_mut.apply_precompile(&address, |_| {
Some(DynPrecompile::from(move |_: PrecompileInput| -> PrecompileResult {
Err(PrecompileError::OutOfGas)
}))
});
}
precompiles_mut.apply_precompile(&address, |f| {
if let Some(precompile) = f {
return Some(precompile);
}
Some(DynPrecompile::from(move |_: PrecompileInput| -> PrecompileResult {
Err(PrecompileError::OutOfGas)
}))
});
}
}