Skip to content

fix: pin get_code_at to proof block in RpcExecutionProvider#780

Open
Galoretka wants to merge 1 commit intoa16z:masterfrom
Galoretka:fix/pin-get-code-at-to-block
Open

fix: pin get_code_at to proof block in RpcExecutionProvider#780
Galoretka wants to merge 1 commit intoa16z:masterfrom
Galoretka:fix/pin-get-code-at-to-block

Conversation

@Galoretka
Copy link
Copy Markdown

Why

get_code_at in [RpcExecutionProvider::get_account]

async fn get_account(
&self,
address: Address,
storage_slots: &[U256],
block_id: Option<BlockId>,
include_code: bool,
) -> Result<AccountResponse> {
let block_id = block_id.unwrap_or_default();
// make sure block ID is not tag but a number or hash
let block_id = match block_id {
BlockId::Number(number_or_tag) => match number_or_tag {
BlockNumberOrTag::Number(_) => Ok(block_id),
tag => Ok(BlockId::Number(
self.rpc
.get_block(tag.into())
.hashes()
.await?
.ok_or_eyre(ExecutionError::BlockNotFound(tag.into()))
.map(|block| block.header().number())?
.into(),
)),
},
BlockId::Hash(_) => Ok(block_id),
}?;
let storage_keys = storage_slots
.iter()
.map(|key| (*key).into())
.collect::<Vec<_>>();
let proof = self
.rpc
.get_proof(address, storage_keys)
.block_id(block_id)
.await?;
let code = if include_code {
Some(self.rpc.get_code_at(address).block_id(block_id).await?)
} else {
None
};
Ok(AccountResponse {
account: TrieAccount {
balance: proof.balance,
nonce: proof.nonce,
code_hash: proof.code_hash,
storage_root: proof.storage_hash,
},
code,
account_proof: proof.account_proof,
storage_proof: proof.storage_proof,
})
}
was called without .block_id(), defaulting to latest. Meanwhile get_proof right above
it was pinned to a specific block hash. If a new block arrived between the two RPC calls, the returned code could belong to a different state than the proof, causing a spurious CodeHashMismatch error.

What

Added .block_id(block.header().hash().into()) to the get_code_at call so it queries the same block as get_proof. This matches how every other callsite in the codebase already uses get_code_at.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant