@aztec/slasher 0.0.1-commit.6d63667d → 0.0.1-commit.7b97ef96e
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/dest/slash_offenses_collector.d.ts +1 -1
- package/dest/slash_offenses_collector.d.ts.map +1 -1
- package/dest/slash_offenses_collector.js +1 -5
- package/dest/watchers/epoch_prune_watcher.d.ts +1 -1
- package/dest/watchers/epoch_prune_watcher.d.ts.map +1 -1
- package/dest/watchers/epoch_prune_watcher.js +3 -2
- package/package.json +9 -9
- package/src/config.ts +13 -0
- package/src/generated/slasher-defaults.ts +2 -0
- package/src/slash_offenses_collector.ts +1 -5
- package/src/watchers/epoch_prune_watcher.ts +5 -3
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
|
|
@@ -42,4 +42,4 @@ export declare class SlashOffensesCollector {
|
|
|
42
42
|
/** Returns whether to skip an offense if it happened during the grace period at the beginning of the chain */
|
|
43
43
|
private shouldSkipOffense;
|
|
44
44
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hfb2ZmZW5zZXNfY29sbGVjdG9yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hfb2ZmZW5zZXNfY29sbGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDckUsT0FBTyxFQUFnQixLQUFLLGlCQUFpQixFQUFxQixNQUFNLHdCQUF3QixDQUFDO0FBRWpHLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkUsT0FBTyxFQUF1QixLQUFLLGVBQWUsRUFBRSxLQUFLLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV2RixNQUFNLE1BQU0sNEJBQTRCLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUseUJBQXlCLENBQUMsQ0FBQyxDQUFDO0FBQ3BHLE1BQU0sTUFBTSw4QkFBOEIsR0FBRyxRQUFRLENBQ25ELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLENBQUMsR0FBRztJQUFFLGVBQWUsRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFBO0NBQUUsQ0FDckcsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxxQkFBYSxzQkFBc0I7SUFJL0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNO0lBQ3ZCLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUTtJQUN6QixPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVE7SUFDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhO0lBQzlCLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRztJQVB0QixPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFzQjtJQUV2RCxZQUNtQixNQUFNLEVBQUUsNEJBQTRCLEVBQ3BDLFFBQVEsRUFBRSw4QkFBOEIsRUFDeEMsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUNuQixhQUFhLEVBQUUsb0JBQW9CLEVBQ25DLEdBQUcseUNBQTZDLEVBQy9EO0lBRUcsS0FBSyxrQkFhWDtJQUVNLElBQUksa0JBU1Y7SUFFRDs7OztPQUlHO0lBQ1UsaUJBQWlCLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxpQkE2QnJEO0lBRUQ7OztPQUdHO0lBQ1UsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLGlCQUt4QztJQUVEOzs7T0FHRztJQUNJLGFBQWEsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsaUJBR2pEO0lBRUQsOEdBQThHO0lBQzlHLE9BQU8sQ0FBQyxpQkFBaUI7Q0FJMUIifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash_offenses_collector.d.ts","sourceRoot":"","sources":["../src/slash_offenses_collector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAgB,KAAK,iBAAiB,EAAqB,MAAM,wBAAwB,CAAC;AAEjG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAuB,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC;AACpG,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CACnD,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,GAAG;IAAE,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAAE,CACrG,CAAC;AAEF;;;;GAIG;AACH,qBAAa,sBAAsB;IAI/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAPtB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD,YACmB,MAAM,EAAE,4BAA4B,EACpC,QAAQ,EAAE,8BAA8B,EACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,aAAa,EAAE,oBAAoB,EACnC,GAAG,yCAA6C,EAC/D;IAEG,KAAK,kBAaX;IAEM,IAAI,kBASV;IAED;;;;OAIG;IACU,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"slash_offenses_collector.d.ts","sourceRoot":"","sources":["../src/slash_offenses_collector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAgB,KAAK,iBAAiB,EAAqB,MAAM,wBAAwB,CAAC;AAEjG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAuB,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC;AACpG,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CACnD,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,GAAG;IAAE,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAAE,CACrG,CAAC;AAEF;;;;GAIG;AACH,qBAAa,sBAAsB;IAI/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAPtB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD,YACmB,MAAM,EAAE,4BAA4B,EACpC,QAAQ,EAAE,8BAA8B,EACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,aAAa,EAAE,oBAAoB,EACnC,GAAG,yCAA6C,EAC/D;IAEG,KAAK,kBAaX;IAEM,IAAI,kBASV;IAED;;;;OAIG;IACU,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,iBA6BrD;IAED;;;OAGG;IACU,cAAc,CAAC,KAAK,EAAE,MAAM,iBAKxC;IAED;;;OAGG;IACI,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,iBAGjD;IAED,8GAA8G;IAC9G,OAAO,CAAC,iBAAiB;CAI1B"}
|
|
@@ -65,11 +65,7 @@ import { WANT_TO_SLASH_EVENT } from './watcher.js';
|
|
|
65
65
|
this.log.warn(`Offense amount ${arg.amount} is below minimum slashing amount ${minSlash}`);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
this.log.info(`Adding pending offense for validator ${arg.validator}`,
|
|
69
|
-
...pendingOffense,
|
|
70
|
-
epochOrSlot: pendingOffense.epochOrSlot.toString(),
|
|
71
|
-
amount: pendingOffense.amount.toString()
|
|
72
|
-
});
|
|
68
|
+
this.log.info(`Adding pending offense for validator ${arg.validator}`, pendingOffense);
|
|
73
69
|
await this.offensesStore.addPendingOffense(pendingOffense);
|
|
74
70
|
}
|
|
75
71
|
}
|
|
@@ -36,4 +36,4 @@ export declare class EpochPruneWatcher extends EpochPruneWatcher_base implements
|
|
|
36
36
|
private validatorsToSlashingArgs;
|
|
37
37
|
}
|
|
38
38
|
export {};
|
|
39
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfcHJ1bmVfd2F0Y2hlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dhdGNoZXJzL2Vwb2NoX3BydW5lX3dhdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBZSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUkzRSxPQUFPLEVBRUwsT0FBTyxFQUNQLEtBQUsseUJBQXlCLEVBRy9CLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsT0FBTyxLQUFLLEVBRVYsbUJBQW1CLEVBQ25CLFdBQVcsRUFFWCxhQUFhLEVBQ2QsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxtQkFBbUIsRUFBNEIsTUFBTSx5QkFBeUIsQ0FBQztBQVk3RixPQUFPLEVBQTZDLEtBQUssT0FBTyxFQUFFLEtBQUssY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdHLFFBQUEsTUFBTSxvQ0FBb0MsK0RBQWdFLENBQUM7QUFFM0csS0FBSywwQkFBMEIsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsT0FBTyxvQ0FBb0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7O0FBRTdHOzs7OztHQUtHO0FBQ0gscUJBQWEsaUJBQWtCLFNBQVEsc0JBQTJDLFlBQVcsT0FBTztJQVNoRyxPQUFPLENBQUMsYUFBYTtJQUNyQixPQUFPLENBQUMsbUJBQW1CO0lBQzNCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxrQkFBa0I7SUFaNUIsT0FBTyxDQUFDLEdBQUcsQ0FBK0M7SUFHMUQsT0FBTyxDQUFDLHdCQUF3QixDQUF1QztJQUV2RSxPQUFPLENBQUMsU0FBUyxDQUE2QjtJQUU5QyxZQUNVLGFBQWEsRUFBRSx5QkFBeUIsRUFDeEMsbUJBQW1CLEVBQUUsbUJBQW1CLEVBQ3hDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDLEVBQ2hELGtCQUFrQixFQUFFLG1CQUFtQixFQUMvQyxTQUFTLEVBQUUsMEJBQTBCLEVBT3RDO0lBRU0sS0FBSyxrQkFHWDtJQUVNLElBQUksa0JBR1Y7SUFFTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBR3hEO0lBRUQsT0FBTyxDQUFDLG1CQUFtQjtZQU9iLGlCQUFpQjtZQVdqQixvQkFBb0I7SUF3QnJCLGNBQWMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUUsV0FBVyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBK0J0RjtZQUVhLGtCQUFrQjtZQXdDbEIseUJBQXlCO1lBOEJ6QixxQkFBcUI7SUFTbkMsT0FBTyxDQUFDLHdCQUF3QjtDQWdCakMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epoch_prune_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/epoch_prune_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAe,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAI3E,OAAO,EAEL,OAAO,EACP,KAAK,yBAAyB,EAG/B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAEV,mBAAmB,EACnB,WAAW,EAEX,aAAa,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,mBAAmB,EAA4B,MAAM,yBAAyB,CAAC;AAY7F,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7G,QAAA,MAAM,oCAAoC,+DAAgE,CAAC;AAE3G,KAAK,0BAA0B,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;;AAE7G;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,sBAA2C,YAAW,OAAO;IAShG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,kBAAkB;IAZ5B,OAAO,CAAC,GAAG,CAA+C;IAG1D,OAAO,CAAC,wBAAwB,CAAuC;IAEvE,OAAO,CAAC,SAAS,CAA6B;IAE9C,YACU,aAAa,EAAE,yBAAyB,EACxC,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAChD,kBAAkB,EAAE,mBAAmB,EAC/C,SAAS,EAAE,0BAA0B,EAOtC;IAEM,KAAK,kBAGX;IAEM,IAAI,kBAGV;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAGxD;IAED,OAAO,CAAC,mBAAmB;YAOb,iBAAiB;YAWjB,oBAAoB;IAwBrB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BtF;YAEa,kBAAkB;
|
|
1
|
+
{"version":3,"file":"epoch_prune_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/epoch_prune_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAe,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAI3E,OAAO,EAEL,OAAO,EACP,KAAK,yBAAyB,EAG/B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAEV,mBAAmB,EACnB,WAAW,EAEX,aAAa,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,mBAAmB,EAA4B,MAAM,yBAAyB,CAAC;AAY7F,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7G,QAAA,MAAM,oCAAoC,+DAAgE,CAAC;AAE3G,KAAK,0BAA0B,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;;AAE7G;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,sBAA2C,YAAW,OAAO;IAShG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,kBAAkB;IAZ5B,OAAO,CAAC,GAAG,CAA+C;IAG1D,OAAO,CAAC,wBAAwB,CAAuC;IAEvE,OAAO,CAAC,SAAS,CAA6B;IAE9C,YACU,aAAa,EAAE,yBAAyB,EACxC,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAChD,kBAAkB,EAAE,mBAAmB,EAC/C,SAAS,EAAE,0BAA0B,EAOtC;IAEM,KAAK,kBAGX;IAEM,IAAI,kBAGV;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAGxD;IAED,OAAO,CAAC,mBAAmB;YAOb,iBAAiB;YAWjB,oBAAoB;IAwBrB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BtF;YAEa,kBAAkB;YAwClB,yBAAyB;YA8BzB,qBAAqB;IASnC,OAAO,CAAC,wBAAwB;CAgBjC"}
|
|
@@ -91,7 +91,7 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
91
91
|
].sort((a, b)=>a.number - b.number);
|
|
92
92
|
const blocksByCheckpoint = chunkBy(sortedBlocks, (b)=>b.checkpointNumber);
|
|
93
93
|
// Get prior checkpoints in the epoch (in case this was a partial prune) to extract the out hashes
|
|
94
|
-
const priorCheckpointOutHashes = (await this.l2BlockSource.
|
|
94
|
+
const priorCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsDataForEpoch(epochNumber)).filter((c)=>c.checkpointNumber < sortedBlocks[0].checkpointNumber).map((c)=>c.checkpointOutHash);
|
|
95
95
|
let previousCheckpointOutHashes = [
|
|
96
96
|
...priorCheckpointOutHashes
|
|
97
97
|
];
|
|
@@ -121,12 +121,13 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
121
121
|
chainId: gv.chainId,
|
|
122
122
|
version: gv.version,
|
|
123
123
|
slotNumber: gv.slotNumber,
|
|
124
|
+
timestamp: gv.timestamp,
|
|
124
125
|
coinbase: gv.coinbase,
|
|
125
126
|
feeRecipient: gv.feeRecipient,
|
|
126
127
|
gasFees: gv.gasFees
|
|
127
128
|
};
|
|
128
129
|
// Start checkpoint builder once for all blocks in this checkpoint
|
|
129
|
-
const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(checkpointNumber, constants, l1ToL2Messages, previousCheckpointOutHashes, fork, this.log.getBindings());
|
|
130
|
+
const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(checkpointNumber, constants, 0n, l1ToL2Messages, previousCheckpointOutHashes, fork, this.log.getBindings());
|
|
130
131
|
// Validate all blocks in the checkpoint sequentially
|
|
131
132
|
for (const block of checkpointBlocks){
|
|
132
133
|
await this.validateBlockInCheckpoint(block, checkpointBuilder);
|
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.7b97ef96e",
|
|
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.7b97ef96e",
|
|
60
|
+
"@aztec/ethereum": "0.0.1-commit.7b97ef96e",
|
|
61
|
+
"@aztec/foundation": "0.0.1-commit.7b97ef96e",
|
|
62
|
+
"@aztec/kv-store": "0.0.1-commit.7b97ef96e",
|
|
63
|
+
"@aztec/l1-artifacts": "0.0.1-commit.7b97ef96e",
|
|
64
|
+
"@aztec/stdlib": "0.0.1-commit.7b97ef96e",
|
|
65
|
+
"@aztec/telemetry-client": "0.0.1-commit.7b97ef96e",
|
|
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.7b97ef96e",
|
|
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,
|
|
@@ -85,11 +85,7 @@ export class SlashOffensesCollector {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
this.log.info(`Adding pending offense for validator ${arg.validator}`,
|
|
89
|
-
...pendingOffense,
|
|
90
|
-
epochOrSlot: pendingOffense.epochOrSlot.toString(),
|
|
91
|
-
amount: pendingOffense.amount.toString(),
|
|
92
|
-
});
|
|
88
|
+
this.log.info(`Adding pending offense for validator ${arg.validator}`, pendingOffense);
|
|
93
89
|
await this.offensesStore.addPendingOffense(pendingOffense);
|
|
94
90
|
}
|
|
95
91
|
}
|
|
@@ -132,9 +132,9 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
132
132
|
const blocksByCheckpoint = chunkBy(sortedBlocks, b => b.checkpointNumber);
|
|
133
133
|
|
|
134
134
|
// Get prior checkpoints in the epoch (in case this was a partial prune) to extract the out hashes
|
|
135
|
-
const priorCheckpointOutHashes = (await this.l2BlockSource.
|
|
136
|
-
.filter(c => c.
|
|
137
|
-
.map(c => c.
|
|
135
|
+
const priorCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsDataForEpoch(epochNumber))
|
|
136
|
+
.filter(c => c.checkpointNumber < sortedBlocks[0].checkpointNumber)
|
|
137
|
+
.map(c => c.checkpointOutHash);
|
|
138
138
|
let previousCheckpointOutHashes: Fr[] = [...priorCheckpointOutHashes];
|
|
139
139
|
|
|
140
140
|
const fork = await this.checkpointsBuilder.getFork(
|
|
@@ -172,6 +172,7 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
172
172
|
chainId: gv.chainId,
|
|
173
173
|
version: gv.version,
|
|
174
174
|
slotNumber: gv.slotNumber,
|
|
175
|
+
timestamp: gv.timestamp,
|
|
175
176
|
coinbase: gv.coinbase,
|
|
176
177
|
feeRecipient: gv.feeRecipient,
|
|
177
178
|
gasFees: gv.gasFees,
|
|
@@ -181,6 +182,7 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
181
182
|
const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(
|
|
182
183
|
checkpointNumber,
|
|
183
184
|
constants,
|
|
185
|
+
0n, // feeAssetPriceModifier is not used for validation of the checkpoint content
|
|
184
186
|
l1ToL2Messages,
|
|
185
187
|
previousCheckpointOutHashes,
|
|
186
188
|
fork,
|