-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat: add eth_getAddressesInBlock RPC method #19858
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
base: main
Are you sure you want to change the base?
feat: add eth_getAddressesInBlock RPC method #19858
Conversation
mattsse
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| use reth_primitives_traits::SignerRecoverable; | ||
| for tx in block.body().transactions() { | ||
| if let Ok(signer) = tx.recover_signer() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should already be recovered so we can iterate over
reth/crates/primitives-traits/src/block/recovered.rs
Lines 341 to 345 in 819330c
| /// Returns an iterator over `Recovered<&Transaction>` | |
| #[inline] | |
| pub fn transactions_recovered( | |
| &self, | |
| ) -> impl Iterator<Item = Recovered<&'_ <B::Body as BlockBody>::Transaction>> + '_ { |
|
|
||
| if block_id.is_pending() { | ||
| return Ok(Vec::new()); | ||
| } | ||
|
|
||
| let block_hash = match self | ||
| .provider() | ||
| .block_hash_for_id(block_id) | ||
| .map_err(|e| reth_rpc_eth_types::EthApiError::Internal(e.into()))? | ||
| { | ||
| Some(hash) => hash, | ||
| None => return Ok(Vec::new()), | ||
| }; | ||
|
|
||
| let block = match self | ||
| .cache() | ||
| .get_recovered_block(block_hash) | ||
| .await | ||
| .map_err(|e| reth_rpc_eth_types::EthApiError::Internal(e.into()))? | ||
| { | ||
| Some(block) => block, | ||
| None => return Ok(Vec::new()), | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this should already be just
| fn recovered_block( |
| let db = StateProviderDatabase::new(&state_provider); | ||
| let block_executor = this.evm_config().executor(db); | ||
|
|
||
| let mut record = ExecutionWitnessRecord::default(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need this here and can instead take a look at the full state output and iterate over the accounts in there
| use alloy_primitives::keccak256; | ||
| for key_bytes in &witness_record.keys { | ||
| // Only consider 20-byte entries as potential addresses | ||
| if key_bytes.len() == 20 && | ||
| let Ok(address_bytes) = <[u8; 20]>::try_from(&key_bytes[..]) | ||
| { | ||
| let address = Address::from(address_bytes); | ||
| let hashed_addr = keccak256(address.as_slice()); | ||
| let hash_b256 = alloy_primitives::B256::from(hashed_addr); | ||
|
|
||
| // Validate this is actually an account by checking if its hash exists in | ||
| // hashed_state This removes false positives while not | ||
| // relying on private fields | ||
| if witness_record.hashed_state.accounts.contains_key(&hash_b256) { | ||
| set.insert(address); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then we don't need any of this
| let Some(receipts) = self | ||
| .provider() | ||
| .receipts_by_block_id(block_id) | ||
| .map_err(|e| reth_rpc_eth_types::EthApiError::Internal(e.into()))? | ||
| else { | ||
| return Ok(set.into_iter().collect()); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can use
| fn load_block_and_receipts( |
to fetch both block and receipts
| pub trait EthAddresses: LoadState<Error: FromEvmError<Self::Evm>> { | ||
| /// Returns the list of addresses that appeared in the given block. | ||
| async fn get_addresses_in_block( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any ideas where we can best integrate this @klkvr
perhaps simply in the Trace api?
| pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> { |
|
yeah I think An address MAY appear in any of the following:
Note that the call tracer "to", "from", "input" and "output" fields are sufficient to capture all |
Add a new method
eth_getAddressesInBlockthat returns all unique addresses that appear in a given block.Implementation:
EthAddressestrait added toFullEthApiFixes #19610