Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol";
import {
FeeLib, FeeHeaderLib, FeeAssetValue, PriceLib
} from "@aztec/core/libraries/rollup/FeeLib.sol";
import {HeaderLib} from "@aztec/core/libraries/rollup/HeaderLib.sol";
import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol";
import {
AddressSnapshotLib,
SnapshottedAddressSet
Expand Down Expand Up @@ -104,7 +104,7 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore {
* @param _flags - The flags to validate
*/
function validateHeader(
bytes calldata _header,
ProposedHeader calldata _header,
CommitteeAttestation[] memory _attestations,
bytes32 _digest,
Timestamp _currentTime,
Expand All @@ -113,7 +113,7 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore {
) external override(IRollup) {
ProposeLib.validateHeader(
ValidateHeaderArgs({
header: HeaderLib.decode(_header),
header: _header,
attestations: _attestations,
digest: _digest,
currentTime: _currentTime,
Expand Down Expand Up @@ -205,7 +205,7 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore {
bytes32 tipArchive = rollupStore.blocks[pendingBlockNumber].archive;
require(tipArchive == _archive, Errors.Rollup__InvalidArchive(tipArchive, _archive));

address proposer = ValidatorSelectionLib.getProposerAt(slot, slot.epochFromSlot());
address proposer = ValidatorSelectionLib.getProposerAt(slot);
require(
proposer == msg.sender, Errors.ValidatorSelection__InvalidProposer(proposer, msg.sender)
);
Expand Down Expand Up @@ -638,9 +638,7 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore {
* @return The address of the proposer
*/
function getProposerAt(Timestamp _ts) public override(IValidatorSelection) returns (address) {
Slot slot = _ts.slotFromTimestamp();
Epoch epochNumber = slot.epochFromSlot();
return ValidatorSelectionLib.getProposerAt(slot, epochNumber);
return ValidatorSelectionLib.getProposerAt(_ts.slotFromTimestamp());
}

/**
Expand Down
3 changes: 2 additions & 1 deletion l1-contracts/src/core/interfaces/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
FeeHeader, L1FeeData, ManaBaseFeeComponents
} from "@aztec/core/libraries/rollup/FeeLib.sol";
import {FeeAssetPerEthE9, EthValue, FeeAssetValue} from "@aztec/core/libraries/rollup/FeeLib.sol";
import {ProposedHeader} from "@aztec/core/libraries/rollup/ProposedHeaderLib.sol";
import {ProposeArgs} from "@aztec/core/libraries/rollup/ProposeLib.sol";
import {Timestamp, Slot, Epoch} from "@aztec/core/libraries/TimeLib.sol";
import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol";
Expand Down Expand Up @@ -143,7 +144,7 @@ interface IRollupCore {

interface IRollup is IRollupCore {
function validateHeader(
bytes calldata _header,
ProposedHeader calldata _header,
CommitteeAttestation[] memory _attestations,
bytes32 _digest,
Timestamp _currentTime,
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/src/core/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ library Errors {
error Rollup__ManaLimitExceeded();
error Rollup__RewardsNotClaimable();

// HeaderLib
// ProposedHeaderLib
error HeaderLib__InvalidHeaderSize(uint256 expected, uint256 actual); // 0xf3ccb247
error HeaderLib__InvalidSlotNumber(Slot expected, Slot actual); // 0x09ba91ff

Expand Down
106 changes: 0 additions & 106 deletions l1-contracts/src/core/libraries/rollup/HeaderLib.sol

This file was deleted.

14 changes: 7 additions & 7 deletions l1-contracts/src/core/libraries/rollup/ProposeLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {Timestamp, Slot, Epoch, TimeLib} from "@aztec/core/libraries/TimeLib.sol
import {ValidatorSelectionLib} from
"@aztec/core/libraries/validator-selection/ValidatorSelectionLib.sol";
import {BlobLib} from "./BlobLib.sol";
import {Header, HeaderLib} from "./HeaderLib.sol";
import {ProposedHeader, ProposedHeaderLib, StateReference} from "./ProposedHeaderLib.sol";
import {STFLib} from "./STFLib.sol";

struct ProposeArgs {
Expand All @@ -26,15 +26,15 @@ struct ProposeArgs {
// It doesn't need to be in the proposed header as the values are not used in propose() and they are committed to
// by the last archive and blobs hash.
// It can be removed if the archiver can refer to world state for the updated roots.
bytes stateReference;
StateReference stateReference;
OracleInput oracleInput;
bytes header;
ProposedHeader header;
bytes32[] txHashes;
}

struct ProposePayload {
bytes32 archive;
bytes stateReference;
StateReference stateReference;
OracleInput oracleInput;
bytes32 headerHash;
bytes32[] txHashes;
Expand All @@ -58,7 +58,7 @@ struct InterimProposeValues {
* @param flags - Flags specific to the execution, whether certain checks should be skipped
*/
struct ValidateHeaderArgs {
Header header;
ProposedHeader header;
CommitteeAttestation[] attestations;
bytes32 digest;
Timestamp currentTime;
Expand Down Expand Up @@ -97,8 +97,8 @@ library ProposeLib {
(v.blobHashes, v.blobsHashesCommitment, v.blobPublicInputsHash) =
BlobLib.validateBlobs(_blobInput, _checkBlob);

Header memory header = HeaderLib.decode(_args.header);
v.headerHash = HeaderLib.hash(_args.header);
ProposedHeader memory header = _args.header;
v.headerHash = ProposedHeaderLib.hash(_args.header);

Epoch currentEpoch = Timestamp.wrap(block.timestamp).epochFromTimestamp();
ValidatorSelectionLib.setupEpoch(currentEpoch);
Expand Down
85 changes: 85 additions & 0 deletions l1-contracts/src/core/libraries/rollup/ProposedHeaderLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2024 Aztec Labs.
pragma solidity >=0.8.27;

import {Hash} from "@aztec/core/libraries/crypto/Hash.sol";

import {Slot, Timestamp} from "@aztec/core/libraries/TimeLib.sol";
import {SafeCast} from "@oz/utils/math/SafeCast.sol";

struct AppendOnlyTreeSnapshot {
bytes32 root;
uint32 nextAvailableLeafIndex;
}

struct PartialStateReference {
AppendOnlyTreeSnapshot noteHashTree;
AppendOnlyTreeSnapshot nullifierTree;
AppendOnlyTreeSnapshot publicDataTree;
}

struct StateReference {
AppendOnlyTreeSnapshot l1ToL2MessageTree;
// Note: Can't use "partial" name here as in protocol specs because it is a reserved solidity keyword
PartialStateReference partialStateReference;
}

struct GasFees {
uint128 feePerDaGas;
uint128 feePerL2Gas;
}

struct ContentCommitment {
uint256 numTxs;
bytes32 blobsHash;
bytes32 inHash;
bytes32 outHash;
}

struct ProposedHeader {
bytes32 lastArchiveRoot;
ContentCommitment contentCommitment;
Slot slotNumber;
Timestamp timestamp;
address coinbase;
bytes32 feeRecipient;
GasFees gasFees;
uint256 totalManaUsed;
}

/**
* @title ProposedHeader Library
* @author Aztec Labs
* @notice Decoding and validating a proposed L2 block header
*/
library ProposedHeaderLib {
using SafeCast for uint256;

/**
* @notice Hash the proposed header
*
* @dev The hashing here MUST match what is in the proposed_block_header.ts
*
* @param _header The header to hash
*
* @return The hash of the header
*/
function hash(ProposedHeader memory _header) internal pure returns (bytes32) {
return Hash.sha256ToField(
abi.encodePacked(
_header.lastArchiveRoot,
_header.contentCommitment.numTxs,
_header.contentCommitment.blobsHash,
_header.contentCommitment.inHash,
_header.contentCommitment.outHash,
_header.slotNumber,
Timestamp.unwrap(_header.timestamp).toUint64(),
_header.coinbase,
_header.feeRecipient,
_header.gasFees.feePerDaGas,
_header.gasFees.feePerL2Gas,
_header.totalManaUsed
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,18 +165,20 @@ library ValidatorSelectionLib {
}
}

function getProposerAt(Slot _slot, Epoch _epochNumber) internal returns (address) {
function getProposerAt(Slot _slot) internal returns (address) {
// @note this is deliberately "bad" for the simple reason of code reduction.
// it does not need to actually return the full committee and then draw from it
// it can just return the proposer directly, but then we duplicate the code
// which we just don't have room for right now...
uint224 sampleSeed = getSampleSeed(_epochNumber);
address[] memory committee = sampleValidators(_epochNumber, sampleSeed);
Epoch epochNumber = _slot.epochFromSlot();

uint224 sampleSeed = getSampleSeed(epochNumber);
address[] memory committee = sampleValidators(epochNumber, sampleSeed);
if (committee.length == 0) {
return address(0);
}

return committee[computeProposerIndex(_epochNumber, _slot, sampleSeed, committee.length)];
return committee[computeProposerIndex(epochNumber, _slot, sampleSeed, committee.length)];
}

/**
Expand Down
5 changes: 3 additions & 2 deletions l1-contracts/test/MultiProof.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ contract MultiProofTest is RollupBase {
modifier setUpFor(string memory _name) {
{
DecoderBase.Full memory full = load(_name);
uint256 slotNumber = full.block.decodedHeader.slotNumber;
uint256 initialTime = full.block.decodedHeader.timestamp - slotNumber * SLOT_DURATION;
uint256 slotNumber = Slot.unwrap(full.block.header.slotNumber);
uint256 initialTime =
Timestamp.unwrap(full.block.header.timestamp) - slotNumber * SLOT_DURATION;
vm.warp(initialTime);
}

Expand Down
Loading
Loading