@aztec/sequencer-client 2.1.2 → 2.1.3-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/client/sequencer-client.js +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +4 -0
- package/dest/sequencer/sequencer.d.ts +4 -2
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +53 -22
- package/package.json +27 -27
- package/src/client/sequencer-client.ts +2 -2
- package/src/config.ts +4 -0
- package/src/sequencer/sequencer.ts +69 -21
|
@@ -83,7 +83,8 @@ import { Sequencer } from '../sequencer/index.js';
|
|
|
83
83
|
// In theory, the L1 slot has an initial 4s phase where the block is propagated, so we could
|
|
84
84
|
// make it with a propagation time into slot equal to 4s. However, we prefer being conservative.
|
|
85
85
|
// See https://www.blocknative.com/blog/anatomy-of-a-slot#7 for more info.
|
|
86
|
-
const
|
|
86
|
+
const maxInclusionBasedOnChain = isAnvilTestChain(config.l1ChainId) ? ethereumSlotDuration - 1 : 0;
|
|
87
|
+
const maxL1TxInclusionTimeIntoSlot = config.maxL1TxInclusionTimeIntoSlot ?? maxInclusionBasedOnChain;
|
|
87
88
|
const l1Constants = {
|
|
88
89
|
l1GenesisTime,
|
|
89
90
|
slotDuration: Number(slotDuration),
|
package/dest/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,YAAY,CAAC;AAE/D,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAuB,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,KAAK,qBAAqB,EAAiC,MAAM,yBAAyB,CAAC;AAEpG,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,uBAAuB,CAAC;AAE/B,cAAc,uBAAuB,CAAC;AACtC,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,eAAO,MAAM,oCAAoC,IAAI,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,eAAe,GACjD,cAAc,GACd,qBAAqB,GACrB,cAAc,GACd,eAAe,GACf,cAAc,GACd,WAAW,GACX,IAAI,CAAC,SAAS,EAAE,wBAAwB,CAAC,GACzC,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC,CAAC;AAE/F,eAAO,MAAM,uBAAuB,EAAE,kBAAkB,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,YAAY,CAAC;AAE/D,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAuB,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,KAAK,qBAAqB,EAAiC,MAAM,yBAAyB,CAAC;AAEpG,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,uBAAuB,CAAC;AAE/B,cAAc,uBAAuB,CAAC;AACtC,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,eAAO,MAAM,oCAAoC,IAAI,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,eAAe,GACjD,cAAc,GACd,qBAAqB,GACrB,cAAc,GACd,eAAe,GACf,cAAc,GACd,WAAW,GACX,IAAI,CAAC,SAAS,EAAE,wBAAwB,CAAC,GACzC,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC,CAAC;AAE/F,eAAO,MAAM,uBAAuB,EAAE,kBAAkB,CAAC,eAAe,CA+GvE,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,CAAC,qBAAqB,CASnF,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CAExD"}
|
package/dest/config.js
CHANGED
|
@@ -110,6 +110,10 @@ export const sequencerConfigMappings = {
|
|
|
110
110
|
description: 'Inject a fake attestation (for testing only)',
|
|
111
111
|
...booleanConfigHelper(false)
|
|
112
112
|
},
|
|
113
|
+
shuffleAttestationOrdering: {
|
|
114
|
+
description: 'Shuffle attestation ordering to create invalid ordering (for testing only)',
|
|
115
|
+
...booleanConfigHelper(false)
|
|
116
|
+
},
|
|
113
117
|
...pickConfigMappings(p2pConfigMappings, [
|
|
114
118
|
'txPublicSetupAllowList'
|
|
115
119
|
])
|
|
@@ -8,7 +8,7 @@ import { type DateProvider } from '@aztec/foundation/timer';
|
|
|
8
8
|
import { type TypedEventEmitter } from '@aztec/foundation/types';
|
|
9
9
|
import type { P2P } from '@aztec/p2p';
|
|
10
10
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
11
|
-
import {
|
|
11
|
+
import { CommitteeAttestationsAndSigners, type L2BlockSource, type ValidateBlockResult } from '@aztec/stdlib/block';
|
|
12
12
|
import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
13
13
|
import { type IFullNodeBlockBuilder, type PublicProcessorLimits, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
14
14
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
@@ -160,7 +160,9 @@ export declare class Sequencer extends Sequencer_base {
|
|
|
160
160
|
* @param proposerAddress - The address of the proposer
|
|
161
161
|
*/
|
|
162
162
|
private buildBlockAndEnqueuePublish;
|
|
163
|
-
protected collectAttestations(block: L2Block, txs: Tx[], proposerAddress: EthAddress | undefined): Promise<
|
|
163
|
+
protected collectAttestations(block: L2Block, txs: Tx[], proposerAddress: EthAddress | undefined): Promise<CommitteeAttestationsAndSigners>;
|
|
164
|
+
/** Breaks the attestations before publishing based on attack configs */
|
|
165
|
+
private manipulateAttestations;
|
|
164
166
|
/**
|
|
165
167
|
* Publishes the L2Block to the rollup contract.
|
|
166
168
|
* @param block - The L2Block to be published.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG5F,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,KAAK,iBAAiB,EAAY,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,
|
|
1
|
+
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
15
15
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
16
16
|
import { Timer } from '@aztec/foundation/timer';
|
|
17
17
|
import { unfreeze } from '@aztec/foundation/types';
|
|
18
|
-
import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
18
|
+
import { CommitteeAttestationsAndSigners, MaliciousCommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
19
19
|
import { getSlotAtTimestamp, getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
20
20
|
import { Gas } from '@aztec/stdlib/gas';
|
|
21
21
|
import { SequencerConfigSchema } from '@aztec/stdlib/interfaces/server';
|
|
@@ -477,15 +477,13 @@ export { SequencerState };
|
|
|
477
477
|
...blockStats
|
|
478
478
|
});
|
|
479
479
|
this.log.debug('Collecting attestations');
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
const attestationsAndSigners = new CommitteeAttestationsAndSigners(attestations ?? []);
|
|
488
|
-
const attestationsAndSignersSignature = this.validatorClient ? await this.validatorClient.signAttestationsAndSigners(attestationsAndSigners, proposerAddress) : Signature.empty();
|
|
480
|
+
const attestationsAndSigners = await this.collectAttestations(block, usedTxs, proposerAddress);
|
|
481
|
+
this.log.verbose(`Collected ${attestationsAndSigners.attestations.length} attestations for block ${blockNumber} at slot ${slot}`, {
|
|
482
|
+
blockHash,
|
|
483
|
+
blockNumber,
|
|
484
|
+
slot
|
|
485
|
+
});
|
|
486
|
+
const attestationsAndSignersSignature = await this.validatorClient?.signAttestationsAndSigners(attestationsAndSigners, proposerAddress ?? publisher.getSenderAddress()) ?? Signature.empty();
|
|
489
487
|
await this.enqueuePublishL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, invalidateBlock, publisher);
|
|
490
488
|
this.metrics.recordBuiltBlock(blockBuildDuration, publicGas.l2Gas);
|
|
491
489
|
return block;
|
|
@@ -495,21 +493,19 @@ export { SequencerState };
|
|
|
495
493
|
}
|
|
496
494
|
}
|
|
497
495
|
async collectAttestations(block, txs, proposerAddress) {
|
|
498
|
-
const { committee } = await this.epochCache.getCommittee(block.
|
|
496
|
+
const { committee, seed, epoch } = await this.epochCache.getCommittee(block.slot);
|
|
499
497
|
// We checked above that the committee is defined, so this should never happen.
|
|
500
498
|
if (!committee) {
|
|
501
499
|
throw new Error('No committee when collecting attestations');
|
|
502
500
|
}
|
|
503
501
|
if (committee.length === 0) {
|
|
504
502
|
this.log.verbose(`Attesting committee is empty`);
|
|
505
|
-
return
|
|
503
|
+
return CommitteeAttestationsAndSigners.empty();
|
|
506
504
|
} else {
|
|
507
505
|
this.log.debug(`Attesting committee length is ${committee.length}`);
|
|
508
506
|
}
|
|
509
507
|
if (!this.validatorClient) {
|
|
510
|
-
|
|
511
|
-
this.log.error(msg);
|
|
512
|
-
throw new Error(msg);
|
|
508
|
+
throw new Error('Missing validator client: Cannot collect attestations');
|
|
513
509
|
}
|
|
514
510
|
const numberOfRequiredAttestations = Math.floor(committee.length * 2 / 3) + 1;
|
|
515
511
|
const slotNumber = block.header.globalVariables.slotNumber.toBigInt();
|
|
@@ -525,7 +521,7 @@ export { SequencerState };
|
|
|
525
521
|
if (this.config.skipCollectingAttestations) {
|
|
526
522
|
this.log.warn('Skipping attestation collection as per config (attesting with own keys only)');
|
|
527
523
|
const attestations = await this.validatorClient?.collectOwnAttestations(proposal);
|
|
528
|
-
return orderAttestations(attestations ?? [], committee);
|
|
524
|
+
return new CommitteeAttestationsAndSigners(orderAttestations(attestations ?? [], committee));
|
|
529
525
|
}
|
|
530
526
|
this.log.debug('Broadcasting block proposal to validators');
|
|
531
527
|
await this.validatorClient.broadcastBlockProposal(proposal);
|
|
@@ -539,13 +535,11 @@ export { SequencerState };
|
|
|
539
535
|
collectedAttestationsCount = attestations.length;
|
|
540
536
|
// note: the smart contract requires that the signatures are provided in the order of the committee
|
|
541
537
|
const sorted = orderAttestations(attestations, committee);
|
|
542
|
-
if
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
this.log.warn(`Injecting fake attestation in block ${block.number}`);
|
|
546
|
-
unfreeze(nonEmpty[randomIndex]).signature = Signature.random();
|
|
538
|
+
// manipulate the attestations if we've been configured to do so
|
|
539
|
+
if (this.config.injectFakeAttestation || this.config.shuffleAttestationOrdering) {
|
|
540
|
+
return this.manipulateAttestations(block, epoch, seed, committee, sorted);
|
|
547
541
|
}
|
|
548
|
-
return sorted;
|
|
542
|
+
return new CommitteeAttestationsAndSigners(sorted);
|
|
549
543
|
} catch (err) {
|
|
550
544
|
if (err && err instanceof AttestationTimeoutError) {
|
|
551
545
|
collectedAttestationsCount = err.collectedCount;
|
|
@@ -555,6 +549,43 @@ export { SequencerState };
|
|
|
555
549
|
this.metrics.recordCollectedAttestations(collectedAttestationsCount, timer.ms());
|
|
556
550
|
}
|
|
557
551
|
}
|
|
552
|
+
/** Breaks the attestations before publishing based on attack configs */ manipulateAttestations(block, epoch, seed, committee, attestations) {
|
|
553
|
+
// Compute the proposer index in the committee, since we dont want to tweak it.
|
|
554
|
+
// Otherwise, the L1 rollup contract will reject the block outright.
|
|
555
|
+
const proposerIndex = Number(this.epochCache.computeProposerIndex(block.slot, epoch, seed, BigInt(committee.length)));
|
|
556
|
+
if (this.config.injectFakeAttestation) {
|
|
557
|
+
// Find non-empty attestations that are not from the proposer
|
|
558
|
+
const nonProposerIndices = [];
|
|
559
|
+
for(let i = 0; i < attestations.length; i++){
|
|
560
|
+
if (!attestations[i].signature.isEmpty() && i !== proposerIndex) {
|
|
561
|
+
nonProposerIndices.push(i);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (nonProposerIndices.length > 0) {
|
|
565
|
+
const targetIndex = nonProposerIndices[randomInt(nonProposerIndices.length)];
|
|
566
|
+
this.log.warn(`Injecting fake attestation in block ${block.number} at index ${targetIndex}`);
|
|
567
|
+
unfreeze(attestations[targetIndex]).signature = Signature.random();
|
|
568
|
+
}
|
|
569
|
+
return new CommitteeAttestationsAndSigners(attestations);
|
|
570
|
+
}
|
|
571
|
+
if (this.config.shuffleAttestationOrdering) {
|
|
572
|
+
this.log.warn(`Shuffling attestation ordering in block ${block.number} (proposer index ${proposerIndex})`);
|
|
573
|
+
const shuffled = [
|
|
574
|
+
...attestations
|
|
575
|
+
];
|
|
576
|
+
const [i, j] = [
|
|
577
|
+
(proposerIndex + 1) % shuffled.length,
|
|
578
|
+
(proposerIndex + 2) % shuffled.length
|
|
579
|
+
];
|
|
580
|
+
const valueI = shuffled[i];
|
|
581
|
+
const valueJ = shuffled[j];
|
|
582
|
+
shuffled[i] = valueJ;
|
|
583
|
+
shuffled[j] = valueI;
|
|
584
|
+
const signers = new CommitteeAttestationsAndSigners(attestations).getSigners();
|
|
585
|
+
return new MaliciousCommitteeAttestationsAndSigners(shuffled, signers);
|
|
586
|
+
}
|
|
587
|
+
return new CommitteeAttestationsAndSigners(attestations);
|
|
588
|
+
}
|
|
558
589
|
/**
|
|
559
590
|
* Publishes the L2Block to the rollup contract.
|
|
560
591
|
* @param block - The L2Block to be published.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "2.1.2",
|
|
3
|
+
"version": "2.1.3-rc.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,37 +26,37 @@
|
|
|
26
26
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@aztec/aztec.js": "2.1.2",
|
|
30
|
-
"@aztec/bb-prover": "2.1.2",
|
|
31
|
-
"@aztec/blob-lib": "2.1.2",
|
|
32
|
-
"@aztec/blob-sink": "2.1.2",
|
|
33
|
-
"@aztec/constants": "2.1.2",
|
|
34
|
-
"@aztec/epoch-cache": "2.1.2",
|
|
35
|
-
"@aztec/ethereum": "2.1.2",
|
|
36
|
-
"@aztec/foundation": "2.1.2",
|
|
37
|
-
"@aztec/l1-artifacts": "2.1.2",
|
|
38
|
-
"@aztec/merkle-tree": "2.1.2",
|
|
39
|
-
"@aztec/node-keystore": "2.1.2",
|
|
40
|
-
"@aztec/noir-acvm_js": "2.1.2",
|
|
41
|
-
"@aztec/noir-contracts.js": "2.1.2",
|
|
42
|
-
"@aztec/noir-protocol-circuits-types": "2.1.2",
|
|
43
|
-
"@aztec/noir-types": "2.1.2",
|
|
44
|
-
"@aztec/p2p": "2.1.2",
|
|
45
|
-
"@aztec/protocol-contracts": "2.1.2",
|
|
46
|
-
"@aztec/prover-client": "2.1.2",
|
|
47
|
-
"@aztec/simulator": "2.1.2",
|
|
48
|
-
"@aztec/slasher": "2.1.2",
|
|
49
|
-
"@aztec/stdlib": "2.1.2",
|
|
50
|
-
"@aztec/telemetry-client": "2.1.2",
|
|
51
|
-
"@aztec/validator-client": "2.1.2",
|
|
52
|
-
"@aztec/world-state": "2.1.2",
|
|
29
|
+
"@aztec/aztec.js": "2.1.3-rc.2",
|
|
30
|
+
"@aztec/bb-prover": "2.1.3-rc.2",
|
|
31
|
+
"@aztec/blob-lib": "2.1.3-rc.2",
|
|
32
|
+
"@aztec/blob-sink": "2.1.3-rc.2",
|
|
33
|
+
"@aztec/constants": "2.1.3-rc.2",
|
|
34
|
+
"@aztec/epoch-cache": "2.1.3-rc.2",
|
|
35
|
+
"@aztec/ethereum": "2.1.3-rc.2",
|
|
36
|
+
"@aztec/foundation": "2.1.3-rc.2",
|
|
37
|
+
"@aztec/l1-artifacts": "2.1.3-rc.2",
|
|
38
|
+
"@aztec/merkle-tree": "2.1.3-rc.2",
|
|
39
|
+
"@aztec/node-keystore": "2.1.3-rc.2",
|
|
40
|
+
"@aztec/noir-acvm_js": "2.1.3-rc.2",
|
|
41
|
+
"@aztec/noir-contracts.js": "2.1.3-rc.2",
|
|
42
|
+
"@aztec/noir-protocol-circuits-types": "2.1.3-rc.2",
|
|
43
|
+
"@aztec/noir-types": "2.1.3-rc.2",
|
|
44
|
+
"@aztec/p2p": "2.1.3-rc.2",
|
|
45
|
+
"@aztec/protocol-contracts": "2.1.3-rc.2",
|
|
46
|
+
"@aztec/prover-client": "2.1.3-rc.2",
|
|
47
|
+
"@aztec/simulator": "2.1.3-rc.2",
|
|
48
|
+
"@aztec/slasher": "2.1.3-rc.2",
|
|
49
|
+
"@aztec/stdlib": "2.1.3-rc.2",
|
|
50
|
+
"@aztec/telemetry-client": "2.1.3-rc.2",
|
|
51
|
+
"@aztec/validator-client": "2.1.3-rc.2",
|
|
52
|
+
"@aztec/world-state": "2.1.3-rc.2",
|
|
53
53
|
"lodash.chunk": "^4.2.0",
|
|
54
54
|
"tslib": "^2.4.0",
|
|
55
55
|
"viem": "npm:@spalladino/viem@2.38.2-eip7594.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@aztec/archiver": "2.1.2",
|
|
59
|
-
"@aztec/kv-store": "2.1.2",
|
|
58
|
+
"@aztec/archiver": "2.1.3-rc.2",
|
|
59
|
+
"@aztec/kv-store": "2.1.3-rc.2",
|
|
60
60
|
"@jest/globals": "^30.0.0",
|
|
61
61
|
"@types/jest": "^30.0.0",
|
|
62
62
|
"@types/lodash.chunk": "^4.2.7",
|
|
@@ -154,8 +154,8 @@ export class SequencerClient {
|
|
|
154
154
|
// In theory, the L1 slot has an initial 4s phase where the block is propagated, so we could
|
|
155
155
|
// make it with a propagation time into slot equal to 4s. However, we prefer being conservative.
|
|
156
156
|
// See https://www.blocknative.com/blog/anatomy-of-a-slot#7 for more info.
|
|
157
|
-
const
|
|
158
|
-
|
|
157
|
+
const maxInclusionBasedOnChain = isAnvilTestChain(config.l1ChainId) ? ethereumSlotDuration - 1 : 0;
|
|
158
|
+
const maxL1TxInclusionTimeIntoSlot = config.maxL1TxInclusionTimeIntoSlot ?? maxInclusionBasedOnChain;
|
|
159
159
|
|
|
160
160
|
const l1Constants = {
|
|
161
161
|
l1GenesisTime,
|
package/src/config.ts
CHANGED
|
@@ -149,6 +149,10 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
|
149
149
|
description: 'Inject a fake attestation (for testing only)',
|
|
150
150
|
...booleanConfigHelper(false),
|
|
151
151
|
},
|
|
152
|
+
shuffleAttestationOrdering: {
|
|
153
|
+
description: 'Shuffle attestation ordering to create invalid ordering (for testing only)',
|
|
154
|
+
...booleanConfigHelper(false),
|
|
155
|
+
},
|
|
152
156
|
...pickConfigMappings(p2pConfigMappings, ['txPublicSetupAllowList']),
|
|
153
157
|
};
|
|
154
158
|
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
CommitteeAttestation,
|
|
18
18
|
CommitteeAttestationsAndSigners,
|
|
19
19
|
type L2BlockSource,
|
|
20
|
+
MaliciousCommitteeAttestationsAndSigners,
|
|
20
21
|
type ValidateBlockResult,
|
|
21
22
|
} from '@aztec/stdlib/block';
|
|
22
23
|
import { type L1RollupConstants, getSlotAtTimestamp, getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
@@ -630,15 +631,17 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
630
631
|
);
|
|
631
632
|
|
|
632
633
|
this.log.debug('Collecting attestations');
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
634
|
+
const attestationsAndSigners = await this.collectAttestations(block, usedTxs, proposerAddress);
|
|
635
|
+
this.log.verbose(
|
|
636
|
+
`Collected ${attestationsAndSigners.attestations.length} attestations for block ${blockNumber} at slot ${slot}`,
|
|
637
|
+
{ blockHash, blockNumber, slot },
|
|
638
|
+
);
|
|
637
639
|
|
|
638
|
-
const
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
640
|
+
const attestationsAndSignersSignature =
|
|
641
|
+
(await this.validatorClient?.signAttestationsAndSigners(
|
|
642
|
+
attestationsAndSigners,
|
|
643
|
+
proposerAddress ?? publisher.getSenderAddress(),
|
|
644
|
+
)) ?? Signature.empty();
|
|
642
645
|
|
|
643
646
|
await this.enqueuePublishL2Block(
|
|
644
647
|
block,
|
|
@@ -664,8 +667,8 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
664
667
|
block: L2Block,
|
|
665
668
|
txs: Tx[],
|
|
666
669
|
proposerAddress: EthAddress | undefined,
|
|
667
|
-
): Promise<
|
|
668
|
-
const { committee } = await this.epochCache.getCommittee(block.
|
|
670
|
+
): Promise<CommitteeAttestationsAndSigners> {
|
|
671
|
+
const { committee, seed, epoch } = await this.epochCache.getCommittee(block.slot);
|
|
669
672
|
|
|
670
673
|
// We checked above that the committee is defined, so this should never happen.
|
|
671
674
|
if (!committee) {
|
|
@@ -674,15 +677,13 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
674
677
|
|
|
675
678
|
if (committee.length === 0) {
|
|
676
679
|
this.log.verbose(`Attesting committee is empty`);
|
|
677
|
-
return
|
|
680
|
+
return CommitteeAttestationsAndSigners.empty();
|
|
678
681
|
} else {
|
|
679
682
|
this.log.debug(`Attesting committee length is ${committee.length}`);
|
|
680
683
|
}
|
|
681
684
|
|
|
682
685
|
if (!this.validatorClient) {
|
|
683
|
-
|
|
684
|
-
this.log.error(msg);
|
|
685
|
-
throw new Error(msg);
|
|
686
|
+
throw new Error('Missing validator client: Cannot collect attestations');
|
|
686
687
|
}
|
|
687
688
|
|
|
688
689
|
const numberOfRequiredAttestations = Math.floor((committee.length * 2) / 3) + 1;
|
|
@@ -709,7 +710,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
709
710
|
if (this.config.skipCollectingAttestations) {
|
|
710
711
|
this.log.warn('Skipping attestation collection as per config (attesting with own keys only)');
|
|
711
712
|
const attestations = await this.validatorClient?.collectOwnAttestations(proposal);
|
|
712
|
-
return orderAttestations(attestations ?? [], committee);
|
|
713
|
+
return new CommitteeAttestationsAndSigners(orderAttestations(attestations ?? [], committee));
|
|
713
714
|
}
|
|
714
715
|
|
|
715
716
|
this.log.debug('Broadcasting block proposal to validators');
|
|
@@ -735,13 +736,13 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
735
736
|
|
|
736
737
|
// note: the smart contract requires that the signatures are provided in the order of the committee
|
|
737
738
|
const sorted = orderAttestations(attestations, committee);
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
this.
|
|
742
|
-
unfreeze(nonEmpty[randomIndex]).signature = Signature.random();
|
|
739
|
+
|
|
740
|
+
// manipulate the attestations if we've been configured to do so
|
|
741
|
+
if (this.config.injectFakeAttestation || this.config.shuffleAttestationOrdering) {
|
|
742
|
+
return this.manipulateAttestations(block, epoch, seed, committee, sorted);
|
|
743
743
|
}
|
|
744
|
-
|
|
744
|
+
|
|
745
|
+
return new CommitteeAttestationsAndSigners(sorted);
|
|
745
746
|
} catch (err) {
|
|
746
747
|
if (err && err instanceof AttestationTimeoutError) {
|
|
747
748
|
collectedAttestationsCount = err.collectedCount;
|
|
@@ -752,6 +753,53 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
752
753
|
}
|
|
753
754
|
}
|
|
754
755
|
|
|
756
|
+
/** Breaks the attestations before publishing based on attack configs */
|
|
757
|
+
private manipulateAttestations(
|
|
758
|
+
block: L2Block,
|
|
759
|
+
epoch: bigint,
|
|
760
|
+
seed: bigint,
|
|
761
|
+
committee: EthAddress[],
|
|
762
|
+
attestations: CommitteeAttestation[],
|
|
763
|
+
) {
|
|
764
|
+
// Compute the proposer index in the committee, since we dont want to tweak it.
|
|
765
|
+
// Otherwise, the L1 rollup contract will reject the block outright.
|
|
766
|
+
const proposerIndex = Number(
|
|
767
|
+
this.epochCache.computeProposerIndex(block.slot, epoch, seed, BigInt(committee.length)),
|
|
768
|
+
);
|
|
769
|
+
|
|
770
|
+
if (this.config.injectFakeAttestation) {
|
|
771
|
+
// Find non-empty attestations that are not from the proposer
|
|
772
|
+
const nonProposerIndices: number[] = [];
|
|
773
|
+
for (let i = 0; i < attestations.length; i++) {
|
|
774
|
+
if (!attestations[i].signature.isEmpty() && i !== proposerIndex) {
|
|
775
|
+
nonProposerIndices.push(i);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
if (nonProposerIndices.length > 0) {
|
|
779
|
+
const targetIndex = nonProposerIndices[randomInt(nonProposerIndices.length)];
|
|
780
|
+
this.log.warn(`Injecting fake attestation in block ${block.number} at index ${targetIndex}`);
|
|
781
|
+
unfreeze(attestations[targetIndex]).signature = Signature.random();
|
|
782
|
+
}
|
|
783
|
+
return new CommitteeAttestationsAndSigners(attestations);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
if (this.config.shuffleAttestationOrdering) {
|
|
787
|
+
this.log.warn(`Shuffling attestation ordering in block ${block.number} (proposer index ${proposerIndex})`);
|
|
788
|
+
|
|
789
|
+
const shuffled = [...attestations];
|
|
790
|
+
const [i, j] = [(proposerIndex + 1) % shuffled.length, (proposerIndex + 2) % shuffled.length];
|
|
791
|
+
const valueI = shuffled[i];
|
|
792
|
+
const valueJ = shuffled[j];
|
|
793
|
+
shuffled[i] = valueJ;
|
|
794
|
+
shuffled[j] = valueI;
|
|
795
|
+
|
|
796
|
+
const signers = new CommitteeAttestationsAndSigners(attestations).getSigners();
|
|
797
|
+
return new MaliciousCommitteeAttestationsAndSigners(shuffled, signers);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
return new CommitteeAttestationsAndSigners(attestations);
|
|
801
|
+
}
|
|
802
|
+
|
|
755
803
|
/**
|
|
756
804
|
* Publishes the L2Block to the rollup contract.
|
|
757
805
|
* @param block - The L2Block to be published.
|