-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
feat(rpc): rpc handler for eth_getUncleByBlock{Hash/Number}AndIndex #1595
feat(rpc): rpc handler for eth_getUncleByBlock{Hash/Number}AndIndex #1595
Conversation
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
crates/rpc/rpc/src/eth/api/block.rs
Outdated
let block_id = block_id.into(); | ||
let index = usize::from(index); | ||
let uncles = self.client().ommers(block_id)?.unwrap_or_default(); | ||
let Some(uncle_header) = uncles.get(index) else { |
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.
let Some(uncle_header) = uncles.get(index) else { | |
let Some(uncle_header) = uncles.skip(index).next() else { |
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'm guessing you meant? 😄 : let Some(uncle_header) = uncles.into_iter().skip(index).next() else {
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.
Clippy suggests nth, so I've used that instead 🙂 .
crates/rpc/rpc/src/eth/api/block.rs
Outdated
let Some(uncle_header) = uncles.get(index) else { | ||
return Ok(None) | ||
}; | ||
self.block(BlockId::from(uncle_header.number), false).await |
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 is not correct, we need to convert he Header into a block response instead.
An uncle doesn't contain individual transactions.
https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclebyblockhashandindex
So need to construct an RPC block from header only.
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.
Does that mean that I should add an RPC type like Block
, that lacks a transactions
field and use it as the return type then? 😄
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.
Correct it should be the same as get block with transaction hashes only
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've added this struct here for the response and a few more changes. Please, let me know what you think and if there's something else to improve 🙂.
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
/// An uncle block RPC response representation. | ||
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct OmmerBlock { |
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 think there's been some confusion about what to return for uncle.
we need to return the actual Block type:
e.g.
cast rpc eth_getUncleByBlockNumberAndIndex "0x27102" "0x0" --rpc-url "https://eth-mainnet.alchemyapi.io/v2/Lc7oIGYeL_QvInzI0Wiu_pOZZDEKBrdf" | jq
{
"difficulty": "0x6222410d3e2",
"extraData": "0xd783010002844765746887676f312e342e32856c696e7578",
"gasLimit": "0x2fefd8",
"gasUsed": "0x0",
"hash": "0x7ddcbe9b51cbead49b0edbb49b1a889a9cbc687cebd2cf05af43124d92472b5b",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5",
"mixHash": "0x98786cd3fc481f59562137daea90e3b7663eacbcee64f758d15e38aca31089c5",
"nonce": "0xdb601d60e4b0146a",
"number": "0x270ff",
"parentHash": "0x00e1e32b60c8a8b24ad81cd9cecab49574424add31933c861bea90df2dce628b",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size": "0x21d",
"stateRoot": "0xda97dd606da5ed4642c2fbb0c80c0cbf6951d5fd175bb258e538c9edaf6fcfab",
"timestamp": "0x55e19b96",
"transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncles": []
}
so it's the same as a regular but but some fields are default values, like bloom, gasUsed
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.
Oh, ok! Pushed some changes to use the original Block type, and this is what I get:
curl --location --request POST 'http://127.0.0.1:8545/' \
--header 'Content-Type: application/json' \
--data-raw '{
"jsonrpc": "2.0",
"method": "eth_getUncleByBlockNumberAndIndex",
"params":
[
"0x21",
"0x0"
],
"id": "0"
}
' | jq -S ".result"
{
"author": "0xdb312d1d6a2ccc64dd94a3892928bac82b4e8c15",
"difficulty": "0x40888145a",
"extraData": "0x476574682f76312e302e302d30636463373634372f6c696e75782f676f312e34",
"gasLimit": "0x1388",
"gasUsed": "0x0",
"hash": "0x962b18a4fcdd215e11db01308f6818735ea1b33377a82af39cb89fa6d4178204",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner": "0xdb312d1d6a2ccc64dd94a3892928bac82b4e8c15",
"mixHash": "0x5870078c7ab1637370a603260f3b25d5f006077df2fa0f868d0970ea32496075",
"nonce": "0x3673ed3d817b95bf",
"number": "0x1f",
"parentHash": "0xd1eb5ef56d30f0d773cccd3075c7fcca14ec9013db6b76344c69dbbaffaa9b8c",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size": "0x220",
"stateRoot": "0x1624d23c380d999ac180022f08f008849ed5a404e50a0a8c704d5a536742e471",
"timestamp": "0x55ba4322",
"transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncles": []
}
It matches the response that I get from Alchemy, except from one small thing, the "author" key.
crates/rpc/rpc/src/eth/api/block.rs
Outdated
return Ok(None) | ||
}; | ||
self.block(BlockId::from(uncle_header.number), false).await | ||
let uncle = uncles.into_iter().skip(index).next().map(|uncle| uncle.into()); |
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.
oh this should be equivalent to nth()
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
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.
only a few nits, otherwise lgtm
fyi: geth marshals uncles like:
which we do now mirror.
I wonder if these changes would make the block type less usable for third party crates. But for simplicity this is ok.
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub transactions: Option<BlockTransactions>, |
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.
the Option seems redundant if we have BlockTransactions::is_uncle
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.
You're right, changed it here 🙂
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub total_difficulty: Option<U256>, |
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.
right, this is excluded if uncle:
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] | ||
#[serde(untagged)] | ||
pub enum BlockTransactions { | ||
/// Only hashes | ||
Hashes(Vec<H256>), | ||
/// Full transactions | ||
Full(Vec<Transaction>), | ||
/// Special case for uncle response. | ||
NoTx, |
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.
can rename this to Uncle
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.
Done
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
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.
lgtm
tysm, nice job!
Changes: