Skip to content

Commit ea7a316

Browse files
just-mitchbenesjan
authored andcommitted
Doc improvements from @benesjan
1 parent 6cdd9b8 commit ea7a316

12 files changed

Lines changed: 119 additions & 63 deletions

File tree

cspell.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@
2828
"bbfree",
2929
"bbmalloc",
3030
"benesjan",
31+
"bignum",
3132
"Bincode",
3233
"bincoded",
3334
"bleurgh",
35+
"blobbasefee",
36+
"blobhash",
37+
"Blobhashes",
38+
"blobshash",
3439
"bodyparser",
3540
"bootnode",
3641
"bootnodes",
@@ -49,6 +54,7 @@
4954
"cbind",
5055
"cbinds",
5156
"Celestia",
57+
"chainid",
5258
"chainsafe",
5359
"cheatcode",
5460
"cheatcodes",
@@ -112,6 +118,7 @@
112118
"enrs",
113119
"entrypoints",
114120
"erc",
121+
"exitable",
115122
"falsey",
116123
"fargate",
117124
"Fernet",
@@ -143,6 +150,7 @@
143150
"hasher",
144151
"headstart",
145152
"herskind",
153+
"hevm",
146154
"homomorphic",
147155
"ierc",
148156
"IGSE",
@@ -247,6 +255,7 @@
247255
"preimage",
248256
"preimages",
249257
"prestat",
258+
"prevrandao",
250259
"println",
251260
"productionify",
252261
"protobuf",
@@ -269,6 +278,7 @@
269278
"reentrancy",
270279
"reexecute",
271280
"reexecution",
281+
"reinitialise",
272282
"repr",
273283
"Reserialize",
274284
"retag",
@@ -289,6 +299,7 @@
289299
"sigchld",
290300
"Signerless",
291301
"siloes",
302+
"slashable",
292303
"sload",
293304
"snakecase",
294305
"socat",
@@ -314,6 +325,7 @@
314325
"sysbox",
315326
"templating",
316327
"tldr",
328+
"tload",
317329
"tmpfs",
318330
"toplevel",
319331
"tparam",
@@ -322,6 +334,7 @@
322334
"trivago",
323335
"tsbuildinfo",
324336
"tsdoc",
337+
"tstore",
325338
"txes",
326339
"typechain",
327340
"typecheck",
@@ -389,5 +402,9 @@
389402
"lib",
390403
"*.cmake"
391404
],
392-
"flagWords": ["anonymous", "offence", "offences"]
405+
"flagWords": [
406+
"anonymous",
407+
"offence",
408+
"offences"
409+
]
393410
}

l1-contracts/src/core/RollupCore.sol

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import {G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol";
5252
* - Slots are grouped into epochs (configurable size, e.g., 32 slots)
5353
* - Each slot has one designated proposer from the validator set
5454
* - Each block is expected to include attestations from committee members
55-
* - Committees remain stable throughout an epoch
55+
* - There is one committee per epoch
5656
*
5757
* Key invariants:
5858
* - The L2 chain is linear (no forks) but can be rolled back
@@ -73,8 +73,8 @@ import {G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol";
7373
* purposes:
7474
* - Attest to data availability for transaction data not posted on L1, which is required by provers to generate
7575
* epoch proofs
76-
* - Re-execute everything and attest to the resulting state root, acting as training wheels for the proving
77-
* system
76+
* - Re-execute everything and attest to the resulting state root, acting as training wheels for the public
77+
* part of the system (proving systems used in public and AVM)
7878
*
7979
* 3) Proposers: Drafted from the validator set (currently proposers are part of the committee for the epoch,
8080
* though this may change). They have exclusive rights to propose a block at a given slot, ensuring orderly
@@ -135,7 +135,7 @@ import {G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol";
135135
* `prune()` manually, or automatically on the next proposal.
136136
* - The committee for the epoch is expected to disseminate transaction data to allow proving, so a prune is
137137
* considered a slashable offense, that causes validators to vote for slashing the committee of the unproven
138-
* epoch.
138+
* epoch.
139139
* - When the pending chain is pruned, all unproven blocks are removed from the pending chain, and the chain
140140
* resumes from the last proven block.
141141
*
@@ -199,7 +199,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
199199
bool public isRewardsClaimable = false;
200200

201201
/**
202-
* @notice Initializes the Aztec rollup with all required configuration
202+
* @notice Initializes the Aztec rollup with all required configurations
203203
* @dev Sets up time parameters, deploys auxiliary contracts (slasher, reward booster),
204204
* initializes staking, validator selection, and creates inbox/outbox contracts
205205
* @param _feeAsset The ERC20 token used for transaction fees
@@ -236,7 +236,7 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
236236
StakingLib.initialize(_stakingAsset, _gse, exitDelay, address(slasher), _config.stakingQueueConfig);
237237
ExtRollupLib2.initializeValidatorSelection(_config.targetCommitteeSize);
238238

239-
// If no booster specifically provided deploy one.
239+
// If no booster is specifically provided, deploy one.
240240
if (address(_config.rewardConfig.booster) == address(0)) {
241241
_config.rewardConfig.booster = ExtRollupLib3.deployRewardBooster(_config.rewardBoostConfig);
242242
}
@@ -520,12 +520,22 @@ contract RollupCore is EIP712("Aztec Rollup", "1"), Ownable, IStakingCore, IVali
520520

521521
/**
522522
* @notice Sets up validator selection for the current epoch
523-
* @dev Can be called by anyone at the start of an epoch. Samples the committee
524-
* and determines proposers for all slots in the epoch. Also stores a seed
525-
* that is used for future sampling. Automatically called during `propose`.
526-
* External mainly for testing and to setup an epoch if there were no block proposals.
523+
* @dev Can be called by anyone at the start of an epoch. Samples the committee and determines proposers for all
524+
* slots in the epoch. Also stores a seed that is used for future sampling. The corresponding library
525+
* functionality is automatically called when `RollupCore.propose(...)` is called (via the
526+
* `ExtRollupLib.propose(...)` -> `ProposeLib.propose(...)` -> `ValidatorSelectionLib.setupEpoch(...)`).
527+
*
528+
* If there are missed proposals then setupEpoch does not get called automatically. Since the next committee
529+
* selection is computed based on the latest stored seed and the epoch number, we would only fail to get a
530+
* fresh seed if:
531+
* 1. All the proposals in the epoch were missed
532+
* 2. Nobody called setupEpoch on the Rollup contract
533+
*
534+
* While an attacker might theoretically benefit from preventing a fresh seed (e.g. by DoSing all proposers),
535+
* preventing anyone from calling this function directly is not really feasible. This makes attacks on seed
536+
* generation impractical.
527537
*/
528-
function setupEpoch() public override(IValidatorSelectionCore) {
538+
function setupEpoch() external override(IValidatorSelectionCore) {
529539
ExtRollupLib2.setupEpoch();
530540
}
531541

l1-contracts/src/core/interfaces/IRollup.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ struct RollupConfig {
8484
struct RollupStore {
8585
CompressedChainTips tips; // put first such that the struct slot structure is easy to follow for cheatcodes
8686
mapping(uint256 blockNumber => bytes32 archive) archives;
87-
mapping(uint256 blockNumber => CompressedTempBlockLog temp) tempBlockLogs;
87+
// The following represents a circular buffer. Key is `blockNumber % size`.
88+
mapping(uint256 circularIndex => CompressedTempBlockLog temp) tempBlockLogs;
8889
RollupConfig config;
8990
}
9091

l1-contracts/src/core/libraries/TimeLib.sol

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,24 @@ library TimeLib {
7373
return _a + Epoch.wrap(store.proofSubmissionEpochs + 1);
7474
}
7575

76+
/**
77+
* @notice Calculates the maximum number of blocks that can be pruned from the pending chain
78+
* @dev The maximum prunable blocks is determined by:
79+
* - epochDuration: number of slots in an epoch
80+
* - proofSubmissionEpochs: number of epochs allowed for proof submission
81+
*
82+
* The formula is: epochDuration * (proofSubmissionEpochs + 1)
83+
*
84+
* The +1 accounts for blocks in the current epoch, ensuring they are included
85+
* in the prunable window along with blocks from previous epochs within the
86+
* proof submission window.
87+
*
88+
* This value is used to:
89+
* 1. Size the circular storage buffer (roundaboutSize = maxPrunableBlocks + 1)
90+
* 2. Determine when blocks become stale and can be overwritten
91+
*
92+
* @return The maximum number of blocks that can be pruned.
93+
*/
7694
function maxPrunableBlocks() internal view returns (uint256) {
7795
TimeStorage storage store = getStorage();
7896
return uint256(store.epochDuration) * (uint256(store.proofSubmissionEpochs) + 1);

l1-contracts/src/core/libraries/crypto/SampleLib.sol

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ library SampleLib {
5858
}
5959

6060
// Clear transient storage.
61-
// Note that we are cleaing the `sampleIndicies` and do not keep track of a separate list of
62-
// `sampleIndex` that was written to. The reasoning being that we are only overwriting for
63-
// duplicate cases, so `sampleIndicies` isa superset of the `sampleIndex` that have been drawn
64-
// (due to account for duplicates). Thereby clearing the `sampleIndicies` clears all.
65-
// Due to the cost of `tstore` and `tload` it is cheaper just to overwrite it all, than checking
66-
// if there is even anything to override.
61+
// Note that we are clearing the `sampleIndices` and do not keep track of a separate list of
62+
// `sampleIndex` values that were written to. The reasoning is that we only overwrite values for
63+
// duplicate cases, so `sampleIndices` is a superset of the `sampleIndex` values that have been drawn
64+
// (to account for duplicates). Therefore, clearing `sampleIndices` clears everything.
65+
// Due to the cost of `tstore` and `tload` operations, it is cheaper to overwrite all values
66+
// rather than checking if there is anything to override.
6767
for (uint256 i = 0; i < _committeeSize; i++) {
6868
setOverrideValue(sampledIndices[i], 0);
6969
}

l1-contracts/src/core/libraries/rollup/AttestationLib.sol

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ enum SignatureDomainSeparator {
1414

1515
// A committee attestation can be made up of a signature and an address.
1616
// Committee members that have attested will produce a signature, and if they have not attested, the signature will be
17-
// empty and
18-
// an address provided.
17+
// empty and an address provided.
1918
struct CommitteeAttestation {
2019
address addr;
2120
Signature signature;
@@ -128,11 +127,14 @@ library AttestationLib {
128127
}
129128

130129
/**
131-
* Returns the addresses from the CommitteeAttestations, using the array of signers to populate where there are
132-
* signatures.
133-
* Indices with signatures will have a zero address.
130+
* Recovers the committee from the addresses in the attestations and signers.
131+
*
134132
* @param _attestations - The committee attestations
133+
* @param _signers The addresses of the committee members that signed the attestations. Provided in order to not have
134+
* to recover them from their attestations' signatures (and hence save gas). The addresses of the non-signing
135+
* committee members are directly included in the attestations.
135136
* @param _length - The number of addresses to return, should match the number of committee members
137+
* @return The addresses of the committee members.
136138
*/
137139
function reconstructCommitteeFromSigners(
138140
CommitteeAttestations memory _attestations,

l1-contracts/src/core/libraries/rollup/BlobLib.sol

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ library BlobLib {
8181
* @notice Validate an L2 block's blobs and return the blobHashes, the hashed blobHashes, and blob commitments.
8282
*
8383
* We assume that the Aztec related blobs will be first in the propose transaction, additional blobs can be
84-
* at the end.
84+
* at the end.
8585
*
8686
* Input bytes:
8787
* input[0] - num blobs in block
8888
* input[1:] - blob commitments (48 bytes * num blobs in block)
8989
* @param _blobsInput - The above bytes to verify our input blob commitments match real blobs
9090
* @param _checkBlob - Whether to skip blob related checks. Hardcoded to true (See RollupCore.sol -> checkBlob),
91-
* exists only to be overriden in tests.
91+
* exists only to be overridden in tests.
92+
*
9293
* Returns for proposal:
9394
* @return blobHashes - All of the blob hashes included in this block, to be emitted in L2BlockProposed event.
9495
* @return blobsHashesCommitment - A hash of all blob hashes in this block, to be included in the block header. See
@@ -156,12 +157,10 @@ library BlobLib {
156157
* we know that the data in each blob of the epoch corresponds to the tx effects of all our proven txs in the epoch.
157158
*
158159
* The rollup circuits calculate each z_i and y_i as above, so if this function passes but they do not match the
159-
* values from the
160-
* circuit, then proof verification will fail.
160+
* values from the circuit, then proof verification will fail.
161161
*
162162
* Each commitment C_i is injected into the circuits and their correctness is validated using the blobCommitmentsHash,
163-
* as
164-
* explained below in calculateBlobCommitmentsHash().
163+
* as explained below in calculateBlobCommitmentsHash().
165164
*
166165
*/
167166
function validateBatchedBlob(bytes calldata _blobInput) internal view returns (bool success) {
@@ -172,7 +171,7 @@ library BlobLib {
172171

173172
/**
174173
* @notice Calculate the current state of the blobCommitmentsHash. Called for each new proposed block.
175-
* @param _previousblobCommitmentsHash - The previous block's blobCommitmentsHash.
174+
* @param _previousBlobCommitmentsHash - The previous block's blobCommitmentsHash.
176175
* @param _blobCommitments - The commitments corresponding to this block's blobs.
177176
* @param _isFirstBlockOfEpoch - Whether this block is the first of an epoch (see below).
178177
*
@@ -195,20 +194,20 @@ library BlobLib {
195194
*
196195
*/
197196
function calculateBlobCommitmentsHash(
198-
bytes32 _previousblobCommitmentsHash,
197+
bytes32 _previousBlobCommitmentsHash,
199198
bytes[] memory _blobCommitments,
200199
bool _isFirstBlockOfEpoch
201-
) internal pure returns (bytes32 currentblobCommitmentsHash) {
200+
) internal pure returns (bytes32 currentBlobCommitmentsHash) {
202201
uint256 i = 0;
203-
currentblobCommitmentsHash = _previousblobCommitmentsHash;
202+
currentBlobCommitmentsHash = _previousBlobCommitmentsHash;
204203
// If we are at the first block of an epoch, we reinitialise the blobCommitmentsHash.
205204
// Blob commitments are collected and proven per root rollup proof => per epoch.
206205
if (_isFirstBlockOfEpoch) {
207206
// Initialise the blobCommitmentsHash
208-
currentblobCommitmentsHash = Hash.sha256ToField(abi.encodePacked(_blobCommitments[i++]));
207+
currentBlobCommitmentsHash = Hash.sha256ToField(abi.encodePacked(_blobCommitments[i++]));
209208
}
210209
for (i; i < _blobCommitments.length; i++) {
211-
currentblobCommitmentsHash = Hash.sha256ToField(abi.encodePacked(currentblobCommitmentsHash, _blobCommitments[i]));
210+
currentBlobCommitmentsHash = Hash.sha256ToField(abi.encodePacked(currentBlobCommitmentsHash, _blobCommitments[i]));
212211
}
213212
}
214213

l1-contracts/src/core/libraries/rollup/EpochProofLib.sol

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {SafeCast} from "@oz/utils/math/SafeCast.sol";
3535
* The submitEpochRootProof() function is the main entry point called from RollupCore.submitEpochRootProof().
3636
* It serves as the mechanism by which provers can finalize epochs, advancing the proven chain tip and
3737
* triggering reward distribution. This is a critical operation that moves blocks from "pending" to "proven"
38-
* status.
38+
* status.
3939
*
4040
* Attestation Verification:
4141
* Before accepting an epoch proof, this library verifies the attestations for the last block in the epoch.
@@ -66,13 +66,6 @@ library EpochProofLib {
6666
using AttestationLib for CommitteeAttestations;
6767
using CompressedTimeMath for CompressedSlot;
6868

69-
// This is a temporary struct to avoid stack too deep errors
70-
struct BlobVarsTemp {
71-
uint256 blobOffset;
72-
uint256 offset;
73-
uint256 i;
74-
}
75-
7669
/**
7770
* @notice Submit a validity proof for an epoch's state transitions, advancing the proven chain tip
7871
*
@@ -116,6 +109,8 @@ library EpochProofLib {
116109
Epoch endEpoch = assertAcceptable(_args.start, _args.end);
117110

118111
// Verify attestations for the last block in the epoch
112+
// -> This serves as training wheels for the public part of the system (proving systems used in public and AVM)
113+
// ensuring committee consensus on the epoch's validity alongside the cryptographic proof verification below.
119114
verifyLastBlockAttestations(_args.end, _args.attestations);
120115

121116
require(verifyEpochRootProof(_args), Errors.Rollup__InvalidProof());
@@ -151,8 +146,6 @@ library EpochProofLib {
151146
) internal view returns (bytes32[] memory) {
152147
RollupStore storage rollupStore = STFLib.getStorage();
153148

154-
// TODO(#7373): Public inputs are not fully verified
155-
156149
{
157150
// We do it this way to provide better error messages than passing along the storage values
158151
{

l1-contracts/src/core/libraries/rollup/STFLib.sol

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {CompressedSlot, CompressedTimeMath} from "@aztec/shared/libraries/Compre
3535
* - The temporary block logs use a circular storage pattern where blocks are stored at index (blockNumber %
3636
* roundaboutSize).
3737
* This reuses storage slots for old blocks that have been proven or pruned.
38-
* The roundabout size is calculated as maxPrunableBlocks() + 1 to ensure at least the last provable block
38+
* The roundabout size is calculated as maxPrunableBlocks() + 1 to ensure at least the last proven block
3939
* remains accessible even after pruning operations. This saves gas costs by minimizing storage writes to fresh
4040
* slots.
4141
*
@@ -195,7 +195,7 @@ library STFLib {
195195
uint256 pending = tips.getPendingBlockNumber();
196196

197197
// @note We are not deleting the blocks, but we are "winding back" the pendingTip to the last block that was
198-
// proven.
198+
// proven.
199199
// We can do because any new block proposed will overwrite a previous block in the block log,
200200
// so no values should "survive".
201201
// People must therefore read the chain using the pendingTip as a boundary.
@@ -221,7 +221,7 @@ library STFLib {
221221
* @return The number of slots in the circular storage buffer
222222
*/
223223
function roundaboutSize() internal view returns (uint256) {
224-
// Must be ensured to contain at least the last provable even after a prune.
224+
// Must be ensured to contain at least the last proven block even after a prune.
225225
return TimeLib.maxPrunableBlocks() + 1;
226226
}
227227

@@ -392,8 +392,9 @@ library STFLib {
392392
* The deadline is the point in time where it is no longer acceptable, (if you touch the line you die)
393393
* - If epoch(_ts) >= epoch N + Proof submission window + 1, pruning is allowed
394394
*
395-
* This mechanism ensures rollup liveness by preventing indefinite stalling on unproven blocks
396-
* while providing sufficient time for proof generation and submission.
395+
* This mechanism ensures rollup liveness by preventing indefinite stalling on unprovable blocks (e.g due to
396+
* the committee failing to disseminate the data) while providing sufficient time for proof generation and
397+
* submission.
397398
*
398399
* @param _ts The current timestamp to check against
399400
* @return True if pruning is allowed at the given timestamp, false otherwise

0 commit comments

Comments
 (0)