@aztec/sequencer-client 0.87.1 → 0.87.2-nightly.20250524
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 +2 -1
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +3 -0
- package/dest/global_variable_builder/global_builder.d.ts +4 -1
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +14 -2
- package/dest/index.d.ts +1 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -2
- package/dest/sequencer/sequencer.d.ts +2 -1
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +4 -1
- package/package.json +26 -25
- package/src/client/sequencer-client.ts +5 -1
- package/src/global_variable_builder/global_builder.ts +16 -2
- package/src/index.ts +1 -2
- package/src/sequencer/sequencer.ts +6 -2
- package/dest/slasher/factory.d.ts +0 -7
- package/dest/slasher/factory.d.ts.map +0 -1
- package/dest/slasher/factory.js +0 -8
- package/dest/slasher/index.d.ts +0 -3
- package/dest/slasher/index.d.ts.map +0 -1
- package/dest/slasher/index.js +0 -2
- package/dest/slasher/slasher_client.d.ts +0 -75
- package/dest/slasher/slasher_client.d.ts.map +0 -1
- package/dest/slasher/slasher_client.js +0 -135
- package/src/slasher/factory.ts +0 -15
- package/src/slasher/index.ts +0 -2
- package/src/slasher/slasher_client.ts +0 -199
|
@@ -4,6 +4,7 @@ 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';
|
|
7
8
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
9
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
9
10
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
@@ -14,7 +15,6 @@ import type { ValidatorClient } from '@aztec/validator-client';
|
|
|
14
15
|
import type { SequencerClientConfig } from '../config.js';
|
|
15
16
|
import { SequencerPublisher } from '../publisher/index.js';
|
|
16
17
|
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,6 +64,7 @@ export declare class SequencerClient {
|
|
|
64
64
|
* Restarts the sequencer after being stopped.
|
|
65
65
|
*/
|
|
66
66
|
restart(): void;
|
|
67
|
+
getSequencer(): Sequencer;
|
|
67
68
|
get coinbase(): EthAddress;
|
|
68
69
|
get feeRecipient(): AztecAddress;
|
|
69
70
|
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,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;
|
|
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,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,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;AAExE;;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;IAIP,YAAY,IAAI,SAAS;IAIhC,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,6 +10,8 @@ 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;
|
|
13
15
|
private readonly rollupContract;
|
|
14
16
|
private readonly publicClient;
|
|
15
17
|
private readonly ethereumSlotDuration;
|
|
@@ -18,8 +20,9 @@ export declare class GlobalVariableBuilder implements GlobalVariableBuilderInter
|
|
|
18
20
|
constructor(config: L1ReaderConfig & Pick<L1ContractsConfig, 'ethereumSlotDuration'>);
|
|
19
21
|
/**
|
|
20
22
|
* Computes the "current" base fees, e.g., the price that you currently should pay to get include in the next block
|
|
21
|
-
* @returns Base fees for the
|
|
23
|
+
* @returns Base fees for the next block
|
|
22
24
|
*/
|
|
25
|
+
private computeCurrentBaseFees;
|
|
23
26
|
getCurrentBaseFees(): Promise<GasFees>;
|
|
24
27
|
getGlobalConstantVariables(): Promise<Pick<GlobalVariables, 'chainId' | 'version'>>;
|
|
25
28
|
/**
|
|
@@ -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;IAChE,OAAO,CAAC,eAAe,CAAoE;IAC3F,OAAO,CAAC,oBAAoB,CAAiC;IAE7D,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;YACW,sBAAsB;IAavB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAYtC,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,6 +8,8 @@ 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;
|
|
11
13
|
rollupContract;
|
|
12
14
|
publicClient;
|
|
13
15
|
ethereumSlotDuration;
|
|
@@ -26,8 +28,8 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
26
28
|
}
|
|
27
29
|
/**
|
|
28
30
|
* Computes the "current" base fees, e.g., the price that you currently should pay to get include in the next block
|
|
29
|
-
* @returns Base fees for the
|
|
30
|
-
*/ async
|
|
31
|
+
* @returns Base fees for the next block
|
|
32
|
+
*/ async computeCurrentBaseFees() {
|
|
31
33
|
// Since this might be called in the middle of a slot where a block might have been published,
|
|
32
34
|
// we need to fetch the last block written, and estimate the earliest timestamp for the next block.
|
|
33
35
|
// The timestamp of that last block will act as a lower bound for the next block.
|
|
@@ -37,6 +39,16 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
37
39
|
const timestamp = earliestTimestamp > nextEthTimestamp ? earliestTimestamp : nextEthTimestamp;
|
|
38
40
|
return new GasFees(Fr.ZERO, new Fr(await this.rollupContract.getManaBaseFeeAt(timestamp, true)));
|
|
39
41
|
}
|
|
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
|
+
}
|
|
40
52
|
async getGlobalConstantVariables() {
|
|
41
53
|
if (!this.chainId) {
|
|
42
54
|
this.chainId = new Fr(this.publicClient.chain.id);
|
package/dest/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export * from './client/index.js';
|
|
2
2
|
export * from './config.js';
|
|
3
3
|
export * from './publisher/index.js';
|
|
4
|
-
export * from './tx_validator/tx_validator_factory.js';
|
|
5
|
-
export * from './slasher/index.js';
|
|
6
4
|
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
5
|
+
export * from './tx_validator/tx_validator_factory.js';
|
|
7
6
|
export * from './global_variable_builder/index.js';
|
|
8
7
|
//# 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,
|
|
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;AACjE,cAAc,wCAAwC,CAAC;AAIvD,cAAc,oCAAoC,CAAC"}
|
package/dest/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export * from './client/index.js';
|
|
2
2
|
export * from './config.js';
|
|
3
3
|
export * from './publisher/index.js';
|
|
4
|
-
export * from './tx_validator/tx_validator_factory.js';
|
|
5
|
-
export * from './slasher/index.js';
|
|
6
4
|
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
5
|
+
export * from './tx_validator/tx_validator_factory.js';
|
|
7
6
|
// Used by the node to simulate public parts of transactions. Should these be moved to a shared library?
|
|
8
7
|
// ISSUE(#9832)
|
|
9
8
|
export * from './global_variable_builder/index.js';
|
|
@@ -6,6 +6,7 @@ import { type DateProvider, Timer } from '@aztec/foundation/timer';
|
|
|
6
6
|
import type { P2P } from '@aztec/p2p';
|
|
7
7
|
import type { BlockBuilderFactory } from '@aztec/prover-client/block-builder';
|
|
8
8
|
import type { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
9
|
+
import type { SlasherClient } from '@aztec/slasher';
|
|
9
10
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
10
11
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
11
12
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
@@ -18,7 +19,6 @@ import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
|
|
|
18
19
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
19
20
|
import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
|
|
20
21
|
import { type SequencerPublisher } from '../publisher/sequencer-publisher.js';
|
|
21
|
-
import type { SlasherClient } from '../slasher/slasher_client.js';
|
|
22
22
|
import type { SequencerConfig } from './config.js';
|
|
23
23
|
import { SequencerTimetable } from './timetable.js';
|
|
24
24
|
import { SequencerState } from './utils.js';
|
|
@@ -195,5 +195,6 @@ export declare class Sequencer {
|
|
|
195
195
|
get coinbase(): EthAddress;
|
|
196
196
|
get feeRecipient(): AztecAddress;
|
|
197
197
|
get maxL2BlockGas(): number | undefined;
|
|
198
|
+
getSlasherClient(): SlasherClient;
|
|
198
199
|
}
|
|
199
200
|
//# 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,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;
|
|
1
|
+
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
|
|
@@ -182,7 +182,7 @@ export { SequencerState };
|
|
|
182
182
|
this.metrics.stop();
|
|
183
183
|
await this.validatorClient?.stop();
|
|
184
184
|
await this.runningPromise?.stop();
|
|
185
|
-
this.slasherClient.stop();
|
|
185
|
+
await this.slasherClient.stop();
|
|
186
186
|
this.publisher.interrupt();
|
|
187
187
|
this.setState(SequencerState.STOPPED, 0n, true);
|
|
188
188
|
this.l1Metrics.stop();
|
|
@@ -643,6 +643,9 @@ export { SequencerState };
|
|
|
643
643
|
get maxL2BlockGas() {
|
|
644
644
|
return this.config.maxL2BlockGas;
|
|
645
645
|
}
|
|
646
|
+
getSlasherClient() {
|
|
647
|
+
return this.slasherClient;
|
|
648
|
+
}
|
|
646
649
|
}
|
|
647
650
|
_ts_decorate([
|
|
648
651
|
trackSpan('Sequencer.work')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "0.87.
|
|
3
|
+
"version": "0.87.2-nightly.20250524",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,36 +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": "0.87.
|
|
30
|
-
"@aztec/bb-prover": "0.87.
|
|
31
|
-
"@aztec/blob-lib": "0.87.
|
|
32
|
-
"@aztec/blob-sink": "0.87.
|
|
33
|
-
"@aztec/constants": "0.87.
|
|
34
|
-
"@aztec/epoch-cache": "0.87.
|
|
35
|
-
"@aztec/ethereum": "0.87.
|
|
36
|
-
"@aztec/foundation": "0.87.
|
|
37
|
-
"@aztec/l1-artifacts": "0.87.
|
|
38
|
-
"@aztec/merkle-tree": "0.87.
|
|
39
|
-
"@aztec/noir-acvm_js": "0.87.
|
|
40
|
-
"@aztec/noir-contracts.js": "0.87.
|
|
41
|
-
"@aztec/noir-protocol-circuits-types": "0.87.
|
|
42
|
-
"@aztec/noir-types": "0.87.
|
|
43
|
-
"@aztec/p2p": "0.87.
|
|
44
|
-
"@aztec/protocol-contracts": "0.87.
|
|
45
|
-
"@aztec/prover-client": "0.87.
|
|
46
|
-
"@aztec/simulator": "0.87.
|
|
47
|
-
"@aztec/
|
|
48
|
-
"@aztec/
|
|
49
|
-
"@aztec/
|
|
50
|
-
"@aztec/
|
|
29
|
+
"@aztec/aztec.js": "0.87.2-nightly.20250524",
|
|
30
|
+
"@aztec/bb-prover": "0.87.2-nightly.20250524",
|
|
31
|
+
"@aztec/blob-lib": "0.87.2-nightly.20250524",
|
|
32
|
+
"@aztec/blob-sink": "0.87.2-nightly.20250524",
|
|
33
|
+
"@aztec/constants": "0.87.2-nightly.20250524",
|
|
34
|
+
"@aztec/epoch-cache": "0.87.2-nightly.20250524",
|
|
35
|
+
"@aztec/ethereum": "0.87.2-nightly.20250524",
|
|
36
|
+
"@aztec/foundation": "0.87.2-nightly.20250524",
|
|
37
|
+
"@aztec/l1-artifacts": "0.87.2-nightly.20250524",
|
|
38
|
+
"@aztec/merkle-tree": "0.87.2-nightly.20250524",
|
|
39
|
+
"@aztec/noir-acvm_js": "0.87.2-nightly.20250524",
|
|
40
|
+
"@aztec/noir-contracts.js": "0.87.2-nightly.20250524",
|
|
41
|
+
"@aztec/noir-protocol-circuits-types": "0.87.2-nightly.20250524",
|
|
42
|
+
"@aztec/noir-types": "0.87.2-nightly.20250524",
|
|
43
|
+
"@aztec/p2p": "0.87.2-nightly.20250524",
|
|
44
|
+
"@aztec/protocol-contracts": "0.87.2-nightly.20250524",
|
|
45
|
+
"@aztec/prover-client": "0.87.2-nightly.20250524",
|
|
46
|
+
"@aztec/simulator": "0.87.2-nightly.20250524",
|
|
47
|
+
"@aztec/slasher": "0.87.2-nightly.20250524",
|
|
48
|
+
"@aztec/stdlib": "0.87.2-nightly.20250524",
|
|
49
|
+
"@aztec/telemetry-client": "0.87.2-nightly.20250524",
|
|
50
|
+
"@aztec/validator-client": "0.87.2-nightly.20250524",
|
|
51
|
+
"@aztec/world-state": "0.87.2-nightly.20250524",
|
|
51
52
|
"lodash.chunk": "^4.2.0",
|
|
52
53
|
"lodash.pick": "^4.4.0",
|
|
53
54
|
"tslib": "^2.4.0",
|
|
54
55
|
"viem": "2.23.7"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
|
-
"@aztec/archiver": "0.87.
|
|
58
|
-
"@aztec/kv-store": "0.87.
|
|
58
|
+
"@aztec/archiver": "0.87.2-nightly.20250524",
|
|
59
|
+
"@aztec/kv-store": "0.87.2-nightly.20250524",
|
|
59
60
|
"@jest/globals": "^29.5.0",
|
|
60
61
|
"@types/jest": "^29.5.0",
|
|
61
62
|
"@types/lodash.chunk": "^4.2.7",
|
|
@@ -16,6 +16,7 @@ import type { DateProvider } from '@aztec/foundation/timer';
|
|
|
16
16
|
import type { P2P } from '@aztec/p2p';
|
|
17
17
|
import { LightweightBlockBuilderFactory } from '@aztec/prover-client/block-builder';
|
|
18
18
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
19
|
+
import type { SlasherClient } from '@aztec/slasher';
|
|
19
20
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
20
21
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
21
22
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
@@ -28,7 +29,6 @@ import type { SequencerClientConfig } from '../config.js';
|
|
|
28
29
|
import { GlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
29
30
|
import { SequencerPublisher } from '../publisher/index.js';
|
|
30
31
|
import { Sequencer, type SequencerConfig } from '../sequencer/index.js';
|
|
31
|
-
import type { SlasherClient } from '../slasher/index.js';
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Encapsulates the full sequencer and publisher.
|
|
@@ -214,6 +214,10 @@ export class SequencerClient {
|
|
|
214
214
|
this.sequencer.restart();
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
public getSequencer(): Sequencer {
|
|
218
|
+
return this.sequencer;
|
|
219
|
+
}
|
|
220
|
+
|
|
217
221
|
get coinbase(): EthAddress {
|
|
218
222
|
return this.sequencer.coinbase;
|
|
219
223
|
}
|
|
@@ -20,6 +20,8 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
20
20
|
*/
|
|
21
21
|
export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
22
22
|
private log = createLogger('sequencer:global_variable_builder');
|
|
23
|
+
private currentBaseFees: Promise<GasFees> = Promise.resolve(new GasFees(Fr.ZERO, Fr.ZERO));
|
|
24
|
+
private currentL1BlockNumber: bigint | undefined = undefined;
|
|
23
25
|
|
|
24
26
|
private readonly rollupContract: RollupContract;
|
|
25
27
|
private readonly publicClient: ViemPublicClient;
|
|
@@ -46,9 +48,9 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
46
48
|
|
|
47
49
|
/**
|
|
48
50
|
* Computes the "current" base fees, e.g., the price that you currently should pay to get include in the next block
|
|
49
|
-
* @returns Base fees for the
|
|
51
|
+
* @returns Base fees for the next block
|
|
50
52
|
*/
|
|
51
|
-
|
|
53
|
+
private async computeCurrentBaseFees(): Promise<GasFees> {
|
|
52
54
|
// Since this might be called in the middle of a slot where a block might have been published,
|
|
53
55
|
// we need to fetch the last block written, and estimate the earliest timestamp for the next block.
|
|
54
56
|
// The timestamp of that last block will act as a lower bound for the next block.
|
|
@@ -61,6 +63,18 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
61
63
|
return new GasFees(Fr.ZERO, new Fr(await this.rollupContract.getManaBaseFeeAt(timestamp, true)));
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
public async getCurrentBaseFees(): Promise<GasFees> {
|
|
67
|
+
// Get the current block number
|
|
68
|
+
const blockNumber = await this.publicClient.getBlockNumber();
|
|
69
|
+
|
|
70
|
+
// If the L1 block number has changed then chain a new promise to get the current base fees
|
|
71
|
+
if (this.currentL1BlockNumber === undefined || blockNumber > this.currentL1BlockNumber) {
|
|
72
|
+
this.currentL1BlockNumber = blockNumber;
|
|
73
|
+
this.currentBaseFees = this.currentBaseFees.then(() => this.computeCurrentBaseFees());
|
|
74
|
+
}
|
|
75
|
+
return this.currentBaseFees;
|
|
76
|
+
}
|
|
77
|
+
|
|
64
78
|
public async getGlobalConstantVariables(): Promise<Pick<GlobalVariables, 'chainId' | 'version'>> {
|
|
65
79
|
if (!this.chainId) {
|
|
66
80
|
this.chainId = new Fr(this.publicClient.chain.id);
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export * from './client/index.js';
|
|
2
2
|
export * from './config.js';
|
|
3
3
|
export * from './publisher/index.js';
|
|
4
|
-
export * from './tx_validator/tx_validator_factory.js';
|
|
5
|
-
export * from './slasher/index.js';
|
|
6
4
|
export { Sequencer, SequencerState } from './sequencer/index.js';
|
|
5
|
+
export * from './tx_validator/tx_validator_factory.js';
|
|
7
6
|
|
|
8
7
|
// Used by the node to simulate public parts of transactions. Should these be moved to a shared library?
|
|
9
8
|
// ISSUE(#9832)
|
|
@@ -12,6 +12,7 @@ import type { P2P } from '@aztec/p2p';
|
|
|
12
12
|
import { getDefaultAllowedSetupFunctions } from '@aztec/p2p/msg_validators';
|
|
13
13
|
import type { BlockBuilderFactory } from '@aztec/prover-client/block-builder';
|
|
14
14
|
import type { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
15
|
+
import type { SlasherClient } from '@aztec/slasher';
|
|
15
16
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
16
17
|
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
17
18
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
@@ -40,7 +41,6 @@ import type { ValidatorClient } from '@aztec/validator-client';
|
|
|
40
41
|
|
|
41
42
|
import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
|
|
42
43
|
import { type SequencerPublisher, VoteType } from '../publisher/sequencer-publisher.js';
|
|
43
|
-
import type { SlasherClient } from '../slasher/slasher_client.js';
|
|
44
44
|
import { createValidatorForBlockBuilding } from '../tx_validator/tx_validator_factory.js';
|
|
45
45
|
import type { SequencerConfig } from './config.js';
|
|
46
46
|
import { SequencerMetrics } from './metrics.js';
|
|
@@ -217,7 +217,7 @@ export class Sequencer {
|
|
|
217
217
|
this.metrics.stop();
|
|
218
218
|
await this.validatorClient?.stop();
|
|
219
219
|
await this.runningPromise?.stop();
|
|
220
|
-
this.slasherClient.stop();
|
|
220
|
+
await this.slasherClient.stop();
|
|
221
221
|
this.publisher.interrupt();
|
|
222
222
|
this.setState(SequencerState.STOPPED, 0n, true /** force */);
|
|
223
223
|
this.l1Metrics.stop();
|
|
@@ -823,4 +823,8 @@ export class Sequencer {
|
|
|
823
823
|
get maxL2BlockGas(): number | undefined {
|
|
824
824
|
return this.config.maxL2BlockGas;
|
|
825
825
|
}
|
|
826
|
+
|
|
827
|
+
public getSlasherClient(): SlasherClient {
|
|
828
|
+
return this.slasherClient;
|
|
829
|
+
}
|
|
826
830
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dest/slasher/factory.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
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
|
-
};
|
package/dest/slasher/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dest/slasher/index.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { createEthereumChain } from '@aztec/ethereum';
|
|
2
|
-
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import { SlashFactoryAbi } from '@aztec/l1-artifacts';
|
|
5
|
-
import { L2BlockSourceEvents } from '@aztec/stdlib/block';
|
|
6
|
-
import { WithTracer, getTelemetryClient } from '@aztec/telemetry-client';
|
|
7
|
-
import { createPublicClient, fallback, getAddress, getContract, http } from 'viem';
|
|
8
|
-
/**
|
|
9
|
-
* Enum defining the possible states of the Slasher client.
|
|
10
|
-
*/ export var SlasherClientState = /*#__PURE__*/ function(SlasherClientState) {
|
|
11
|
-
SlasherClientState[SlasherClientState["IDLE"] = 0] = "IDLE";
|
|
12
|
-
SlasherClientState[SlasherClientState["RUNNING"] = 1] = "RUNNING";
|
|
13
|
-
SlasherClientState[SlasherClientState["STOPPED"] = 2] = "STOPPED";
|
|
14
|
-
return SlasherClientState;
|
|
15
|
-
}({});
|
|
16
|
-
/**
|
|
17
|
-
* @notice A Hypomeiones slasher client implementation
|
|
18
|
-
*
|
|
19
|
-
* Hypomeiones: a class of individuals in ancient Sparta who were considered inferior or lesser citizens compared
|
|
20
|
-
* to the full Spartan citizens.
|
|
21
|
-
*
|
|
22
|
-
* The implementation here is less than ideal. It exists, not to be the end all be all, but to show that
|
|
23
|
-
* slashing can be done with this mechanism.
|
|
24
|
-
*
|
|
25
|
-
* The implementation is VERY brute in the sense that it only looks for pruned blocks and then tries to slash
|
|
26
|
-
* the full committee of that.
|
|
27
|
-
* If it sees a prune, it will mark the full epoch as "to be slashed".
|
|
28
|
-
*
|
|
29
|
-
* Also, it is not particularly smart around what it should if there were to be multiple slashing events.
|
|
30
|
-
*
|
|
31
|
-
* A few improvements:
|
|
32
|
-
* - 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.
|
|
33
|
-
* - Stop voting on a payload once it is processed.
|
|
34
|
-
* - Only vote on the proposal if it have not already been executed
|
|
35
|
-
* - Caveat, we need to fully decide if it is acceptable to have the same payload address multiple times. In the current
|
|
36
|
-
* slash factory that could mean slashing the same committee for the same error multiple times.
|
|
37
|
-
* - Decide how to deal with multiple slashing events in the same round.
|
|
38
|
-
* - This could be that multiple epochs are pruned in the same round, but with the current naive implementation we could end up
|
|
39
|
-
* slashing only the first, because the "lifetime" of the second would have passed after that vote
|
|
40
|
-
*/ export class SlasherClient extends WithTracer {
|
|
41
|
-
config;
|
|
42
|
-
l2BlockSource;
|
|
43
|
-
log;
|
|
44
|
-
slashEvents;
|
|
45
|
-
slashFactoryContract;
|
|
46
|
-
// The amount to slash for a prune.
|
|
47
|
-
// Note that we set it to 0, such that no actual slashing will happen, but the event will be fired,
|
|
48
|
-
// showing that the slashing mechanism is working.
|
|
49
|
-
slashingAmount;
|
|
50
|
-
constructor(config, l2BlockSource, telemetry = getTelemetryClient(), log = createLogger('slasher')){
|
|
51
|
-
super(telemetry, 'slasher'), this.config = config, this.l2BlockSource = l2BlockSource, this.log = log, this.slashEvents = [], this.slashFactoryContract = undefined, this.slashingAmount = 0n;
|
|
52
|
-
if (config.l1Contracts.slashFactoryAddress && !config.l1Contracts.slashFactoryAddress.equals(EthAddress.ZERO)) {
|
|
53
|
-
const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
54
|
-
const publicClient = createPublicClient({
|
|
55
|
-
chain: chain.chainInfo,
|
|
56
|
-
transport: fallback(chain.rpcUrls.map((url)=>http(url))),
|
|
57
|
-
pollingInterval: config.viemPollingIntervalMS
|
|
58
|
-
});
|
|
59
|
-
this.slashFactoryContract = getContract({
|
|
60
|
-
address: getAddress(config.l1Contracts.slashFactoryAddress.toString()),
|
|
61
|
-
abi: SlashFactoryAbi,
|
|
62
|
-
client: publicClient
|
|
63
|
-
});
|
|
64
|
-
} else {
|
|
65
|
-
this.log.warn('No slash factory address found, slashing will not be enabled');
|
|
66
|
-
}
|
|
67
|
-
this.log.info(`Slasher client initialized`);
|
|
68
|
-
}
|
|
69
|
-
start() {
|
|
70
|
-
this.log.info('Starting Slasher client...');
|
|
71
|
-
this.l2BlockSource.on(L2BlockSourceEvents.L2PruneDetected, this.handlePruneL2Blocks.bind(this));
|
|
72
|
-
}
|
|
73
|
-
// This is where we should put a bunch of the improvements mentioned earlier.
|
|
74
|
-
async getSlashPayload(slotNumber) {
|
|
75
|
-
if (!this.slashFactoryContract) {
|
|
76
|
-
return undefined;
|
|
77
|
-
}
|
|
78
|
-
// As long as the slot is greater than the lifetime, we want to keep deleting the first element
|
|
79
|
-
// since it will not make sense to include anymore.
|
|
80
|
-
while(this.slashEvents.length > 0 && this.slashEvents[0].lifetime < slotNumber){
|
|
81
|
-
this.slashEvents.shift();
|
|
82
|
-
}
|
|
83
|
-
if (this.slashEvents.length == 0) {
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
const slashEvent = this.slashEvents[0];
|
|
87
|
-
const [payloadAddress, isDeployed] = await this.slashFactoryContract.read.getAddressAndIsDeployed([
|
|
88
|
-
slashEvent.epoch,
|
|
89
|
-
slashEvent.amount
|
|
90
|
-
]);
|
|
91
|
-
if (!isDeployed) {
|
|
92
|
-
// The proposal cannot be executed until it is deployed
|
|
93
|
-
this.log.verbose(`Voting on not yet deployed payload for epoch ${slashEvent.epoch} and amount ${slashEvent.amount} at: ${payloadAddress}`);
|
|
94
|
-
}
|
|
95
|
-
return EthAddress.fromString(payloadAddress);
|
|
96
|
-
}
|
|
97
|
-
handleBlockStreamEvent(event) {
|
|
98
|
-
this.log.debug(`Handling block stream event ${event.type}`);
|
|
99
|
-
switch(event.type){
|
|
100
|
-
case L2BlockSourceEvents.L2PruneDetected:
|
|
101
|
-
this.handlePruneL2Blocks(event);
|
|
102
|
-
break;
|
|
103
|
-
default:
|
|
104
|
-
{
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return Promise.resolve();
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Allows consumers to stop the instance of the slasher client.
|
|
112
|
-
* 'ready' will now return 'false' and the running promise that keeps the client synced is interrupted.
|
|
113
|
-
*/ stop() {
|
|
114
|
-
this.log.debug('Stopping Slasher client...');
|
|
115
|
-
this.l2BlockSource.removeListener(L2BlockSourceEvents.L2PruneDetected, this.handlePruneL2Blocks.bind(this));
|
|
116
|
-
this.log.info('Slasher client stopped.');
|
|
117
|
-
}
|
|
118
|
-
handlePruneL2Blocks(event) {
|
|
119
|
-
// We do not try to slash if the penalty is 0
|
|
120
|
-
if (this.slashingAmount == 0n) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const { slotNumber, epochNumber } = event;
|
|
124
|
-
this.log.info(`Detected chain prune. Punishing the validators at epoch ${epochNumber}`, event);
|
|
125
|
-
// Set the lifetime such that we have a full round that we could vote throughout.
|
|
126
|
-
const slotsIntoRound = slotNumber % BigInt(this.config.slashingRoundSize);
|
|
127
|
-
const toNext = slotsIntoRound == 0n ? 0n : BigInt(this.config.slashingRoundSize) - slotsIntoRound;
|
|
128
|
-
const lifetime = slotNumber + toNext + BigInt(this.config.slashingRoundSize);
|
|
129
|
-
this.slashEvents.push({
|
|
130
|
-
epoch: epochNumber,
|
|
131
|
-
amount: this.slashingAmount,
|
|
132
|
-
lifetime
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}
|
package/src/slasher/factory.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { L1ContractsConfig, L1ReaderConfig } from '@aztec/ethereum';
|
|
2
|
-
import type { L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
|
|
3
|
-
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
4
|
-
|
|
5
|
-
import { SlasherClient } from './slasher_client.js';
|
|
6
|
-
import type { SlasherConfig } from './slasher_client.js';
|
|
7
|
-
|
|
8
|
-
export const createSlasherClient = (
|
|
9
|
-
_config: SlasherConfig & L1ContractsConfig & L1ReaderConfig,
|
|
10
|
-
l2BlockSource: L2BlockSourceEventEmitter,
|
|
11
|
-
telemetry: TelemetryClient = getTelemetryClient(),
|
|
12
|
-
) => {
|
|
13
|
-
const config = { ..._config };
|
|
14
|
-
return new SlasherClient(config, l2BlockSource, telemetry);
|
|
15
|
-
};
|
package/src/slasher/index.ts
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type L1ContractsConfig,
|
|
3
|
-
type L1ReaderConfig,
|
|
4
|
-
type ViemPublicClient,
|
|
5
|
-
createEthereumChain,
|
|
6
|
-
} from '@aztec/ethereum';
|
|
7
|
-
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
8
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
9
|
-
import { SlashFactoryAbi } from '@aztec/l1-artifacts';
|
|
10
|
-
import {
|
|
11
|
-
type L2BlockId,
|
|
12
|
-
type L2BlockSourceEvent,
|
|
13
|
-
type L2BlockSourceEventEmitter,
|
|
14
|
-
L2BlockSourceEvents,
|
|
15
|
-
} from '@aztec/stdlib/block';
|
|
16
|
-
import { type TelemetryClient, WithTracer, getTelemetryClient } from '@aztec/telemetry-client';
|
|
17
|
-
|
|
18
|
-
import { type GetContractReturnType, createPublicClient, fallback, getAddress, getContract, http } from 'viem';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Enum defining the possible states of the Slasher client.
|
|
22
|
-
*/
|
|
23
|
-
export enum SlasherClientState {
|
|
24
|
-
IDLE,
|
|
25
|
-
RUNNING,
|
|
26
|
-
STOPPED,
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* The synchronization status of the Slasher client.
|
|
31
|
-
*/
|
|
32
|
-
export interface SlasherSyncState {
|
|
33
|
-
/**
|
|
34
|
-
* The current state of the slasher client.
|
|
35
|
-
*/
|
|
36
|
-
state: SlasherClientState;
|
|
37
|
-
/**
|
|
38
|
-
* The block number that the slasher client is synced to.
|
|
39
|
-
*/
|
|
40
|
-
syncedToL2Block: L2BlockId;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface SlasherConfig {
|
|
44
|
-
blockCheckIntervalMS: number;
|
|
45
|
-
blockRequestBatchSize: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
type SlashEvent = {
|
|
49
|
-
epoch: bigint;
|
|
50
|
-
amount: bigint;
|
|
51
|
-
lifetime: bigint;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @notice A Hypomeiones slasher client implementation
|
|
56
|
-
*
|
|
57
|
-
* Hypomeiones: a class of individuals in ancient Sparta who were considered inferior or lesser citizens compared
|
|
58
|
-
* to the full Spartan citizens.
|
|
59
|
-
*
|
|
60
|
-
* The implementation here is less than ideal. It exists, not to be the end all be all, but to show that
|
|
61
|
-
* slashing can be done with this mechanism.
|
|
62
|
-
*
|
|
63
|
-
* The implementation is VERY brute in the sense that it only looks for pruned blocks and then tries to slash
|
|
64
|
-
* the full committee of that.
|
|
65
|
-
* If it sees a prune, it will mark the full epoch as "to be slashed".
|
|
66
|
-
*
|
|
67
|
-
* Also, it is not particularly smart around what it should if there were to be multiple slashing events.
|
|
68
|
-
*
|
|
69
|
-
* A few improvements:
|
|
70
|
-
* - 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.
|
|
71
|
-
* - Stop voting on a payload once it is processed.
|
|
72
|
-
* - Only vote on the proposal if it have not already been executed
|
|
73
|
-
* - Caveat, we need to fully decide if it is acceptable to have the same payload address multiple times. In the current
|
|
74
|
-
* slash factory that could mean slashing the same committee for the same error multiple times.
|
|
75
|
-
* - Decide how to deal with multiple slashing events in the same round.
|
|
76
|
-
* - This could be that multiple epochs are pruned in the same round, but with the current naive implementation we could end up
|
|
77
|
-
* slashing only the first, because the "lifetime" of the second would have passed after that vote
|
|
78
|
-
*/
|
|
79
|
-
export class SlasherClient extends WithTracer {
|
|
80
|
-
private slashEvents: SlashEvent[] = [];
|
|
81
|
-
|
|
82
|
-
protected slashFactoryContract?: GetContractReturnType<typeof SlashFactoryAbi, ViemPublicClient> = undefined;
|
|
83
|
-
|
|
84
|
-
// The amount to slash for a prune.
|
|
85
|
-
// Note that we set it to 0, such that no actual slashing will happen, but the event will be fired,
|
|
86
|
-
// showing that the slashing mechanism is working.
|
|
87
|
-
private slashingAmount: bigint = 0n;
|
|
88
|
-
|
|
89
|
-
constructor(
|
|
90
|
-
private config: SlasherConfig & L1ContractsConfig & L1ReaderConfig,
|
|
91
|
-
private l2BlockSource: L2BlockSourceEventEmitter,
|
|
92
|
-
telemetry: TelemetryClient = getTelemetryClient(),
|
|
93
|
-
private log = createLogger('slasher'),
|
|
94
|
-
) {
|
|
95
|
-
super(telemetry, 'slasher');
|
|
96
|
-
|
|
97
|
-
if (config.l1Contracts.slashFactoryAddress && !config.l1Contracts.slashFactoryAddress.equals(EthAddress.ZERO)) {
|
|
98
|
-
const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
99
|
-
const publicClient = createPublicClient({
|
|
100
|
-
chain: chain.chainInfo,
|
|
101
|
-
transport: fallback(chain.rpcUrls.map(url => http(url))),
|
|
102
|
-
pollingInterval: config.viemPollingIntervalMS,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
this.slashFactoryContract = getContract({
|
|
106
|
-
address: getAddress(config.l1Contracts.slashFactoryAddress.toString()),
|
|
107
|
-
abi: SlashFactoryAbi,
|
|
108
|
-
client: publicClient,
|
|
109
|
-
});
|
|
110
|
-
} else {
|
|
111
|
-
this.log.warn('No slash factory address found, slashing will not be enabled');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
this.log.info(`Slasher client initialized`);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
public start() {
|
|
118
|
-
this.log.info('Starting Slasher client...');
|
|
119
|
-
this.l2BlockSource.on(L2BlockSourceEvents.L2PruneDetected, this.handlePruneL2Blocks.bind(this));
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// This is where we should put a bunch of the improvements mentioned earlier.
|
|
123
|
-
public async getSlashPayload(slotNumber: bigint): Promise<EthAddress | undefined> {
|
|
124
|
-
if (!this.slashFactoryContract) {
|
|
125
|
-
return undefined;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// As long as the slot is greater than the lifetime, we want to keep deleting the first element
|
|
129
|
-
// since it will not make sense to include anymore.
|
|
130
|
-
while (this.slashEvents.length > 0 && this.slashEvents[0].lifetime < slotNumber) {
|
|
131
|
-
this.slashEvents.shift();
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (this.slashEvents.length == 0) {
|
|
135
|
-
return undefined;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const slashEvent = this.slashEvents[0];
|
|
139
|
-
|
|
140
|
-
const [payloadAddress, isDeployed] = await this.slashFactoryContract.read.getAddressAndIsDeployed([
|
|
141
|
-
slashEvent.epoch,
|
|
142
|
-
slashEvent.amount,
|
|
143
|
-
]);
|
|
144
|
-
|
|
145
|
-
if (!isDeployed) {
|
|
146
|
-
// The proposal cannot be executed until it is deployed
|
|
147
|
-
this.log.verbose(
|
|
148
|
-
`Voting on not yet deployed payload for epoch ${slashEvent.epoch} and amount ${slashEvent.amount} at: ${payloadAddress}`,
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return EthAddress.fromString(payloadAddress);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
public handleBlockStreamEvent(event: L2BlockSourceEvent): Promise<void> {
|
|
156
|
-
this.log.debug(`Handling block stream event ${event.type}`);
|
|
157
|
-
switch (event.type as L2BlockSourceEvents) {
|
|
158
|
-
case L2BlockSourceEvents.L2PruneDetected:
|
|
159
|
-
this.handlePruneL2Blocks(event);
|
|
160
|
-
break;
|
|
161
|
-
default: {
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return Promise.resolve();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Allows consumers to stop the instance of the slasher client.
|
|
170
|
-
* 'ready' will now return 'false' and the running promise that keeps the client synced is interrupted.
|
|
171
|
-
*/
|
|
172
|
-
public stop() {
|
|
173
|
-
this.log.debug('Stopping Slasher client...');
|
|
174
|
-
this.l2BlockSource.removeListener(L2BlockSourceEvents.L2PruneDetected, this.handlePruneL2Blocks.bind(this));
|
|
175
|
-
this.log.info('Slasher client stopped.');
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private handlePruneL2Blocks(event: L2BlockSourceEvent): void {
|
|
179
|
-
// We do not try to slash if the penalty is 0
|
|
180
|
-
if (this.slashingAmount == 0n) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const { slotNumber, epochNumber } = event;
|
|
185
|
-
this.log.info(`Detected chain prune. Punishing the validators at epoch ${epochNumber}`, event);
|
|
186
|
-
|
|
187
|
-
// Set the lifetime such that we have a full round that we could vote throughout.
|
|
188
|
-
const slotsIntoRound = slotNumber % BigInt(this.config.slashingRoundSize);
|
|
189
|
-
const toNext = slotsIntoRound == 0n ? 0n : BigInt(this.config.slashingRoundSize) - slotsIntoRound;
|
|
190
|
-
|
|
191
|
-
const lifetime = slotNumber + toNext + BigInt(this.config.slashingRoundSize);
|
|
192
|
-
|
|
193
|
-
this.slashEvents.push({
|
|
194
|
-
epoch: epochNumber,
|
|
195
|
-
amount: this.slashingAmount,
|
|
196
|
-
lifetime,
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
}
|