Skip to content
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

RPC API Headers doesn't match actual block header #1247

Open
Lohann opened this issue Nov 13, 2023 · 2 comments
Open

RPC API Headers doesn't match actual block header #1247

Lohann opened this issue Nov 13, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@Lohann
Copy link

Lohann commented Nov 13, 2023

Description
I'm building an ethereum light-client, and one of the steps is verifying the block hash, however there's a mismatch between the block header returned by the RPC API and the actual header stored, as such I cannot recompute the block hash, preventing frontier from working with ethereum light-clients that relies on the RPC API.

After a investigation I realized this happens because of two issues:

  1. The block header stores the timestamp in milliseconds, while the API converts it to seconds: https://github.com/polkadot-evm/frontier/blob/pallet-evm-v5.0.0/client/rpc/src/eth.rs#L135
  2. The RPC API returns the baseFeePerGas field, but this field is not encoded in the header. EIP-1559 says this field MUST be part of the block header:
  1. The timestamp is important for TIMESTAMP opcode, a ethereum light-client relies on getting the contract state using eth_createAccessList and eth_getProof for executing the call locally, by returning the wrong timestamp the light-client and the real node will get different results.

Example, the eth_getBlockByNumber endpoint returns:

{
  "author": "0xf02ddb48eda520c915c0dabadc70ba12d1b49ad2",
  "baseFeePerGas": "0x1e4073dfbf",
  "difficulty": "0x0",
  "extraData": "0x",
  "gasLimit": "0xe4e1c0",
  "gasUsed": "0x4e6b11",
  "hash": "0x84471574a6645fe3c4ea4fa7fb588f53f8cea681dd92d27d2de7c23f3040a7aa",
  "logsBloom": "0x825080001000080802020000108400509000410406003440c08000402084300000021000910005c000300400022000004b000000210228020008001c31208000000008418c21101800082008c04880020408240008008c008200400ac22010448401040002820001000000080000080002030000020180030000001480988003240082802888080802200164000010208024040b0810a0004041208004200060224000400200040002b20b0409016048a1020080100210102001f12c40000ac0880144020048000603280802800014210400001001240001018022008400a100001908900000830420000018000260000800000640001040004600012c000060",
  "miner": "0xf02ddb48eda520c915c0dabadc70ba12d1b49ad2",
  "nonce": "0x0000000000000000",
  "number": "0x4a1dbd",
  "parentHash": "0x93434fec7bb917a3fdf071d43e6bda1061eab7c4d5663192ad88353925b49849",
  "receiptsRoot": "0x088e158e77aa12898ed02e3ec20f030cd18054cd56890ad56a78a7ffadd4f5f3",
  "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  "size": "0x11f8",
  "stateRoot": "0xa7b30b5144ee34730d42b8ea7b5f240d830190ad83b098ddce0e89978ea1055a",
  "timestamp": "0x6551a2be",
  "totalDifficulty": "0x0",
  "transactions": [
	  "0xc42bbbe43ffbaa15c3f6fdd335eba12adf37520313d15b5496e77a67fbd35b1d",
	  "0x3df5b3ddaab690c68ed9e94cc086f210555d8ecc39c34aad292e8bd623b827d7",
	  "0xf708668e3002ec8a079e803e041091d8d5f2a7c3161a75c5c40592c18a9c67d2",
	  "0x5411f16773adac1f407d0161d3a0627fece66479e244d040d856e065794d4f04",
	  "0x0ba4819248cd220f1beb3f72482ef15f14121d7ab28d2deab0656452945db38b",
	  "0x9e01fd45eedbdf68665531dc9795f97c7a130b6bfbe633095b92f94a21c96adb",
	  "0xe227e458184c315517ea2c926d6505a6d53528d86acc1b29758f7c85e42a9821"
  ],
  "transactionsRoot": "0xa34082f12ca71f5b7111e910ed9fb1350e5692a09456a37edc791f055e0603e5",
  "uncles": []
}

But for correctly represent the block header, it should omit the baseFeePerGas and return the correct timestamp:

{
  "author": "0xf02ddb48eda520c915c0dabadc70ba12d1b49ad2",
  "difficulty": "0x0",
  "extraData": "0x",
  "gasLimit": "0xe4e1c0",
  "gasUsed": "0x4e6b11",
  "hash": "0x84471574a6645fe3c4ea4fa7fb588f53f8cea681dd92d27d2de7c23f3040a7aa",
  "logsBloom": "0x825080001000080802020000108400509000410406003440c08000402084300000021000910005c000300400022000004b000000210228020008001c31208000000008418c21101800082008c04880020408240008008c008200400ac22010448401040002820001000000080000080002030000020180030000001480988003240082802888080802200164000010208024040b0810a0004041208004200060224000400200040002b20b0409016048a1020080100210102001f12c40000ac0880144020048000603280802800014210400001001240001018022008400a100001908900000830420000018000260000800000640001040004600012c000060",
  "miner": "0xf02ddb48eda520c915c0dabadc70ba12d1b49ad2",
  "nonce": "0x0000000000000000",
  "number": "0x4a1dbd",
  "parentHash": "0x93434fec7bb917a3fdf071d43e6bda1061eab7c4d5663192ad88353925b49849",
  "receiptsRoot": "0x088e158e77aa12898ed02e3ec20f030cd18054cd56890ad56a78a7ffadd4f5f3",
  "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  "size": "0x11f8",
  "stateRoot": "0xa7b30b5144ee34730d42b8ea7b5f240d830190ad83b098ddce0e89978ea1055a",
  "timestamp": "0x18bc6e3b748",
  "totalDifficulty": "0x0",
  "transactions": [
	  "0xc42bbbe43ffbaa15c3f6fdd335eba12adf37520313d15b5496e77a67fbd35b1d",
	  "0x3df5b3ddaab690c68ed9e94cc086f210555d8ecc39c34aad292e8bd623b827d7",
	  "0xf708668e3002ec8a079e803e041091d8d5f2a7c3161a75c5c40592c18a9c67d2",
	  "0x5411f16773adac1f407d0161d3a0627fece66479e244d040d856e065794d4f04",
	  "0x0ba4819248cd220f1beb3f72482ef15f14121d7ab28d2deab0656452945db38b",
	  "0x9e01fd45eedbdf68665531dc9795f97c7a130b6bfbe633095b92f94a21c96adb",
	  "0xe227e458184c315517ea2c926d6505a6d53528d86acc1b29758f7c85e42a9821"
  ],
  "transactionsRoot": "0xa34082f12ca71f5b7111e910ed9fb1350e5692a09456a37edc791f055e0603e5",
  "uncles": []
}

Steps to Reproduce

To reproduce the issue above, simply build the Header using the block returned by the eth_getBlockBy* and notice the hash doesn't match:

use ethereum::Header;
use hex_literal::hex;

let header = Header {
    parent_hash: hex!("93434fec7bb917a3fdf071d43e6bda1061eab7c4d5663192ad88353925b49849").into(),
    ommers_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(),,
    beneficiary: hex!("f02ddb48eda520c915c0dabadc70ba12d1b49ad2").into(),
    state_root: hex!("a7b30b5144ee34730d42b8ea7b5f240d830190ad83b098ddce0e89978ea1055a").into(),
    transactions_root: hex!("a34082f12ca71f5b7111e910ed9fb1350e5692a09456a37edc791f055e0603e5").into(),
    receipts_root: hex!("088e158e77aa12898ed02e3ec20f030cd18054cd56890ad56a78a7ffadd4f5f3").into(),
    logs_bloom: hex!("825080001000080802020000108400509000410406003440c08000402084300000021000910005c000300400022000004b000000210228020008001c31208000000008418c21101800082008c04880020408240008008c008200400ac22010448401040002820001000000080000080002030000020180030000001480988003240082802888080802200164000010208024040b0810a0004041208004200060224000400200040002b20b0409016048a1020080100210102001f12c40000ac0880144020048000603280802800014210400001001240001018022008400a100001908900000830420000018000260000800000640001040004600012c000060").into(),
    difficulty: Default::default(),
    number: 0x004a1dbd.into(),
    gas_limit: 0x00e4e1c0.into(),
    gas_used: 0x004e6b11.into(),
    timestamp: 0x6551a2be,
    extra_data: Default::default(),
    mix_hash: Default::default(),
    nonce: Default::default(),
};

let expected = hex!("84471574a6645fe3c4ea4fa7fb588f53f8cea681dd92d27d2de7c23f3040a7aa").into();
let actual = header.hash();
assert_eq(expected, actual);

For testing the baseFeePerGas example, see the reth RLP encoder as reference:
https://github.com/paradigmxyz/reth/blob/v0.1.0-alpha.10/crates/primitives/src/header.rs#L324-L391

@arthur-cw
Copy link

arthur-cw commented Dec 6, 2023

hey @sorpaas, this is indeed happening, is it worth it to create a PR to fix the return of the RPC API?

@vedhavyas
Copy link
Contributor

hey @sorpaas, are you currently working on this fix ?
wanted to check since we are seeing an issue with forge when trying to send transaction so we are falling back to legacy instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants