-
Notifications
You must be signed in to change notification settings - Fork 0
feat: alias addresses #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
887bfdd
feat: alias addresses
prestwich d48ce80
feat: alias oracle
prestwich 3081915
chore: bump to 0.13 off aliasing branch
prestwich c86e37d
fix: tests pass again
prestwich a588cb1
chore: remove state provider height
prestwich 8e96f38
chore: remove block height arg and add test
prestwich 2259df5
fix: use revm spec consistently
prestwich 1932253
chore: bump to compat signet-sdk
prestwich 18ea175
chore: bump reth and update everything
prestwich File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| use alloy::{ | ||
| consensus::constants::KECCAK_EMPTY, | ||
| primitives::{Address, map::HashSet}, | ||
| }; | ||
| use eyre::OptionExt; | ||
| use reth::providers::{StateProvider, StateProviderFactory}; | ||
| use std::sync::{Arc, Mutex}; | ||
|
|
||
| /// Simple trait to allow checking if an address should be aliased. | ||
| pub trait AliasOracle { | ||
| /// Returns true if the given address is an alias. | ||
| fn should_alias(&self, address: Address) -> eyre::Result<bool>; | ||
| } | ||
|
|
||
| /// Default implementation of [`AliasOracle`] for any type implementing | ||
| /// [`StateProvider`]. This implementation checks if the address has bytecode | ||
| /// associated with it, and if so, whether that bytecode matches the pattern | ||
| /// for a 7702 delegation contract. If it is a delegation contract, it is not | ||
| /// aliased; otherwise, it is aliased. | ||
| impl AliasOracle for Box<dyn StateProvider> { | ||
| fn should_alias(&self, address: Address) -> eyre::Result<bool> { | ||
| // No account at this address. | ||
| let Some(acct) = self.basic_account(&address)? else { return Ok(false) }; | ||
| // Get the bytecode hash for this account. | ||
| let bch = match acct.bytecode_hash { | ||
| Some(hash) => hash, | ||
| // No bytecode hash; not a contract. | ||
| None => return Ok(false), | ||
| }; | ||
| // No code at this address. | ||
| if bch == KECCAK_EMPTY { | ||
| return Ok(false); | ||
| } | ||
| // Fetch the code associated with this bytecode hash. | ||
| let code = self | ||
| .bytecode_by_hash(&bch)? | ||
| .ok_or_eyre("code not found. This indicates a corrupted database")?; | ||
|
|
||
| // If not a 7702 delegation contract, alias it. | ||
| Ok(!code.is_eip7702()) | ||
| } | ||
| } | ||
|
|
||
| impl AliasOracle for HashSet<Address> { | ||
| fn should_alias(&self, address: Address) -> eyre::Result<bool> { | ||
| Ok(self.contains(&address)) | ||
| } | ||
| } | ||
|
|
||
| /// Factory trait to create new [`AliasOracle`] instances. | ||
| /// | ||
| /// The default implementation on `Box<dyn StateProviderFactory>` creates | ||
| /// [`AliasOracle`] instances backed by the state provider for a given block | ||
| /// height. It will error if that state provider cannot be obtained. | ||
| /// | ||
| /// This trait is primarily intended to allow injecting test implementations | ||
| /// of [`AliasOracle`] into the Signet Node for testing purposes. The test | ||
| /// implementation on [`HashSet<Address>`] allows specifying a fixed set of | ||
| /// addresses to be aliased. | ||
| pub trait AliasOracleFactory: Send + Sync + 'static { | ||
| /// The [`AliasOracle`] type. | ||
| type Oracle: AliasOracle; | ||
|
|
||
| /// Create a new [`AliasOracle`]. | ||
| fn create(&self) -> eyre::Result<Self::Oracle>; | ||
| } | ||
|
|
||
| impl AliasOracleFactory for Box<dyn StateProviderFactory> { | ||
| type Oracle = Box<dyn StateProvider>; | ||
|
|
||
| fn create(&self) -> eyre::Result<Self::Oracle> { | ||
| // NB: This becomes a problem if anyone ever birthday attacks a | ||
| // contract/EOA pair (c.f. EIP-3607). In practice this is unlikely to | ||
| // happen for the foreseeable future, and if it does we can revisit | ||
| // this decision. | ||
| // We considered taking the host height as an argument to this method, | ||
| // but this would require all nodes to be archive nodes in order to | ||
| // sync, which is less than ideal | ||
| self.state_by_block_number_or_tag(alloy::eips::BlockNumberOrTag::Latest).map_err(Into::into) | ||
| } | ||
| } | ||
|
|
||
| /// This implementation is primarily for testing purposes. | ||
| impl AliasOracleFactory for HashSet<Address> { | ||
| type Oracle = HashSet<Address>; | ||
|
|
||
| fn create(&self) -> eyre::Result<Self::Oracle> { | ||
| Ok(self.clone()) | ||
| } | ||
| } | ||
|
|
||
| impl<T> AliasOracleFactory for Mutex<T> | ||
| where | ||
| T: AliasOracleFactory, | ||
| { | ||
| type Oracle = T::Oracle; | ||
|
|
||
| fn create(&self) -> eyre::Result<Self::Oracle> { | ||
| let guard = | ||
| self.lock().map_err(|_| eyre::eyre!("failed to lock AliasOracleFactory mutex"))?; | ||
| guard.create() | ||
| } | ||
| } | ||
|
|
||
| impl<T> AliasOracleFactory for Arc<T> | ||
| where | ||
| T: AliasOracleFactory, | ||
| { | ||
| type Oracle = T::Oracle; | ||
|
|
||
| fn create(&self) -> eyre::Result<Self::Oracle> { | ||
| self.as_ref().create() | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| use reth::revm::primitives::hardfork::SpecId; | ||
| use reth_chainspec::EthereumHardforks; | ||
|
|
||
| /// Equivalent to [`reth_evm_ethereum::revm_spec`], however, always starts at | ||
| /// [`SpecId::PRAGUE`] and transitions to [`SpecId::OSAKA`]. | ||
| pub fn revm_spec(chain_spec: &reth::chainspec::ChainSpec, timestamp: u64) -> SpecId { | ||
| if chain_spec.is_amsterdam_active_at_timestamp(timestamp) { | ||
| SpecId::AMSTERDAM | ||
| } else if chain_spec.is_osaka_active_at_timestamp(timestamp) { | ||
| SpecId::OSAKA | ||
| } else { | ||
| SpecId::PRAGUE | ||
| } | ||
| } | ||
|
|
||
| /// This is simply a compile-time assertion to ensure that all SpecIds are | ||
| /// covered in the match. When this fails to compile, it indicates that a new | ||
| /// hardfork has been added and [`revm_spec`] needs to be updated. | ||
| #[allow(dead_code)] | ||
| const fn assert_in_range(spec_id: SpecId) { | ||
| match spec_id { | ||
| SpecId::FRONTIER | ||
| | SpecId::FRONTIER_THAWING | ||
| | SpecId::HOMESTEAD | ||
| | SpecId::DAO_FORK | ||
| | SpecId::TANGERINE | ||
| | SpecId::SPURIOUS_DRAGON | ||
| | SpecId::BYZANTIUM | ||
| | SpecId::CONSTANTINOPLE | ||
| | SpecId::PETERSBURG | ||
| | SpecId::ISTANBUL | ||
| | SpecId::MUIR_GLACIER | ||
| | SpecId::BERLIN | ||
| | SpecId::LONDON | ||
| | SpecId::ARROW_GLACIER | ||
| | SpecId::GRAY_GLACIER | ||
| | SpecId::MERGE | ||
| | SpecId::SHANGHAI | ||
| | SpecId::CANCUN | ||
| | SpecId::PRAGUE | ||
| | SpecId::OSAKA | ||
| | SpecId::AMSTERDAM => {} | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.