Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7b3a315
chore: metrics
alexghr Apr 27, 2026
6cca236
chore: pass through p2p tx pool size
alexghr Apr 27, 2026
d2f0562
chore: pass through p2p tx pool size (#22804)
alexghr Apr 27, 2026
41d5b94
feat: track sequencer state time (#22800)
alexghr Apr 27, 2026
4673485
Merge branch 'next' into merge-train/spartan
Apr 28, 2026
0e194c4
Merge branch 'next' into merge-train/spartan
Apr 28, 2026
35e1bb0
feat(rpc)!: updated rpc api for blocks and checkpoints (#22781)
spalladino Apr 28, 2026
549bd10
feat(pipelining): complete attestations by build-slot end (#22735)
spalladino Apr 28, 2026
eef329c
feat(archiver): handle multiple proposed checkpoints (#22784)
spalladino Apr 28, 2026
65e48ae
Merge branch 'next' into merge-train/spartan
Apr 28, 2026
01f2bc5
feat: scrape bench-10tps (#22803)
alexghr Apr 28, 2026
625f9f2
feat!: make proposals EIP-712 (#22531)
LHerskind Apr 28, 2026
134f412
Merge branch 'next' into merge-train/spartan
Apr 28, 2026
690c21b
Merge branch 'next' into merge-train/spartan
Apr 28, 2026
7607046
Merge branch 'next' into merge-train/spartan
Apr 28, 2026
c649be5
Merge branch 'next' into merge-train/spartan
Apr 28, 2026
8011ef1
Merge branch 'next' into merge-train/spartan
Apr 29, 2026
73d7a90
Merge branch 'next' into merge-train/spartan
Apr 29, 2026
acb9d2b
chore: remove default env (#22837)
alexghr Apr 29, 2026
7da4e28
chore: remove default env (#22839)
alexghr Apr 29, 2026
103cb93
chore: grafana provisioning (#22843)
alexghr Apr 29, 2026
edd9dd7
feat: add extra getters (#22563)
LHerskind Apr 29, 2026
309cfbe
fix: use number config helper for NaN protection (#22598)
spypsy Apr 29, 2026
69da037
test(e2e): relax blocks per checkpoint in high tps e2e (#22846)
spalladino Apr 29, 2026
b6be617
Merge branch 'next' into merge-train/spartan
Apr 29, 2026
33dcab2
test(e2e): equivocation recovery under proposer pipelining (#22831)
spalladino Apr 29, 2026
c6ae018
Merge branch 'next' into merge-train/spartan
Apr 29, 2026
eda32cd
feat: scrape metrics data (#22840)
alexghr Apr 29, 2026
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
4 changes: 0 additions & 4 deletions .github/workflows/metrics-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,6 @@ jobs:
echo "Terraform state bucket already exists"
fi

- name: Import Dashboard
working-directory: ./spartan/metrics
run: ./copy-dashboard.sh

- name: Setup Terraform
uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1
with:
Expand Down
2 changes: 1 addition & 1 deletion bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ case "$cmd" in
;;
"ci-network-bench-10tps")
# Args: <env_file> <namespace> [docker_image]
# Deploys bench-10tps and runs the 38-min sustained 10 TPS benchmark.
# Deploys bench-10tps and runs the 10-min sustained 10 TPS benchmark.
# Cleanup is done separately via ci-network-teardown.
export CI=1
env_file="${1:?env_file is required}"
Expand Down
2 changes: 1 addition & 1 deletion ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ case "$cmd" in
;;
network-bench-10tps)
# Args: <scenario> <namespace> [docker_image]
# Deploys the bench-10tps network and runs the 38-min 10 TPS benchmark.
# Deploys the bench-10tps network and runs the 10-min 10 TPS benchmark.
export CI_DASHBOARD="network"
export JOB_ID="x-${2:?namespace is required}-network-bench-10tps" CPUS=16
export INSTANCE_POSTFIX="n-bench-10tps"
Expand Down
52 changes: 52 additions & 0 deletions docs/docs-developers/docs/resources/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,58 @@ The wallet SDK now supplies the default sender-for-tags from the transaction's `

The save/restore idiom previously used in account-contract constructors (`get` → `set(self.address)` → work → `set(prev)`) is also no longer needed and has been removed: the override never leaks out of the constructor, so there is nothing to restore.

### [Aztec Node] Unified `getBlock` / `getCheckpoint` RPC API

The Aztec Node JSON-RPC surface for fetching blocks and checkpoints has been consolidated. The unified `getBlock` and `getCheckpoint` methods return uniform `BlockResponse` / `CheckpointResponse` shapes. The extra fields a caller cares about (tx bodies, L1 publish info, committee attestations, nested blocks) are now controlled by an `options` argument rather than by picking the right method. `getBlocks` and `getCheckpoints` retain their names but now return the new response shapes.

**Removed methods:**

| Removed | Replacement |
|---|---|
| `getBlockByHash(hash)` | `getBlock(hash)` or `getBlock({ hash })` |
| `getBlockByArchive(archive)` | `getBlock({ archive })` |
| `getBlockHeaderByArchive(archive)` | `getBlock({ archive }).then(r => r?.header)` |
| `getProvenBlockNumber()` | `getBlockNumber('proven')` |
| `getCheckpointedBlockNumber()` | `getBlockNumber('checkpointed')` |

**Deprecated but still present** (scheduled for removal once internal consumers of the archiver shape are rewired): `getL2Tips` (use `getChainTips`), `getBlockHeader` (use `getBlock(param).then(r => r?.header)`), `getCheckpointedBlocks` (use `getBlocks(from, limit, { includeL1PublishInfo: true, includeAttestations: true })`), `getCheckpointsDataForEpoch` (use `getCheckpoints(from, limit)` over the epoch's checkpoint range). Do not adopt these in new code.

**New response shapes:** `BlockResponse` always carries `header`, `archive`, `hash`, `number`, `checkpointNumber`, and `indexWithinCheckpoint`. `body`, `l1` (an `L1PublishInfo` discriminated union), and `attestations` are present only when the matching include option is set. `CheckpointResponse` mirrors this for checkpoints, with `blocks` gated on `includeBlocks`, and always carries `feeAssetPriceModifier` as a base field. The response types are generic over the options object, so passing a literal `{ includeTransactions: true }` narrows the return type and `response.body` becomes non-optional.

**Nested blocks on `getCheckpoint`:** only `includeTransactions` is forwarded to the blocks embedded by `includeBlocks: true`. `includeL1PublishInfo` and `includeAttestations` on a checkpoint request attach L1 / attestation data to the checkpoint itself, not to its nested blocks.

**Return type changes for `getBlocks` / `getCheckpoints`:** the return type is now `BlockResponse[]` / `CheckpointResponse[]` instead of `L2Block[]` / `PublishedCheckpoint[]`. Callers that previously consumed fields of `L2Block` (e.g. `.body`) must now opt in via `{ includeTransactions: true }`; callers that consumed `PublishedCheckpoint.checkpoint.blocks` must opt in via `{ includeBlocks: true }`.

**Migration for wallet/SDK consumers (`@aztec/aztec.js`, `@aztec/wallet-sdk`):**

```diff
- const block = await node.getBlockByHash(hash);
+ const block = await node.getBlock(hash, { includeTransactions: true });

- const archiveBlock = await node.getBlockByArchive(archive);
+ const archiveBlock = await node.getBlock({ archive }, { includeTransactions: true });

- const provenNumber = await node.getProvenBlockNumber();
+ const provenNumber = await node.getBlockNumber('proven');

- const checkpointedNumber = await node.getCheckpointedBlockNumber();
+ const checkpointedNumber = await node.getBlockNumber('checkpointed');

- const tips = await node.getL2Tips();
+ const tips = await node.getChainTips();
```

`getBlockHeader`, `getCheckpointedBlocks`, `getCheckpointsDataForEpoch`, and `getL2Tips` continue to work in this release but are deprecated; migrate to the replacements above.

**Chain-tip selectors:** `getBlockNumber` and `getCheckpointNumber` now accept an optional `ChainTip` argument (`'proposed' | 'checkpointed' | 'proven' | 'finalized'`). Note the semantic difference: on the block side `'proposed'` means the latest proposed block (chain head), whereas on the checkpoint side `'proposed'` resolves to the latest L1-confirmed checkpoint. Pre-L1-confirmation checkpoints are not exposed over RPC.

**Block parameter variants:** `BlockParameter` now also accepts a block hash, an archive root, and chain-tip names. The existing `number | 'latest'` forms continue to work — `'latest'` is an alias for `'proposed'`.

**Impact**: Source changes are required anywhere the removed methods are called. Type changes are required anywhere `L2Block` / `BlockHeader` / `CheckpointedL2Block` were consumed from the RPC — those call sites now receive `BlockResponse` / `CheckpointResponse` and must request the fields they need via `options`. Production nodes will reject JSON-RPC calls to the removed method names.

### [Aztec Node] `feeAssetPriceModifier` now correctly populated on confirmed checkpoints

Confirmed checkpoints previously reported `feeAssetPriceModifier = 0n` regardless of the value observed on L1, because the archiver dropped the field on checkpoint confirmation. The field is now persisted and returned correctly on `CheckpointResponse`. Any wallet or indexer logic that special-cased `0n` as a sentinel for "no modifier" will need to be updated; it is now a valid value in its own right.

### [CLI] `aztec-up` no longer exposes transitive npm bins on PATH

Expand Down
4 changes: 2 additions & 2 deletions docs/examples/ts/aave_bridge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,13 @@ if (!exitReceipt.blockNumber) {
}
const exitBlockNumber = exitReceipt.blockNumber;
console.log("Waiting for block to be proven...");
let provenBlockNumber = await node.getProvenBlockNumber();
let provenBlockNumber = await node.getBlockNumber('proven');
while (provenBlockNumber < exitBlockNumber) {
console.log(
` Waiting... (proven: ${provenBlockNumber}, needed: ${exitBlockNumber})`,
);
await new Promise((resolve) => setTimeout(resolve, 10000));
provenBlockNumber = await node.getProvenBlockNumber();
provenBlockNumber = await node.getBlockNumber('proven');
}
console.log("Block proven!\n");

Expand Down
4 changes: 2 additions & 2 deletions docs/examples/ts/example_swap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,13 +384,13 @@ console.log("✓ WETH transferred to bridge for swap\n");
// docs:start:wait_for_proof
console.log("Waiting for block to be proven...\n");

let provenBlockNumber = await node.getProvenBlockNumber();
let provenBlockNumber = await node.getBlockNumber('proven');
while (provenBlockNumber < swapReceipt.blockNumber!) {
console.log(
` Waiting... (proven: ${provenBlockNumber}, needed: ${swapReceipt.blockNumber})`,
);
await new Promise((resolve) => setTimeout(resolve, 10000));
provenBlockNumber = await node.getProvenBlockNumber();
provenBlockNumber = await node.getBlockNumber('proven');
}

console.log("Block proven!\n");
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/ts/token_bridge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,15 @@ const msgLeaf = computeL2ToL1MessageHash({
console.log("Waiting for block to be proven...");
console.log(` Exit block number: ${exitReceipt.blockNumber}`);

let provenBlockNumber = await node.getProvenBlockNumber();
let provenBlockNumber = await node.getBlockNumber('proven');
console.log(` Current proven block: ${provenBlockNumber}`);

while (provenBlockNumber < exitReceipt.blockNumber!) {
console.log(
` Waiting... (proven: ${provenBlockNumber}, needed: ${exitReceipt.blockNumber})`,
);
await new Promise((resolve) => setTimeout(resolve, 10000)); // Wait 10 seconds
provenBlockNumber = await node.getProvenBlockNumber();
provenBlockNumber = await node.getBlockNumber('proven');
}

console.log("Block proven!\n");
Expand Down
19 changes: 10 additions & 9 deletions l1-contracts/gas_benchmark.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,22 @@

| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas |
|----------------------|---------|---------|---------------|--------------|
| propose | 195,201 | 221,411 | 932 | 14,912 |
| submitEpochRootProof | 698,976 | 744,776 | 2,820 | 45,120 |
| setupEpoch | 31,965 | 113,616 | - | - |
| propose | 195,988 | 222,201 | 932 | 14,912 |
| submitEpochRootProof | 697,655 | 743,529 | 2,820 | 45,120 |
| setupEpoch | 31,998 | 113,793 | - | - |

**Avg Gas Cost per Second**: 3,331.7 gas/second
**Avg Gas Cost per Second**: 3,341.5 gas/second
*Epoch duration*: 0h 38m 24s

## Validators

| Function | Avg Gas | Max Gas | Calldata Size | Calldata Gas |
|----------------------|---------|---------|---------------|--------------|
| propose | 322,945 | 350,085 | 4,452 | 71,232 |
| submitEpochRootProof | 897,150 | 942,954 | 5,316 | 85,056 |
| aggregate3 | 371,401 | 384,831 | - | - |
| setupEpoch | 46,426 | 547,449 | - | - |
| propose | 324,449 | 351,604 | 4,452 | 71,232 |
| submitEpochRootProof | 896,101 | 941,944 | 5,316 | 85,056 |
| aggregate3 | 373,118 | 386,457 | - | - |
| setupEpoch | 46,459 | 547,626 | - | - |

**Avg Gas Cost per Second**: 5,284.3 gas/second
**Avg Gas Cost per Second**: 5,304.3 gas/second
*Epoch duration*: 0h 38m 24s

58 changes: 29 additions & 29 deletions l1-contracts/gas_benchmark_results.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,62 @@
"no_validators": {
"propose": {
"calls": 150,
"min": 181595,
"mean": 195201,
"median": 190979,
"max": 221411,
"min": 182373,
"mean": 195988,
"median": 191762,
"max": 222201,
"calldata_size": 932,
"calldata_gas": 14912
},
"setupEpoch": {
"calls": 150,
"min": 29236,
"mean": 31965,
"median": 29236,
"max": 113616
"min": 29264,
"mean": 31998,
"median": 29264,
"max": 113793
},
"submitEpochRootProof": {
"calls": 4,
"min": 677928,
"mean": 698976,
"median": 686601,
"max": 744776,
"min": 676491,
"mean": 697655,
"median": 685300,
"max": 743529,
"calldata_size": 2820,
"calldata_gas": 45120
}
},
"validators": {
"propose": {
"calls": 150,
"min": 300568,
"mean": 322945,
"median": 322454,
"max": 350085,
"min": 302105,
"mean": 324449,
"median": 323910,
"max": 351604,
"calldata_size": 4452,
"calldata_gas": 71232
},
"setupEpoch": {
"calls": 150,
"min": 29236,
"mean": 46426,
"median": 29236,
"max": 547449
"min": 29264,
"mean": 46459,
"median": 29264,
"max": 547626
},
"submitEpochRootProof": {
"calls": 4,
"min": 876112,
"mean": 897150,
"median": 884767,
"max": 942954,
"min": 874924,
"mean": 896101,
"median": 883769,
"max": 941944,
"calldata_size": 5316,
"calldata_gas": 85056
},
"aggregate3": {
"calls": 55,
"min": 360298,
"mean": 371401,
"median": 371165,
"max": 384831
"min": 362015,
"mean": 373118,
"median": 372828,
"max": 386457
}
}
}
}
12 changes: 12 additions & 0 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,18 @@ contract Rollup is IStaking, IValidatorSelection, IRollup, RollupCore {
return STFLib.getStorage().config.feeAssetPortal;
}

function getVkTreeRoot() external view override(IRollup) returns (bytes32) {
return STFLib.getStorage().config.vkTreeRoot;
}

function getProtocolContractsHash() external view override(IRollup) returns (bytes32) {
return STFLib.getStorage().config.protocolContractsHash;
}

function getEpochProofVerifier() external view override(IRollup) returns (IVerifier) {
return STFLib.getStorage().config.epochProofVerifier;
}

function getRewardDistributor() external view override(IRollup) returns (IRewardDistributor) {
return RewardExtLib.getRewardDistributor();
}
Expand Down
4 changes: 4 additions & 0 deletions l1-contracts/src/core/interfaces/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ interface IRollup is IRollupCore, IHaveVersion {
function getInbox() external view returns (IInbox);
function getOutbox() external view returns (IOutbox);

function getVkTreeRoot() external view returns (bytes32);
function getProtocolContractsHash() external view returns (bytes32);
function getEpochProofVerifier() external view returns (IVerifier);

function getRewardConfig() external view returns (RewardConfig memory);
function getCheckpointReward() external view returns (uint256);
}
36 changes: 19 additions & 17 deletions l1-contracts/src/core/libraries/rollup/AttestationLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,12 @@
pragma solidity ^0.8.27;

import {Errors} from "@aztec/core/libraries/Errors.sol";
import {CoordinationSignatureLib} from "@aztec/core/libraries/rollup/CoordinationSignatureLib.sol";
import {Signature, SignatureLib} from "@aztec/shared/libraries/SignatureLib.sol";

uint256 constant SIGNATURE_LENGTH = 65; // v (1) + r (32) + s (32)
uint256 constant ADDRESS_LENGTH = 20;

/**
* @notice The domain separator for the signatures
*/
enum SignatureDomainSeparator {
checkpointProposal,
checkpointAttestation,
attestationsAndSigners
}

// A committee attestation can be made up of a signature and an address.
// Committee members that have attested will produce a signature, and if they have not attested, the signature will be
// empty and an address provided.
Expand All @@ -35,6 +27,24 @@ struct CommitteeAttestations {
library AttestationLib {
using SignatureLib for Signature;

function getAttestationsAndSignersDigest(CommitteeAttestations memory _attestations, address[] memory _signers)
internal
view
returns (bytes32)
{
return getAttestationsAndSignersDigest(_attestations, _signers, address(this));
}

function getAttestationsAndSignersDigest(
CommitteeAttestations memory _attestations,
address[] memory _signers,
address _verifyingContract
) internal view returns (bytes32) {
return CoordinationSignatureLib.attestationsAndSignersDigest(
keccak256(abi.encode(_attestations, _signers)), _verifyingContract
);
}

/**
* @notice Checks if the given CommitteeAttestations is empty
* Wll return true if either component is empty as they are needed together.
Expand Down Expand Up @@ -217,12 +227,4 @@ library AttestationLib {

return addresses;
}

function getAttestationsAndSignersDigest(CommitteeAttestations memory _attestations, address[] memory _signers)
internal
pure
returns (bytes32)
{
return keccak256(abi.encode(SignatureDomainSeparator.attestationsAndSigners, _attestations, _signers));
}
}
Loading
Loading