Skip to content

Commit 48f9044

Browse files
authored
chore: merge v4 into backport-to-v4-next-staging (#22010)
## Summary Merges v4 branch into backport-to-v4-next-staging to bring in 17 commits from v4 that were missing. Key changes from v4: - fix: verify accumulated pairing points in native ChonkVerifier (#21975) - chore: Properly compute finalized block (#21795, #21850) - feat(archiver): validate contract instance addresses before storing (#21787) - feat(p2p): add tx validator for contract instance deployment addresses (#21771) - Various accumulated backports and bug fixes ## Conflicts resolved 6 files had merge conflicts, all resolved: - `archiver/src/factory.ts` — kept `ContractClassPublicWithCommitment` type from staging - `archiver/src/modules/data_store_updater.ts` — merged imports from both branches - `archiver/src/store/kv_archiver_store.test.ts` — took v4's richer describe block structure, adapted to singular `addProposedBlock` API - `aztec-node/src/aztec-node/server.ts` — kept staging's block 0 check and `getWorldState` method name - `stdlib/src/tx/validator/error_texts.ts` — kept staging's contract class error constants - `world-state/src/synchronizer/server_world_state_synchronizer.ts` — kept verbose log level ## Test plan - CI should verify the merge compiles and tests pass - Once merged, this branch can be merged into the backport-to-v4-next branch ClaudeBox log: https://claudebox.work/s/0150633f06bfb379?run=1
2 parents 7b620da + 311b34a commit 48f9044

File tree

57 files changed

+969
-181
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+969
-181
lines changed

barretenberg/cpp/src/barretenberg/chonk/chonk_verifier.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ template <> ChonkVerifier<false>::Output ChonkVerifier<false>::verify(const Proo
2727
HidingKernelIO kernel_io;
2828
kernel_io.reconstruct_from_public(verifier.get_public_inputs());
2929

30+
// Check accumulated pairing points from the IVC chain (inner recursive verifications)
31+
if (!kernel_io.pairing_inputs.check()) {
32+
info("ChonkVerifier: verification failed at PI pairing points check");
33+
return false;
34+
}
35+
3036
// Step 2: Perform databus consistency check
3137
const Commitment calldata_commitment = verifier.get_calldata_commitment();
3238
const Commitment return_data_commitment = kernel_io.kernel_return_data;

barretenberg/rust/bootstrap.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ function release {
6060
(cd ../ts && yarn generate)
6161
fi
6262

63+
# Check if this version is already published on crates.io (idempotent re-runs).
64+
if curl -sf -H "User-Agent: aztec-packages-ci (tech@aztec-labs.com)" "https://crates.io/api/v1/crates/barretenberg-rs/$version" | jq -e '.version.num' &>/dev/null; then
65+
echo "barretenberg-rs@$version already published on crates.io. Skipping."
66+
return 0
67+
fi
68+
6369
# Publish to crates.io (--allow-dirty because version was just set and generated files are gitignored)
6470
local extra_flags=""
6571
if ! gh release view "v$version" --repo AztecProtocol/aztec-packages &>/dev/null; then

noir-projects/aztec-nr/aztec/src/macros/functions/initialization_utils.nr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ pub fn assert_is_initialized_private(context: &mut PrivateContext) {
117117
/// Asserts that the contract has been initialized, from a utility function's perspective.
118118
///
119119
/// Only checks the private initialization nullifier in the settled nullifier tree. Since both nullifiers are emitted
120-
/// in
121-
/// the same transaction, the private nullifier's presence in settled state guarantees the public one is also settled.
120+
/// in the same transaction, the private nullifier's presence in settled state guarantees the public one is also
121+
/// settled.
122122
pub unconstrained fn assert_is_initialized_utility(context: UtilityContext) {
123123
let address = context.this_address();
124124
let instance = get_contract_instance(address);

spartan/environments/network-defaults.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -280,19 +280,19 @@ networks:
280280
# P2P
281281
P2P_MAX_PENDING_TX_COUNT: 1000
282282
P2P_TX_POOL_DELETE_TXS_AFTER_REORG: true
283-
# Slasher penalties
284-
SLASH_PRUNE_PENALTY: 10e18
285-
SLASH_DATA_WITHHOLDING_PENALTY: 10e18
286-
SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9
287-
SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 1
288-
SLASH_INACTIVITY_PENALTY: 10e18
289-
SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18
290-
SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18
291-
SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18
292-
SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18
293-
SLASH_UNKNOWN_PENALTY: 10e18
294-
SLASH_INVALID_BLOCK_PENALTY: 10e18
295-
SLASH_GRACE_PERIOD_L2_SLOTS: 64
283+
# Slasher penalties — must be >= AZTEC_SLASH_AMOUNT_SMALL (100000e18) to trigger votes
284+
SLASH_PRUNE_PENALTY: 0
285+
SLASH_DATA_WITHHOLDING_PENALTY: 0
286+
SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.7
287+
SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 2
288+
SLASH_INACTIVITY_PENALTY: 100000e18
289+
SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 100000e18
290+
SLASH_DUPLICATE_PROPOSAL_PENALTY: 0
291+
SLASH_DUPLICATE_ATTESTATION_PENALTY: 0
292+
SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 100000e18
293+
SLASH_UNKNOWN_PENALTY: 100000e18
294+
SLASH_INVALID_BLOCK_PENALTY: 100000e18
295+
SLASH_GRACE_PERIOD_L2_SLOTS: 3600
296296
ENABLE_VERSION_CHECK: true
297297

298298
mainnet:

yarn-project/archiver/src/archiver-misc.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ describe('Archiver misc', () => {
5555

5656
const tracer = getTelemetryClient().getTracer('');
5757
const instrumentation = mock<ArchiverInstrumentation>({ isEnabled: () => true, tracer });
58-
const archiverStore = new KVArchiverDataStore(await openTmpStore('archiver_misc_test'), 1000, {
59-
epochDuration: EPOCH_DURATION,
60-
});
58+
const archiverStore = new KVArchiverDataStore(await openTmpStore('archiver_misc_test'), 1000);
6159
const events = new EventEmitter() as ArchiverEmitter;
6260
const l2TipsCache = new L2TipsCache(archiverStore.blockStore);
6361

yarn-project/archiver/src/archiver-store.test.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ describe('Archiver Store', () => {
6161
const tracer = getTelemetryClient().getTracer('');
6262
instrumentation = mock<ArchiverInstrumentation>({ isEnabled: () => true, tracer });
6363

64-
archiverStore = new KVArchiverDataStore(await openTmpStore('archiver_test'), 1000, { epochDuration: 4 });
64+
archiverStore = new KVArchiverDataStore(await openTmpStore('archiver_test'), 1000);
6565

6666
l1Constants = {
6767
l1GenesisTime: BigInt(now),
@@ -544,5 +544,47 @@ describe('Archiver Store', () => {
544544
expect(await archiver.getSynchedCheckpointNumber()).toEqual(CheckpointNumber(2));
545545
expect(await archiver.getProvenCheckpointNumber()).toEqual(CheckpointNumber(1));
546546
});
547+
548+
it('rolls back finalized checkpoint number when target is before finalized block', async () => {
549+
const genesisArchive = new AppendOnlyTreeSnapshot(new Fr(GENESIS_ARCHIVE_ROOT), 1);
550+
// Checkpoint 1: blocks 1-2, Checkpoint 2: blocks 3-4, Checkpoint 3: blocks 5-6
551+
const testCheckpoints = await makeChainedCheckpoints(3, {
552+
previousArchive: genesisArchive,
553+
blocksPerCheckpoint: 2,
554+
});
555+
await archiverStore.addCheckpoints(testCheckpoints);
556+
557+
// Mark checkpoints 1 and 2 as proven and finalized
558+
await archiverStore.setProvenCheckpointNumber(CheckpointNumber(2));
559+
await archiverStore.setFinalizedCheckpointNumber(CheckpointNumber(2));
560+
expect(await archiver.getFinalizedL2BlockNumber()).toEqual(BlockNumber(4));
561+
562+
// Roll back to block 2 (end of checkpoint 1), which is before finalized block 4
563+
await archiver.rollbackTo(BlockNumber(2));
564+
565+
expect(await archiver.getSynchedCheckpointNumber()).toEqual(CheckpointNumber(1));
566+
expect(await archiver.getFinalizedL2BlockNumber()).toEqual(BlockNumber(2));
567+
});
568+
569+
it('preserves finalized checkpoint number when target is after finalized block', async () => {
570+
const genesisArchive = new AppendOnlyTreeSnapshot(new Fr(GENESIS_ARCHIVE_ROOT), 1);
571+
// Checkpoint 1: blocks 1-2, Checkpoint 2: blocks 3-4, Checkpoint 3: blocks 5-6
572+
const testCheckpoints = await makeChainedCheckpoints(3, {
573+
previousArchive: genesisArchive,
574+
blocksPerCheckpoint: 2,
575+
});
576+
await archiverStore.addCheckpoints(testCheckpoints);
577+
578+
// Mark checkpoint 1 as finalized, checkpoint 2 as proven
579+
await archiverStore.setProvenCheckpointNumber(CheckpointNumber(2));
580+
await archiverStore.setFinalizedCheckpointNumber(CheckpointNumber(1));
581+
expect(await archiver.getFinalizedL2BlockNumber()).toEqual(BlockNumber(2));
582+
583+
// Roll back to block 4 (end of checkpoint 2), which is after finalized block 2
584+
await archiver.rollbackTo(BlockNumber(4));
585+
586+
expect(await archiver.getSynchedCheckpointNumber()).toEqual(CheckpointNumber(2));
587+
expect(await archiver.getFinalizedL2BlockNumber()).toEqual(BlockNumber(2));
588+
});
547589
});
548590
});

yarn-project/archiver/src/archiver-sync.test.ts

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ describe('Archiver Sync', () => {
9595
instrumentation = mock<ArchiverInstrumentation>({ isEnabled: () => true, tracer });
9696

9797
// Create archiver store
98-
archiverStore = new KVArchiverDataStore(await openTmpStore('archiver_sync_test'), 1000, { epochDuration: 32 });
98+
archiverStore = new KVArchiverDataStore(await openTmpStore('archiver_sync_test'), 1000);
9999

100100
const contractAddresses = {
101101
registryAddress,
@@ -1225,6 +1225,71 @@ describe('Archiver Sync', () => {
12251225
}, 15_000);
12261226
});
12271227

1228+
describe('finalized checkpoint', () => {
1229+
it('reports no finalized blocks before any checkpoint is proven', async () => {
1230+
fake.setL1BlockNumber(100n);
1231+
fake.setFinalizedL1BlockNumber(100n);
1232+
await archiver.syncImmediate();
1233+
1234+
const tips = await archiver.getL2Tips();
1235+
expect(tips.finalized.checkpoint.number).toEqual(CheckpointNumber(0));
1236+
expect(tips.finalized.block.number).toEqual(BlockNumber(0));
1237+
});
1238+
1239+
it('updates finalized checkpoint when the L1 finalized block is at or past the proven checkpoint L1 block', async () => {
1240+
const { checkpoint: cp1 } = await fake.addCheckpoint(CheckpointNumber(1), {
1241+
l1BlockNumber: 70n,
1242+
messagesL1BlockNumber: 50n,
1243+
numL1ToL2Messages: 3,
1244+
});
1245+
1246+
// Sync all checkpoints
1247+
fake.setL1BlockNumber(100n);
1248+
await archiver.syncImmediate();
1249+
1250+
// Mark checkpoint 1 as proven and advance L1 so proven is registered
1251+
fake.markCheckpointAsProven(CheckpointNumber(1));
1252+
fake.setL1BlockNumber(101n);
1253+
await archiver.syncImmediate();
1254+
expect(await archiver.getProvenCheckpointNumber()).toEqual(CheckpointNumber(1));
1255+
1256+
// Finalized L1 block is at or past where checkpoint 1 was published (70)
1257+
fake.setFinalizedL1BlockNumber(70n);
1258+
fake.setL1BlockNumber(102n);
1259+
await archiver.syncImmediate();
1260+
1261+
const tips = await archiver.getL2Tips();
1262+
const lastBlockInCp1 = cp1.blocks.at(-1)!.number;
1263+
expect(tips.finalized.checkpoint.number).toEqual(CheckpointNumber(1));
1264+
expect(tips.finalized.block.number).toEqual(lastBlockInCp1);
1265+
});
1266+
1267+
it('does not advance finalized checkpoint when finalized L1 block is before the proven checkpoint', async () => {
1268+
await fake.addCheckpoint(CheckpointNumber(1), {
1269+
l1BlockNumber: 70n,
1270+
messagesL1BlockNumber: 50n,
1271+
numL1ToL2Messages: 3,
1272+
});
1273+
1274+
fake.setL1BlockNumber(100n);
1275+
await archiver.syncImmediate();
1276+
1277+
fake.markCheckpointAsProven(CheckpointNumber(1));
1278+
fake.setL1BlockNumber(101n);
1279+
await archiver.syncImmediate();
1280+
expect(await archiver.getProvenCheckpointNumber()).toEqual(CheckpointNumber(1));
1281+
1282+
// Finalized L1 block is before where checkpoint 1 was published (70)
1283+
fake.setFinalizedL1BlockNumber(50n);
1284+
fake.setL1BlockNumber(102n);
1285+
await archiver.syncImmediate();
1286+
1287+
const tips = await archiver.getL2Tips();
1288+
expect(tips.finalized.checkpoint.number).toEqual(CheckpointNumber(0));
1289+
expect(tips.finalized.block.number).toEqual(BlockNumber(0));
1290+
});
1291+
});
1292+
12281293
describe('checkpointing local proposed blocks', () => {
12291294
let pruneSpy: jest.Mock;
12301295

yarn-project/archiver/src/archiver.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -492,11 +492,10 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
492492
this.log.info(`Rolling back proven L2 checkpoint to ${targetCheckpointNumber}`);
493493
await this.updater.setProvenCheckpointNumber(targetCheckpointNumber);
494494
}
495-
// TODO(palla/reorg): Set the finalized block when we add support for it.
496-
// const currentFinalizedBlock = currentBlocks.finalized.block.number;
497-
// if (targetL2BlockNumber < currentFinalizedBlock) {
498-
// this.log.info(`Rolling back finalized L2 checkpoint to ${targetCheckpointNumber}`);
499-
// await this.updater.setFinalizedCheckpointNumber(targetCheckpointNumber);
500-
// }
495+
const currentFinalizedBlock = currentBlocks.finalized.block.number;
496+
if (targetL2BlockNumber < currentFinalizedBlock) {
497+
this.log.info(`Rolling back finalized L2 checkpoint to ${targetCheckpointNumber}`);
498+
await this.updater.setFinalizedCheckpointNumber(targetCheckpointNumber);
499+
}
501500
}
502501
}

yarn-project/archiver/src/factory.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/prov
1515
import { FunctionType, decodeFunctionSignature } from '@aztec/stdlib/abi';
1616
import type { ArchiverEmitter } from '@aztec/stdlib/block';
1717
import { type ContractClassPublicWithCommitment, computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
18-
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
1918
import { getTelemetryClient } from '@aztec/telemetry-client';
2019

2120
import { EventEmitter } from 'events';
@@ -33,14 +32,13 @@ export const ARCHIVER_STORE_NAME = 'archiver';
3332
/** Creates an archiver store. */
3433
export async function createArchiverStore(
3534
userConfig: Pick<ArchiverConfig, 'archiverStoreMapSizeKb' | 'maxLogs'> & DataStoreConfig,
36-
l1Constants: Pick<L1RollupConstants, 'epochDuration'>,
3735
) {
3836
const config = {
3937
...userConfig,
4038
dataStoreMapSizeKb: userConfig.archiverStoreMapSizeKb ?? userConfig.dataStoreMapSizeKb,
4139
};
4240
const store = await createStore(ARCHIVER_STORE_NAME, ARCHIVER_DB_VERSION, config);
43-
return new KVArchiverDataStore(store, config.maxLogs, l1Constants);
41+
return new KVArchiverDataStore(store, config.maxLogs);
4442
}
4543

4644
/**
@@ -55,7 +53,7 @@ export async function createArchiver(
5553
deps: ArchiverDeps,
5654
opts: { blockUntilSync: boolean } = { blockUntilSync: true },
5755
): Promise<Archiver> {
58-
const archiverStore = await createArchiverStore(config, { epochDuration: config.aztecEpochDuration });
56+
const archiverStore = await createArchiverStore(config);
5957
await registerProtocolContracts(archiverStore);
6058

6159
// Create Ethereum clients

yarn-project/archiver/src/modules/data_store_updater.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ describe('ArchiverDataStoreUpdater', () => {
4242
let instanceAddress: AztecAddress;
4343

4444
beforeEach(async () => {
45-
store = new KVArchiverDataStore(await openTmpStore('data_store_updater_test'), 1000, { epochDuration: 32 });
45+
store = new KVArchiverDataStore(await openTmpStore('data_store_updater_test'), 1000);
4646
updater = new ArchiverDataStoreUpdater(store);
4747

4848
// Create contract class log from sample fixture data

0 commit comments

Comments
 (0)