@aztec/slasher 0.0.1-commit.f5d02921e → 0.0.1-commit.f650c0a5c
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/README.md +28 -52
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +0 -12
- package/dest/factory/create_facade.d.ts +2 -2
- package/dest/factory/create_facade.d.ts.map +1 -1
- package/dest/factory/create_facade.js +1 -1
- package/dest/factory/create_implementation.d.ts +4 -6
- package/dest/factory/create_implementation.d.ts.map +1 -1
- package/dest/factory/create_implementation.js +7 -59
- package/dest/factory/get_settings.d.ts +4 -4
- package/dest/factory/get_settings.d.ts.map +1 -1
- package/dest/factory/get_settings.js +3 -3
- package/dest/factory/index.d.ts +2 -2
- package/dest/factory/index.d.ts.map +1 -1
- package/dest/factory/index.js +1 -1
- package/dest/generated/slasher-defaults.d.ts +1 -3
- package/dest/generated/slasher-defaults.d.ts.map +1 -1
- package/dest/generated/slasher-defaults.js +0 -2
- package/dest/index.d.ts +2 -3
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -2
- package/dest/null_slasher_client.d.ts +3 -4
- package/dest/null_slasher_client.d.ts.map +1 -1
- package/dest/null_slasher_client.js +1 -4
- package/dest/slash_offenses_collector.d.ts +1 -7
- package/dest/slash_offenses_collector.d.ts.map +1 -1
- package/dest/slash_offenses_collector.js +7 -16
- package/dest/slasher_client.d.ts +112 -0
- package/dest/slasher_client.d.ts.map +1 -0
- package/dest/{tally_slasher_client.js → slasher_client.js} +20 -34
- package/dest/slasher_client_facade.d.ts +4 -7
- package/dest/slasher_client_facade.d.ts.map +1 -1
- package/dest/slasher_client_facade.js +4 -9
- package/dest/slasher_client_interface.d.ts +7 -21
- package/dest/slasher_client_interface.d.ts.map +1 -1
- package/dest/slasher_client_interface.js +1 -4
- package/dest/stores/offenses_store.d.ts +6 -12
- package/dest/stores/offenses_store.d.ts.map +1 -1
- package/dest/stores/offenses_store.js +5 -24
- package/package.json +9 -9
- package/src/config.ts +0 -12
- package/src/factory/create_facade.ts +1 -2
- package/src/factory/create_implementation.ts +11 -117
- package/src/factory/get_settings.ts +8 -8
- package/src/factory/index.ts +1 -1
- package/src/generated/slasher-defaults.ts +0 -2
- package/src/index.ts +1 -2
- package/src/null_slasher_client.ts +2 -6
- package/src/slash_offenses_collector.ts +8 -17
- package/src/{tally_slasher_client.ts → slasher_client.ts} +25 -42
- package/src/slasher_client_facade.ts +3 -10
- package/src/slasher_client_interface.ts +6 -21
- package/src/stores/offenses_store.ts +8 -33
- package/dest/empire_slasher_client.d.ts +0 -190
- package/dest/empire_slasher_client.d.ts.map +0 -1
- package/dest/empire_slasher_client.js +0 -564
- package/dest/stores/payloads_store.d.ts +0 -29
- package/dest/stores/payloads_store.d.ts.map +0 -1
- package/dest/stores/payloads_store.js +0 -128
- package/dest/tally_slasher_client.d.ts +0 -125
- package/dest/tally_slasher_client.d.ts.map +0 -1
- package/src/empire_slasher_client.ts +0 -649
- package/src/stores/payloads_store.ts +0 -149
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
+
import { RollupContract, SlasherContract, SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
3
|
+
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
4
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
5
|
+
import type { Prettify } from '@aztec/foundation/types';
|
|
6
|
+
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
|
+
import { type Offense, type ProposerSlashAction, type ProposerSlashActionProvider } from '@aztec/stdlib/slashing';
|
|
8
|
+
import type { Hex } from 'viem';
|
|
9
|
+
import { SlashOffensesCollector, type SlashOffensesCollectorConfig, type SlashOffensesCollectorSettings } from './slash_offenses_collector.js';
|
|
10
|
+
import { SlashRoundMonitor, type SlashRoundMonitorSettings } from './slash_round_monitor.js';
|
|
11
|
+
import type { SlasherClientInterface } from './slasher_client_interface.js';
|
|
12
|
+
import type { SlasherOffensesStore } from './stores/offenses_store.js';
|
|
13
|
+
import type { Watcher } from './watcher.js';
|
|
14
|
+
/** Settings used in the slasher client, loaded from the L1 contracts during initialization */
|
|
15
|
+
export type SlasherSettings = Prettify<SlashRoundMonitorSettings & SlashOffensesCollectorSettings & {
|
|
16
|
+
slashingLifetimeInRounds: number;
|
|
17
|
+
slashingExecutionDelayInRounds: number;
|
|
18
|
+
slashingRoundSizeInEpochs: number;
|
|
19
|
+
slashingOffsetInRounds: number;
|
|
20
|
+
slashingQuorumSize: number;
|
|
21
|
+
slashingAmounts: [bigint, bigint, bigint];
|
|
22
|
+
/** Committee size for block proposal */
|
|
23
|
+
targetCommitteeSize: number;
|
|
24
|
+
}>;
|
|
25
|
+
export type SlasherClientConfig = SlashOffensesCollectorConfig & Pick<SlasherConfig, 'slashValidatorsAlways' | 'slashValidatorsNever' | 'slashExecuteRoundsLookBack' | 'slashMaxPayloadSize'>;
|
|
26
|
+
/**
|
|
27
|
+
* The Slasher client is responsible for managing slashable offenses using
|
|
28
|
+
* the consensus-based slashing model where proposers vote on individual validator offenses.
|
|
29
|
+
*
|
|
30
|
+
* The client subscribes to several slash watchers that emit offenses and tracks them. When the slasher is the
|
|
31
|
+
* proposer, it votes for which validators from past epochs should be slashed based on collected offenses.
|
|
32
|
+
* Voting is handled by the sequencer publisher, the slasher client does not interact with L1 directly.
|
|
33
|
+
* The client also monitors rounds and executes slashing when rounds become executable after reaching quorum.
|
|
34
|
+
*
|
|
35
|
+
* Voting and offense collection
|
|
36
|
+
* - Time is divided into rounds (ROUND_SIZE slots each). During each round, block proposers can submit votes
|
|
37
|
+
* indicating which validators from SLASH_OFFSET_IN_ROUNDS rounds ago should be slashed.
|
|
38
|
+
* - Votes are encoded as bytes where each validator's vote is represented by 2 bits indicating the slash amount (0-3 slash units)
|
|
39
|
+
* for the validator in the committee being slashed.
|
|
40
|
+
* - When gathering offenses for round N, the system looks at offenses from round N-2 (where 2 is the hardcoded
|
|
41
|
+
* offset), giving time to detect offenses and vote on them in a later round.
|
|
42
|
+
* - Each offense carries an epoch or block identifier to differentiate multiple offenses by the same validator.
|
|
43
|
+
*
|
|
44
|
+
* Quorum and execution
|
|
45
|
+
* - After a round ends, there is an execution delay period for review so the VETOER in the Slasher can veto
|
|
46
|
+
* if needed.
|
|
47
|
+
* - Once the delay passes, anyone can call executeRound() to tally votes and execute slashing.
|
|
48
|
+
* - Validators that reach the quorum threshold are slashed. A vote for slashing N units is also considered
|
|
49
|
+
* a vote for slashing N-1, N-2, ..., 1 units. The system slashes for the largest amount that reaches quorum.
|
|
50
|
+
* - The client monitors executable rounds and triggers execution when appropriate.
|
|
51
|
+
*/
|
|
52
|
+
export declare class SlasherClient implements ProposerSlashActionProvider, SlasherClientInterface {
|
|
53
|
+
private config;
|
|
54
|
+
private settings;
|
|
55
|
+
private slashingProposer;
|
|
56
|
+
private slasher;
|
|
57
|
+
private rollup;
|
|
58
|
+
private epochCache;
|
|
59
|
+
private dateProvider;
|
|
60
|
+
private offensesStore;
|
|
61
|
+
private log;
|
|
62
|
+
protected unwatchCallbacks: (() => void)[];
|
|
63
|
+
protected roundMonitor: SlashRoundMonitor;
|
|
64
|
+
protected offensesCollector: SlashOffensesCollector;
|
|
65
|
+
constructor(config: SlasherClientConfig, settings: SlasherSettings, slashingProposer: SlashingProposerContract, slasher: SlasherContract, rollup: RollupContract, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, offensesStore: SlasherOffensesStore, log?: import("@aztec/foundation/log").Logger);
|
|
66
|
+
start(): Promise<void>;
|
|
67
|
+
/** Stop the slasher client */
|
|
68
|
+
stop(): Promise<void>;
|
|
69
|
+
/** Returns the current config */
|
|
70
|
+
getConfig(): SlasherConfig;
|
|
71
|
+
/** Update the config of the slasher client */
|
|
72
|
+
updateConfig(config: Partial<SlasherConfig>): void;
|
|
73
|
+
/** Triggered on a time basis when we enter a new slashing round. Clears expired offenses. */
|
|
74
|
+
protected handleNewRound(round: bigint): Promise<void>;
|
|
75
|
+
/** Called when we see a RoundExecuted event on the SlashingProposer (just for logging). */
|
|
76
|
+
protected handleRoundExecuted(round: bigint, slashCount: bigint, l1BlockHash: Hex): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the actions the proposer should take for slashing
|
|
79
|
+
* @param slotNumber - The current slot number
|
|
80
|
+
* @returns The actions to take
|
|
81
|
+
*/
|
|
82
|
+
getProposerActions(slotNumber: SlotNumber): Promise<ProposerSlashAction[]>;
|
|
83
|
+
/**
|
|
84
|
+
* Returns an execute slash action if there are any rounds ready to be executed.
|
|
85
|
+
* Returns the oldest slash action if there are multiple rounds pending execution.
|
|
86
|
+
*/
|
|
87
|
+
protected getExecuteSlashAction(slotNumber: SlotNumber): Promise<ProposerSlashAction | undefined>;
|
|
88
|
+
private tryGetRoundExecuteAction;
|
|
89
|
+
/** Returns a vote action based on offenses from the target round (with offset applied) */
|
|
90
|
+
protected getVoteOffensesAction(slotNumber: SlotNumber): Promise<ProposerSlashAction | undefined>;
|
|
91
|
+
/** Returns the committees that were active during the timespan of a given round */
|
|
92
|
+
private collectCommitteesActiveDuringRound;
|
|
93
|
+
/**
|
|
94
|
+
* Gather offenses to be slashed on a given round.
|
|
95
|
+
* Round N slashes validators from round N - slashOffsetInRounds.
|
|
96
|
+
* @param round - The round to get offenses for, defaults to current round
|
|
97
|
+
* @returns Array of pending offenses for the round with offset applied
|
|
98
|
+
*/
|
|
99
|
+
gatherOffensesForRound(round?: bigint): Promise<Offense[]>;
|
|
100
|
+
/** Returns all offenses stored */
|
|
101
|
+
getOffenses(): Promise<Offense[]>;
|
|
102
|
+
/**
|
|
103
|
+
* Returns the round to be slashed given the current round by applying the slash offset.
|
|
104
|
+
* During round N, we cannot slash the validators from the epochs of the same round, since the round is not over,
|
|
105
|
+
* and besides we would be asking the current validators to vote to slash themselves. So during round N we look at the
|
|
106
|
+
* epochs spanned during round N - SLASH_OFFSET_IN_ROUNDS. This offset means that the epochs we slash are complete,
|
|
107
|
+
* and also gives nodes time to detect any misbehavior (eg slashing for prunes requires the proof submission window to
|
|
108
|
+
* pass).
|
|
109
|
+
*/
|
|
110
|
+
private getSlashedRound;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hlcl9jbGllbnQuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zbGFzaGVyX2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXRHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUc3RCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsS0FBSyxPQUFPLEVBRVosS0FBSyxtQkFBbUIsRUFDeEIsS0FBSywyQkFBMkIsRUFHakMsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFaEMsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixLQUFLLDRCQUE0QixFQUNqQyxLQUFLLDhCQUE4QixFQUNwQyxNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxLQUFLLHlCQUF5QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDN0YsT0FBTyxLQUFLLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM1RSxPQUFPLEtBQUssRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU1Qyw4RkFBOEY7QUFDOUYsTUFBTSxNQUFNLGVBQWUsR0FBRyxRQUFRLENBQ3BDLHlCQUF5QixHQUN2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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slasher_client.d.ts","sourceRoot":"","sources":["../src/slasher_client.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import { OffenseType, getEpochsForRound, getSlashConsensusVotesFromOffenses } fr
|
|
|
6
6
|
import { SlashOffensesCollector } from './slash_offenses_collector.js';
|
|
7
7
|
import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
8
8
|
/**
|
|
9
|
-
* The
|
|
9
|
+
* The Slasher client is responsible for managing slashable offenses using
|
|
10
10
|
* the consensus-based slashing model where proposers vote on individual validator offenses.
|
|
11
11
|
*
|
|
12
12
|
* The client subscribes to several slash watchers that emit offenses and tracks them. When the slasher is the
|
|
@@ -30,16 +30,10 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
30
30
|
* - Validators that reach the quorum threshold are slashed. A vote for slashing N units is also considered
|
|
31
31
|
* a vote for slashing N-1, N-2, ..., 1 units. The system slashes for the largest amount that reaches quorum.
|
|
32
32
|
* - The client monitors executable rounds and triggers execution when appropriate.
|
|
33
|
-
|
|
34
|
-
* Differences from Empire model
|
|
35
|
-
* - No fixed slash payloads - votes are for individual validator offenses encoded in bytes
|
|
36
|
-
* - The L1 contract determines which offenses reach quorum rather than nodes agreeing on a payload
|
|
37
|
-
* - Proposers vote directly on which validators to slash and by how much
|
|
38
|
-
* - Uses a slash offset to vote on validators from past rounds (e.g., round N votes on round N-2)
|
|
39
|
-
*/ export class TallySlasherClient {
|
|
33
|
+
*/ export class SlasherClient {
|
|
40
34
|
config;
|
|
41
35
|
settings;
|
|
42
|
-
|
|
36
|
+
slashingProposer;
|
|
43
37
|
slasher;
|
|
44
38
|
rollup;
|
|
45
39
|
epochCache;
|
|
@@ -49,10 +43,10 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
49
43
|
unwatchCallbacks;
|
|
50
44
|
roundMonitor;
|
|
51
45
|
offensesCollector;
|
|
52
|
-
constructor(config, settings,
|
|
46
|
+
constructor(config, settings, slashingProposer, slasher, rollup, watchers, epochCache, dateProvider, offensesStore, log = createLogger('slasher:consensus')){
|
|
53
47
|
this.config = config;
|
|
54
48
|
this.settings = settings;
|
|
55
|
-
this.
|
|
49
|
+
this.slashingProposer = slashingProposer;
|
|
56
50
|
this.slasher = slasher;
|
|
57
51
|
this.rollup = rollup;
|
|
58
52
|
this.epochCache = epochCache;
|
|
@@ -64,26 +58,24 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
64
58
|
this.offensesCollector = new SlashOffensesCollector(config, settings, watchers, offensesStore);
|
|
65
59
|
}
|
|
66
60
|
async start() {
|
|
67
|
-
this.log.debug('Starting
|
|
61
|
+
this.log.debug('Starting slasher client...');
|
|
68
62
|
this.roundMonitor.start();
|
|
69
63
|
await this.offensesCollector.start();
|
|
70
64
|
// Listen for RoundExecuted events
|
|
71
|
-
this.unwatchCallbacks.push(this.
|
|
65
|
+
this.unwatchCallbacks.push(this.slashingProposer.listenToRoundExecuted(({ round, slashCount, l1BlockHash })=>void this.handleRoundExecuted(round, slashCount, l1BlockHash).catch((err)=>this.log.error('Error handling round executed', err))));
|
|
72
66
|
// Check for round changes
|
|
73
67
|
this.unwatchCallbacks.push(this.roundMonitor.listenToNewRound((round)=>this.handleNewRound(round)));
|
|
74
|
-
this.log.info(`Started
|
|
68
|
+
this.log.info(`Started slasher client`);
|
|
75
69
|
return Promise.resolve();
|
|
76
70
|
}
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
*/ async stop() {
|
|
80
|
-
this.log.debug('Stopping Tally Slasher client...');
|
|
71
|
+
/** Stop the slasher client */ async stop() {
|
|
72
|
+
this.log.debug('Stopping slasher client...');
|
|
81
73
|
for (const unwatchCallback of this.unwatchCallbacks){
|
|
82
74
|
unwatchCallback();
|
|
83
75
|
}
|
|
84
76
|
this.roundMonitor.stop();
|
|
85
77
|
await this.offensesCollector.stop();
|
|
86
|
-
this.log.info('
|
|
78
|
+
this.log.info('Slasher client stopped');
|
|
87
79
|
}
|
|
88
80
|
/** Returns the current config */ getConfig() {
|
|
89
81
|
return this.config;
|
|
@@ -95,10 +87,10 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
95
87
|
};
|
|
96
88
|
}
|
|
97
89
|
/** Triggered on a time basis when we enter a new slashing round. Clears expired offenses. */ async handleNewRound(round) {
|
|
98
|
-
this.log.info(`Starting new
|
|
90
|
+
this.log.info(`Starting new slashing round ${round}`);
|
|
99
91
|
await this.offensesCollector.handleNewRound(round);
|
|
100
92
|
}
|
|
101
|
-
/** Called when we see a RoundExecuted event on the
|
|
93
|
+
/** Called when we see a RoundExecuted event on the SlashingProposer (just for logging). */ async handleRoundExecuted(round, slashCount, l1BlockHash) {
|
|
102
94
|
const slashes = await this.rollup.getSlashEvents(l1BlockHash);
|
|
103
95
|
this.log.info(`Slashing round ${round} has been executed with ${slashCount} slashes`, {
|
|
104
96
|
slashes
|
|
@@ -170,7 +162,7 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
170
162
|
};
|
|
171
163
|
this.log.debug(`Testing if slashing round ${executableRound} is executable`, logData);
|
|
172
164
|
try {
|
|
173
|
-
const roundInfo = await this.
|
|
165
|
+
const roundInfo = await this.slashingProposer.getRound(executableRound);
|
|
174
166
|
logData = {
|
|
175
167
|
...logData,
|
|
176
168
|
roundInfo
|
|
@@ -186,19 +178,19 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
186
178
|
return undefined;
|
|
187
179
|
}
|
|
188
180
|
// Check if round is ready to execute at the given slot
|
|
189
|
-
const isReadyToExecute = await this.
|
|
181
|
+
const isReadyToExecute = await this.slashingProposer.isRoundReadyToExecute(executableRound, slotNumber);
|
|
190
182
|
if (!isReadyToExecute) {
|
|
191
183
|
this.log.warn(`Round ${executableRound} is not ready to execute at slot ${slotNumber} according to contract check`, logData);
|
|
192
184
|
return undefined;
|
|
193
185
|
}
|
|
194
186
|
// Check if the round yields any slashing at all
|
|
195
|
-
const { actions: slashActions, committees } = await this.
|
|
187
|
+
const { actions: slashActions, committees } = await this.slashingProposer.getTally(executableRound);
|
|
196
188
|
if (slashActions.length === 0) {
|
|
197
189
|
this.log.verbose(`Round ${executableRound} does not resolve in any slashing`, logData);
|
|
198
190
|
return undefined;
|
|
199
191
|
}
|
|
200
192
|
// Check if the slash payload is vetoed
|
|
201
|
-
const payload = await this.
|
|
193
|
+
const payload = await this.slashingProposer.getPayload(executableRound);
|
|
202
194
|
const isVetoed = await this.slasher.isPayloadVetoed(payload.address);
|
|
203
195
|
if (isVetoed) {
|
|
204
196
|
this.log.warn(`Round ${executableRound} payload is vetoed (skipping execution)`, {
|
|
@@ -320,14 +312,8 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
320
312
|
return Promise.all(epochsToSlash.map((epoch)=>this.epochCache.getCommitteeForEpoch(epoch).then((c)=>c.committee ?? emptyCommittee)));
|
|
321
313
|
}
|
|
322
314
|
/**
|
|
323
|
-
* Get slash payloads is NOT SUPPORTED in tally model
|
|
324
|
-
* @throws Error indicating this operation is not supported
|
|
325
|
-
*/ getSlashPayloads() {
|
|
326
|
-
return Promise.reject(new Error('Tally slashing model does not support slash payloads'));
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
315
|
* Gather offenses to be slashed on a given round.
|
|
330
|
-
*
|
|
316
|
+
* Round N slashes validators from round N - slashOffsetInRounds.
|
|
331
317
|
* @param round - The round to get offenses for, defaults to current round
|
|
332
318
|
* @returns Array of pending offenses for the round with offset applied
|
|
333
319
|
*/ async gatherOffensesForRound(round) {
|
|
@@ -337,8 +323,8 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
337
323
|
}
|
|
338
324
|
return await this.offensesStore.getOffensesForRound(targetRound);
|
|
339
325
|
}
|
|
340
|
-
/** Returns all
|
|
341
|
-
return this.offensesStore.
|
|
326
|
+
/** Returns all offenses stored */ getOffenses() {
|
|
327
|
+
return this.offensesStore.getOffenses();
|
|
342
328
|
}
|
|
343
329
|
/**
|
|
344
330
|
* Returns the round to be slashed given the current round by applying the slash offset.
|
|
@@ -2,12 +2,11 @@ import { EpochCache } from '@aztec/epoch-cache';
|
|
|
2
2
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
3
3
|
import type { ViemClient } from '@aztec/ethereum/types';
|
|
4
4
|
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
5
|
-
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
5
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
7
6
|
import { AztecLMDBStoreV2 } from '@aztec/kv-store/lmdb-v2';
|
|
8
7
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
9
8
|
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
10
|
-
import type { Offense, ProposerSlashAction
|
|
9
|
+
import type { Offense, ProposerSlashAction } from '@aztec/stdlib/slashing';
|
|
11
10
|
import type { SlasherClientInterface } from './slasher_client_interface.js';
|
|
12
11
|
import type { Watcher } from './watcher.js';
|
|
13
12
|
/**
|
|
@@ -19,7 +18,6 @@ export declare class SlasherClientFacade implements SlasherClientInterface {
|
|
|
19
18
|
private config;
|
|
20
19
|
private rollup;
|
|
21
20
|
private l1Client;
|
|
22
|
-
private slashFactoryAddress;
|
|
23
21
|
private watchers;
|
|
24
22
|
private epochCache;
|
|
25
23
|
private dateProvider;
|
|
@@ -30,16 +28,15 @@ export declare class SlasherClientFacade implements SlasherClientInterface {
|
|
|
30
28
|
private unwatch;
|
|
31
29
|
constructor(config: SlasherConfig & DataStoreConfig & {
|
|
32
30
|
ethereumSlotDuration: number;
|
|
33
|
-
}, rollup: RollupContract, l1Client: ViemClient,
|
|
31
|
+
}, rollup: RollupContract, l1Client: ViemClient, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, kvStore: AztecLMDBStoreV2, rollupRegisteredAtL2Slot: SlotNumber, logger?: import("@aztec/foundation/log").Logger);
|
|
34
32
|
start(): Promise<void>;
|
|
35
33
|
stop(): Promise<void>;
|
|
36
34
|
getConfig(): SlasherConfig;
|
|
37
35
|
updateConfig(config: Partial<SlasherConfig>): void;
|
|
38
|
-
getSlashPayloads(): Promise<SlashPayloadRound[]>;
|
|
39
36
|
gatherOffensesForRound(round?: bigint): Promise<Offense[]>;
|
|
40
|
-
|
|
37
|
+
getOffenses(): Promise<Offense[]>;
|
|
41
38
|
getProposerActions(slotNumber: SlotNumber): Promise<ProposerSlashAction[]>;
|
|
42
39
|
private createSlasherClient;
|
|
43
40
|
private handleSlasherChange;
|
|
44
41
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hlcl9jbGllbnRfZmFjYWRlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hlcl9jbGllbnRfZmFjYWRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDM0QsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDeEQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzlELE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzNFLE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDNUUsT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTVDOzs7O0dBSUc7QUFDSCxxQkFBYSxtQkFBb0IsWUFBVyxzQkFBc0I7SUFLOUQsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsTUFBTTtJQUNkLE9BQU8sQ0FBQyxRQUFRO0lBQ2hCLE9BQU8sQ0FBQyxRQUFRO0lBQ2hCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxZQUFZO0lBQ3BCLE9BQU8sQ0FBQyxPQUFPO0lBQ2YsT0FBTyxDQUFDLHdCQUF3QjtJQUNoQyxPQUFPLENBQUMsTUFBTTtJQVpoQixPQUFPLENBQUMsTUFBTSxDQUFxQztJQUNuRCxPQUFPLENBQUMsT0FBTyxDQUEyQjtJQUUxQyxZQUNVLE1BQU0sRUFBRSxhQUFhLEdBQUcsZUFBZSxHQUFHO1FBQUUsb0JBQW9CLEVBQUUsTUFBTSxDQUFBO0tBQUUsRUFDMUUsTUFBTSxFQUFFLGNBQWMsRUFDdEIsUUFBUSxFQUFFLFVBQVUsRUFDcEIsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUNuQixVQUFVLEVBQUUsVUFBVSxFQUN0QixZQUFZLEVBQUUsWUFBWSxFQUMxQixPQUFPLEVBQUUsZ0JBQWdCLEVBQ3pCLHdCQUF3QixFQUFFLFVBQVUsRUFDcEMsTUFBTSx5Q0FBMEIsRUFDdEM7SUFFUyxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQVNsQztJQUVZLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWpDO0lBRU0sU0FBUyxJQUFJLGFBQWEsQ0FFaEM7SUFFTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBSXhEO0lBRU0sc0JBQXNCLENBQUMsS0FBSyxDQUFDLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUVoRTtJQUVNLFdBQVcsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FFdkM7SUFFTSxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBRWhGO0lBRUQsT0FBTyxDQUFDLG1CQUFtQjtZQWNiLG1CQUFtQjtDQU1sQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slasher_client_facade.d.ts","sourceRoot":"","sources":["../src/slasher_client_facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"slasher_client_facade.d.ts","sourceRoot":"","sources":["../src/slasher_client_facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,sBAAsB;IAK9D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,wBAAwB;IAChC,OAAO,CAAC,MAAM;IAZhB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,OAAO,CAA2B;IAE1C,YACU,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG;QAAE,oBAAoB,EAAE,MAAM,CAAA;KAAE,EAC1E,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,gBAAgB,EACzB,wBAAwB,EAAE,UAAU,EACpC,MAAM,yCAA0B,EACtC;IAES,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CASlC;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjC;IAEM,SAAS,IAAI,aAAa,CAEhC;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAIxD;IAEM,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAEhE;IAEM,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAEvC;IAEM,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAEhF;IAED,OAAO,CAAC,mBAAmB;YAcb,mBAAmB;CAMlC"}
|
|
@@ -8,7 +8,6 @@ import { createSlasherImplementation } from './factory/create_implementation.js'
|
|
|
8
8
|
config;
|
|
9
9
|
rollup;
|
|
10
10
|
l1Client;
|
|
11
|
-
slashFactoryAddress;
|
|
12
11
|
watchers;
|
|
13
12
|
epochCache;
|
|
14
13
|
dateProvider;
|
|
@@ -17,11 +16,10 @@ import { createSlasherImplementation } from './factory/create_implementation.js'
|
|
|
17
16
|
logger;
|
|
18
17
|
client;
|
|
19
18
|
unwatch;
|
|
20
|
-
constructor(config, rollup, l1Client,
|
|
19
|
+
constructor(config, rollup, l1Client, watchers, epochCache, dateProvider, kvStore, rollupRegisteredAtL2Slot, logger = createLogger('slasher')){
|
|
21
20
|
this.config = config;
|
|
22
21
|
this.rollup = rollup;
|
|
23
22
|
this.l1Client = l1Client;
|
|
24
|
-
this.slashFactoryAddress = slashFactoryAddress;
|
|
25
23
|
this.watchers = watchers;
|
|
26
24
|
this.epochCache = epochCache;
|
|
27
25
|
this.dateProvider = dateProvider;
|
|
@@ -54,20 +52,17 @@ import { createSlasherImplementation } from './factory/create_implementation.js'
|
|
|
54
52
|
this.client?.updateConfig(config);
|
|
55
53
|
this.watchers.forEach((watcher)=>watcher.updateConfig?.(config));
|
|
56
54
|
}
|
|
57
|
-
getSlashPayloads() {
|
|
58
|
-
return this.client?.getSlashPayloads() ?? Promise.reject(new Error('Slasher client not initialized'));
|
|
59
|
-
}
|
|
60
55
|
gatherOffensesForRound(round) {
|
|
61
56
|
return this.client?.gatherOffensesForRound(round) ?? Promise.reject(new Error('Slasher client not initialized'));
|
|
62
57
|
}
|
|
63
|
-
|
|
64
|
-
return this.client?.
|
|
58
|
+
getOffenses() {
|
|
59
|
+
return this.client?.getOffenses() ?? Promise.reject(new Error('Slasher client not initialized'));
|
|
65
60
|
}
|
|
66
61
|
getProposerActions(slotNumber) {
|
|
67
62
|
return this.client?.getProposerActions(slotNumber) ?? Promise.reject(new Error('Slasher client not initialized'));
|
|
68
63
|
}
|
|
69
64
|
createSlasherClient() {
|
|
70
|
-
return createSlasherImplementation(this.config, this.rollup, this.l1Client, this.
|
|
65
|
+
return createSlasherImplementation(this.config, this.rollup, this.l1Client, this.watchers, this.epochCache, this.dateProvider, this.kvStore, this.rollupRegisteredAtL2Slot, this.logger);
|
|
71
66
|
}
|
|
72
67
|
async handleSlasherChange() {
|
|
73
68
|
this.logger.warn('Slasher contract changed, recreating slasher client');
|
|
@@ -1,31 +1,17 @@
|
|
|
1
1
|
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
3
|
-
import type { Offense, ProposerSlashAction
|
|
4
|
-
/**
|
|
5
|
-
* Common interface for slasher clients used by the Aztec node.
|
|
6
|
-
* Both Empire and Consensus slasher clients implement this interface.
|
|
7
|
-
*/
|
|
3
|
+
import type { Offense, ProposerSlashAction } from '@aztec/stdlib/slashing';
|
|
4
|
+
/** Common interface for slasher clients used by the Aztec node. */
|
|
8
5
|
export interface SlasherClientInterface {
|
|
9
6
|
/** Start the slasher client */
|
|
10
7
|
start(): Promise<void>;
|
|
11
8
|
/** Stop the slasher client */
|
|
12
9
|
stop(): Promise<void>;
|
|
13
|
-
/**
|
|
14
|
-
* Get slash payloads for the Empire model.
|
|
15
|
-
* The Consensus model should throw an error when this is called.
|
|
16
|
-
*/
|
|
17
|
-
getSlashPayloads(): Promise<SlashPayloadRound[]>;
|
|
18
|
-
/**
|
|
19
|
-
* Gather offenses for a given round, defaults to current.
|
|
20
|
-
* Used by both Empire and Consensus models.
|
|
21
|
-
*/
|
|
10
|
+
/** Gather offenses for a given round, defaults to current. */
|
|
22
11
|
gatherOffensesForRound(round?: bigint): Promise<Offense[]>;
|
|
23
|
-
/** Returns all
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Update the configuration.
|
|
27
|
-
* Used by both Empire and Consensus models.
|
|
28
|
-
*/
|
|
12
|
+
/** Returns all offenses */
|
|
13
|
+
getOffenses(): Promise<Offense[]>;
|
|
14
|
+
/** Update the configuration. */
|
|
29
15
|
updateConfig(config: Partial<SlasherConfig>): void;
|
|
30
16
|
/**
|
|
31
17
|
* Get the actions the proposer should take for slashing.
|
|
@@ -36,4 +22,4 @@ export interface SlasherClientInterface {
|
|
|
36
22
|
/** Returns the current config */
|
|
37
23
|
getConfig(): SlasherConfig;
|
|
38
24
|
}
|
|
39
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hlcl9jbGllbnRfaW50ZXJmYWNlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hlcl9jbGllbnRfaW50ZXJmYWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTNFLG1FQUFtRTtBQUNuRSxNQUFNLFdBQVcsc0JBQXNCO0lBQ3JDLCtCQUErQjtJQUMvQixLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXZCLDhCQUE4QjtJQUM5QixJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXRCLDhEQUE4RDtJQUM5RCxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFFM0QsMkJBQTJCO0lBQzNCLFdBQVcsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUVsQyxnQ0FBZ0M7SUFDaEMsWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBRW5EOzs7O09BSUc7SUFDSCxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUM7SUFFM0UsaUNBQWlDO0lBQ2pDLFNBQVMsSUFBSSxhQUFhLENBQUM7Q0FDNUIifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slasher_client_interface.d.ts","sourceRoot":"","sources":["../src/slasher_client_interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"slasher_client_interface.d.ts","sourceRoot":"","sources":["../src/slasher_client_interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE3E,mEAAmE;AACnE,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,8BAA8B;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB,8DAA8D;IAC9D,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAE3D,2BAA2B;IAC3B,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAElC,gCAAgC;IAChC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAEnD;;;;OAIG;IACH,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAE3E,iCAAiC;IACjC,SAAS,IAAI,aAAa,CAAC;CAC5B"}
|
|
@@ -6,9 +6,7 @@ export declare class SlasherOffensesStore {
|
|
|
6
6
|
private settings;
|
|
7
7
|
/** Map from offense key to offense data */
|
|
8
8
|
private offenses;
|
|
9
|
-
/**
|
|
10
|
-
private offensesSlashed;
|
|
11
|
-
/** Multimap from round to offense keys (only used for consensus based slashing) */
|
|
9
|
+
/** Multimap from round to offense keys */
|
|
12
10
|
private roundsOffenses;
|
|
13
11
|
private log;
|
|
14
12
|
constructor(kvStore: AztecAsyncKVStore, settings: {
|
|
@@ -16,22 +14,18 @@ export declare class SlasherOffensesStore {
|
|
|
16
14
|
epochDuration: number;
|
|
17
15
|
slashOffenseExpirationRounds?: number;
|
|
18
16
|
});
|
|
19
|
-
/** Returns all offenses
|
|
20
|
-
|
|
17
|
+
/** Returns all offenses */
|
|
18
|
+
getOffenses(): Promise<Offense[]>;
|
|
21
19
|
/** Returns all offenses tracked for the given round */
|
|
22
20
|
getOffensesForRound(round: bigint): Promise<Offense[]>;
|
|
23
|
-
/** Returns whether an offense is pending (ie not marked as slashed) */
|
|
24
|
-
hasPendingOffense(offense: OffenseIdentifier): Promise<boolean>;
|
|
25
21
|
/** Returns whether we have seen this offense */
|
|
26
22
|
hasOffense(offense: OffenseIdentifier): Promise<boolean>;
|
|
27
|
-
/** Adds a new offense
|
|
28
|
-
|
|
29
|
-
/** Marks the given offenses as slashed (regardless of whether they are known or not) */
|
|
30
|
-
markAsSlashed(offenses: OffenseIdentifier[]): Promise<void>;
|
|
23
|
+
/** Adds a new offense */
|
|
24
|
+
addOffense(offense: Offense): Promise<void>;
|
|
31
25
|
/** Prunes all offenses expired from the store */
|
|
32
26
|
clearExpiredOffenses(currentRound: bigint): Promise<number>;
|
|
33
27
|
/** Generate a unique key for an offense */
|
|
34
28
|
private getOffenseKey;
|
|
35
29
|
private getRoundKey;
|
|
36
30
|
}
|
|
37
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2ZmZW5zZXNfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZXMvb2ZmZW5zZXNfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQXFDLE1BQU0saUJBQWlCLENBQUM7QUFDNUYsT0FBTyxFQUNMLEtBQUssT0FBTyxFQUNaLEtBQUssaUJBQWlCLEVBSXZCLE1BQU0sd0JBQXdCLENBQUM7QUFFaEMsZUFBTyxNQUFNLGNBQWMsSUFBSSxDQUFDO0FBRWhDLHFCQUFhLG9CQUFvQjtJQVU3QixPQUFPLENBQUMsT0FBTztJQUNmLE9BQU8sQ0FBQyxRQUFRO0lBVmxCLDJDQUEyQztJQUMzQyxPQUFPLENBQUMsUUFBUSxDQUFnQztJQUVoRCwwQ0FBMEM7SUFDMUMsT0FBTyxDQUFDLGNBQWMsQ0FBcUM7SUFFM0QsT0FBTyxDQUFDLEdBQUcsQ0FBMEM7SUFFckQsWUFDVSxPQUFPLEVBQUUsaUJBQWlCLEVBQzFCLFFBQVEsRUFBRTtRQUNoQixpQkFBaUIsRUFBRSxNQUFNLENBQUM7UUFDMUIsYUFBYSxFQUFFLE1BQU0sQ0FBQztRQUN0Qiw0QkFBNEIsQ0FBQyxFQUFFLE1BQU0sQ0FBQztLQUN2QyxFQUlGO0lBRUQsMkJBQTJCO0lBQ2QsV0FBVyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQU03QztJQUVELHVEQUF1RDtJQUMxQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQVVsRTtJQUVELGdEQUFnRDtJQUNuQyxVQUFVLENBQUMsT0FBTyxFQUFFLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FHcEU7SUFFRCx5QkFBeUI7SUFDWixVQUFVLENBQUMsT0FBTyxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBUXZEO0lBRUQsaURBQWlEO0lBQ3BDLG9CQUFvQixDQUFDLFlBQVksRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQXNDdkU7SUFFRCwyQ0FBMkM7SUFDM0MsT0FBTyxDQUFDLGFBQWE7SUFJckIsT0FBTyxDQUFDLFdBQVc7Q0FHcEIifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offenses_store.d.ts","sourceRoot":"","sources":["../../src/stores/offenses_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"offenses_store.d.ts","sourceRoot":"","sources":["../../src/stores/offenses_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,iBAAiB,EAIvB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,qBAAa,oBAAoB;IAU7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;IAVlB,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,0CAA0C;IAC1C,OAAO,CAAC,cAAc,CAAqC;IAE3D,OAAO,CAAC,GAAG,CAA0C;IAErD,YACU,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE;QAChB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,4BAA4B,CAAC,EAAE,MAAM,CAAC;KACvC,EAIF;IAED,2BAA2B;IACd,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAM7C;IAED,uDAAuD;IAC1C,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAUlE;IAED,gDAAgD;IACnC,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAGpE;IAED,yBAAyB;IACZ,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQvD;IAED,iDAAiD;IACpC,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsCvE;IAED,2CAA2C;IAC3C,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -5,8 +5,7 @@ export class SlasherOffensesStore {
|
|
|
5
5
|
kvStore;
|
|
6
6
|
settings;
|
|
7
7
|
/** Map from offense key to offense data */ offenses;
|
|
8
|
-
/**
|
|
9
|
-
/** Multimap from round to offense keys (only used for consensus based slashing) */ roundsOffenses;
|
|
8
|
+
/** Multimap from round to offense keys */ roundsOffenses;
|
|
10
9
|
log;
|
|
11
10
|
constructor(kvStore, settings){
|
|
12
11
|
this.kvStore = kvStore;
|
|
@@ -14,16 +13,11 @@ export class SlasherOffensesStore {
|
|
|
14
13
|
this.log = createLogger('slasher:store:offenses');
|
|
15
14
|
this.offenses = kvStore.openMap('offenses');
|
|
16
15
|
this.roundsOffenses = kvStore.openMultiMap('rounds-offenses');
|
|
17
|
-
this.offensesSlashed = kvStore.openSet('offenses-slashed');
|
|
18
16
|
}
|
|
19
|
-
/** Returns all offenses
|
|
17
|
+
/** Returns all offenses */ async getOffenses() {
|
|
20
18
|
const offenses = [];
|
|
21
|
-
for await (const [
|
|
22
|
-
|
|
23
|
-
continue; // Skip executed offenses
|
|
24
|
-
}
|
|
25
|
-
const offense = deserializeOffense(buffer);
|
|
26
|
-
offenses.push(offense);
|
|
19
|
+
for await (const [, buffer] of this.offenses.entriesAsync()){
|
|
20
|
+
offenses.push(deserializeOffense(buffer));
|
|
27
21
|
}
|
|
28
22
|
return offenses;
|
|
29
23
|
}
|
|
@@ -38,15 +32,11 @@ export class SlasherOffensesStore {
|
|
|
38
32
|
}
|
|
39
33
|
return offenses;
|
|
40
34
|
}
|
|
41
|
-
/** Returns whether an offense is pending (ie not marked as slashed) */ async hasPendingOffense(offense) {
|
|
42
|
-
const key = this.getOffenseKey(offense);
|
|
43
|
-
return await this.offenses.getAsync(key) !== undefined && !await this.offensesSlashed.hasAsync(key);
|
|
44
|
-
}
|
|
45
35
|
/** Returns whether we have seen this offense */ async hasOffense(offense) {
|
|
46
36
|
const key = this.getOffenseKey(offense);
|
|
47
37
|
return await this.offenses.getAsync(key) !== undefined;
|
|
48
38
|
}
|
|
49
|
-
/** Adds a new offense
|
|
39
|
+
/** Adds a new offense */ async addOffense(offense) {
|
|
50
40
|
const key = this.getOffenseKey(offense);
|
|
51
41
|
const round = getRoundForOffense(offense, this.settings);
|
|
52
42
|
await this.kvStore.transactionAsync(async ()=>{
|
|
@@ -55,14 +45,6 @@ export class SlasherOffensesStore {
|
|
|
55
45
|
});
|
|
56
46
|
this.log.trace(`Adding pending offense ${key} for round ${round}`);
|
|
57
47
|
}
|
|
58
|
-
/** Marks the given offenses as slashed (regardless of whether they are known or not) */ async markAsSlashed(offenses) {
|
|
59
|
-
await this.kvStore.transactionAsync(async ()=>{
|
|
60
|
-
for (const offense of offenses){
|
|
61
|
-
const key = this.getOffenseKey(offense);
|
|
62
|
-
await this.offensesSlashed.add(key);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
48
|
/** Prunes all offenses expired from the store */ async clearExpiredOffenses(currentRound) {
|
|
67
49
|
const expirationRounds = this.settings.slashOffenseExpirationRounds ?? 0;
|
|
68
50
|
if (expirationRounds <= 0) {
|
|
@@ -89,7 +71,6 @@ export class SlasherOffensesStore {
|
|
|
89
71
|
for (const key of expiredOffenseKeys){
|
|
90
72
|
this.log.trace(`Deleting offense ${key}`);
|
|
91
73
|
await this.offenses.delete(key);
|
|
92
|
-
await this.offensesSlashed.delete(key);
|
|
93
74
|
}
|
|
94
75
|
for (const roundKey of expiredRoundKeys){
|
|
95
76
|
this.log.trace(`Deleting round info for ${roundKey}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/slasher",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.f650c0a5c",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -56,20 +56,20 @@
|
|
|
56
56
|
]
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
60
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
61
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
62
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
63
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
64
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
65
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
59
|
+
"@aztec/epoch-cache": "0.0.1-commit.f650c0a5c",
|
|
60
|
+
"@aztec/ethereum": "0.0.1-commit.f650c0a5c",
|
|
61
|
+
"@aztec/foundation": "0.0.1-commit.f650c0a5c",
|
|
62
|
+
"@aztec/kv-store": "0.0.1-commit.f650c0a5c",
|
|
63
|
+
"@aztec/l1-artifacts": "0.0.1-commit.f650c0a5c",
|
|
64
|
+
"@aztec/stdlib": "0.0.1-commit.f650c0a5c",
|
|
65
|
+
"@aztec/telemetry-client": "0.0.1-commit.f650c0a5c",
|
|
66
66
|
"source-map-support": "^0.5.21",
|
|
67
67
|
"tslib": "^2.4.0",
|
|
68
68
|
"viem": "npm:@aztec/viem@2.38.2",
|
|
69
69
|
"zod": "^3.23.8"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@aztec/aztec.js": "0.0.1-commit.
|
|
72
|
+
"@aztec/aztec.js": "0.0.1-commit.f650c0a5c",
|
|
73
73
|
"@jest/globals": "^30.0.0",
|
|
74
74
|
"@types/jest": "^30.0.0",
|
|
75
75
|
"@types/node": "^22.15.17",
|
package/src/config.ts
CHANGED
|
@@ -14,8 +14,6 @@ export type { SlasherConfig };
|
|
|
14
14
|
|
|
15
15
|
export const DefaultSlasherConfig: SlasherConfig = {
|
|
16
16
|
slashOverridePayload: undefined,
|
|
17
|
-
slashMinPenaltyPercentage: slasherDefaultEnv.SLASH_MIN_PENALTY_PERCENTAGE,
|
|
18
|
-
slashMaxPenaltyPercentage: slasherDefaultEnv.SLASH_MAX_PENALTY_PERCENTAGE,
|
|
19
17
|
slashValidatorsAlways: [], // Empty by default
|
|
20
18
|
slashValidatorsNever: [], // Empty by default
|
|
21
19
|
slashPrunePenalty: BigInt(slasherDefaultEnv.SLASH_PRUNE_PENALTY),
|
|
@@ -43,16 +41,6 @@ export const slasherConfigMappings: ConfigMappingsType<SlasherConfig> = {
|
|
|
43
41
|
parseEnv: (val: string) => (val ? EthAddress.fromString(val) : undefined),
|
|
44
42
|
defaultValue: DefaultSlasherConfig.slashOverridePayload,
|
|
45
43
|
},
|
|
46
|
-
slashMinPenaltyPercentage: {
|
|
47
|
-
env: 'SLASH_MIN_PENALTY_PERCENTAGE',
|
|
48
|
-
description: 'Minimum penalty percentage for slashing offenses (0.1 is 10%).',
|
|
49
|
-
...floatConfigHelper(DefaultSlasherConfig.slashMinPenaltyPercentage),
|
|
50
|
-
},
|
|
51
|
-
slashMaxPenaltyPercentage: {
|
|
52
|
-
env: 'SLASH_MAX_PENALTY_PERCENTAGE',
|
|
53
|
-
description: 'Maximum penalty percentage for slashing offenses (2.0 is 200%).',
|
|
54
|
-
...floatConfigHelper(DefaultSlasherConfig.slashMaxPenaltyPercentage),
|
|
55
|
-
},
|
|
56
44
|
slashValidatorsAlways: {
|
|
57
45
|
env: 'SLASH_VALIDATORS_ALWAYS',
|
|
58
46
|
description: 'Comma-separated list of validator addresses that should always be slashed.',
|