Skip to content

Commit d48ce80

Browse files
committed
feat: alias oracle
1 parent 887bfdd commit d48ce80

File tree

4 files changed

+84
-12
lines changed

4 files changed

+84
-12
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use alloy::{
2+
consensus::constants::KECCAK_EMPTY,
3+
primitives::{Address, map::HashSet},
4+
};
5+
use eyre::OptionExt;
6+
use reth::providers::{StateProvider, StateProviderFactory};
7+
8+
/// Simple trait to allow checking if an address should be aliased.
9+
pub trait AliasOracle {
10+
/// Returns true if the given address is an alias.
11+
fn should_alias(&self, address: Address) -> eyre::Result<bool>;
12+
}
13+
14+
impl AliasOracle for Box<dyn StateProvider> {
15+
fn should_alias(&self, address: Address) -> eyre::Result<bool> {
16+
let Some(acct) = self.basic_account(&address)? else { return Ok(false) };
17+
let bch = match acct.bytecode_hash {
18+
Some(hash) => hash,
19+
None => return Ok(false),
20+
};
21+
if bch == KECCAK_EMPTY {
22+
return Ok(false);
23+
}
24+
let code = self
25+
.bytecode_by_hash(&bch)?
26+
.ok_or_eyre("code not found. This indicates a corrupted database")?;
27+
28+
// Check for 7702 delegations.
29+
if code.len() != 23 || !code.bytecode().starts_with(&[0xef, 0x01, 0x00]) {
30+
return Ok(true);
31+
}
32+
Ok(false)
33+
}
34+
}
35+
36+
impl AliasOracle for &HashSet<Address> {
37+
fn should_alias(&self, address: Address) -> eyre::Result<bool> {
38+
Ok(self.contains(&address))
39+
}
40+
}
41+
42+
/// Factory trait to create new [`AliasOracle`] instances.
43+
pub trait AliasOracleFactory: Send + Sync + 'static {
44+
/// The [`AliasOracle`] type.
45+
type Oracle<'a>: AliasOracle;
46+
47+
/// Create a new [`AliasOracle`].
48+
fn create(&self, block_height: u64) -> eyre::Result<Self::Oracle<'_>>;
49+
}
50+
51+
impl AliasOracleFactory for Box<dyn StateProviderFactory> {
52+
type Oracle<'a> = Box<dyn StateProvider>;
53+
54+
fn create(&self, block_height: u64) -> eyre::Result<Self::Oracle<'_>> {
55+
self.state_by_block_number_or_tag(block_height.into()).map_err(Into::into)
56+
}
57+
}
58+
59+
impl AliasOracleFactory for HashSet<Address> {
60+
type Oracle<'a> = &'a HashSet<Address>;
61+
62+
fn create(&self, _block_height: u64) -> eyre::Result<Self::Oracle<'_>> {
63+
Ok(self)
64+
}
65+
}

crates/block-processor/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
pub(crate) mod metrics;
1515

16+
mod alias;
17+
pub use alias::{AliasOracle, AliasOracleFactory};
18+
1619
mod v1;
1720
pub use v1::SignetBlockProcessor as SignetBlockProcessorV1;
1821

crates/block-processor/src/v1/processor.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Chain, metrics};
1+
use crate::{AliasOracle, AliasOracleFactory, Chain, metrics};
22
use alloy::{
33
consensus::BlockHeader,
44
primitives::{Address, B256, map::HashSet},
@@ -29,7 +29,7 @@ use trevm::revm::primitives::hardfork::SpecId;
2929

3030
/// A block processor that listens to host chain commits and processes
3131
/// Signet blocks accordingly.
32-
pub struct SignetBlockProcessor<Db>
32+
pub struct SignetBlockProcessor<Db, Alias = Box<dyn StateProviderFactory>>
3333
where
3434
Db: NodeTypesDbTrait,
3535
{
@@ -43,7 +43,7 @@ where
4343
ru_provider: ProviderFactory<SignetNodeTypes<Db>>,
4444

4545
/// A [`ProviderFactory`] instance to allow Host database access.
46-
host_provider: Box<dyn StateProviderFactory>,
46+
alias_oracle: Alias,
4747

4848
/// The slot calculator.
4949
slot_calculator: SlotCalculator,
@@ -61,20 +61,21 @@ where
6161
}
6262
}
6363

64-
impl<Db> SignetBlockProcessor<Db>
64+
impl<Db, Alias> SignetBlockProcessor<Db, Alias>
6565
where
6666
Db: NodeTypesDbTrait,
67+
Alias: AliasOracleFactory,
6768
{
6869
/// Create a new [`SignetBlockProcessor`].
6970
pub const fn new(
7071
constants: SignetSystemConstants,
7172
chain_spec: Arc<ChainSpec>,
7273
ru_provider: ProviderFactory<SignetNodeTypes<Db>>,
73-
host_provider: Box<dyn StateProviderFactory>,
74+
alias_oracle: Alias,
7475
slot_calculator: SlotCalculator,
7576
blob_cacher: CacheHandle,
7677
) -> Self {
77-
Self { constants, chain_spec, ru_provider, host_provider, slot_calculator, blob_cacher }
78+
Self { constants, chain_spec, ru_provider, alias_oracle, slot_calculator, blob_cacher }
7879
}
7980

8081
/// Get the active spec id at the given timestamp.
@@ -111,9 +112,8 @@ where
111112
}
112113

113114
/// Check if the given address should be aliased.
114-
fn should_alias(&self, host_height: u64, address: Address) -> eyre::Result<bool> {
115-
let state = self.host_provider.history_by_block_number(host_height)?;
116-
state.account_code(&address).map(|code| code.is_some()).map_err(Into::into)
115+
fn should_alias(&self, address: Address, host_height: u64) -> eyre::Result<bool> {
116+
self.alias_oracle.create(host_height)?.should_alias(address)
117117
}
118118

119119
/// Called when the host chain has committed a block or set of blocks.
@@ -263,10 +263,11 @@ where
263263
None => VecDeque::new(),
264264
};
265265

266+
// Determine which addresses need to be aliased.
266267
let mut to_alias: HashSet<Address> = Default::default();
267268
for transact in block_extracts.transacts() {
268269
let addr = transact.host_sender();
269-
if self.should_alias(host_height, addr)? {
270+
if !to_alias.contains(&addr) && self.should_alias(addr, host_height)? {
270271
to_alias.insert(addr);
271272
}
272273
}

crates/node/src/node.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ use reth::{
1111
providers::{
1212
BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, CanonChainTracker,
1313
CanonStateNotification, CanonStateNotifications, CanonStateSubscriptions, HeaderProvider,
14-
NodePrimitivesProvider, ProviderFactory, providers::BlockchainProvider,
14+
NodePrimitivesProvider, ProviderFactory, StateProviderFactory,
15+
providers::BlockchainProvider,
1516
},
1617
rpc::types::engine::ForkchoiceState,
1718
};
@@ -173,11 +174,13 @@ where
173174
.wrap_err("failed to create blob cacher")?
174175
.spawn();
175176

177+
let bdsp: Box<dyn StateProviderFactory> = Box::new(ctx.provider().clone());
178+
176179
let processor = SignetBlockProcessorV1::new(
177180
constants.clone(),
178181
config.chain_spec().clone(),
179182
factory.clone(),
180-
Box::new(ctx.provider().clone()),
183+
bdsp,
181184
config.slot_calculator(),
182185
blob_cacher,
183186
);

0 commit comments

Comments
 (0)