Skip to content

Conversation

@0xChaddB
Copy link
Contributor

Add a new method eth_getAddressesInBlock that returns all unique addresses that appear in a given block.

Implementation:

  • New EthAddresses trait added to FullEthApi

Fixes #19610

Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks pretty good already

left some nits

last q we need solve @klkvr is where to put this

Comment on lines +243 to +245
use reth_primitives_traits::SignerRecoverable;
for tx in block.body().transactions() {
if let Ok(signer) = tx.recover_signer() {
Copy link
Collaborator

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

/// Returns an iterator over `Recovered<&Transaction>`
#[inline]
pub fn transactions_recovered(
&self,
) -> impl Iterator<Item = Recovered<&'_ <B::Body as BlockBody>::Transaction>> + '_ {

Comment on lines +210 to +232

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()),
};
Copy link
Collaborator

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

let db = StateProviderDatabase::new(&state_provider);
let block_executor = this.evm_config().executor(db);

let mut record = ExecutionWitnessRecord::default();
Copy link
Collaborator

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

Comment on lines +280 to +297
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);
}
}
}
Copy link
Collaborator

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

Comment on lines +299 to +305
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());
};
Copy link
Collaborator

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

Comment on lines +455 to +457
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(
Copy link
Collaborator

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>> {

@github-project-automation github-project-automation bot moved this from Backlog to In Progress in Reth Tracker Nov 19, 2025
@mattsse mattsse added C-enhancement New feature or request A-rpc Related to the RPC implementation labels Nov 19, 2025
@klkvr
Copy link
Member

klkvr commented Nov 19, 2025

yeah I think Trace will be appropriate, it also seems like we need to do some actual tracing here? based on ethereum/execution-apis#456

An address MAY appear in any of the following:

Short description Description Access Comment
Opcode address argument Opcode "address" parameter (including but not limited to CALL, CALLCODE, STATICCALL, DELEGATECALL, SELFDESTRUCT) Accessible via call tracer "to" field
Internal return data RETURN data defined by "offset" and "size" fields Accessible via call tracer "output" field. 32 byte aligned, modulo 32 bytes
Create address Create family opcode (CREATE or CREATE2) return "address" field Accessible via call tracer "to" field
Internal calldata Call family opcode (CALL, CALLCODE, STATICCALL or DELGATECALL) argument data defined by opcode "argsOffset" and "argsSize" fields Accessible via call tracer "input" field. 32 byte aligned, modulo 32 bytes
Internal return data Call family opcode (CALL, CALLCODE, STATICCALL or DELGATECALL) return data defined by opcode "retOffset" and "retSize" fields Accessible via call tracer "output" field. 32 byte aligned, modulo 32 bytes
Internal create data Create-family (CREATE or CREATE2) data defined by opcode "offset" and "size" fields Accessible via call tracer "input" field. 32 byte aligned, modulo 32 bytes

Note that the call tracer "to", "from", "input" and "output" fields are sufficient to capture all
the required data not present in the transaction body and receipts. See below for an algorithm
for finding Appearances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-rpc Related to the RPC implementation C-enhancement New feature or request

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Add eth_getAddressesInBlock support

3 participants