@aztec/slasher 0.0.1-commit.43c09e3f → 0.0.1-commit.4ad48494d
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 +23 -13
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +12 -0
- package/dest/generated/slasher-defaults.d.ts +3 -1
- package/dest/generated/slasher-defaults.d.ts.map +1 -1
- package/dest/generated/slasher-defaults.js +2 -0
- package/package.json +9 -9
- package/src/config.ts +13 -0
- package/src/generated/slasher-defaults.ts +2 -0
package/README.md
CHANGED
|
@@ -137,9 +137,15 @@ List of all slashable offenses in the system:
|
|
|
137
137
|
**Time Unit**: Slot-based offense.
|
|
138
138
|
|
|
139
139
|
### ATTESTED_DESCENDANT_OF_INVALID
|
|
140
|
-
**Description**: A committee member attested to a block built on top of an invalid ancestor.
|
|
141
|
-
**Detection**: AttestationsBlockWatcher tracks invalid blocks and their descendants.
|
|
142
|
-
**Target**: Committee members who attested to the descendant block.
|
|
140
|
+
**Description**: A committee member attested to a block built on top of an invalid ancestor.
|
|
141
|
+
**Detection**: AttestationsBlockWatcher tracks invalid blocks and their descendants.
|
|
142
|
+
**Target**: Committee members who attested to the descendant block.
|
|
143
|
+
**Time Unit**: Slot-based offense.
|
|
144
|
+
|
|
145
|
+
### DUPLICATE_PROPOSAL
|
|
146
|
+
**Description**: A proposer sent multiple block or checkpoint proposals for the same position (slot and indexWithinCheckpoint for blocks, or slot for checkpoints) with different content. Since each slot has exactly one designated proposer, sending conflicting proposals is equivocation.
|
|
147
|
+
**Detection**: Detected in the P2P layer when proposals are received. The AttestationPool tracks proposals by position; when a second proposal arrives for the same position with a different archive, it flags the duplicate. The first duplicate is propagated (Accept) so other validators can witness the offense.
|
|
148
|
+
**Target**: Proposer who broadcast the duplicate proposal.
|
|
143
149
|
**Time Unit**: Slot-based offense.
|
|
144
150
|
|
|
145
151
|
## Configuration
|
|
@@ -175,6 +181,7 @@ These settings are configured locally on each validator node:
|
|
|
175
181
|
- `slashDataWithholdingPenalty`: Penalty for DATA_WITHHOLDING
|
|
176
182
|
- `slashInactivityPenalty`: Penalty for INACTIVITY
|
|
177
183
|
- `slashBroadcastedInvalidBlockPenalty`: Penalty for BROADCASTED_INVALID_BLOCK_PROPOSAL
|
|
184
|
+
- `slashDuplicateProposalPenalty`: Penalty for DUPLICATE_PROPOSAL
|
|
178
185
|
- `slashProposeInvalidAttestationsPenalty`: Penalty for PROPOSED_INSUFFICIENT_ATTESTATIONS and PROPOSED_INCORRECT_ATTESTATIONS
|
|
179
186
|
- `slashAttestDescendantOfInvalidPenalty`: Penalty for ATTESTED_DESCENDANT_OF_INVALID
|
|
180
187
|
- `slashUnknownPenalty`: Default penalty for unknown offense types
|
|
@@ -195,21 +202,24 @@ Details about specific offenses in the system:
|
|
|
195
202
|
|
|
196
203
|
Inactivity slashing is one of the most critical, since it allows purging validators that are not fulfilling their duties, which could potentially bring the chain to a halt. This slashing must be aggressive enough to balance out the rate of the entry queue, in case the queue is filled with inactive validators. Furthermore, if enough inactive validators join the system, it may become impossible to gather enough quorum to pass any governance proposal.
|
|
197
204
|
|
|
198
|
-
Inactivity slashing is handled by the `Sentinel` which monitors performance of all validators slot-by-slot. After each slot, the sentinel assigns one of the following to the
|
|
199
|
-
- `
|
|
200
|
-
- `
|
|
201
|
-
- `
|
|
205
|
+
Inactivity slashing is handled by the `Sentinel` which monitors performance of all validators slot-by-slot. With the multiple-blocks-per-slot model, block proposals and checkpoints are distinct concepts: proposers build multiple blocks per slot, but attestations are only for checkpoints. After each slot, the sentinel assigns one of the following to the proposer for the slot:
|
|
206
|
+
- `checkpoint-mined` if the checkpoint was added to L1
|
|
207
|
+
- `checkpoint-proposed` if the checkpoint received at least one attestation, but didn't make it to L1
|
|
208
|
+
- `checkpoint-missed` if blocks were proposed but the checkpoint received no attestations
|
|
209
|
+
- `blocks-missed` if no block proposals were sent for this slot at all
|
|
210
|
+
|
|
211
|
+
And assigns one of the following to each validator (these refer to checkpoint attestations):
|
|
212
|
+
- `attestation-sent` if there was a `checkpoint-proposed` or `checkpoint-mined` and a checkpoint attestation from this validator was seen on either on L1 or on the P2P network
|
|
213
|
+
- `attestation-missed` if there was a `checkpoint-proposed` or `checkpoint-mined` but no checkpoint attestation was seen
|
|
214
|
+
- none if the slot was a `blocks-missed`
|
|
202
215
|
|
|
203
|
-
|
|
204
|
-
- `attestation-sent` if there was a `block-proposed` or `block-mined` and an attestation from this validator was seen on either on L1 or on the P2P network
|
|
205
|
-
- `attestation-missed` if there was a `block-proposed` or `block-mined` but no attestation was seen
|
|
206
|
-
- none if the slot was a `block-missed`
|
|
216
|
+
Both `blocks-missed` and `checkpoint-missed` count as proposer inactivity.
|
|
207
217
|
|
|
208
218
|
Once an epoch is proven, the sentinel computes the _proven performance_ for the epoch for each validator. Note that we wait until the epoch is proven so we know that the data for all blocks in the epoch was available, and validators who did not attest were effectively inactive. Then, for each validator such that:
|
|
209
219
|
|
|
210
220
|
```
|
|
211
|
-
total_failures = count(
|
|
212
|
-
total = count(
|
|
221
|
+
total_failures = count(blocks-missed) + count(checkpoint-missed) + count(attestation-missed)
|
|
222
|
+
total = count(checkpoint-*) + count(blocks-*) + count(attestation-*)
|
|
213
223
|
total_failures / total >= slash_inactivity_target_percentage
|
|
214
224
|
```
|
|
215
225
|
|
package/dest/config.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
|
3
3
|
export type { SlasherConfig };
|
|
4
4
|
export declare const DefaultSlasherConfig: SlasherConfig;
|
|
5
5
|
export declare const slasherConfigMappings: ConfigMappingsType<SlasherConfig>;
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFRbkUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFJckUsWUFBWSxFQUFFLGFBQWEsRUFBRSxDQUFDO0FBRTlCLGVBQU8sTUFBTSxvQkFBb0IsRUFBRSxhQXNCbEMsQ0FBQztBQUVGLGVBQU8sTUFBTSxxQkFBcUIsRUFBRSxrQkFBa0IsQ0FBQyxhQUFhLENBb0luRSxDQUFDIn0=
|
package/dest/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAIrE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,eAAO,MAAM,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAIrE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,eAAO,MAAM,oBAAoB,EAAE,aAsBlC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,kBAAkB,CAAC,aAAa,CAoInE,CAAC"}
|
package/dest/config.js
CHANGED
|
@@ -12,6 +12,8 @@ export const DefaultSlasherConfig = {
|
|
|
12
12
|
slashInactivityTargetPercentage: slasherDefaultEnv.SLASH_INACTIVITY_TARGET_PERCENTAGE,
|
|
13
13
|
slashInactivityConsecutiveEpochThreshold: slasherDefaultEnv.SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD,
|
|
14
14
|
slashBroadcastedInvalidBlockPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_BLOCK_PENALTY),
|
|
15
|
+
slashDuplicateProposalPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_PROPOSAL_PENALTY),
|
|
16
|
+
slashDuplicateAttestationPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_ATTESTATION_PENALTY),
|
|
15
17
|
slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY),
|
|
16
18
|
slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY),
|
|
17
19
|
slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY),
|
|
@@ -66,6 +68,16 @@ export const slasherConfigMappings = {
|
|
|
66
68
|
description: 'Penalty amount for slashing a validator for an invalid block proposed via p2p.',
|
|
67
69
|
...bigintConfigHelper(DefaultSlasherConfig.slashBroadcastedInvalidBlockPenalty)
|
|
68
70
|
},
|
|
71
|
+
slashDuplicateProposalPenalty: {
|
|
72
|
+
env: 'SLASH_DUPLICATE_PROPOSAL_PENALTY',
|
|
73
|
+
description: 'Penalty amount for slashing a validator for sending duplicate proposals.',
|
|
74
|
+
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateProposalPenalty)
|
|
75
|
+
},
|
|
76
|
+
slashDuplicateAttestationPenalty: {
|
|
77
|
+
env: 'SLASH_DUPLICATE_ATTESTATION_PENALTY',
|
|
78
|
+
description: 'Penalty amount for slashing a validator for signing attestations for different proposals at the same slot.',
|
|
79
|
+
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateAttestationPenalty)
|
|
80
|
+
},
|
|
69
81
|
slashInactivityTargetPercentage: {
|
|
70
82
|
env: 'SLASH_INACTIVITY_TARGET_PERCENTAGE',
|
|
71
83
|
description: 'Missed attestation percentage to trigger creation of inactivity slash payload (0, 1]. Must be greater than 0',
|
|
@@ -12,8 +12,10 @@ export declare const slasherDefaultEnv: {
|
|
|
12
12
|
readonly SLASH_INACTIVITY_PENALTY: 10000000000000000000;
|
|
13
13
|
readonly SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000;
|
|
14
14
|
readonly SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10000000000000000000;
|
|
15
|
+
readonly SLASH_DUPLICATE_PROPOSAL_PENALTY: 10000000000000000000;
|
|
16
|
+
readonly SLASH_DUPLICATE_ATTESTATION_PENALTY: 10000000000000000000;
|
|
15
17
|
readonly SLASH_UNKNOWN_PENALTY: 10000000000000000000;
|
|
16
18
|
readonly SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000;
|
|
17
19
|
readonly SLASH_GRACE_PERIOD_L2_SLOTS: 0;
|
|
18
20
|
};
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hlci1kZWZhdWx0cy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2dlbmVyYXRlZC9zbGFzaGVyLWRlZmF1bHRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLHFFQUFxRTtBQUNyRSxlQUFPLE1BQU0saUJBQWlCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FrQnBCLENBQUMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slasher-defaults.d.ts","sourceRoot":"","sources":["../../src/generated/slasher-defaults.ts"],"names":[],"mappings":"AAGA,qEAAqE;AACrE,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"slasher-defaults.d.ts","sourceRoot":"","sources":["../../src/generated/slasher-defaults.ts"],"names":[],"mappings":"AAGA,qEAAqE;AACrE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;CAkBpB,CAAC"}
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
SLASH_INACTIVITY_PENALTY: 10000000000000000000,
|
|
14
14
|
SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000,
|
|
15
15
|
SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10000000000000000000,
|
|
16
|
+
SLASH_DUPLICATE_PROPOSAL_PENALTY: 10000000000000000000,
|
|
17
|
+
SLASH_DUPLICATE_ATTESTATION_PENALTY: 10000000000000000000,
|
|
16
18
|
SLASH_UNKNOWN_PENALTY: 10000000000000000000,
|
|
17
19
|
SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000,
|
|
18
20
|
SLASH_GRACE_PERIOD_L2_SLOTS: 0
|
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.4ad48494d",
|
|
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.4ad48494d",
|
|
60
|
+
"@aztec/ethereum": "0.0.1-commit.4ad48494d",
|
|
61
|
+
"@aztec/foundation": "0.0.1-commit.4ad48494d",
|
|
62
|
+
"@aztec/kv-store": "0.0.1-commit.4ad48494d",
|
|
63
|
+
"@aztec/l1-artifacts": "0.0.1-commit.4ad48494d",
|
|
64
|
+
"@aztec/stdlib": "0.0.1-commit.4ad48494d",
|
|
65
|
+
"@aztec/telemetry-client": "0.0.1-commit.4ad48494d",
|
|
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.4ad48494d",
|
|
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
|
@@ -23,6 +23,8 @@ export const DefaultSlasherConfig: SlasherConfig = {
|
|
|
23
23
|
slashInactivityTargetPercentage: slasherDefaultEnv.SLASH_INACTIVITY_TARGET_PERCENTAGE,
|
|
24
24
|
slashInactivityConsecutiveEpochThreshold: slasherDefaultEnv.SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD,
|
|
25
25
|
slashBroadcastedInvalidBlockPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_BLOCK_PENALTY),
|
|
26
|
+
slashDuplicateProposalPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_PROPOSAL_PENALTY),
|
|
27
|
+
slashDuplicateAttestationPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_ATTESTATION_PENALTY),
|
|
26
28
|
slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY),
|
|
27
29
|
slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY),
|
|
28
30
|
slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY),
|
|
@@ -88,6 +90,17 @@ export const slasherConfigMappings: ConfigMappingsType<SlasherConfig> = {
|
|
|
88
90
|
description: 'Penalty amount for slashing a validator for an invalid block proposed via p2p.',
|
|
89
91
|
...bigintConfigHelper(DefaultSlasherConfig.slashBroadcastedInvalidBlockPenalty),
|
|
90
92
|
},
|
|
93
|
+
slashDuplicateProposalPenalty: {
|
|
94
|
+
env: 'SLASH_DUPLICATE_PROPOSAL_PENALTY',
|
|
95
|
+
description: 'Penalty amount for slashing a validator for sending duplicate proposals.',
|
|
96
|
+
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateProposalPenalty),
|
|
97
|
+
},
|
|
98
|
+
slashDuplicateAttestationPenalty: {
|
|
99
|
+
env: 'SLASH_DUPLICATE_ATTESTATION_PENALTY',
|
|
100
|
+
description:
|
|
101
|
+
'Penalty amount for slashing a validator for signing attestations for different proposals at the same slot.',
|
|
102
|
+
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateAttestationPenalty),
|
|
103
|
+
},
|
|
91
104
|
slashInactivityTargetPercentage: {
|
|
92
105
|
env: 'SLASH_INACTIVITY_TARGET_PERCENTAGE',
|
|
93
106
|
description:
|
|
@@ -15,6 +15,8 @@ export const slasherDefaultEnv = {
|
|
|
15
15
|
SLASH_INACTIVITY_PENALTY: 10000000000000000000,
|
|
16
16
|
SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000,
|
|
17
17
|
SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10000000000000000000,
|
|
18
|
+
SLASH_DUPLICATE_PROPOSAL_PENALTY: 10000000000000000000,
|
|
19
|
+
SLASH_DUPLICATE_ATTESTATION_PENALTY: 10000000000000000000,
|
|
18
20
|
SLASH_UNKNOWN_PENALTY: 10000000000000000000,
|
|
19
21
|
SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000,
|
|
20
22
|
SLASH_GRACE_PERIOD_L2_SLOTS: 0,
|