Skip to content

Commit

Permalink
feat(protocol): update LibBlockHeader to hash post Shanghai fork bl…
Browse files Browse the repository at this point in the history
…ocks (#13278)

Co-authored-by: dave | d1onys1us <[email protected]>
  • Loading branch information
davidtaikocha and dionysuzx authored Mar 9, 2023
1 parent 8ca632c commit 2e34634
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 8 deletions.
20 changes: 14 additions & 6 deletions packages/protocol/contracts/libs/LibBlockHeader.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct BlockHeader {
bytes32 mixHash;
uint64 nonce;
uint256 baseFeePerGas;
bytes32 withdrawalsRoot;
}

library LibBlockHeader {
Expand All @@ -44,12 +45,15 @@ library LibBlockHeader {
BlockHeader memory header,
uint256 extraCapacity
) internal pure returns (bytes[] memory list) {
if (header.baseFeePerGas == 0) {
// non-EIP11559 transaction
list = new bytes[](15 + extraCapacity);
} else {
// EIP1159 transaction
if (header.withdrawalsRoot != 0) {
// EIP-4895 transaction
list = new bytes[](17 + extraCapacity);
} else if (header.baseFeePerGas != 0) {
// EIP-1559 transaction
list = new bytes[](16 + extraCapacity);
} else {
// non-EIP-1559 transaction
list = new bytes[](15 + extraCapacity);
}
list[0] = LibRLPWriter.writeHash(header.parentHash);
list[1] = LibRLPWriter.writeHash(header.ommersHash);
Expand All @@ -69,9 +73,13 @@ library LibBlockHeader {
// as [8]byte when hashing the block.
list[14] = LibRLPWriter.writeBytes(abi.encodePacked(header.nonce));
if (header.baseFeePerGas != 0) {
// non-EIP11559 transaction
// EIP-1559 transaction
list[15] = LibRLPWriter.writeUint(header.baseFeePerGas);
}
if (header.withdrawalsRoot != 0) {
// EIP-4895 transaction
list[16] = LibRLPWriter.writeHash(header.withdrawalsRoot);
}
}

function isPartiallyValidForTaiko(
Expand Down
50 changes: 49 additions & 1 deletion packages/protocol/test/libs/LibBlockHeader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe("LibBlockHeader tests", function () {
"0xf5ba25df1e92e89a09e0b32063b81795f631100801158f5fa733f2ba26843bd0",
nonce: EBN.from("0x738b7e38476abe98"),
baseFeePerGas: 0,
withdrawalsRoot: ethers.constants.HashZero,
};

const headerComputed = await libBlockHeader.hashBlockHeader(
Expand Down Expand Up @@ -87,6 +88,7 @@ describe("LibBlockHeader tests", function () {
mixHash: ethers.constants.HashZero,
nonce: EBN.from("0x0"),
baseFeePerGas: 0,
withdrawalsRoot: ethers.constants.HashZero,
};

const headerComputed = await libBlockHeader.hashBlockHeader(
Expand All @@ -96,7 +98,7 @@ describe("LibBlockHeader tests", function () {
expect(headerComputed).to.equal(blockHash);
});

it("can calculate EIP1159", async function () {
it("can calculate EIP-1559", async function () {
const blockHash =
"0xb39b05b327d23ca29286fa7e2331d8269cd257cf10a8310b40ebaddf411f191e";
// block 0xb39b05b327d23ca29286fa7e2331d8269cd257cf10a8310b40ebaddf411f191e on our L1 testnet
Expand Down Expand Up @@ -130,6 +132,52 @@ describe("LibBlockHeader tests", function () {
"0x0000000000000000000000000000000000000000000000000000000000000000",
nonce: "0x0",
baseFeePerGas: EBN.from("0x37"),
withdrawalsRoot: ethers.constants.HashZero,
};

const headerComputed = await libBlockHeader.hashBlockHeader(
l2BlockHeader
);
log.debug("headerComputed:", headerComputed);

expect(headerComputed).to.equal(blockHash);
});

it("can hash post Shanghai fork blocks", async function () {
const blockHash =
"0x0fb703aea6875ca7e78a73552064cf96a0985879c3b1fa27c846d41b1aa4e98e";
// block 0x0fb703aea6875ca7e78a73552064cf96a0985879c3b1fa27c846d41b1aa4e98e on Sepolia.

const parentHash =
"0xe122a2cc28199703e3ed6bee61875dc1703aa97c3187d8df507f1f789e363977";

const l2BlockHeader: any = {
parentHash: parentHash,
ommersHash:
"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
beneficiary: "0x3826539cbd8d68dcf119e80b994557b4278cec9f",
stateRoot:
"0x2525478f8cd349640e6d1780334e63c56fa0bfb44d89fbd75cb3fcf82d38521c",
transactionsRoot:
"0x97ea65e77b43073c372976694916209b916caa0caef1445d53e9757b9824bdef",
receiptsRoot:
"0xa8b034a217a5d4d4615ee0ed28c4d5275b93888c01c65a98fcdd1aeda6903e1c",
logsBloom:
"00000004000000000000000000100000000100000010001000000000000000000000880000000000000400001100000000000000000000000000000010300000000000000000000000000008000000000000200000000000000000008080000000002000020040000200000400000900000000000000000010000014000000000020024008000000000800000000900000211001000040002000000000000810021000000040400000102000000000040400002000000000000008000000001000008002300000000000000020000008004000000001000110000001000028000014440800010000000000000000000004210000000000400000000000000000"
.match(/.{1,64}/g)!
.map((s) => "0x" + s),
difficulty: EBN.from("0x0"),
height: EBN.from("0x2e93c3"),
gasLimit: EBN.from("0x1c9c380"),
gasUsed: EBN.from("0x44dd61"),
timestamp: EBN.from("0x64097a78"),
extraData: "0x",
mixHash:
"0xa3fedc5083947ffb01157d6a89aa00f0592e14b94da8768ac0e6ded0aa490eb8",
nonce: "0x0000000000000000",
baseFeePerGas: EBN.from("0x7"),
withdrawalsRoot:
"0x0975bba9482fab7591735f9dc8c344078d27abac007086d5dd62ee3a21e3ed29",
};

const headerComputed = await libBlockHeader.hashBlockHeader(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ describe("LibBlockHeaderDecoder", async function () {
"0xf5ba25df1e92e89a09e0b32063b81795f631100801158f5fa733f2ba26843bd0",
nonce: EBN.from("0x738b7e38476abe98"),
baseFeePerGas: 0,
withdrawalsRoot: ethers.constants.HashZero,
};

const encodedBlockHeader = await hashBlockHeader.rlpBlockHeader(
Expand Down Expand Up @@ -103,6 +104,7 @@ describe("LibBlockHeaderDecoder", async function () {
mixHash: block.mixHash,
nonce: block.nonce,
baseFeePerGas: 0,
withdrawalsRoot: ethers.constants.HashZero,
};
const encodedBlockHeader = await hashBlockHeader.rlpBlockHeader(
blockHeader
Expand Down Expand Up @@ -146,6 +148,7 @@ describe("LibBlockHeaderDecoder", async function () {
mixHash: block.mixHash,
nonce: block.nonce,
baseFeePerGas: 0,
withdrawalsRoot: ethers.constants.HashZero,
};
const encodedBlockHeader = await hashBlockHeader.rlpBlockHeader(
blockHeader
Expand Down
4 changes: 4 additions & 0 deletions packages/protocol/test/utils/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Block = {
uncles: string[];
baseFeePerGas?: string;
mixHash: string;
withdrawalsRoot: string;
};

type BlockHeader = {
Expand All @@ -56,6 +57,7 @@ type BlockHeader = {
mixHash: string;
nonce: number;
baseFeePerGas: number;
withdrawalsRoot: string;
};

async function getBlockHeader(
Expand Down Expand Up @@ -90,6 +92,8 @@ async function getBlockHeader(
mixHash: block.mixHash,
nonce: block.nonce,
baseFeePerGas: block.baseFeePerGas ? parseInt(block.baseFeePerGas) : 0,
// set to zero for pre-shanghai L1 blocks used in the integration test node
withdrawalsRoot: ethers.constants.HashZero,
};

return { block, blockHeader };
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/test/utils/signal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ async function getSignalProof(
// encode the SignalProof struct from LibBridgeSignal
const signalProof = ethers.utils.defaultAbiCoder.encode(
[
"tuple(tuple(bytes32 parentHash, bytes32 ommersHash, address beneficiary, bytes32 stateRoot, bytes32 transactionsRoot, bytes32 receiptsRoot, bytes32[8] logsBloom, uint256 difficulty, uint128 height, uint64 gasLimit, uint64 gasUsed, uint64 timestamp, bytes extraData, bytes32 mixHash, uint64 nonce, uint256 baseFeePerGas) header, bytes proof)",
"tuple(tuple(bytes32 parentHash, bytes32 ommersHash, address beneficiary, bytes32 stateRoot, bytes32 transactionsRoot, bytes32 receiptsRoot, bytes32[8] logsBloom, uint256 difficulty, uint128 height, uint64 gasLimit, uint64 gasUsed, uint64 timestamp, bytes extraData, bytes32 mixHash, uint64 nonce, uint256 baseFeePerGas, bytes32 withdrawalsRoot) header, bytes proof)",
],
[{ header: blockHeader, proof: encodedProof }]
);
Expand Down

0 comments on commit 2e34634

Please sign in to comment.