@aztec/slasher 2.0.0-nightly.20250902 → 3.0.0-canary.a9708bd
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/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,eAAO,MAAM,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,eAAO,MAAM,oBAAoB,EAAE,aAmBlC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,kBAAkB,CAAC,aAAa,CAoHnE,CAAC"}
|
package/dest/config.js
CHANGED
|
@@ -10,6 +10,7 @@ export const DefaultSlasherConfig = {
|
|
|
10
10
|
slashPrunePenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
11
11
|
slashDataWithholdingPenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
12
12
|
slashInactivityTargetPercentage: 0.9,
|
|
13
|
+
slashInactivityConsecutiveEpochThreshold: 1,
|
|
13
14
|
slashBroadcastedInvalidBlockPenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
14
15
|
slashInactivityPenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
15
16
|
slashProposeInvalidAttestationsPenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
@@ -73,6 +74,18 @@ export const slasherConfigMappings = {
|
|
|
73
74
|
}
|
|
74
75
|
})
|
|
75
76
|
},
|
|
77
|
+
slashInactivityConsecutiveEpochThreshold: {
|
|
78
|
+
env: 'SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD',
|
|
79
|
+
description: 'Number of consecutive epochs a validator must be inactive before slashing (minimum 1).',
|
|
80
|
+
...numberConfigHelper(DefaultSlasherConfig.slashInactivityConsecutiveEpochThreshold),
|
|
81
|
+
parseEnv: (val)=>{
|
|
82
|
+
const parsed = parseInt(val, 10);
|
|
83
|
+
if (parsed < 1) {
|
|
84
|
+
throw new RangeError(`SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD must be at least 1 (got ${parsed})`);
|
|
85
|
+
}
|
|
86
|
+
return parsed;
|
|
87
|
+
}
|
|
88
|
+
},
|
|
76
89
|
slashInactivityPenalty: {
|
|
77
90
|
env: 'SLASH_INACTIVITY_PENALTY',
|
|
78
91
|
description: 'Penalty amount for slashing an inactive validator (set to 0 to disable).',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tally_slasher_client.d.ts","sourceRoot":"","sources":["../src/tally_slasher_client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAI1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EACL,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"tally_slasher_client.d.ts","sourceRoot":"","sources":["../src/tally_slasher_client.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { EthAddress } from '@aztec/aztec.js';
|
|
|
2
2
|
import { compactArray, partition, times } from '@aztec/foundation/collection';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { sleep } from '@aztec/foundation/sleep';
|
|
5
|
-
import { getEpochsForRound, getSlashConsensusVotesFromOffenses } from '@aztec/stdlib/slashing';
|
|
5
|
+
import { OffenseType, getEpochsForRound, getSlashConsensusVotesFromOffenses } from '@aztec/stdlib/slashing';
|
|
6
6
|
import { SlashOffensesCollector } from './slash_offenses_collector.js';
|
|
7
7
|
import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
8
8
|
/**
|
|
@@ -191,7 +191,8 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
191
191
|
const offensesForRound = await this.gatherOffensesForRound(currentRound);
|
|
192
192
|
const offensesFromAlwaysSlash = (this.config.slashValidatorsAlways ?? []).map((validator)=>({
|
|
193
193
|
validator,
|
|
194
|
-
amount: this.settings.slashingAmounts[2]
|
|
194
|
+
amount: this.settings.slashingAmounts[2],
|
|
195
|
+
offenseType: OffenseType.UNKNOWN
|
|
195
196
|
}));
|
|
196
197
|
const [offensesToForgive, offensesToSlash] = partition([
|
|
197
198
|
...offensesForRound,
|
|
@@ -230,7 +231,8 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
230
231
|
offensesToSlash
|
|
231
232
|
});
|
|
232
233
|
const committees = await this.collectCommitteesActiveDuringRound(slashedRound);
|
|
233
|
-
const
|
|
234
|
+
const epochsForCommittees = getEpochsForRound(slashedRound, this.settings);
|
|
235
|
+
const votes = getSlashConsensusVotesFromOffenses(offensesToSlash, committees, epochsForCommittees, this.settings);
|
|
234
236
|
if (votes.every((v)=>v === 0)) {
|
|
235
237
|
this.log.warn(`Computed votes for offenses are all zero. Skipping vote.`, {
|
|
236
238
|
slotNumber,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/slasher",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-canary.a9708bd",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -54,20 +54,20 @@
|
|
|
54
54
|
]
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@aztec/epoch-cache": "
|
|
58
|
-
"@aztec/ethereum": "
|
|
59
|
-
"@aztec/foundation": "
|
|
60
|
-
"@aztec/kv-store": "
|
|
61
|
-
"@aztec/l1-artifacts": "
|
|
62
|
-
"@aztec/stdlib": "
|
|
63
|
-
"@aztec/telemetry-client": "
|
|
57
|
+
"@aztec/epoch-cache": "3.0.0-canary.a9708bd",
|
|
58
|
+
"@aztec/ethereum": "3.0.0-canary.a9708bd",
|
|
59
|
+
"@aztec/foundation": "3.0.0-canary.a9708bd",
|
|
60
|
+
"@aztec/kv-store": "3.0.0-canary.a9708bd",
|
|
61
|
+
"@aztec/l1-artifacts": "3.0.0-canary.a9708bd",
|
|
62
|
+
"@aztec/stdlib": "3.0.0-canary.a9708bd",
|
|
63
|
+
"@aztec/telemetry-client": "3.0.0-canary.a9708bd",
|
|
64
64
|
"source-map-support": "^0.5.21",
|
|
65
65
|
"tslib": "^2.4.0",
|
|
66
66
|
"viem": "2.23.7",
|
|
67
67
|
"zod": "^3.23.8"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@aztec/aztec.js": "
|
|
70
|
+
"@aztec/aztec.js": "3.0.0-canary.a9708bd",
|
|
71
71
|
"@jest/globals": "^30.0.0",
|
|
72
72
|
"@types/jest": "^30.0.0",
|
|
73
73
|
"@types/node": "^22.15.17",
|
package/src/config.ts
CHANGED
|
@@ -20,6 +20,7 @@ export const DefaultSlasherConfig: SlasherConfig = {
|
|
|
20
20
|
slashPrunePenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
21
21
|
slashDataWithholdingPenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
22
22
|
slashInactivityTargetPercentage: 0.9,
|
|
23
|
+
slashInactivityConsecutiveEpochThreshold: 1, // Default to 1 for backward compatibility
|
|
23
24
|
slashBroadcastedInvalidBlockPenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
24
25
|
slashInactivityPenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
25
26
|
slashProposeInvalidAttestationsPenalty: DefaultL1ContractsConfig.slashAmountSmall,
|
|
@@ -95,6 +96,18 @@ export const slasherConfigMappings: ConfigMappingsType<SlasherConfig> = {
|
|
|
95
96
|
}
|
|
96
97
|
}),
|
|
97
98
|
},
|
|
99
|
+
slashInactivityConsecutiveEpochThreshold: {
|
|
100
|
+
env: 'SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD',
|
|
101
|
+
description: 'Number of consecutive epochs a validator must be inactive before slashing (minimum 1).',
|
|
102
|
+
...numberConfigHelper(DefaultSlasherConfig.slashInactivityConsecutiveEpochThreshold),
|
|
103
|
+
parseEnv: (val: string) => {
|
|
104
|
+
const parsed = parseInt(val, 10);
|
|
105
|
+
if (parsed < 1) {
|
|
106
|
+
throw new RangeError(`SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD must be at least 1 (got ${parsed})`);
|
|
107
|
+
}
|
|
108
|
+
return parsed;
|
|
109
|
+
},
|
|
110
|
+
},
|
|
98
111
|
slashInactivityPenalty: {
|
|
99
112
|
env: 'SLASH_INACTIVITY_PENALTY',
|
|
100
113
|
description: 'Penalty amount for slashing an inactive validator (set to 0 to disable).',
|
|
@@ -9,6 +9,7 @@ import type { Prettify } from '@aztec/foundation/types';
|
|
|
9
9
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
10
10
|
import {
|
|
11
11
|
type Offense,
|
|
12
|
+
OffenseType,
|
|
12
13
|
type ProposerSlashAction,
|
|
13
14
|
type ProposerSlashActionProvider,
|
|
14
15
|
type SlashPayloadRound,
|
|
@@ -253,6 +254,7 @@ export class TallySlasherClient implements ProposerSlashActionProvider, SlasherC
|
|
|
253
254
|
const offensesFromAlwaysSlash = (this.config.slashValidatorsAlways ?? []).map(validator => ({
|
|
254
255
|
validator,
|
|
255
256
|
amount: this.settings.slashingAmounts[2],
|
|
257
|
+
offenseType: OffenseType.UNKNOWN,
|
|
256
258
|
}));
|
|
257
259
|
const [offensesToForgive, offensesToSlash] = partition([...offensesForRound, ...offensesFromAlwaysSlash], offense =>
|
|
258
260
|
this.config.slashValidatorsNever?.some(v => v.equals(offense.validator)),
|
|
@@ -291,7 +293,8 @@ export class TallySlasherClient implements ProposerSlashActionProvider, SlasherC
|
|
|
291
293
|
});
|
|
292
294
|
|
|
293
295
|
const committees = await this.collectCommitteesActiveDuringRound(slashedRound);
|
|
294
|
-
const
|
|
296
|
+
const epochsForCommittees = getEpochsForRound(slashedRound, this.settings);
|
|
297
|
+
const votes = getSlashConsensusVotesFromOffenses(offensesToSlash, committees, epochsForCommittees, this.settings);
|
|
295
298
|
if (votes.every(v => v === 0)) {
|
|
296
299
|
this.log.warn(`Computed votes for offenses are all zero. Skipping vote.`, {
|
|
297
300
|
slotNumber,
|