@aztec/slasher 1.0.0-nightly.20250708 → 1.0.0-staging.1
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
2
2
|
import { L2Block, type L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
|
|
3
|
-
import type { IFullNodeBlockBuilder,
|
|
3
|
+
import type { IFullNodeBlockBuilder, ITxCollector, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
4
4
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
5
5
|
import { type WantToSlashArgs, type Watcher, type WatcherEmitter } from './config.js';
|
|
6
6
|
declare const EpochPruneWatcher_base: new () => WatcherEmitter;
|
|
@@ -14,15 +14,14 @@ export declare class EpochPruneWatcher extends EpochPruneWatcher_base implements
|
|
|
14
14
|
private l2BlockSource;
|
|
15
15
|
private l1ToL2MessageSource;
|
|
16
16
|
private epochCache;
|
|
17
|
-
private
|
|
17
|
+
private txCollector;
|
|
18
18
|
private blockBuilder;
|
|
19
19
|
private penalty;
|
|
20
20
|
private maxPenalty;
|
|
21
21
|
private log;
|
|
22
22
|
private slashableCommittees;
|
|
23
23
|
private maxSlashableEpochs;
|
|
24
|
-
|
|
25
|
-
constructor(l2BlockSource: L2BlockSourceEventEmitter, l1ToL2MessageSource: L1ToL2MessageSource, epochCache: EpochCache, txProvider: Pick<ITxProvider, 'getAvailableTxs'>, blockBuilder: IFullNodeBlockBuilder, penalty: bigint, maxPenalty: bigint);
|
|
24
|
+
constructor(l2BlockSource: L2BlockSourceEventEmitter, l1ToL2MessageSource: L1ToL2MessageSource, epochCache: EpochCache, txCollector: ITxCollector, blockBuilder: IFullNodeBlockBuilder, penalty: bigint, maxPenalty: bigint);
|
|
26
25
|
start(): Promise<void>;
|
|
27
26
|
stop(): Promise<void>;
|
|
28
27
|
private handlePruneL2Blocks;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epoch_prune_watcher.d.ts","sourceRoot":"","sources":["../src/epoch_prune_watcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"epoch_prune_watcher.d.ts","sourceRoot":"","sources":["../src/epoch_prune_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAEL,OAAO,EAEP,KAAK,yBAAyB,EAE/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACtH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAUnE,OAAO,EAAgC,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;sCAQ5D,UAAU,cAAc;AANhF;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,sBAA2C,YAAW,OAAO;IAShG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAdpB,OAAO,CAAC,GAAG,CAA+C;IAG1D,OAAO,CAAC,mBAAmB,CAAwC;IAEnE,OAAO,CAAC,kBAAkB,CAAO;gBAGvB,aAAa,EAAE,yBAAyB,EACxC,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,YAAY,EACzB,YAAY,EAAE,qBAAqB,EACnC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM;IAMrB,KAAK;IAKL,IAAI;IAKX,OAAO,CAAC,mBAAmB;IA8Cd,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAchD,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BhG,OAAO,CAAC,oBAAoB;YAUd,qBAAqB;IASnC,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,mBAAmB;IAIpB,WAAW,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;CAS7E"}
|
|
@@ -12,7 +12,7 @@ import { Offense, WANT_TO_SLASH_EVENT } from './config.js';
|
|
|
12
12
|
l2BlockSource;
|
|
13
13
|
l1ToL2MessageSource;
|
|
14
14
|
epochCache;
|
|
15
|
-
|
|
15
|
+
txCollector;
|
|
16
16
|
blockBuilder;
|
|
17
17
|
penalty;
|
|
18
18
|
maxPenalty;
|
|
@@ -21,18 +21,16 @@ import { Offense, WANT_TO_SLASH_EVENT } from './config.js';
|
|
|
21
21
|
slashableCommittees;
|
|
22
22
|
// Only keep track of the last N slashable epochs
|
|
23
23
|
maxSlashableEpochs;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
constructor(l2BlockSource, l1ToL2MessageSource, epochCache, txProvider, blockBuilder, penalty, maxPenalty){
|
|
27
|
-
super(), this.l2BlockSource = l2BlockSource, this.l1ToL2MessageSource = l1ToL2MessageSource, this.epochCache = epochCache, this.txProvider = txProvider, this.blockBuilder = blockBuilder, this.penalty = penalty, this.maxPenalty = maxPenalty, this.log = createLogger('epoch-prune-watcher'), this.slashableCommittees = new Map(), this.maxSlashableEpochs = 100, this.boundHandlePruneL2Blocks = this.handlePruneL2Blocks.bind(this);
|
|
24
|
+
constructor(l2BlockSource, l1ToL2MessageSource, epochCache, txCollector, blockBuilder, penalty, maxPenalty){
|
|
25
|
+
super(), this.l2BlockSource = l2BlockSource, this.l1ToL2MessageSource = l1ToL2MessageSource, this.epochCache = epochCache, this.txCollector = txCollector, this.blockBuilder = blockBuilder, this.penalty = penalty, this.maxPenalty = maxPenalty, this.log = createLogger('epoch-prune-watcher'), this.slashableCommittees = new Map(), this.maxSlashableEpochs = 100;
|
|
28
26
|
this.log.info('EpochPruneWatcher initialized');
|
|
29
27
|
}
|
|
30
28
|
start() {
|
|
31
|
-
this.l2BlockSource.on(L2BlockSourceEvents.L2PruneDetected, this.
|
|
29
|
+
this.l2BlockSource.on(L2BlockSourceEvents.L2PruneDetected, this.handlePruneL2Blocks.bind(this));
|
|
32
30
|
return Promise.resolve();
|
|
33
31
|
}
|
|
34
32
|
stop() {
|
|
35
|
-
this.l2BlockSource.removeListener(L2BlockSourceEvents.L2PruneDetected, this.
|
|
33
|
+
this.l2BlockSource.removeListener(L2BlockSourceEvents.L2PruneDetected, this.handlePruneL2Blocks.bind(this));
|
|
36
34
|
return Promise.resolve();
|
|
37
35
|
}
|
|
38
36
|
handlePruneL2Blocks(event) {
|
|
@@ -91,12 +89,9 @@ import { Offense, WANT_TO_SLASH_EVENT } from './config.js';
|
|
|
91
89
|
async validateBlock(blockFromL1, fork) {
|
|
92
90
|
this.log.debug(`Validating pruned block ${blockFromL1.header.globalVariables.blockNumber}`);
|
|
93
91
|
const txHashes = blockFromL1.body.txEffects.map((txEffect)=>txEffect.txHash);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const { txs, missingTxs } = await this.txProvider.getAvailableTxs(txHashes);
|
|
98
|
-
if (missingTxs && missingTxs.length > 0) {
|
|
99
|
-
throw new TransactionsNotAvailableError(missingTxs);
|
|
92
|
+
const { txs, missing } = await this.txCollector.collectTransactions(txHashes, undefined);
|
|
93
|
+
if (missing && missing.length > 0) {
|
|
94
|
+
throw new TransactionsNotAvailableError(missing);
|
|
100
95
|
}
|
|
101
96
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(blockFromL1.number);
|
|
102
97
|
const { block, failedTxs, numTxs } = await this.blockBuilder.buildBlock(txs, l1ToL2Messages, blockFromL1.header.globalVariables, {}, fork);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/slasher",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-staging.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -54,19 +54,19 @@
|
|
|
54
54
|
]
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@aztec/epoch-cache": "1.0.0-
|
|
58
|
-
"@aztec/ethereum": "1.0.0-
|
|
59
|
-
"@aztec/foundation": "1.0.0-
|
|
60
|
-
"@aztec/l1-artifacts": "1.0.0-
|
|
61
|
-
"@aztec/stdlib": "1.0.0-
|
|
62
|
-
"@aztec/telemetry-client": "1.0.0-
|
|
57
|
+
"@aztec/epoch-cache": "1.0.0-staging.1",
|
|
58
|
+
"@aztec/ethereum": "1.0.0-staging.1",
|
|
59
|
+
"@aztec/foundation": "1.0.0-staging.1",
|
|
60
|
+
"@aztec/l1-artifacts": "1.0.0-staging.1",
|
|
61
|
+
"@aztec/stdlib": "1.0.0-staging.1",
|
|
62
|
+
"@aztec/telemetry-client": "1.0.0-staging.1",
|
|
63
63
|
"source-map-support": "^0.5.21",
|
|
64
64
|
"tslib": "^2.4.0",
|
|
65
65
|
"viem": "2.23.7",
|
|
66
66
|
"zod": "^3.23.8"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@aztec/aztec.js": "1.0.0-
|
|
69
|
+
"@aztec/aztec.js": "1.0.0-staging.1",
|
|
70
70
|
"@jest/globals": "^30.0.0",
|
|
71
71
|
"@types/jest": "^30.0.0",
|
|
72
72
|
"@types/node": "^22.15.17",
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Tx } from '@aztec/aztec.js';
|
|
2
1
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
3
2
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
3
|
import {
|
|
@@ -8,7 +7,7 @@ import {
|
|
|
8
7
|
type L2BlockSourceEventEmitter,
|
|
9
8
|
L2BlockSourceEvents,
|
|
10
9
|
} from '@aztec/stdlib/block';
|
|
11
|
-
import type { IFullNodeBlockBuilder,
|
|
10
|
+
import type { IFullNodeBlockBuilder, ITxCollector, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
12
11
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
13
12
|
import {
|
|
14
13
|
ReExFailedTxsError,
|
|
@@ -35,14 +34,11 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
35
34
|
// Only keep track of the last N slashable epochs
|
|
36
35
|
private maxSlashableEpochs = 100;
|
|
37
36
|
|
|
38
|
-
// Store bound function reference for proper listener removal
|
|
39
|
-
private boundHandlePruneL2Blocks = this.handlePruneL2Blocks.bind(this);
|
|
40
|
-
|
|
41
37
|
constructor(
|
|
42
38
|
private l2BlockSource: L2BlockSourceEventEmitter,
|
|
43
39
|
private l1ToL2MessageSource: L1ToL2MessageSource,
|
|
44
40
|
private epochCache: EpochCache,
|
|
45
|
-
private
|
|
41
|
+
private txCollector: ITxCollector,
|
|
46
42
|
private blockBuilder: IFullNodeBlockBuilder,
|
|
47
43
|
private penalty: bigint,
|
|
48
44
|
private maxPenalty: bigint,
|
|
@@ -52,12 +48,12 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
public start() {
|
|
55
|
-
this.l2BlockSource.on(L2BlockSourceEvents.L2PruneDetected, this.
|
|
51
|
+
this.l2BlockSource.on(L2BlockSourceEvents.L2PruneDetected, this.handlePruneL2Blocks.bind(this));
|
|
56
52
|
return Promise.resolve();
|
|
57
53
|
}
|
|
58
54
|
|
|
59
55
|
public stop() {
|
|
60
|
-
this.l2BlockSource.removeListener(L2BlockSourceEvents.L2PruneDetected, this.
|
|
56
|
+
this.l2BlockSource.removeListener(L2BlockSourceEvents.L2PruneDetected, this.handlePruneL2Blocks.bind(this));
|
|
61
57
|
return Promise.resolve();
|
|
62
58
|
}
|
|
63
59
|
|
|
@@ -124,18 +120,16 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
124
120
|
public async validateBlock(blockFromL1: L2Block, fork: MerkleTreeWriteOperations): Promise<void> {
|
|
125
121
|
this.log.debug(`Validating pruned block ${blockFromL1.header.globalVariables.blockNumber}`);
|
|
126
122
|
const txHashes = blockFromL1.body.txEffects.map(txEffect => txEffect.txHash);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
throw new TransactionsNotAvailableError(missingTxs);
|
|
123
|
+
const { txs, missing } = await this.txCollector.collectTransactions(
|
|
124
|
+
txHashes,
|
|
125
|
+
undefined, // ask from no one in particular
|
|
126
|
+
);
|
|
127
|
+
if (missing && missing.length > 0) {
|
|
128
|
+
throw new TransactionsNotAvailableError(missing);
|
|
134
129
|
}
|
|
135
|
-
|
|
136
130
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(blockFromL1.number);
|
|
137
131
|
const { block, failedTxs, numTxs } = await this.blockBuilder.buildBlock(
|
|
138
|
-
txs
|
|
132
|
+
txs,
|
|
139
133
|
l1ToL2Messages,
|
|
140
134
|
blockFromL1.header.globalVariables,
|
|
141
135
|
{},
|