Skip to content

Commit

Permalink
refactor: unifying Header serialization accross domains (AztecProtoco…
Browse files Browse the repository at this point in the history
…l#4230)

Fixes AztecProtocol#4045
\+ renamed `HeaderDecoderHelper` as `HeaderLibHelper` to match the new
naming.
  • Loading branch information
benesjan authored Jan 26, 2024
1 parent 7e88fe8 commit 92080a0
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 80 deletions.
104 changes: 58 additions & 46 deletions l1-contracts/src/core/libraries/HeaderLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,29 @@ import {Hash} from "./Hash.sol";
* | byte start | num bytes | name
* | --- | --- | ---
* | | | Header {
* | | | GlobalVariables {
* | 0x0000 | 0x20 | chainId
* | 0x0020 | 0x20 | version
* | 0x0040 | 0x20 | blockNumber
* | 0x0060 | 0x20 | timestamp
* | | | }
* | 0x0000 | 0x20 | lastArchive.root
* | 0x0020 | 0x04 | lastArchive.nextAvailableLeafIndex
* | 0x0024 | 0x20 | bodyHash
* | | | StateReference {
* | 0x0080 | 0x20 | l1ToL2MessageTree.root
* | 0x00a0 | 0x04 | l1ToL2MessageTree.nextAvailableLeafIndex
* | 0x0044 | 0x20 | l1ToL2MessageTree.root
* | 0x0064 | 0x04 | l1ToL2MessageTree.nextAvailableLeafIndex
* | | | PartialStateReference {
* | 0x00a4 | 0x20 | noteHashTree.root
* | 0x00c4 | 0x04 | noteHashTree.nextAvailableLeafIndex
* | 0x00c8 | 0x20 | nullifierTree.root
* | 0x00e8 | 0x04 | nullifierTree.nextAvailableLeafIndex
* | 0x00ec | 0x20 | contractTree.root
* | 0x010c | 0x04 | contractTree.nextAvailableLeafIndex
* | 0x0110 | 0x20 | publicDataTree.root
* | 0x0130 | 0x04 | publicDataTree.nextAvailableLeafIndex
* | 0x0068 | 0x20 | noteHashTree.root
* | 0x0088 | 0x04 | noteHashTree.nextAvailableLeafIndex
* | 0x008c | 0x20 | nullifierTree.root
* | 0x00ac | 0x04 | nullifierTree.nextAvailableLeafIndex
* | 0x00b0 | 0x20 | contractTree.root
* | 0x00d0 | 0x04 | contractTree.nextAvailableLeafIndex
* | 0x00d4 | 0x20 | publicDataTree.root
* | 0x00f4 | 0x04 | publicDataTree.nextAvailableLeafIndex
* | | | }
* | | | }
* | 0x0134 | 0x20 | lastArchive.root
* | 0x0154 | 0x04 | lastArchive.nextAvailableLeafIndex
* | 0x0158 | 0x20 | bodyHash
* | | | GlobalVariables {
* | 0x00f8 | 0x20 | chainId
* | 0x0118 | 0x20 | version
* | 0x0138 | 0x20 | blockNumber
* | 0x0158 | 0x20 | timestamp
* | | | }
* | | | }
* | --- | --- | ---
*/
Expand All @@ -54,13 +54,6 @@ library HeaderLib {
uint32 nextAvailableLeafIndex;
}

struct GlobalVariables {
uint256 chainId;
uint256 version;
uint256 blockNumber;
uint256 timestamp;
}

struct PartialStateReference {
AppendOnlyTreeSnapshot noteHashTree;
AppendOnlyTreeSnapshot nullifierTree;
Expand All @@ -74,11 +67,18 @@ library HeaderLib {
PartialStateReference partialStateReference;
}

struct GlobalVariables {
uint256 chainId;
uint256 version;
uint256 blockNumber;
uint256 timestamp;
}

struct Header {
GlobalVariables globalVariables;
StateReference stateReference;
AppendOnlyTreeSnapshot lastArchive;
bytes32 bodyHash;
StateReference stateReference;
GlobalVariables globalVariables;
}

/**
Expand Down Expand Up @@ -132,24 +132,36 @@ library HeaderLib {

Header memory header;

header.globalVariables.chainId = uint256(bytes32(_header[:0x20]));
header.globalVariables.version = uint256(bytes32(_header[0x20:0x40]));
header.globalVariables.blockNumber = uint256(bytes32(_header[0x40:0x60]));
header.globalVariables.timestamp = uint256(bytes32(_header[0x60:0x80]));
header.stateReference.l1ToL2MessageTree =
AppendOnlyTreeSnapshot(bytes32(_header[0x80:0xa0]), uint32(bytes4(_header[0xa0:0xa4])));
header.stateReference.partialStateReference.noteHashTree =
AppendOnlyTreeSnapshot(bytes32(_header[0xa4:0xc4]), uint32(bytes4(_header[0xc4:0xc8])));
header.stateReference.partialStateReference.nullifierTree =
AppendOnlyTreeSnapshot(bytes32(_header[0xc8:0xe8]), uint32(bytes4(_header[0xe8:0xec])));
header.stateReference.partialStateReference.contractTree =
AppendOnlyTreeSnapshot(bytes32(_header[0xec:0x10c]), uint32(bytes4(_header[0x10c:0x110])));
header.stateReference.partialStateReference.publicDataTree =
AppendOnlyTreeSnapshot(bytes32(_header[0x110:0x130]), uint32(bytes4(_header[0x130:0x134])));
header.lastArchive =
AppendOnlyTreeSnapshot(bytes32(_header[0x134:0x154]), uint32(bytes4(_header[0x154:0x158])));

header.bodyHash = bytes32(_header[0x158:0x178]);
// Reading lastArchive
header.lastArchive = AppendOnlyTreeSnapshot(
bytes32(_header[0x0000:0x0020]), uint32(bytes4(_header[0x0020:0x0024]))
);

// Reading bodyHash
header.bodyHash = bytes32(_header[0x0024:0x0044]);

// Reading StateReference
header.stateReference.l1ToL2MessageTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x0044:0x0064]), uint32(bytes4(_header[0x0064:0x0068]))
);
header.stateReference.partialStateReference.noteHashTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x0068:0x0088]), uint32(bytes4(_header[0x0088:0x008c]))
);
header.stateReference.partialStateReference.nullifierTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x008c:0x00ac]), uint32(bytes4(_header[0x00ac:0x00b0]))
);
header.stateReference.partialStateReference.contractTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x00b0:0x00d0]), uint32(bytes4(_header[0x00d0:0x00d4]))
);
header.stateReference.partialStateReference.publicDataTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x00d4:0x00f4]), uint32(bytes4(_header[0x00f4:0x00f8]))
);

// Reading GlobalVariables
header.globalVariables.chainId = uint256(bytes32(_header[0x00f8:0x0118]));
header.globalVariables.version = uint256(bytes32(_header[0x0118:0x0138]));
header.globalVariables.blockNumber = uint256(bytes32(_header[0x0138:0x0158]));
header.globalVariables.timestamp = uint256(bytes32(_header[0x0158:0x0178]));

return header;
}
Expand Down
6 changes: 3 additions & 3 deletions l1-contracts/test/Rollup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ contract RollupTest is DecoderBase {
bytes memory body = data.body;

assembly {
mstore(add(header, 0x20), 0x420)
mstore(add(header, add(0x20, 0x00f8)), 0x420)
}

bytes32 txsHash = availabilityOracle.publish(body);
Expand All @@ -83,7 +83,7 @@ contract RollupTest is DecoderBase {
bytes memory body = data.body;

assembly {
mstore(add(header, 0x40), 0x420)
mstore(add(header, add(0x20, 0x0118)), 0x420)
}

bytes32 txsHash = availabilityOracle.publish(body);
Expand All @@ -100,7 +100,7 @@ contract RollupTest is DecoderBase {

uint256 ts = block.timestamp + 1;
assembly {
mstore(add(header, 0x80), ts)
mstore(add(header, add(0x20, 0x0158)), ts)
}

bytes32 txsHash = availabilityOracle.publish(body);
Expand Down
6 changes: 3 additions & 3 deletions l1-contracts/test/decoders/Decoder.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {Hash} from "../../src/core/libraries/Hash.sol";
import {DataStructures} from "../../src/core/libraries/DataStructures.sol";

import {DecoderHelper} from "./helpers/DecoderHelper.sol";
import {HeaderDecoderHelper} from "./helpers/HeaderDecoderHelper.sol";
import {HeaderLibHelper} from "./helpers/HeaderLibHelper.sol";
import {MessagesDecoderHelper} from "./helpers/MessagesDecoderHelper.sol";
import {TxsDecoderHelper} from "./helpers/TxsDecoderHelper.sol";
import {HeaderLib} from "../../src/core/libraries/HeaderLib.sol";
Expand All @@ -27,13 +27,13 @@ import {AvailabilityOracle} from "../../src/core/availability_oracle/Availabilit
*/
contract DecoderTest is DecoderBase {
DecoderHelper internal helper;
HeaderDecoderHelper internal headerHelper;
HeaderLibHelper internal headerHelper;
MessagesDecoderHelper internal messagesHelper;
TxsDecoderHelper internal txsHelper;

function setUp() public virtual {
helper = new DecoderHelper();
headerHelper = new HeaderDecoderHelper();
headerHelper = new HeaderLibHelper();
messagesHelper = new MessagesDecoderHelper();
txsHelper = new TxsDecoderHelper();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity >=0.8.18;

import {HeaderLib} from "../../../src/core/libraries/HeaderLib.sol";

contract HeaderDecoderHelper {
contract HeaderLibHelper {
// A wrapper used such that we get "calldata" and not memory
function decode(bytes calldata _header) public pure returns (HeaderLib.Header memory) {
return HeaderLib.decode(_header);
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/test/fixtures/empty_block_0.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
}
}
},
"header": "0x0000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000001016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000001000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001801864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000041ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000601a005071a487e4891787073a91504fe6ea55280bc6f65a021fd6f7ca1f10aa02000000015b89af3c0d0bf66ac691697d317108e8f51bb8e3217d56f152b80867ad25d4a7",
"header": "0x1a005071a487e4891787073a91504fe6ea55280bc6f65a021fd6f7ca1f10aa02000000015b89af3c0d0bf66ac691697d317108e8f51bb8e3217d56f152b80867ad25d4a71864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000001016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000001000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001801864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000041ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000600000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000",
"l1ToL2MessagesHash": "0x076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560",
"publicInputsHash": "0x1476d6b0483d0d5fc4c9d3b04f50105d97a06bb01054ec7acccac3ff6c85f960"
}
Expand Down
8 changes: 4 additions & 4 deletions l1-contracts/test/fixtures/empty_block_1.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions l1-contracts/test/fixtures/mixed_block_0.json

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions l1-contracts/test/fixtures/mixed_block_1.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion yarn-project/circuits.js/src/structs/global_variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class GlobalVariables {
}

static getFields(fields: FieldsOf<GlobalVariables>) {
// Note: The order here must match the order in the HeaderDecoder solidity library.
// Note: The order here must match the order in the HeaderLib solidity library.
return [fields.chainId, fields.version, fields.blockNumber, fields.timestamp] as const;
}

Expand Down
17 changes: 9 additions & 8 deletions yarn-project/circuits.js/src/structs/header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,18 @@ export class Header {
}

toBuffer() {
// Note: The order here must match the order in the HeaderDecoder solidity library.
return serializeToBuffer(this.globalVariables, this.state, this.lastArchive, this.bodyHash);
// Note: The order here must match the order in the HeaderLib solidity library.
return serializeToBuffer(this.lastArchive, this.bodyHash, this.state, this.globalVariables);
}

static fromBuffer(buffer: Buffer | BufferReader): Header {
const reader = BufferReader.asReader(buffer);
// TODO(#4045): unify ordering here with ordering in constructor.
const globalVariables = reader.readObject(GlobalVariables);
const state = reader.readObject(StateReference);
const lastArchive = reader.readObject(AppendOnlyTreeSnapshot);
const bodyHash = reader.readBytes(NUM_BYTES_PER_SHA256);
return new Header(lastArchive, bodyHash, state, globalVariables);

return new Header(
reader.readObject(AppendOnlyTreeSnapshot),
reader.readBytes(NUM_BYTES_PER_SHA256),
reader.readObject(StateReference),
reader.readObject(GlobalVariables),
);
}
}
2 changes: 1 addition & 1 deletion yarn-project/circuits.js/src/structs/state_reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class StateReference {
) {}

toBuffer() {
// Note: The order here must match the order in the HeaderDecoder solidity library.
// Note: The order here must match the order in the HeaderLib solidity library.
return serializeToBuffer(this.l1ToL2MessageTree, this.partial);
}

Expand Down

0 comments on commit 92080a0

Please sign in to comment.