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
2 changes: 1 addition & 1 deletion .github/workflows/devnet-deploys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ jobs:
# working-directory: ./yarn-project/aztec/terraform/pxe
# run: |
# set -eo pipefail
# docker run aztecprotocol/aztec:${{ env.DEPLOY_TAG }} set-proven-until \
# docker run aztecprotocol/aztec:${{ env.DEPLOY_TAG }} set-proven-through \
# --rpc-url https://api.aztec.network/${{ env.DEPLOY_TAG }}/aztec-pxe/${{ env.API_KEY }} \
# --l1-rpc-url https://${{ env.DEPLOY_TAG }}-mainnet-fork.aztec.network:8545/admin-${{ env.FORK_ADMIN_API_KEY }} \
# --l1-chain-id ${{ env.L1_CHAIN_ID }} \
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.provernet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ services:
SEQ_PUBLISHER_PRIVATE_KEY: "0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a"
VALIDATOR_PRIVATE_KEY: "0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a"
PROVER_REAL_PROOFS: "${PROVER_REAL_PROOFS:-false}"
ASSUME_PROVEN_UNTIL_BLOCK_NUMBER: "${ASSUME_PROVEN_UNTIL_BLOCK_NUMBER:-4}"
ASSUME_PROVEN_THROUGH_BLOCK_NUMBER: "${ASSUME_PROVEN_THROUGH_BLOCK_NUMBER:-4}"
P2P_ENABLED: false
IS_DEV_NET: true
volumes:
Expand Down Expand Up @@ -104,7 +104,7 @@ services:
PROVER_AGENT_ENABLED: false
PROVER_PUBLISHER_PRIVATE_KEY: "0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97"
PROVER_REAL_PROOFS: "${PROVER_REAL_PROOFS:-false}"
ASSUME_PROVEN_UNTIL_BLOCK_NUMBER: "${ASSUME_PROVEN_UNTIL_BLOCK_NUMBER:-4}"
ASSUME_PROVEN_THROUGH_BLOCK_NUMBER: "${ASSUME_PROVEN_THROUGH_BLOCK_NUMBER:-4}"
IS_DEV_NET: true
volumes:
- ./log/aztec-prover/:/usr/src/yarn-project/aztec/log:rw
Expand Down
105 changes: 41 additions & 64 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,9 @@ import {Leonidas} from "./sequencer_selection/Leonidas.sol";
contract Rollup is Leonidas, IRollup, ITestRollup {
using SafeCast for uint256;

struct ChainTip {
uint256 blockNumber;
uint256 slotNumber;
}

struct State {
ChainTip pendingTip;
ChainTip provenTip;
struct ChainTips {
uint256 pendingBlockNumber;
uint256 provenBlockNumber;
}

struct BlockLog {
Expand All @@ -64,7 +59,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
IFeeJuicePortal public immutable FEE_JUICE_PORTAL;
IVerifier public verifier;

State public state;
ChainTips public tips;

// @todo Validate assumption:
// Currently we assume that the archive root following a block is specific to the block
Expand All @@ -75,9 +70,9 @@ contract Rollup is Leonidas, IRollup, ITestRollup {

bytes32 public vkTreeRoot;

// @note Assume that all blocks up to this value (exclusive) are automatically proven. Speeds up bootstrapping.
// @note Assume that all blocks up to this value (inclusive) are automatically proven. Speeds up bootstrapping.
// Testing only. This should be removed eventually.
uint256 private assumeProvenUntilBlockNumber;
uint256 private assumeProvenThroughBlockNumber;

constructor(
IRegistry _registry,
Expand All @@ -101,10 +96,6 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
blockHash: bytes32(0),
slotNumber: 0
});

state.pendingTip = ChainTip({blockNumber: 0, slotNumber: 0});
state.provenTip = ChainTip({blockNumber: 0, slotNumber: 0});

for (uint256 i = 0; i < _validators.length; i++) {
_addValidator(_validators[i]);
}
Expand All @@ -119,11 +110,11 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
* @dev While in devnet, this will be guarded behind an `onlyOwner`
*/
function prune() external override(IRollup) onlyOwner {
if (state.pendingTip.blockNumber == state.provenTip.blockNumber) {
if (tips.pendingBlockNumber == tips.provenBlockNumber) {
revert Errors.Rollup__NothingToPrune();
}

BlockLog storage firstPendingNotInProven = blocks[state.provenTip.blockNumber + 1];
BlockLog storage firstPendingNotInProven = blocks[tips.provenBlockNumber + 1];
uint256 prunableAtSlot =
uint256(firstPendingNotInProven.slotNumber) + TIMELINESS_PROVING_IN_SLOTS;
uint256 currentSlot = getCurrentSlot();
Expand All @@ -132,32 +123,30 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
revert Errors.Rollup__NotReadyToPrune(currentSlot, prunableAtSlot);
}

uint256 pending = tips.pendingBlockNumber;

// @note We are not deleting the blocks, but we are "winding back" the pendingTip to the last block that was proven.
// We can do because any new block proposed will overwrite a previous block in the block log,
// so no values should "survive".
// People must therefore read the chain using the pendingTip as a boundary.
state.pendingTip = state.provenTip;
tips.pendingBlockNumber = tips.provenBlockNumber;

emit PrunedPending(state.pendingTip.blockNumber);
emit PrunedPending(tips.provenBlockNumber, pending);
}

/**
* Sets the assumeProvenUntilBlockNumber. Only the contract deployer can set it.
* Sets the assumeProvenThroughBlockNumber. Only the contract deployer can set it.
* @param blockNumber - New value.
*/
function setAssumeProvenUntilBlockNumber(uint256 blockNumber)
function setAssumeProvenThroughBlockNumber(uint256 blockNumber)
external
override(ITestRollup)
onlyOwner
{
if (
blockNumber > (state.provenTip.blockNumber + 1)
&& blockNumber <= (state.pendingTip.blockNumber + 1)
) {
state.provenTip =
ChainTip({blockNumber: blockNumber - 1, slotNumber: blocks[blockNumber - 1].slotNumber});
if (blockNumber > tips.provenBlockNumber && blockNumber <= tips.pendingBlockNumber) {
tips.provenBlockNumber = blockNumber;
}
assumeProvenUntilBlockNumber = blockNumber;
assumeProvenThroughBlockNumber = blockNumber;
}

/**
Expand Down Expand Up @@ -216,19 +205,16 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
_flags: DataStructures.ExecutionFlags({ignoreDA: false, ignoreSignatures: false})
});

state.pendingTip = ChainTip({
blockNumber: header.globalVariables.blockNumber,
slotNumber: header.globalVariables.slotNumber.toUint128()
});
uint256 blockNumber = ++tips.pendingBlockNumber;

blocks[header.globalVariables.blockNumber] = BlockLog({
blocks[blockNumber] = BlockLog({
archive: _archive,
blockHash: _blockHash,
slotNumber: header.globalVariables.slotNumber.toUint128()
});

// @note The block number here will always be >=1 as the genesis block is at 0
bytes32 inHash = INBOX.consume(header.globalVariables.blockNumber);
bytes32 inHash = INBOX.consume(blockNumber);
if (header.contentCommitment.inHash != inHash) {
revert Errors.Rollup__InvalidInHash(inHash, header.contentCommitment.inHash);
}
Expand All @@ -237,18 +223,13 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
// Min size = smallest path of the rollup tree + 1
(uint256 min,) = MerkleLib.computeMinMaxPathLength(header.contentCommitment.numTxs);
uint256 l2ToL1TreeMinHeight = min + 1;
OUTBOX.insert(
header.globalVariables.blockNumber, header.contentCommitment.outHash, l2ToL1TreeMinHeight
);
OUTBOX.insert(blockNumber, header.contentCommitment.outHash, l2ToL1TreeMinHeight);

emit L2BlockProposed(header.globalVariables.blockNumber);
emit L2BlockProposed(blockNumber);

// Automatically flag the block as proven if we have cheated and set assumeProvenUntilBlockNumber.
if (header.globalVariables.blockNumber < assumeProvenUntilBlockNumber) {
state.provenTip = ChainTip({
blockNumber: header.globalVariables.blockNumber,
slotNumber: header.globalVariables.slotNumber.toUint128()
});
// Automatically flag the block as proven if we have cheated and set assumeProvenThroughBlockNumber.
if (blockNumber <= assumeProvenThroughBlockNumber) {
tips.provenBlockNumber = blockNumber;

if (header.globalVariables.coinbase != address(0) && header.totalFees > 0) {
// @note This will currently fail if there are insufficient funds in the bridge
Expand All @@ -257,7 +238,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
FEE_JUICE_PORTAL.distributeFees(header.globalVariables.coinbase, header.totalFees);
}

emit L2ProofVerified(header.globalVariables.blockNumber, "CHEAT");
emit L2ProofVerified(blockNumber, "CHEAT");
}
}

Expand Down Expand Up @@ -294,20 +275,19 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
) external override(IRollup) {
HeaderLib.Header memory header = HeaderLib.decode(_header);

if (header.globalVariables.blockNumber > state.pendingTip.blockNumber) {
if (header.globalVariables.blockNumber > tips.pendingBlockNumber) {
revert Errors.Rollup__TryingToProveNonExistingBlock();
}

// @note This implicitly also ensures that we have not already proven, since
// the value `provenBlockCount` is incremented at the end of this function
if (header.globalVariables.blockNumber != state.provenTip.blockNumber + 1) {
// the value `tips.provenBlockNumber` is incremented at the end of this function
if (header.globalVariables.blockNumber != tips.provenBlockNumber + 1) {
revert Errors.Rollup__NonSequentialProving();
}

bytes32 expectedLastArchive = blocks[header.globalVariables.blockNumber - 1].archive;
// We do it this way to provide better error messages than passing along the storage values
// TODO(#4148) Proper genesis state. If the state is empty, we allow anything for now.
if (expectedLastArchive != bytes32(0) && header.lastArchive.root != expectedLastArchive) {
if (header.lastArchive.root != expectedLastArchive) {
revert Errors.Rollup__InvalidArchive(expectedLastArchive, header.lastArchive.root);
}

Expand Down Expand Up @@ -386,10 +366,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
revert Errors.Rollup__InvalidProof();
}

state.provenTip = ChainTip({
blockNumber: header.globalVariables.blockNumber,
slotNumber: header.globalVariables.slotNumber.toUint128()
});
tips.provenBlockNumber = header.globalVariables.blockNumber;

for (uint256 i = 0; i < 32; i++) {
address coinbase = address(uint160(uint256(publicInputs[25 + i * 2])));
Expand Down Expand Up @@ -433,7 +410,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
{
uint256 slot = getSlotAt(_ts);

uint256 lastSlot = uint256(state.pendingTip.slotNumber);
uint256 lastSlot = uint256(blocks[tips.pendingBlockNumber].slotNumber);
if (slot <= lastSlot) {
revert Errors.Rollup__SlotAlreadyInChain(lastSlot, slot);
}
Expand All @@ -449,7 +426,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
DataStructures.ExecutionFlags({ignoreDA: true, ignoreSignatures: true});
_validateLeonidas(slot, sigs, _archive, flags);

return (slot, state.pendingTip.blockNumber + 1);
return (slot, tips.pendingBlockNumber + 1);
}

/**
Expand Down Expand Up @@ -491,15 +468,15 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
* @return bytes32 - The current archive root
*/
function archive() public view override(IRollup) returns (bytes32) {
return blocks[state.pendingTip.blockNumber].archive;
return blocks[tips.pendingBlockNumber].archive;
}

function provenBlockNum() public view override(IRollup) returns (uint256) {
return state.provenTip.blockNumber;
function getProvenBlockNumber() public view override(IRollup) returns (uint256) {
return tips.provenBlockNumber;
}

function pendingBlockNum() public view override(IRollup) returns (uint256) {
return state.pendingTip.blockNumber;
function getPendingBlockNumber() public view override(IRollup) returns (uint256) {
return tips.pendingBlockNumber;
}

/**
Expand Down Expand Up @@ -600,9 +577,9 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
revert Errors.Rollup__InvalidVersion(VERSION, _header.globalVariables.version);
}

if (_header.globalVariables.blockNumber != state.pendingTip.blockNumber + 1) {
if (_header.globalVariables.blockNumber != tips.pendingBlockNumber + 1) {
revert Errors.Rollup__InvalidBlockNumber(
state.pendingTip.blockNumber + 1, _header.globalVariables.blockNumber
tips.pendingBlockNumber + 1, _header.globalVariables.blockNumber
);
}

Expand All @@ -616,7 +593,7 @@ contract Rollup is Leonidas, IRollup, ITestRollup {
revert Errors.Rollup__SlotValueTooLarge(slot);
}

uint256 lastSlot = uint256(state.pendingTip.slotNumber);
uint256 lastSlot = uint256(blocks[tips.pendingBlockNumber].slotNumber);
if (slot <= lastSlot) {
revert Errors.Rollup__SlotAlreadyInChain(lastSlot, slot);
}
Expand Down
8 changes: 4 additions & 4 deletions l1-contracts/src/core/interfaces/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import {DataStructures} from "../libraries/DataStructures.sol";
interface ITestRollup {
function setVerifier(address _verifier) external;
function setVkTreeRoot(bytes32 _vkTreeRoot) external;
function setAssumeProvenUntilBlockNumber(uint256 blockNumber) external;
function setAssumeProvenThroughBlockNumber(uint256 blockNumber) external;
}

interface IRollup {
event L2BlockProposed(uint256 indexed blockNumber);
event L2ProofVerified(uint256 indexed blockNumber, bytes32 indexed proverId);
event PrunedPending(uint256 provenBlockNumber);
event PrunedPending(uint256 provenBlockNumber, uint256 pendingBlockNumber);

function prune() external;

Expand Down Expand Up @@ -68,7 +68,7 @@ interface IRollup {

function archive() external view returns (bytes32);
function archiveAt(uint256 _blockNumber) external view returns (bytes32);
function provenBlockNum() external view returns (uint256);
function pendingBlockNum() external view returns (uint256);
function getProvenBlockNumber() external view returns (uint256);
function getPendingBlockNumber() external view returns (uint256);
function computeTxsEffectsHash(bytes calldata _body) external pure returns (bytes32);
}
4 changes: 2 additions & 2 deletions l1-contracts/src/core/messagebridge/Outbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ contract Outbox is IOutbox {
uint256 _leafIndex,
bytes32[] calldata _path
) external override(IOutbox) {
if (_l2BlockNumber > ROLLUP.provenBlockNum()) {
if (_l2BlockNumber > ROLLUP.getProvenBlockNumber()) {
revert Errors.Outbox__BlockNotProven(_l2BlockNumber);
}

Expand Down Expand Up @@ -157,7 +157,7 @@ contract Outbox is IOutbox {
override(IOutbox)
returns (bytes32 root, uint256 minHeight)
{
if (_l2BlockNumber > ROLLUP.provenBlockNum()) {
if (_l2BlockNumber > ROLLUP.getProvenBlockNumber()) {
return (bytes32(0), 0);
}
RootData storage rootData = roots[_l2BlockNumber];
Expand Down
4 changes: 2 additions & 2 deletions l1-contracts/test/Outbox.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import {NaiveMerkle} from "./merkle/Naive.sol";
import {MerkleTestUtil} from "./merkle/TestUtil.sol";

contract FakeRollup {
uint256 public provenBlockNum = 0;
uint256 public getProvenBlockNumber = 0;

function setProvenBlockNum(uint256 _provenBlockNum) public {
provenBlockNum = _provenBlockNum;
getProvenBlockNumber = _provenBlockNum;
}
}

Expand Down
Loading