@aztec/sequencer-client 0.87.3-nightly.20250528 → 0.87.3
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.d.ts +1 -2
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +0 -3
- package/dest/global_variable_builder/global_builder.d.ts +1 -4
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +2 -14
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/publisher/sequencer-publisher.d.ts +4 -4
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +6 -14
- package/dest/sequencer/sequencer.d.ts +12 -5
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +34 -26
- package/dest/sequencer/utils.d.ts +2 -2
- package/dest/sequencer/utils.d.ts.map +1 -1
- package/dest/sequencer/utils.js +4 -6
- package/dest/slasher/factory.d.ts +7 -0
- package/dest/slasher/factory.d.ts.map +1 -0
- package/dest/slasher/factory.js +8 -0
- package/dest/slasher/index.d.ts +3 -0
- package/dest/slasher/index.d.ts.map +1 -0
- package/dest/slasher/index.js +2 -0
- package/dest/slasher/slasher_client.d.ts +75 -0
- package/dest/slasher/slasher_client.d.ts.map +1 -0
- package/dest/slasher/slasher_client.js +135 -0
- package/package.json +25 -26
- package/src/client/sequencer-client.ts +1 -5
- package/src/global_variable_builder/global_builder.ts +2 -16
- package/src/index.ts +2 -1
- package/src/publisher/sequencer-publisher.ts +13 -22
- package/src/sequencer/sequencer.ts +42 -32
- package/src/sequencer/utils.ts +6 -14
- package/src/slasher/factory.ts +15 -0
- package/src/slasher/index.ts +2 -0
- package/src/slasher/slasher_client.ts +199 -0
|
@@ -4,7 +4,6 @@ import { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs';
|
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
6
6
|
import type { P2P } from '@aztec/p2p';
|
|
7
|
-
import type { SlasherClient } from '@aztec/slasher';
|
|
8
7
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
8
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
10
9
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
@@ -15,6 +14,7 @@ import type { ValidatorClient } from '@aztec/validator-client';
|
|
|
15
14
|
import type { SequencerClientConfig } from '../config.js';
|
|
16
15
|
import { SequencerPublisher } from '../publisher/index.js';
|
|
17
16
|
import { Sequencer, type SequencerConfig } from '../sequencer/index.js';
|
|
17
|
+
import type { SlasherClient } from '../slasher/index.js';
|
|
18
18
|
/**
|
|
19
19
|
* Encapsulates the full sequencer and publisher.
|
|
20
20
|
*/
|
|
@@ -64,7 +64,6 @@ export declare class SequencerClient {
|
|
|
64
64
|
* Restarts the sequencer after being stopped.
|
|
65
65
|
*/
|
|
66
66
|
restart(): void;
|
|
67
|
-
getSequencer(): Sequencer;
|
|
68
67
|
get coinbase(): EthAddress;
|
|
69
68
|
get feeRecipient(): AztecAddress;
|
|
70
69
|
get forwarderAddress(): EthAddress;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer-client.d.ts","sourceRoot":"","sources":["../../src/client/sequencer-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAUhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"sequencer-client.d.ts","sourceRoot":"","sources":["../../src/client/sequencer-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAUhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;GAEG;AACH,qBAAa,eAAe;IACd,SAAS,CAAC,SAAS,EAAE,SAAS;gBAApB,SAAS,EAAE,SAAS;IAE1C;;;;;;;;;;;;OAYG;WACiB,GAAG,CACrB,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE;QACJ,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;QAC7C,SAAS,EAAE,GAAG,CAAC;QACf,sBAAsB,EAAE,sBAAsB,CAAC;QAC/C,aAAa,EAAE,aAAa,CAAC;QAC7B,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,aAAa,EAAE,aAAa,CAAC;QAC7B,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,SAAS,EAAE,eAAe,CAAC;QAC3B,SAAS,CAAC,EAAE,kBAAkB,CAAC;QAC/B,cAAc,CAAC,EAAE,uBAAuB,CAAC;QACzC,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,SAAS,CAAC,EAAE,kBAAkB,CAAC;KAChC;IA0HH;;;OAGG;IACI,qBAAqB,CAAC,MAAM,EAAE,eAAe;IAIpD;;OAEG;IACU,IAAI;IAIjB,uGAAuG;IAChG,KAAK;IAIZ;;OAEG;IACI,OAAO;IAId,IAAI,QAAQ,IAAI,UAAU,CAEzB;IAED,IAAI,YAAY,IAAI,YAAY,CAE/B;IAED,IAAI,gBAAgB,IAAI,UAAU,CAEjC;IAED,IAAI,gBAAgB,IAAI,UAAU,GAAG,SAAS,CAE7C;IAED,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAEtC;CACF"}
|
|
@@ -10,8 +10,6 @@ import { GlobalVariables } from '@aztec/stdlib/tx';
|
|
|
10
10
|
*/
|
|
11
11
|
export declare class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
12
12
|
private log;
|
|
13
|
-
private currentBaseFees;
|
|
14
|
-
private currentL1BlockNumber;
|
|
15
13
|
private readonly rollupContract;
|
|
16
14
|
private readonly publicClient;
|
|
17
15
|
private readonly ethereumSlotDuration;
|
|
@@ -20,9 +18,8 @@ export declare class GlobalVariableBuilder implements GlobalVariableBuilderInter
|
|
|
20
18
|
constructor(config: L1ReaderConfig & Pick<L1ContractsConfig, 'ethereumSlotDuration'>);
|
|
21
19
|
/**
|
|
22
20
|
* Computes the "current" base fees, e.g., the price that you currently should pay to get include in the next block
|
|
23
|
-
* @returns Base fees for the next block
|
|
21
|
+
* @returns Base fees for the expected next block
|
|
24
22
|
*/
|
|
25
|
-
private computeCurrentBaseFees;
|
|
26
23
|
getCurrentBaseFees(): Promise<GasFees>;
|
|
27
24
|
getGlobalConstantVariables(): Promise<Pick<GlobalVariables, 'chainId' | 'version'>>;
|
|
28
25
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global_builder.d.ts","sourceRoot":"","sources":["../../src/global_variable_builder/global_builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAIpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAE,qBAAqB,IAAI,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInD;;GAEG;AACH,qBAAa,qBAAsB,YAAW,8BAA8B;IAC1E,OAAO,CAAC,GAAG,CAAqD;
|
|
1
|
+
{"version":3,"file":"global_builder.d.ts","sourceRoot":"","sources":["../../src/global_variable_builder/global_builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAIpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAE,qBAAqB,IAAI,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInD;;GAEG;AACH,qBAAa,qBAAsB,YAAW,8BAA8B;IAC1E,OAAO,CAAC,GAAG,CAAqD;IAEhE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAChD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAE9C,OAAO,CAAC,OAAO,CAAC,CAAK;IACrB,OAAO,CAAC,OAAO,CAAC,CAAK;gBAET,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;IAgBpF;;;OAGG;IACU,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAatC,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;IAUhG;;;;;;;OAOG;IACU,oBAAoB,CAC/B,WAAW,EAAE,EAAE,EACf,QAAQ,EAAE,UAAU,EACpB,YAAY,EAAE,YAAY,EAC1B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC;CA6B5B"}
|
|
@@ -8,8 +8,6 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
8
8
|
* Simple global variables builder.
|
|
9
9
|
*/ export class GlobalVariableBuilder {
|
|
10
10
|
log = createLogger('sequencer:global_variable_builder');
|
|
11
|
-
currentBaseFees = Promise.resolve(new GasFees(Fr.ZERO, Fr.ZERO));
|
|
12
|
-
currentL1BlockNumber = undefined;
|
|
13
11
|
rollupContract;
|
|
14
12
|
publicClient;
|
|
15
13
|
ethereumSlotDuration;
|
|
@@ -28,8 +26,8 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
28
26
|
}
|
|
29
27
|
/**
|
|
30
28
|
* Computes the "current" base fees, e.g., the price that you currently should pay to get include in the next block
|
|
31
|
-
* @returns Base fees for the next block
|
|
32
|
-
*/ async
|
|
29
|
+
* @returns Base fees for the expected next block
|
|
30
|
+
*/ async getCurrentBaseFees() {
|
|
33
31
|
// Since this might be called in the middle of a slot where a block might have been published,
|
|
34
32
|
// we need to fetch the last block written, and estimate the earliest timestamp for the next block.
|
|
35
33
|
// The timestamp of that last block will act as a lower bound for the next block.
|
|
@@ -39,16 +37,6 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
39
37
|
const timestamp = earliestTimestamp > nextEthTimestamp ? earliestTimestamp : nextEthTimestamp;
|
|
40
38
|
return new GasFees(Fr.ZERO, new Fr(await this.rollupContract.getManaBaseFeeAt(timestamp, true)));
|
|
41
39
|
}
|
|
42
|
-
async getCurrentBaseFees() {
|
|
43
|
-
// Get the current block number
|
|
44
|
-
const blockNumber = await this.publicClient.getBlockNumber();
|
|
45
|
-
// If the L1 block number has changed then chain a new promise to get the current base fees
|
|
46
|
-
if (this.currentL1BlockNumber === undefined || blockNumber > this.currentL1BlockNumber) {
|
|
47
|
-
this.currentL1BlockNumber = blockNumber;
|
|
48
|
-
this.currentBaseFees = this.currentBaseFees.then(()=>this.computeCurrentBaseFees());
|
|
49
|
-
}
|
|
50
|
-
return this.currentBaseFees;
|
|
51
|
-
}
|
|
52
40
|
async getGlobalConstantVariables() {
|
|
53
41
|
if (!this.chainId) {
|
|
54
42
|
this.chainId = new Fr(this.publicClient.chain.id);
|
package/dest/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from './client/index.js';
|
|
2
2
|
export * from './config.js';
|
|
3
3
|
export * from './publisher/index.js';
|
|
4
|
-
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
5
4
|
export * from './tx_validator/tx_validator_factory.js';
|
|
5
|
+
export * from './slasher/index.js';
|
|
6
|
+
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
6
7
|
export * from './global_variable_builder/index.js';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dest/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wCAAwC,CAAC;AACvD,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAIjE,cAAc,oCAAoC,CAAC"}
|
package/dest/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export * from './client/index.js';
|
|
2
2
|
export * from './config.js';
|
|
3
3
|
export * from './publisher/index.js';
|
|
4
|
-
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
5
4
|
export * from './tx_validator/tx_validator_factory.js';
|
|
5
|
+
export * from './slasher/index.js';
|
|
6
|
+
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
6
7
|
// Used by the node to simulate public parts of transactions. Should these be moved to a shared library?
|
|
7
8
|
// ISSUE(#9832)
|
|
8
9
|
export * from './global_variable_builder/index.js';
|
|
@@ -5,7 +5,7 @@ import type { EpochCache } from '@aztec/epoch-cache';
|
|
|
5
5
|
import { type ForwarderContract, type GasPrice, type GovernanceProposerContract, type L1BlobInputs, type L1ContractsConfig, type L1GasConfig, type L1TxRequest, RollupContract, type SlashingProposerContract, type TransactionStats } from '@aztec/ethereum';
|
|
6
6
|
import type { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs';
|
|
7
7
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
8
|
-
import {
|
|
8
|
+
import type { Signature } from '@aztec/foundation/eth-signature';
|
|
9
9
|
import { type ProposedBlockHeader, TxHash } from '@aztec/stdlib/tx';
|
|
10
10
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
11
11
|
import { type TransactionReceipt } from 'viem';
|
|
@@ -32,7 +32,7 @@ interface RequestWithExpiry {
|
|
|
32
32
|
export declare class SequencerPublisher {
|
|
33
33
|
private interrupted;
|
|
34
34
|
private metrics;
|
|
35
|
-
epochCache
|
|
35
|
+
private epochCache;
|
|
36
36
|
private forwarderContract;
|
|
37
37
|
protected governanceLog: import("@aztec/foundation/log").Logger;
|
|
38
38
|
protected governanceProposerAddress?: EthAddress;
|
|
@@ -108,7 +108,7 @@ export declare class SequencerPublisher {
|
|
|
108
108
|
*/
|
|
109
109
|
validateBlockForSubmission(header: ProposedBlockHeader, attestationData?: {
|
|
110
110
|
digest: Buffer;
|
|
111
|
-
|
|
111
|
+
signatures: Signature[];
|
|
112
112
|
}): Promise<bigint>;
|
|
113
113
|
getCurrentEpochCommittee(): Promise<EthAddress[]>;
|
|
114
114
|
private enqueueCastVoteHelper;
|
|
@@ -127,7 +127,7 @@ export declare class SequencerPublisher {
|
|
|
127
127
|
* @param block - L2 block to propose.
|
|
128
128
|
* @returns True if the tx has been enqueued, throws otherwise. See #9315
|
|
129
129
|
*/
|
|
130
|
-
enqueueProposeL2Block(block: L2Block, attestations?:
|
|
130
|
+
enqueueProposeL2Block(block: L2Block, attestations?: Signature[], txHashes?: TxHash[], opts?: {
|
|
131
131
|
txTimeoutAt?: Date;
|
|
132
132
|
}): Promise<boolean>;
|
|
133
133
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,KAAK,uBAAuB,EAAwB,MAAM,yBAAyB,CAAC;AAC7F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,0BAA0B,EAE/B,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAEjF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"sequencer-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,6 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
6
6
|
import { createLogger } from '@aztec/foundation/log';
|
|
7
7
|
import { Timer } from '@aztec/foundation/timer';
|
|
8
8
|
import { ForwarderAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
9
|
-
import { CommitteeAttestation } from '@aztec/stdlib/block';
|
|
10
9
|
import { ConsensusPayload, SignatureDomainSeparator, getHashedSignaturePayload } from '@aztec/stdlib/p2p';
|
|
11
10
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
12
11
|
import pick from 'lodash.pick';
|
|
@@ -187,24 +186,17 @@ export class SequencerPublisher {
|
|
|
187
186
|
*
|
|
188
187
|
*/ async validateBlockForSubmission(header, attestationData = {
|
|
189
188
|
digest: Buffer.alloc(32),
|
|
190
|
-
|
|
189
|
+
signatures: []
|
|
191
190
|
}) {
|
|
192
191
|
const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
|
|
193
|
-
|
|
194
|
-
// so that the committee is recalculated correctly
|
|
195
|
-
const ignoreSignatures = attestationData.attestations.length === 0;
|
|
196
|
-
if (ignoreSignatures) {
|
|
197
|
-
const committee = await this.epochCache.getCommittee(header.slotNumber.toBigInt());
|
|
198
|
-
attestationData.attestations = committee.committee.map((committeeMember)=>CommitteeAttestation.fromAddress(committeeMember));
|
|
199
|
-
}
|
|
200
|
-
const formattedAttestations = attestationData.attestations.map((attest)=>attest.toViem());
|
|
192
|
+
const formattedSignatures = attestationData.signatures.map((attest)=>attest.toViemSignature());
|
|
201
193
|
const flags = {
|
|
202
194
|
ignoreDA: true,
|
|
203
|
-
ignoreSignatures
|
|
195
|
+
ignoreSignatures: formattedSignatures.length == 0
|
|
204
196
|
};
|
|
205
197
|
const args = [
|
|
206
198
|
toHex(header.toBuffer()),
|
|
207
|
-
|
|
199
|
+
formattedSignatures,
|
|
208
200
|
toHex(attestationData.digest),
|
|
209
201
|
ts,
|
|
210
202
|
toHex(header.contentCommitment.blobsHash),
|
|
@@ -312,7 +304,7 @@ export class SequencerPublisher {
|
|
|
312
304
|
// make time consistency checks break.
|
|
313
305
|
const ts = await this.validateBlockForSubmission(proposedBlockHeader, {
|
|
314
306
|
digest: digest.toBuffer(),
|
|
315
|
-
|
|
307
|
+
signatures: attestations ?? []
|
|
316
308
|
});
|
|
317
309
|
this.log.debug(`Submitting propose transaction`);
|
|
318
310
|
await this.addProposeTx(block, proposeTxArgs, opts, ts);
|
|
@@ -359,7 +351,7 @@ export class SequencerPublisher {
|
|
|
359
351
|
});
|
|
360
352
|
throw new Error('Failed to validate blobs');
|
|
361
353
|
});
|
|
362
|
-
const attestations = encodedData.attestations ? encodedData.attestations.map((attest)=>attest.
|
|
354
|
+
const attestations = encodedData.attestations ? encodedData.attestations.map((attest)=>attest.toViemSignature()) : [];
|
|
363
355
|
const txHashes = encodedData.txHashes ? encodedData.txHashes.map((txHash)=>txHash.toString()) : [];
|
|
364
356
|
const args = [
|
|
365
357
|
{
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { type L2Block } from '@aztec/aztec.js';
|
|
2
2
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import type { Signature } from '@aztec/foundation/eth-signature';
|
|
3
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
4
5
|
import { type DateProvider, Timer } from '@aztec/foundation/timer';
|
|
5
6
|
import type { P2P } from '@aztec/p2p';
|
|
6
7
|
import type { BlockBuilderFactory } from '@aztec/prover-client/block-builder';
|
|
7
8
|
import type { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
8
|
-
import type { SlasherClient } from '@aztec/slasher';
|
|
9
9
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
10
|
-
import type {
|
|
10
|
+
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
11
11
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
12
12
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
13
13
|
import { Gas } from '@aztec/stdlib/gas';
|
|
@@ -18,6 +18,7 @@ import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
|
|
|
18
18
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
19
19
|
import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
|
|
20
20
|
import { type SequencerPublisher } from '../publisher/sequencer-publisher.js';
|
|
21
|
+
import type { SlasherClient } from '../slasher/slasher_client.js';
|
|
21
22
|
import type { SequencerConfig } from './config.js';
|
|
22
23
|
import { SequencerTimetable } from './timetable.js';
|
|
23
24
|
import { SequencerState } from './utils.js';
|
|
@@ -107,6 +108,13 @@ export declare class Sequencer {
|
|
|
107
108
|
protected doRealWork(): Promise<void>;
|
|
108
109
|
protected work(): Promise<void>;
|
|
109
110
|
getForwarderAddress(): EthAddress;
|
|
111
|
+
/**
|
|
112
|
+
* Checks if we can propose at the next block and returns the slot number if we can.
|
|
113
|
+
* @param tipArchive - The archive of the previous block.
|
|
114
|
+
* @param proposalBlockNumber - The block number of the proposal.
|
|
115
|
+
* @returns The slot number if we can propose at the next block, otherwise undefined.
|
|
116
|
+
*/
|
|
117
|
+
slotForProposal(tipArchive: Buffer, proposalBlockNumber: bigint): Promise<bigint | undefined>;
|
|
110
118
|
/**
|
|
111
119
|
* Sets the sequencer state and checks if we have enough time left in the slot to transition to the new state.
|
|
112
120
|
* @param proposedState - The new state to transition to.
|
|
@@ -166,12 +174,12 @@ export declare class Sequencer {
|
|
|
166
174
|
* @param proposalHeader - The partial header constructed for the proposal
|
|
167
175
|
*/
|
|
168
176
|
private buildBlockAndEnqueuePublish;
|
|
169
|
-
protected collectAttestations(block: L2Block, txs: Tx[]): Promise<
|
|
177
|
+
protected collectAttestations(block: L2Block, txs: Tx[]): Promise<Signature[] | undefined>;
|
|
170
178
|
/**
|
|
171
179
|
* Publishes the L2Block to the rollup contract.
|
|
172
180
|
* @param block - The L2Block to be published.
|
|
173
181
|
*/
|
|
174
|
-
protected enqueuePublishL2Block(block: L2Block, attestations?:
|
|
182
|
+
protected enqueuePublishL2Block(block: L2Block, attestations?: Signature[], txHashes?: TxHash[]): Promise<void>;
|
|
175
183
|
/**
|
|
176
184
|
* Returns whether all dependencies have caught up.
|
|
177
185
|
* We don't check against the previous block submitted since it may have been reorg'd out.
|
|
@@ -187,6 +195,5 @@ export declare class Sequencer {
|
|
|
187
195
|
get coinbase(): EthAddress;
|
|
188
196
|
get feeRecipient(): AztecAddress;
|
|
189
197
|
get maxL2BlockGas(): number | undefined;
|
|
190
|
-
getSlasherClient(): SlasherClient;
|
|
191
198
|
}
|
|
192
199
|
//# sourceMappingURL=sequencer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,iBAAiB,CAAC;AAI3D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,EAAW,MAAM,yBAAyB,CAAC;AAC5E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,
|
|
1
|
+
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,iBAAiB,CAAC;AAI3D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,EAAW,MAAM,yBAAyB,CAAC;AAC5E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAKnE,OAAO,EAAqB,eAAe,EAAE,mBAAmB,EAAE,EAAE,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,MAAM,EAGZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAC1F,OAAO,EAAE,KAAK,kBAAkB,EAAY,MAAM,qCAAqC,CAAC;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,kBAAkB,EAAyB,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAqB,MAAM,YAAY,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,KAAK,wBAAwB,GAAG,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,GAAG,eAAe,GAAG,cAAc,CAAC,CAAC;AAEnH;;;;;;;;GAQG;AACH,qBAAa,SAAS;IAuBlB,SAAS,CAAC,SAAS,EAAE,kBAAkB;IACvC,SAAS,CAAC,eAAe,EAAE,eAAe,GAAG,SAAS;IACtD,SAAS,CAAC,cAAc,EAAE,qBAAqB;IAC/C,SAAS,CAAC,SAAS,EAAE,GAAG;IACxB,SAAS,CAAC,UAAU,EAAE,sBAAsB;IAC5C,SAAS,CAAC,aAAa,EAAE,aAAa;IACtC,SAAS,CAAC,mBAAmB,EAAE,mBAAmB;IAClD,SAAS,CAAC,aAAa,EAAE,aAAa;IACtC,SAAS,CAAC,mBAAmB,EAAE,mBAAmB;IAClD,SAAS,CAAC,sBAAsB,EAAE,sBAAsB;IACxD,SAAS,CAAC,kBAAkB,EAAE,kBAAkB;IAChD,SAAS,CAAC,WAAW,EAAE,wBAAwB;IAC/C,SAAS,CAAC,YAAY,EAAE,YAAY;IACpC,SAAS,CAAC,MAAM,EAAE,eAAe;IAEjC,SAAS,CAAC,GAAG;IArCf,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,4BAA4B,CAAK;IAEzC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,sBAAsB,CAAwB;IACtD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAkB;IAEpC,+GAA+G;IAC/G,SAAS,CAAC,SAAS,EAAG,kBAAkB,CAAC;IAEzC,SAAS,CAAC,gBAAgB,EAAE,OAAO,CAAS;gBAGhC,SAAS,EAAE,kBAAkB,EAC7B,eAAe,EAAE,eAAe,GAAG,SAAS,EAAE,wDAAwD;IACtG,cAAc,EAAE,qBAAqB,EACrC,SAAS,EAAE,GAAG,EACd,UAAU,EAAE,sBAAsB,EAClC,aAAa,EAAE,aAAa,EAC5B,mBAAmB,EAAE,mBAAmB,EACxC,aAAa,EAAE,aAAa,EAC5B,mBAAmB,EAAE,mBAAmB,EACxC,sBAAsB,EAAE,sBAAsB,EAC9C,kBAAkB,EAAE,kBAAkB,EACtC,WAAW,EAAE,wBAAwB,EACrC,YAAY,EAAE,YAAY,EAC1B,MAAM,GAAE,eAAoB,EACtC,SAAS,GAAE,eAAsC,EACvC,GAAG,mCAA4B;IAsB3C,IAAI,MAAM,IAAI,MAAM,CAEnB;IAEM,mBAAmB;IAI1B;;;OAGG;IACU,YAAY,CAAC,MAAM,EAAE,eAAe;IAoDjD,OAAO,CAAC,YAAY;IAYpB;;OAEG;IACU,KAAK;IAUlB;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAYlC;;OAEG;IACI,OAAO;IAOd;;;OAGG;IACI,MAAM;;;IAIb,uGAAuG;IAChG,KAAK;IAIZ;;;;;;;OAOG;cACa,UAAU;cAoGV,IAAI;IAeb,mBAAmB;IAI1B;;;;;OAKG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAiBnG;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,GAAE,OAAe;IAWzF;;;;;;OAMG;cACa,UAAU,CACxB,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,EAC5C,kBAAkB,EAAE,eAAe,EACnC,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO;;;;;;;;;;IAwIvC;;;;;;;OAOG;IACG,sBAAsB,CAC1B,WAAW,EAAE,EAAE,EACf,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,EAC5C,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO;;;;;;;;;;IAavC;;;;;;;;OAQG;YAIW,2BAA2B;cAkEzB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC;IAqDhG;;;OAGG;cAIa,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,YAAY,CAAC,EAAE,SAAS,EAAE,EAC1B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC;IAiBhB;;;;OAIG;cACa,WAAW,IAAI,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,EAAE,CAAA;KAAE,GAAG,SAAS,CAAC;IA+CxF,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,kBAAkB;IAK1B,IAAI,iBAAiB,WAEpB;IAED,IAAI,QAAQ,IAAI,UAAU,CAEzB;IAED,IAAI,YAAY,IAAI,YAAY,CAE/B;IAED,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAEtC;CACF"}
|
|
@@ -6,7 +6,6 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
6
6
|
}
|
|
7
7
|
import { retryUntil } from '@aztec/aztec.js';
|
|
8
8
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
9
|
-
import { FormattedViemError } from '@aztec/ethereum';
|
|
10
9
|
import { omit } from '@aztec/foundation/collection';
|
|
11
10
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
12
11
|
import { Fr } from '@aztec/foundation/fields';
|
|
@@ -183,7 +182,7 @@ export { SequencerState };
|
|
|
183
182
|
this.metrics.stop();
|
|
184
183
|
await this.validatorClient?.stop();
|
|
185
184
|
await this.runningPromise?.stop();
|
|
186
|
-
|
|
185
|
+
this.slasherClient.stop();
|
|
187
186
|
this.publisher.interrupt();
|
|
188
187
|
this.setState(SequencerState.STOPPED, 0n, true);
|
|
189
188
|
this.l1Metrics.stop();
|
|
@@ -227,16 +226,10 @@ export { SequencerState };
|
|
|
227
226
|
const newBlockNumber = chainTip.blockNumber + 1;
|
|
228
227
|
// If we cannot find a tip archive, assume genesis.
|
|
229
228
|
const chainTipArchive = chainTip.archive;
|
|
230
|
-
const
|
|
229
|
+
const slot = await this.slotForProposal(chainTipArchive.toBuffer(), BigInt(newBlockNumber));
|
|
231
230
|
this.metrics.observeSlotChange(slot, this.publisher.getSenderAddress().toString());
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
// If we calculate a proposer in the next slot, and it is not us, then stop
|
|
235
|
-
if (proposerInNextSlot !== undefined && !proposerInNextSlot.equals(this.validatorClient.getValidatorAddress())) {
|
|
236
|
-
this.log.debug(`Cannot propose block ${newBlockNumber}`, {
|
|
237
|
-
us: this.validatorClient.getValidatorAddress(),
|
|
238
|
-
proposer: proposerInNextSlot
|
|
239
|
-
});
|
|
231
|
+
if (!slot) {
|
|
232
|
+
this.log.debug(`Cannot propose block ${newBlockNumber}`);
|
|
240
233
|
return;
|
|
241
234
|
}
|
|
242
235
|
this.log.debug(`Can propose block ${newBlockNumber} at slot ${slot}`);
|
|
@@ -264,15 +257,10 @@ export { SequencerState };
|
|
|
264
257
|
// and also we may need to fetch more if we don't have enough valid txs.
|
|
265
258
|
const pendingTxs = this.p2pClient.iteratePendingTxs();
|
|
266
259
|
await this.buildBlockAndEnqueuePublish(pendingTxs, proposalHeader, newGlobalVariables).catch((err)=>{
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
this.log.error(`Error building/enqueuing block`, err, {
|
|
272
|
-
blockNumber: newBlockNumber,
|
|
273
|
-
slot
|
|
274
|
-
});
|
|
275
|
-
}
|
|
260
|
+
this.log.error(`Error building/enqueuing block`, err, {
|
|
261
|
+
blockNumber: newBlockNumber,
|
|
262
|
+
slot
|
|
263
|
+
});
|
|
276
264
|
});
|
|
277
265
|
finishedFlushing = true;
|
|
278
266
|
} else {
|
|
@@ -324,6 +312,24 @@ export { SequencerState };
|
|
|
324
312
|
return this.publisher.getForwarderAddress();
|
|
325
313
|
}
|
|
326
314
|
/**
|
|
315
|
+
* Checks if we can propose at the next block and returns the slot number if we can.
|
|
316
|
+
* @param tipArchive - The archive of the previous block.
|
|
317
|
+
* @param proposalBlockNumber - The block number of the proposal.
|
|
318
|
+
* @returns The slot number if we can propose at the next block, otherwise undefined.
|
|
319
|
+
*/ async slotForProposal(tipArchive, proposalBlockNumber) {
|
|
320
|
+
const result = await this.publisher.canProposeAtNextEthBlock(tipArchive);
|
|
321
|
+
if (!result) {
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
const [slot, blockNumber] = result;
|
|
325
|
+
if (proposalBlockNumber !== blockNumber) {
|
|
326
|
+
const msg = `Sequencer block number mismatch. Expected ${proposalBlockNumber} but got ${blockNumber}.`;
|
|
327
|
+
this.log.warn(msg);
|
|
328
|
+
throw new Error(msg);
|
|
329
|
+
}
|
|
330
|
+
return slot;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
327
333
|
* Sets the sequencer state and checks if we have enough time left in the slot to transition to the new state.
|
|
328
334
|
* @param proposedState - The new state to transition to.
|
|
329
335
|
* @param currentSlotNumber - The current slot number.
|
|
@@ -362,15 +368,16 @@ export { SequencerState };
|
|
|
362
368
|
// Sync to the previous block at least. If we cannot sync to that block because the archiver hasn't caught up,
|
|
363
369
|
// we keep retrying until the reexecution deadline. Note that this could only happen when we are a validator,
|
|
364
370
|
// for if we are the proposer, then world-state should already be caught up, as we check this earlier.
|
|
365
|
-
await retryUntil(()
|
|
371
|
+
await retryUntil(()=>this.worldState.syncImmediate(blockNumber - 1, true).then((syncedTo)=>syncedTo >= blockNumber - 1), 'sync to previous block', this.timetable.getValidatorReexecTimeEnd(), 0.1);
|
|
366
372
|
this.log.debug(`Synced to previous block ${blockNumber - 1}`);
|
|
367
373
|
// NB: separating the dbs because both should update the state
|
|
368
374
|
const publicProcessorDBFork = await this.worldState.fork();
|
|
369
|
-
const
|
|
375
|
+
const orchestratorDBFork = await this.worldState.fork();
|
|
376
|
+
const previousBlockHeader = (await this.l2BlockSource.getBlock(blockNumber - 1))?.header ?? orchestratorDBFork.getInitialHeader();
|
|
370
377
|
try {
|
|
371
378
|
const processor = this.publicProcessorFactory.create(publicProcessorDBFork, newGlobalVariables, true);
|
|
372
379
|
const blockBuildingTimer = new Timer();
|
|
373
|
-
const blockBuilder = this.blockBuilderFactory.create(
|
|
380
|
+
const blockBuilder = this.blockBuilderFactory.create(orchestratorDBFork);
|
|
374
381
|
await blockBuilder.startNewBlock(newGlobalVariables, l1ToL2Messages, previousBlockHeader);
|
|
375
382
|
// Deadline for processing depends on whether we're proposing a block
|
|
376
383
|
const secondsIntoSlot = this.getSecondsIntoSlot(slot);
|
|
@@ -384,6 +391,9 @@ export { SequencerState };
|
|
|
384
391
|
deadline
|
|
385
392
|
});
|
|
386
393
|
const validator = createValidatorForBlockBuilding(publicProcessorDBFork, this.contractDataSource, newGlobalVariables, this.txPublicSetupAllowList);
|
|
394
|
+
// TODO(#11000): Public processor should just handle processing, one tx at a time. It should be responsibility
|
|
395
|
+
// of the sequencer to update world state and iterate over txs. We should refactor this along with unifying the
|
|
396
|
+
// publicProcessorFork and orchestratorFork, to avoid doing tree insertions twice when building the block.
|
|
387
397
|
const proposerLimits = {
|
|
388
398
|
maxTransactions: this.maxTxsPerBlock,
|
|
389
399
|
maxBlockSize: this.maxBlockSizeInBytes,
|
|
@@ -439,6 +449,7 @@ export { SequencerState };
|
|
|
439
449
|
setTimeout(async ()=>{
|
|
440
450
|
try {
|
|
441
451
|
await publicProcessorDBFork.close();
|
|
452
|
+
await orchestratorDBFork.close();
|
|
442
453
|
} catch (err) {
|
|
443
454
|
// This can happen if the sequencer is stopped before we hit this timeout.
|
|
444
455
|
this.log.warn(`Error closing forks for block processing`, err);
|
|
@@ -632,9 +643,6 @@ export { SequencerState };
|
|
|
632
643
|
get maxL2BlockGas() {
|
|
633
644
|
return this.config.maxL2BlockGas;
|
|
634
645
|
}
|
|
635
|
-
getSlasherClient() {
|
|
636
|
-
return this.slasherClient;
|
|
637
|
-
}
|
|
638
646
|
}
|
|
639
647
|
_ts_decorate([
|
|
640
648
|
trackSpan('Sequencer.work')
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
-
import {
|
|
2
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
3
3
|
import type { BlockAttestation } from '@aztec/stdlib/p2p';
|
|
4
4
|
export declare enum SequencerState {
|
|
5
5
|
/**
|
|
@@ -44,5 +44,5 @@ export declare function sequencerStateToNumber(state: SequencerState): number;
|
|
|
44
44
|
*
|
|
45
45
|
* @todo: perform this logic within the memory attestation store instead?
|
|
46
46
|
*/
|
|
47
|
-
export declare function orderAttestations(attestations: BlockAttestation[], orderAddresses: EthAddress[]):
|
|
47
|
+
export declare function orderAttestations(attestations: BlockAttestation[], orderAddresses: EthAddress[]): Signature[];
|
|
48
48
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sequencer/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sequencer/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,oBAAY,cAAc;IACxB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,aAAa,kBAAkB;IAC/B;;OAEG;IACH,cAAc,mBAAmB;IACjC;;OAEG;IACH,qBAAqB,0BAA0B;IAC/C;;OAEG;IACH,cAAc,mBAAmB;IACjC;;OAEG;IACH,uBAAuB,4BAA4B;IACnD;;OAEG;IACH,gBAAgB,qBAAqB;CACtC;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,cAAc,CAAC;AAE1D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,gBAAgB,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,SAAS,EAAE,CAgB7G"}
|
package/dest/sequencer/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
2
2
|
export var SequencerState = /*#__PURE__*/ function(SequencerState) {
|
|
3
3
|
/**
|
|
4
4
|
* Sequencer is stopped and not processing any txs from the pool.
|
|
@@ -40,14 +40,12 @@ export function sequencerStateToNumber(state) {
|
|
|
40
40
|
const attestationMap = new Map();
|
|
41
41
|
for (const attestation of attestations){
|
|
42
42
|
const sender = attestation.getSender();
|
|
43
|
-
|
|
44
|
-
attestationMap.set(sender.toString(), CommitteeAttestation.fromAddressAndSignature(sender, attestation.signature));
|
|
45
|
-
}
|
|
43
|
+
attestationMap.set(sender.toString(), attestation);
|
|
46
44
|
}
|
|
47
|
-
// Create the ordered array based on the orderAddresses, else return an empty
|
|
45
|
+
// Create the ordered array based on the orderAddresses, else return an empty signature
|
|
48
46
|
const orderedAttestations = orderAddresses.map((address)=>{
|
|
49
47
|
const addressString = address.toString();
|
|
50
|
-
return attestationMap.get(addressString) ||
|
|
48
|
+
return attestationMap.get(addressString)?.signature || Signature.empty();
|
|
51
49
|
});
|
|
52
50
|
return orderedAttestations;
|
|
53
51
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { L1ContractsConfig, L1ReaderConfig } from '@aztec/ethereum';
|
|
2
|
+
import type { L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
|
|
3
|
+
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
4
|
+
import { SlasherClient } from './slasher_client.js';
|
|
5
|
+
import type { SlasherConfig } from './slasher_client.js';
|
|
6
|
+
export declare const createSlasherClient: (_config: SlasherConfig & L1ContractsConfig & L1ReaderConfig, l2BlockSource: L2BlockSourceEventEmitter, telemetry?: TelemetryClient) => SlasherClient;
|
|
7
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/slasher/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,eAAO,MAAM,mBAAmB,GAC9B,SAAS,aAAa,GAAG,iBAAiB,GAAG,cAAc,EAC3D,eAAe,yBAAyB,EACxC,YAAW,eAAsC,kBAIlD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
2
|
+
import { SlasherClient } from './slasher_client.js';
|
|
3
|
+
export const createSlasherClient = (_config, l2BlockSource, telemetry = getTelemetryClient())=>{
|
|
4
|
+
const config = {
|
|
5
|
+
..._config
|
|
6
|
+
};
|
|
7
|
+
return new SlasherClient(config, l2BlockSource, telemetry);
|
|
8
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/slasher/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type L1ContractsConfig, type L1ReaderConfig, type ViemPublicClient } from '@aztec/ethereum';
|
|
2
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import { SlashFactoryAbi } from '@aztec/l1-artifacts';
|
|
4
|
+
import { type L2BlockId, type L2BlockSourceEvent, type L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
|
|
5
|
+
import { type TelemetryClient, WithTracer } from '@aztec/telemetry-client';
|
|
6
|
+
import { type GetContractReturnType } from 'viem';
|
|
7
|
+
/**
|
|
8
|
+
* Enum defining the possible states of the Slasher client.
|
|
9
|
+
*/
|
|
10
|
+
export declare enum SlasherClientState {
|
|
11
|
+
IDLE = 0,
|
|
12
|
+
RUNNING = 1,
|
|
13
|
+
STOPPED = 2
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The synchronization status of the Slasher client.
|
|
17
|
+
*/
|
|
18
|
+
export interface SlasherSyncState {
|
|
19
|
+
/**
|
|
20
|
+
* The current state of the slasher client.
|
|
21
|
+
*/
|
|
22
|
+
state: SlasherClientState;
|
|
23
|
+
/**
|
|
24
|
+
* The block number that the slasher client is synced to.
|
|
25
|
+
*/
|
|
26
|
+
syncedToL2Block: L2BlockId;
|
|
27
|
+
}
|
|
28
|
+
export interface SlasherConfig {
|
|
29
|
+
blockCheckIntervalMS: number;
|
|
30
|
+
blockRequestBatchSize: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @notice A Hypomeiones slasher client implementation
|
|
34
|
+
*
|
|
35
|
+
* Hypomeiones: a class of individuals in ancient Sparta who were considered inferior or lesser citizens compared
|
|
36
|
+
* to the full Spartan citizens.
|
|
37
|
+
*
|
|
38
|
+
* The implementation here is less than ideal. It exists, not to be the end all be all, but to show that
|
|
39
|
+
* slashing can be done with this mechanism.
|
|
40
|
+
*
|
|
41
|
+
* The implementation is VERY brute in the sense that it only looks for pruned blocks and then tries to slash
|
|
42
|
+
* the full committee of that.
|
|
43
|
+
* If it sees a prune, it will mark the full epoch as "to be slashed".
|
|
44
|
+
*
|
|
45
|
+
* Also, it is not particularly smart around what it should if there were to be multiple slashing events.
|
|
46
|
+
*
|
|
47
|
+
* A few improvements:
|
|
48
|
+
* - Only vote on the proposal if it is possible to reach, e.g., if 6 votes are needed and only 4 slots are left don't vote.
|
|
49
|
+
* - Stop voting on a payload once it is processed.
|
|
50
|
+
* - Only vote on the proposal if it have not already been executed
|
|
51
|
+
* - Caveat, we need to fully decide if it is acceptable to have the same payload address multiple times. In the current
|
|
52
|
+
* slash factory that could mean slashing the same committee for the same error multiple times.
|
|
53
|
+
* - Decide how to deal with multiple slashing events in the same round.
|
|
54
|
+
* - This could be that multiple epochs are pruned in the same round, but with the current naive implementation we could end up
|
|
55
|
+
* slashing only the first, because the "lifetime" of the second would have passed after that vote
|
|
56
|
+
*/
|
|
57
|
+
export declare class SlasherClient extends WithTracer {
|
|
58
|
+
private config;
|
|
59
|
+
private l2BlockSource;
|
|
60
|
+
private log;
|
|
61
|
+
private slashEvents;
|
|
62
|
+
protected slashFactoryContract?: GetContractReturnType<typeof SlashFactoryAbi, ViemPublicClient>;
|
|
63
|
+
private slashingAmount;
|
|
64
|
+
constructor(config: SlasherConfig & L1ContractsConfig & L1ReaderConfig, l2BlockSource: L2BlockSourceEventEmitter, telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
|
|
65
|
+
start(): void;
|
|
66
|
+
getSlashPayload(slotNumber: bigint): Promise<EthAddress | undefined>;
|
|
67
|
+
handleBlockStreamEvent(event: L2BlockSourceEvent): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Allows consumers to stop the instance of the slasher client.
|
|
70
|
+
* 'ready' will now return 'false' and the running promise that keeps the client synced is interrupted.
|
|
71
|
+
*/
|
|
72
|
+
stop(): void;
|
|
73
|
+
private handlePruneL2Blocks;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=slasher_client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slasher_client.d.ts","sourceRoot":"","sources":["../../src/slasher/slasher_client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EACL,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAE/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,eAAe,EAAE,UAAU,EAAsB,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,KAAK,qBAAqB,EAA+D,MAAM,MAAM,CAAC;AAE/G;;GAEG;AACH,oBAAY,kBAAkB;IAC5B,IAAI,IAAA;IACJ,OAAO,IAAA;IACP,OAAO,IAAA;CACR;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,KAAK,EAAE,kBAAkB,CAAC;IAC1B;;OAEG;IACH,eAAe,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAQD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,aAAc,SAAQ,UAAU;IAWzC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,aAAa;IAErB,OAAO,CAAC,GAAG;IAbb,OAAO,CAAC,WAAW,CAAoB;IAEvC,SAAS,CAAC,oBAAoB,CAAC,EAAE,qBAAqB,CAAC,OAAO,eAAe,EAAE,gBAAgB,CAAC,CAAa;IAK7G,OAAO,CAAC,cAAc,CAAc;gBAG1B,MAAM,EAAE,aAAa,GAAG,iBAAiB,GAAG,cAAc,EAC1D,aAAa,EAAE,yBAAyB,EAChD,SAAS,GAAE,eAAsC,EACzC,GAAG,yCAA0B;IAwBhC,KAAK;IAMC,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAgC1E,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAavE;;;OAGG;IACI,IAAI;IAMX,OAAO,CAAC,mBAAmB;CAqB5B"}
|