@aztec/slasher 0.0.1-commit.a072138 → 0.0.1-commit.a5db02d
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 +90 -76
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +41 -29
- package/dest/factory/create_facade.d.ts +3 -3
- package/dest/factory/create_facade.d.ts.map +1 -1
- package/dest/factory/create_facade.js +25 -2
- package/dest/factory/create_implementation.d.ts +6 -7
- package/dest/factory/create_implementation.d.ts.map +1 -1
- package/dest/factory/create_implementation.js +8 -56
- 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 +8 -6
- package/dest/generated/slasher-defaults.d.ts.map +1 -1
- package/dest/generated/slasher-defaults.js +7 -5
- package/dest/index.d.ts +6 -4
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +5 -3
- package/dest/metrics.d.ts +7 -0
- package/dest/metrics.d.ts.map +1 -0
- package/dest/metrics.js +11 -0
- 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 +10 -9
- package/dest/slash_offenses_collector.d.ts.map +1 -1
- package/dest/slash_offenses_collector.js +50 -34
- package/dest/{tally_slasher_client.d.ts → slasher_client.d.ts} +17 -28
- package/dest/slasher_client.d.ts.map +1 -0
- package/dest/{tally_slasher_client.js → slasher_client.js} +50 -45
- package/dest/slasher_client_facade.d.ts +6 -8
- package/dest/slasher_client_facade.d.ts.map +1 -1
- package/dest/slasher_client_facade.js +6 -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 +12 -12
- package/dest/stores/offenses_store.d.ts.map +1 -1
- package/dest/stores/offenses_store.js +61 -38
- package/dest/watcher.d.ts +8 -1
- package/dest/watcher.d.ts.map +1 -1
- package/dest/watcher.js +1 -0
- package/dest/watchers/attestations_block_watcher.d.ts +26 -13
- package/dest/watchers/attestations_block_watcher.d.ts.map +1 -1
- package/dest/watchers/attestations_block_watcher.js +76 -61
- package/dest/watchers/attested_invalid_proposal_watcher.d.ts +42 -0
- package/dest/watchers/attested_invalid_proposal_watcher.d.ts.map +1 -0
- package/dest/watchers/attested_invalid_proposal_watcher.js +117 -0
- package/dest/watchers/broadcasted_invalid_checkpoint_proposal_watcher.d.ts +38 -0
- package/dest/watchers/broadcasted_invalid_checkpoint_proposal_watcher.d.ts.map +1 -0
- package/dest/watchers/broadcasted_invalid_checkpoint_proposal_watcher.js +138 -0
- package/dest/watchers/checkpoint_equivocation_watcher.d.ts +30 -0
- package/dest/watchers/checkpoint_equivocation_watcher.d.ts.map +1 -0
- package/dest/watchers/checkpoint_equivocation_watcher.js +69 -0
- package/dest/watchers/data_withholding_watcher.d.ts +63 -0
- package/dest/watchers/data_withholding_watcher.d.ts.map +1 -0
- package/dest/watchers/data_withholding_watcher.js +193 -0
- package/package.json +10 -10
- package/src/config.ts +48 -29
- package/src/factory/create_facade.ts +32 -4
- package/src/factory/create_implementation.ts +24 -105
- package/src/factory/get_settings.ts +8 -8
- package/src/factory/index.ts +1 -1
- package/src/generated/slasher-defaults.ts +7 -5
- package/src/index.ts +5 -3
- package/src/metrics.ts +19 -0
- package/src/null_slasher_client.ts +2 -6
- package/src/slash_offenses_collector.ts +70 -36
- package/src/{tally_slasher_client.ts → slasher_client.ts} +67 -54
- package/src/slasher_client_facade.ts +6 -11
- package/src/slasher_client_interface.ts +6 -21
- package/src/stores/offenses_store.ts +73 -47
- package/src/watcher.ts +8 -0
- package/src/watchers/attestations_block_watcher.ts +88 -82
- package/src/watchers/attested_invalid_proposal_watcher.ts +168 -0
- package/src/watchers/broadcasted_invalid_checkpoint_proposal_watcher.ts +192 -0
- package/src/watchers/checkpoint_equivocation_watcher.ts +96 -0
- package/src/watchers/data_withholding_watcher.ts +225 -0
- 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.map +0 -1
- package/dest/watchers/epoch_prune_watcher.d.ts +0 -38
- package/dest/watchers/epoch_prune_watcher.d.ts.map +0 -1
- package/dest/watchers/epoch_prune_watcher.js +0 -158
- package/src/empire_slasher_client.ts +0 -649
- package/src/stores/payloads_store.ts +0 -149
- package/src/watchers/epoch_prune_watcher.ts +0 -221
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RollupContract,
|
|
2
|
-
import type {
|
|
3
|
-
export declare function
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
1
|
+
import type { RollupContract, SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
2
|
+
import type { SlasherSettings } from '../slasher_client.js';
|
|
3
|
+
export declare function getSlasherSettings(rollup: RollupContract, slashingProposer?: SlashingProposerContract): Promise<Omit<SlasherSettings, 'rollupRegisteredAtL2Slot'>>;
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0X3NldHRpbmdzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmFjdG9yeS9nZXRfc2V0dGluZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFMUYsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFNUQsd0JBQXNCLGtCQUFrQixDQUN0QyxNQUFNLEVBQUUsY0FBYyxFQUN0QixnQkFBZ0IsQ0FBQyxFQUFFLHdCQUF3QixHQUMxQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSwwQkFBMEIsQ0FBQyxDQUFDLENBa0Q1RCJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_settings.d.ts","sourceRoot":"","sources":["../../src/factory/get_settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"get_settings.d.ts","sourceRoot":"","sources":["../../src/factory/get_settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAE1F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,gBAAgB,CAAC,EAAE,wBAAwB,GAC1C,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,0BAA0B,CAAC,CAAC,CAkD5D"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export async function
|
|
1
|
+
export async function getSlasherSettings(rollup, slashingProposer) {
|
|
2
2
|
if (!slashingProposer) {
|
|
3
3
|
const rollupSlashingProposer = await rollup.getSlashingProposer();
|
|
4
|
-
if (!rollupSlashingProposer
|
|
5
|
-
throw new Error('Rollup slashing proposer
|
|
4
|
+
if (!rollupSlashingProposer) {
|
|
5
|
+
throw new Error('Rollup slashing proposer not found');
|
|
6
6
|
}
|
|
7
7
|
slashingProposer = rollupSlashingProposer;
|
|
8
8
|
}
|
package/dest/factory/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { createSlasherFacade as createSlasher } from './create_facade.js';
|
|
2
|
-
export {
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
2
|
+
export { getSlasherSettings } from './get_settings.js';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9mYWN0b3J5L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxtQkFBbUIsSUFBSSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMxRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/factory/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/factory/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dest/factory/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { createSlasherFacade as createSlasher } from './create_facade.js';
|
|
2
|
-
export {
|
|
2
|
+
export { getSlasherSettings } from './get_settings.js';
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
/** Default slasher configuration values from network-defaults.yml */
|
|
2
2
|
export declare const slasherDefaultEnv: {
|
|
3
|
-
readonly SLASH_MIN_PENALTY_PERCENTAGE: 0.5;
|
|
4
|
-
readonly SLASH_MAX_PENALTY_PERCENTAGE: 2;
|
|
5
3
|
readonly SLASH_OFFENSE_EXPIRATION_ROUNDS: 4;
|
|
6
|
-
readonly SLASH_MAX_PAYLOAD_SIZE:
|
|
4
|
+
readonly SLASH_MAX_PAYLOAD_SIZE: 80;
|
|
7
5
|
readonly SLASH_EXECUTE_ROUNDS_LOOK_BACK: 4;
|
|
8
|
-
readonly SLASH_PRUNE_PENALTY: 10000000000000000000;
|
|
9
6
|
readonly SLASH_DATA_WITHHOLDING_PENALTY: 10000000000000000000;
|
|
7
|
+
readonly SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS: 3;
|
|
10
8
|
readonly SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9;
|
|
11
9
|
readonly SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 1;
|
|
12
10
|
readonly SLASH_INACTIVITY_PENALTY: 10000000000000000000;
|
|
13
11
|
readonly SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000;
|
|
14
|
-
readonly
|
|
12
|
+
readonly SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000;
|
|
13
|
+
readonly SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10000000000000000000;
|
|
14
|
+
readonly SLASH_DUPLICATE_PROPOSAL_PENALTY: 0;
|
|
15
|
+
readonly SLASH_DUPLICATE_ATTESTATION_PENALTY: 0;
|
|
15
16
|
readonly SLASH_UNKNOWN_PENALTY: 10000000000000000000;
|
|
16
17
|
readonly SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000;
|
|
18
|
+
readonly SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0;
|
|
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"}
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
// Auto-generated from spartan/environments/network-defaults.yml
|
|
2
2
|
// Do not edit manually - run yarn generate to regenerate
|
|
3
3
|
/** Default slasher configuration values from network-defaults.yml */ export const slasherDefaultEnv = {
|
|
4
|
-
SLASH_MIN_PENALTY_PERCENTAGE: 0.5,
|
|
5
|
-
SLASH_MAX_PENALTY_PERCENTAGE: 2,
|
|
6
4
|
SLASH_OFFENSE_EXPIRATION_ROUNDS: 4,
|
|
7
|
-
SLASH_MAX_PAYLOAD_SIZE:
|
|
5
|
+
SLASH_MAX_PAYLOAD_SIZE: 80,
|
|
8
6
|
SLASH_EXECUTE_ROUNDS_LOOK_BACK: 4,
|
|
9
|
-
SLASH_PRUNE_PENALTY: 10000000000000000000,
|
|
10
7
|
SLASH_DATA_WITHHOLDING_PENALTY: 10000000000000000000,
|
|
8
|
+
SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS: 3,
|
|
11
9
|
SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.9,
|
|
12
10
|
SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 1,
|
|
13
11
|
SLASH_INACTIVITY_PENALTY: 10000000000000000000,
|
|
14
12
|
SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000,
|
|
15
|
-
|
|
13
|
+
SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000,
|
|
14
|
+
SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10000000000000000000,
|
|
15
|
+
SLASH_DUPLICATE_PROPOSAL_PENALTY: 0,
|
|
16
|
+
SLASH_DUPLICATE_ATTESTATION_PENALTY: 0,
|
|
16
17
|
SLASH_UNKNOWN_PENALTY: 10000000000000000000,
|
|
17
18
|
SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000,
|
|
19
|
+
SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 0,
|
|
18
20
|
SLASH_GRACE_PERIOD_L2_SLOTS: 0
|
|
19
21
|
};
|
package/dest/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export * from './config.js';
|
|
2
|
-
export * from './watchers/
|
|
2
|
+
export * from './watchers/data_withholding_watcher.js';
|
|
3
3
|
export * from './watchers/attestations_block_watcher.js';
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
4
|
+
export * from './watchers/attested_invalid_proposal_watcher.js';
|
|
5
|
+
export * from './watchers/broadcasted_invalid_checkpoint_proposal_watcher.js';
|
|
6
|
+
export * from './watchers/checkpoint_equivocation_watcher.js';
|
|
7
|
+
export * from './slasher_client.js';
|
|
6
8
|
export * from './slash_offenses_collector.js';
|
|
7
9
|
export * from './slasher_client_interface.js';
|
|
8
10
|
export * from './factory/index.js';
|
|
9
11
|
export * from './watcher.js';
|
|
10
12
|
export * from '@aztec/stdlib/slashing';
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLHdDQUF3QyxDQUFDO0FBQ3ZELGNBQWMsMENBQTBDLENBQUM7QUFDekQsY0FBYyxpREFBaUQsQ0FBQztBQUNoRSxjQUFjLCtEQUErRCxDQUFDO0FBQzlFLGNBQWMsK0NBQStDLENBQUM7QUFDOUQsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsK0JBQStCLENBQUM7QUFDOUMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLHdCQUF3QixDQUFDIn0=
|
package/dest/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,iDAAiD,CAAC;AAChE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC"}
|
package/dest/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export * from './config.js';
|
|
2
|
-
export * from './watchers/
|
|
2
|
+
export * from './watchers/data_withholding_watcher.js';
|
|
3
3
|
export * from './watchers/attestations_block_watcher.js';
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
4
|
+
export * from './watchers/attested_invalid_proposal_watcher.js';
|
|
5
|
+
export * from './watchers/broadcasted_invalid_checkpoint_proposal_watcher.js';
|
|
6
|
+
export * from './watchers/checkpoint_equivocation_watcher.js';
|
|
7
|
+
export * from './slasher_client.js';
|
|
6
8
|
export * from './slash_offenses_collector.js';
|
|
7
9
|
export * from './slasher_client_interface.js';
|
|
8
10
|
export * from './factory/index.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
2
|
+
export declare class SlasherMetrics {
|
|
3
|
+
private readonly roundExecuted;
|
|
4
|
+
constructor(client: TelemetryClient, name?: string);
|
|
5
|
+
recordRoundExecuted(): void;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLEtBQUssZUFBZSxFQUdyQixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLHFCQUFhLGNBQWM7SUFDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQWdCO0lBRTlDLFlBQVksTUFBTSxFQUFFLGVBQWUsRUFBRSxJQUFJLFNBQVksRUFHcEQ7SUFFTSxtQkFBbUIsSUFBSSxJQUFJLENBRWpDO0NBQ0YifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EAGrB,MAAM,yBAAyB,CAAC;AAEjC,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAE9C,YAAY,MAAM,EAAE,eAAe,EAAE,IAAI,SAAY,EAGpD;IAEM,mBAAmB,IAAI,IAAI,CAEjC;CACF"}
|
package/dest/metrics.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Metrics, createUpDownCounterWithDefault } from '@aztec/telemetry-client';
|
|
2
|
+
export class SlasherMetrics {
|
|
3
|
+
roundExecuted;
|
|
4
|
+
constructor(client, name = 'Slasher'){
|
|
5
|
+
const meter = client.getMeter(name);
|
|
6
|
+
this.roundExecuted = createUpDownCounterWithDefault(meter, Metrics.SLASHER_ROUND_EXECUTED_COUNT);
|
|
7
|
+
}
|
|
8
|
+
recordRoundExecuted() {
|
|
9
|
+
this.roundExecuted.add(1);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
-
import type { Offense, ProposerSlashAction
|
|
2
|
+
import type { Offense, ProposerSlashAction } from '@aztec/stdlib/slashing';
|
|
3
3
|
import type { SlasherConfig } from './config.js';
|
|
4
4
|
import type { SlasherClientInterface } from './slasher_client_interface.js';
|
|
5
5
|
export declare class NullSlasherClient implements SlasherClientInterface {
|
|
@@ -7,11 +7,10 @@ export declare class NullSlasherClient implements SlasherClientInterface {
|
|
|
7
7
|
constructor(config: SlasherConfig);
|
|
8
8
|
start(): Promise<void>;
|
|
9
9
|
stop(): Promise<void>;
|
|
10
|
-
getSlashPayloads(): Promise<SlashPayloadRound[]>;
|
|
11
10
|
gatherOffensesForRound(_round?: bigint): Promise<Offense[]>;
|
|
12
|
-
|
|
11
|
+
getOffenses(): Promise<Offense[]>;
|
|
13
12
|
updateConfig(config: Partial<SlasherConfig>): void;
|
|
14
13
|
getProposerActions(_slotNumber: SlotNumber): Promise<ProposerSlashAction[]>;
|
|
15
14
|
getConfig(): SlasherConfig;
|
|
16
15
|
}
|
|
17
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVsbF9zbGFzaGVyX2NsaWVudC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL251bGxfc2xhc2hlcl9jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbEUsT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFM0UsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2pELE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFNUUscUJBQWEsaUJBQWtCLFlBQVcsc0JBQXNCO0lBQ2xELE9BQU8sQ0FBQyxNQUFNO0lBQTFCLFlBQW9CLE1BQU0sRUFBRSxhQUFhLEVBQUk7SUFFdEMsS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFNUI7SUFFTSxJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUUzQjtJQUVNLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FFakU7SUFFTSxXQUFXLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBRXZDO0lBRU0sWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUV4RDtJQUVNLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxVQUFVLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FFakY7SUFFTSxTQUFTLElBQUksYUFBYSxDQUVoQztDQUNGIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"null_slasher_client.d.ts","sourceRoot":"","sources":["../src/null_slasher_client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"null_slasher_client.d.ts","sourceRoot":"","sources":["../src/null_slasher_client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,qBAAa,iBAAkB,YAAW,sBAAsB;IAClD,OAAO,CAAC,MAAM;IAA1B,YAAoB,MAAM,EAAE,aAAa,EAAI;IAEtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5B;IAEM,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAEM,sBAAsB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAEjE;IAEM,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAEvC;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAExD;IAEM,kBAAkB,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAEjF;IAEM,SAAS,IAAI,aAAa,CAEhC;CACF"}
|
|
@@ -9,13 +9,10 @@ export class NullSlasherClient {
|
|
|
9
9
|
stop() {
|
|
10
10
|
return Promise.resolve();
|
|
11
11
|
}
|
|
12
|
-
getSlashPayloads() {
|
|
13
|
-
return Promise.resolve([]);
|
|
14
|
-
}
|
|
15
12
|
gatherOffensesForRound(_round) {
|
|
16
13
|
return Promise.resolve([]);
|
|
17
14
|
}
|
|
18
|
-
|
|
15
|
+
getOffenses() {
|
|
19
16
|
return Promise.resolve([]);
|
|
20
17
|
}
|
|
21
18
|
updateConfig(config) {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import type { Prettify } from '@aztec/foundation/types';
|
|
2
3
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
3
4
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
4
|
-
import { type OffenseIdentifier } from '@aztec/stdlib/slashing';
|
|
5
5
|
import type { SlasherOffensesStore } from './stores/offenses_store.js';
|
|
6
|
-
import { type WantToSlashArgs, type Watcher } from './watcher.js';
|
|
6
|
+
import { type WantToClearSlashArgs, type WantToSlashArgs, type Watcher } from './watcher.js';
|
|
7
7
|
export type SlashOffensesCollectorConfig = Prettify<Pick<SlasherConfig, 'slashGracePeriodL2Slots'>>;
|
|
8
8
|
export type SlashOffensesCollectorSettings = Prettify<Pick<L1RollupConstants, 'epochDuration'> & {
|
|
9
9
|
slashingAmounts: [bigint, bigint, bigint] | undefined;
|
|
10
|
+
/** L2 slot at which the rollup was registered as canonical in the Registry. Used to anchor the slash grace period. */
|
|
11
|
+
rollupRegisteredAtL2Slot: SlotNumber;
|
|
10
12
|
}>;
|
|
11
13
|
/**
|
|
12
14
|
* Collects and manages slashable offenses from watchers.
|
|
@@ -20,6 +22,7 @@ export declare class SlashOffensesCollector {
|
|
|
20
22
|
private readonly offensesStore;
|
|
21
23
|
private readonly log;
|
|
22
24
|
private readonly unwatchCallbacks;
|
|
25
|
+
private readonly storeMutationQueue;
|
|
23
26
|
constructor(config: SlashOffensesCollectorConfig, settings: SlashOffensesCollectorSettings, watchers: Watcher[], offensesStore: SlasherOffensesStore, log?: import("@aztec/foundation/log").Logger);
|
|
24
27
|
start(): Promise<void>;
|
|
25
28
|
stop(): Promise<void>;
|
|
@@ -29,17 +32,15 @@ export declare class SlashOffensesCollector {
|
|
|
29
32
|
* @param args - the arguments from the watcher, including the validators, amounts, and offenses
|
|
30
33
|
*/
|
|
31
34
|
handleWantToSlash(args: WantToSlashArgs[]): Promise<void>;
|
|
35
|
+
handleWantToClearSlash(args: WantToClearSlashArgs[]): Promise<void>;
|
|
32
36
|
/**
|
|
33
37
|
* Triggered on a time basis when we enter a new slashing round.
|
|
34
38
|
* Clears expired offenses from stores.
|
|
35
39
|
*/
|
|
36
40
|
handleNewRound(round: bigint): Promise<void>;
|
|
37
|
-
/**
|
|
38
|
-
* Marks offenses as slashed (no longer pending)
|
|
39
|
-
* @param offenses - The offenses to mark as slashed
|
|
40
|
-
*/
|
|
41
|
-
markAsSlashed(offenses: OffenseIdentifier[]): Promise<void>;
|
|
42
|
-
/** Returns whether to skip an offense if it happened during the grace period at the beginning of the chain */
|
|
41
|
+
/** Returns whether to skip an offense if it happened during the grace period after the network upgrade */
|
|
43
42
|
private shouldSkipOffense;
|
|
43
|
+
private getOffenseLogData;
|
|
44
|
+
private enqueueStoreMutation;
|
|
44
45
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
46
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hfb2ZmZW5zZXNfY29sbGVjdG9yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hfb2ZmZW5zZXNfY29sbGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBR2xFLE9BQU8sS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFHckUsT0FBTyxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN2RSxPQUFPLEVBR0wsS0FBSyxvQkFBb0IsRUFDekIsS0FBSyxlQUFlLEVBQ3BCLEtBQUssT0FBTyxFQUNiLE1BQU0sY0FBYyxDQUFDO0FBRXRCLE1BQU0sTUFBTSw0QkFBNEIsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDLENBQUM7QUFDcEcsTUFBTSxNQUFNLDhCQUE4QixHQUFHLFFBQVEsQ0FDbkQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLGVBQWUsQ0FBQyxHQUFHO0lBQ3pDLGVBQWUsRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDO0lBQ3RELHNIQUFzSDtJQUN0SCx3QkFBd0IsRUFBRSxVQUFVLENBQUM7Q0FDdEMsQ0FDRixDQUFDO0FBRUY7Ozs7R0FJRztBQUNILHFCQUFhLHNCQUFzQjtJQUsvQixPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07SUFDdkIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRO0lBQ3pCLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUTtJQUN6QixPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWE7SUFDOUIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHO0lBUnRCLE9BQU8sQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQXNCO0lBQ3ZELE9BQU8sQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQXFCO0lBRXhELFlBQ21CLE1BQU0sRUFBRSw0QkFBNEIsRUFDcEMsUUFBUSxFQUFFLDhCQUE4QixFQUN4QyxRQUFRLEVBQUUsT0FBTyxFQUFFLEVBQ25CLGFBQWEsRUFBRSxvQkFBb0IsRUFDbkMsR0FBRyx5Q0FBNkMsRUFDL0Q7SUFFRyxLQUFLLGtCQW1CWDtJQUVZLElBQUksa0JBVWhCO0lBRUQ7Ozs7T0FJRztJQUNVLGlCQUFpQixDQUFDLElBQUksRUFBRSxlQUFlLEVBQUUsaUJBK0JyRDtJQUVZLHNCQUFzQixDQUFDLElBQUksRUFBRSxvQkFBb0IsRUFBRSxpQkFXL0Q7SUFFRDs7O09BR0c7SUFDVSxjQUFjLENBQUMsS0FBSyxFQUFFLE1BQU0saUJBS3hDO0lBRUQsMEdBQTBHO0lBQzFHLE9BQU8sQ0FBQyxpQkFBaUI7SUFLekIsT0FBTyxDQUFDLGlCQUFpQjtJQVF6QixPQUFPLENBQUMsb0JBQW9CO0NBRzdCIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash_offenses_collector.d.ts","sourceRoot":"","sources":["../src/slash_offenses_collector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slash_offenses_collector.d.ts","sourceRoot":"","sources":["../src/slash_offenses_collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAGlE,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;AAGrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,OAAO,EACb,MAAM,cAAc,CAAC;AAEtB,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;IACzC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACtD,sHAAsH;IACtH,wBAAwB,EAAE,UAAU,CAAC;CACtC,CACF,CAAC;AAEF;;;;GAIG;AACH,qBAAa,sBAAsB;IAK/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;IARtB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IACvD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IAExD,YACmB,MAAM,EAAE,4BAA4B,EACpC,QAAQ,EAAE,8BAA8B,EACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,aAAa,EAAE,oBAAoB,EACnC,GAAG,yCAA6C,EAC/D;IAEG,KAAK,kBAmBX;IAEY,IAAI,kBAUhB;IAED;;;;OAIG;IACU,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,iBA+BrD;IAEY,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,EAAE,iBAW/D;IAED;;;OAGG;IACU,cAAc,CAAC,KAAK,EAAE,MAAM,iBAKxC;IAED,0GAA0G;IAC1G,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,oBAAoB;CAG7B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { SerialQueue } from '@aztec/foundation/queue';
|
|
3
|
+
import { getOffenseTypeName, getSlotForOffense } from '@aztec/stdlib/slashing';
|
|
4
|
+
import { WANT_TO_CLEAR_SLASH_EVENT, WANT_TO_SLASH_EVENT } from './watcher.js';
|
|
4
5
|
/**
|
|
5
6
|
* Collects and manages slashable offenses from watchers.
|
|
6
7
|
* This class handles the common logic for subscribing to slash watcher events,
|
|
@@ -12,6 +13,7 @@ import { WANT_TO_SLASH_EVENT } from './watcher.js';
|
|
|
12
13
|
offensesStore;
|
|
13
14
|
log;
|
|
14
15
|
unwatchCallbacks;
|
|
16
|
+
storeMutationQueue;
|
|
15
17
|
constructor(config, settings, watchers, offensesStore, log = createLogger('slasher:offenses-collector')){
|
|
16
18
|
this.config = config;
|
|
17
19
|
this.settings = settings;
|
|
@@ -19,25 +21,30 @@ import { WANT_TO_SLASH_EVENT } from './watcher.js';
|
|
|
19
21
|
this.offensesStore = offensesStore;
|
|
20
22
|
this.log = log;
|
|
21
23
|
this.unwatchCallbacks = [];
|
|
24
|
+
this.storeMutationQueue = new SerialQueue();
|
|
22
25
|
}
|
|
23
26
|
start() {
|
|
24
27
|
this.log.debug('Starting SlashOffensesCollector...');
|
|
25
|
-
|
|
28
|
+
this.storeMutationQueue.start();
|
|
29
|
+
// Subscribe to watcher slashing events.
|
|
26
30
|
for (const watcher of this.watchers){
|
|
27
|
-
const wantToSlashCallback = (args)=>
|
|
31
|
+
const wantToSlashCallback = (args)=>this.enqueueStoreMutation('wantToSlash', ()=>this.handleWantToSlash(args));
|
|
28
32
|
watcher.on(WANT_TO_SLASH_EVENT, wantToSlashCallback);
|
|
29
33
|
this.unwatchCallbacks.push(()=>watcher.removeListener(WANT_TO_SLASH_EVENT, wantToSlashCallback));
|
|
34
|
+
const wantToClearSlashCallback = (args)=>this.enqueueStoreMutation('wantToClearSlash', ()=>this.handleWantToClearSlash(args));
|
|
35
|
+
watcher.on(WANT_TO_CLEAR_SLASH_EVENT, wantToClearSlashCallback);
|
|
36
|
+
this.unwatchCallbacks.push(()=>watcher.removeListener(WANT_TO_CLEAR_SLASH_EVENT, wantToClearSlashCallback));
|
|
30
37
|
}
|
|
31
38
|
this.log.info('Started SlashOffensesCollector');
|
|
32
39
|
return Promise.resolve();
|
|
33
40
|
}
|
|
34
|
-
stop() {
|
|
41
|
+
async stop() {
|
|
35
42
|
this.log.debug('Stopping SlashOffensesCollector...');
|
|
36
43
|
for (const unwatchCallback of this.unwatchCallbacks){
|
|
37
44
|
unwatchCallback();
|
|
38
45
|
}
|
|
46
|
+
await this.storeMutationQueue.end();
|
|
39
47
|
this.log.info('SlashOffensesCollector stopped');
|
|
40
|
-
return Promise.resolve();
|
|
41
48
|
}
|
|
42
49
|
/**
|
|
43
50
|
* Called when a slash watcher emits WANT_TO_SLASH_EVENT.
|
|
@@ -45,32 +52,40 @@ import { WANT_TO_SLASH_EVENT } from './watcher.js';
|
|
|
45
52
|
* @param args - the arguments from the watcher, including the validators, amounts, and offenses
|
|
46
53
|
*/ async handleWantToSlash(args) {
|
|
47
54
|
for (const arg of args){
|
|
48
|
-
const
|
|
55
|
+
const offense = {
|
|
49
56
|
validator: arg.validator,
|
|
50
57
|
amount: arg.amount,
|
|
51
58
|
offenseType: arg.offenseType,
|
|
52
59
|
epochOrSlot: arg.epochOrSlot
|
|
53
60
|
};
|
|
54
|
-
if (this.shouldSkipOffense(
|
|
55
|
-
this.log.verbose('Skipping offense during grace period',
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (await this.offensesStore.hasOffense(pendingOffense)) {
|
|
59
|
-
this.log.debug('Skipping repeated offense', pendingOffense);
|
|
61
|
+
if (this.shouldSkipOffense(offense)) {
|
|
62
|
+
this.log.verbose('Skipping offense during grace period', this.getOffenseLogData(offense));
|
|
60
63
|
continue;
|
|
61
64
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (
|
|
65
|
-
this.
|
|
65
|
+
const added = await this.offensesStore.addOffense(offense);
|
|
66
|
+
if (added) {
|
|
67
|
+
if (this.settings.slashingAmounts) {
|
|
68
|
+
const minSlash = this.settings.slashingAmounts[0];
|
|
69
|
+
if (arg.amount < minSlash) {
|
|
70
|
+
this.log.warn(`Offense amount ${arg.amount} is below minimum slashing amount ${minSlash}`, this.getOffenseLogData(offense));
|
|
71
|
+
}
|
|
66
72
|
}
|
|
73
|
+
this.log.info(`Adding pending offense for validator ${arg.validator}`, this.getOffenseLogData(offense));
|
|
74
|
+
} else {
|
|
75
|
+
this.log.debug('Skipping repeated offense', this.getOffenseLogData(offense));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async handleWantToClearSlash(args) {
|
|
80
|
+
for (const arg of args){
|
|
81
|
+
const cleared = await this.offensesStore.clearOffenses(arg);
|
|
82
|
+
if (cleared > 0) {
|
|
83
|
+
this.log.info(`Cleared ${cleared} pending offenses`, {
|
|
84
|
+
offenseType: getOffenseTypeName(arg.offenseType),
|
|
85
|
+
epochOrSlot: arg.epochOrSlot,
|
|
86
|
+
validators: arg.validators?.map((validator)=>validator.toString())
|
|
87
|
+
});
|
|
67
88
|
}
|
|
68
|
-
this.log.info(`Adding pending offense for validator ${arg.validator}`, {
|
|
69
|
-
...pendingOffense,
|
|
70
|
-
epochOrSlot: pendingOffense.epochOrSlot.toString(),
|
|
71
|
-
amount: pendingOffense.amount.toString()
|
|
72
|
-
});
|
|
73
|
-
await this.offensesStore.addPendingOffense(pendingOffense);
|
|
74
89
|
}
|
|
75
90
|
}
|
|
76
91
|
/**
|
|
@@ -82,17 +97,18 @@ import { WANT_TO_SLASH_EVENT } from './watcher.js';
|
|
|
82
97
|
this.log.debug(`Cleared ${cleared} expired offenses for round ${round}`);
|
|
83
98
|
}
|
|
84
99
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Marks offenses as slashed (no longer pending)
|
|
87
|
-
* @param offenses - The offenses to mark as slashed
|
|
88
|
-
*/ markAsSlashed(offenses) {
|
|
89
|
-
this.log.verbose(`Marking offenses as slashed`, {
|
|
90
|
-
offenses
|
|
91
|
-
});
|
|
92
|
-
return this.offensesStore.markAsSlashed(offenses);
|
|
93
|
-
}
|
|
94
|
-
/** Returns whether to skip an offense if it happened during the grace period at the beginning of the chain */ shouldSkipOffense(offense) {
|
|
100
|
+
/** Returns whether to skip an offense if it happened during the grace period after the network upgrade */ shouldSkipOffense(offense) {
|
|
95
101
|
const offenseSlot = getSlotForOffense(offense, this.settings);
|
|
96
|
-
return offenseSlot < this.config.slashGracePeriodL2Slots;
|
|
102
|
+
return offenseSlot < this.settings.rollupRegisteredAtL2Slot + this.config.slashGracePeriodL2Slots;
|
|
103
|
+
}
|
|
104
|
+
getOffenseLogData(offense) {
|
|
105
|
+
return {
|
|
106
|
+
...offense,
|
|
107
|
+
validator: offense.validator.toString(),
|
|
108
|
+
offenseType: getOffenseTypeName(offense.offenseType)
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
enqueueStoreMutation(label, callback) {
|
|
112
|
+
void this.storeMutationQueue.put(callback).catch((err)=>this.log.error(`Error handling ${label}`, err));
|
|
97
113
|
}
|
|
98
114
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
-
import { RollupContract, SlasherContract,
|
|
2
|
+
import { RollupContract, SlasherContract, SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
3
3
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
4
4
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
5
5
|
import type { Prettify } from '@aztec/foundation/types';
|
|
6
6
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
|
-
import { type Offense, type ProposerSlashAction, type ProposerSlashActionProvider
|
|
7
|
+
import { type Offense, type ProposerSlashAction, type ProposerSlashActionProvider } from '@aztec/stdlib/slashing';
|
|
8
8
|
import type { Hex } from 'viem';
|
|
9
|
+
import { SlasherMetrics } from './metrics.js';
|
|
9
10
|
import { SlashOffensesCollector, type SlashOffensesCollectorConfig, type SlashOffensesCollectorSettings } from './slash_offenses_collector.js';
|
|
10
11
|
import { SlashRoundMonitor, type SlashRoundMonitorSettings } from './slash_round_monitor.js';
|
|
11
12
|
import type { SlasherClientInterface } from './slasher_client_interface.js';
|
|
12
13
|
import type { SlasherOffensesStore } from './stores/offenses_store.js';
|
|
13
14
|
import type { Watcher } from './watcher.js';
|
|
14
|
-
/** Settings used in the
|
|
15
|
-
export type
|
|
15
|
+
/** Settings used in the slasher client, loaded from the L1 contracts during initialization */
|
|
16
|
+
export type SlasherSettings = Prettify<SlashRoundMonitorSettings & SlashOffensesCollectorSettings & {
|
|
16
17
|
slashingLifetimeInRounds: number;
|
|
17
18
|
slashingExecutionDelayInRounds: number;
|
|
18
19
|
slashingRoundSizeInEpochs: number;
|
|
@@ -22,9 +23,9 @@ export type TallySlasherSettings = Prettify<SlashRoundMonitorSettings & SlashOff
|
|
|
22
23
|
/** Committee size for block proposal */
|
|
23
24
|
targetCommitteeSize: number;
|
|
24
25
|
}>;
|
|
25
|
-
export type
|
|
26
|
+
export type SlasherClientConfig = SlashOffensesCollectorConfig & Pick<SlasherConfig, 'slashValidatorsAlways' | 'slashValidatorsNever' | 'slashExecuteRoundsLookBack' | 'slashMaxPayloadSize'>;
|
|
26
27
|
/**
|
|
27
|
-
* The
|
|
28
|
+
* The Slasher client is responsible for managing slashable offenses using
|
|
28
29
|
* the consensus-based slashing model where proposers vote on individual validator offenses.
|
|
29
30
|
*
|
|
30
31
|
* The client subscribes to several slash watchers that emit offenses and tracks them. When the slasher is the
|
|
@@ -48,31 +49,24 @@ export type TallySlasherClientConfig = SlashOffensesCollectorConfig & Pick<Slash
|
|
|
48
49
|
* - Validators that reach the quorum threshold are slashed. A vote for slashing N units is also considered
|
|
49
50
|
* a vote for slashing N-1, N-2, ..., 1 units. The system slashes for the largest amount that reaches quorum.
|
|
50
51
|
* - The client monitors executable rounds and triggers execution when appropriate.
|
|
51
|
-
*
|
|
52
|
-
* Differences from Empire model
|
|
53
|
-
* - No fixed slash payloads - votes are for individual validator offenses encoded in bytes
|
|
54
|
-
* - The L1 contract determines which offenses reach quorum rather than nodes agreeing on a payload
|
|
55
|
-
* - Proposers vote directly on which validators to slash and by how much
|
|
56
|
-
* - Uses a slash offset to vote on validators from past rounds (e.g., round N votes on round N-2)
|
|
57
52
|
*/
|
|
58
|
-
export declare class
|
|
53
|
+
export declare class SlasherClient implements ProposerSlashActionProvider, SlasherClientInterface {
|
|
59
54
|
private config;
|
|
60
55
|
private settings;
|
|
61
|
-
private
|
|
56
|
+
private slashingProposer;
|
|
62
57
|
private slasher;
|
|
63
58
|
private rollup;
|
|
64
59
|
private epochCache;
|
|
65
60
|
private dateProvider;
|
|
66
61
|
private offensesStore;
|
|
67
62
|
private log;
|
|
63
|
+
private readonly metrics;
|
|
68
64
|
protected unwatchCallbacks: (() => void)[];
|
|
69
65
|
protected roundMonitor: SlashRoundMonitor;
|
|
70
66
|
protected offensesCollector: SlashOffensesCollector;
|
|
71
|
-
constructor(config:
|
|
67
|
+
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, metrics?: SlasherMetrics);
|
|
72
68
|
start(): Promise<void>;
|
|
73
|
-
/**
|
|
74
|
-
* Stop the tally slasher client
|
|
75
|
-
*/
|
|
69
|
+
/** Stop the slasher client */
|
|
76
70
|
stop(): Promise<void>;
|
|
77
71
|
/** Returns the current config */
|
|
78
72
|
getConfig(): SlasherConfig;
|
|
@@ -80,7 +74,7 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
|
|
|
80
74
|
updateConfig(config: Partial<SlasherConfig>): void;
|
|
81
75
|
/** Triggered on a time basis when we enter a new slashing round. Clears expired offenses. */
|
|
82
76
|
protected handleNewRound(round: bigint): Promise<void>;
|
|
83
|
-
/** Called when we see a RoundExecuted event on the
|
|
77
|
+
/** Called when we see a RoundExecuted event on the SlashingProposer (just for logging). */
|
|
84
78
|
protected handleRoundExecuted(round: bigint, slashCount: bigint, l1BlockHash: Hex): Promise<void>;
|
|
85
79
|
/**
|
|
86
80
|
* Get the actions the proposer should take for slashing
|
|
@@ -98,20 +92,15 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
|
|
|
98
92
|
protected getVoteOffensesAction(slotNumber: SlotNumber): Promise<ProposerSlashAction | undefined>;
|
|
99
93
|
/** Returns the committees that were active during the timespan of a given round */
|
|
100
94
|
private collectCommitteesActiveDuringRound;
|
|
101
|
-
/**
|
|
102
|
-
* Get slash payloads is NOT SUPPORTED in tally model
|
|
103
|
-
* @throws Error indicating this operation is not supported
|
|
104
|
-
*/
|
|
105
|
-
getSlashPayloads(): Promise<SlashPayloadRound[]>;
|
|
106
95
|
/**
|
|
107
96
|
* Gather offenses to be slashed on a given round.
|
|
108
|
-
*
|
|
97
|
+
* Round N slashes validators from round N - slashOffsetInRounds.
|
|
109
98
|
* @param round - The round to get offenses for, defaults to current round
|
|
110
99
|
* @returns Array of pending offenses for the round with offset applied
|
|
111
100
|
*/
|
|
112
101
|
gatherOffensesForRound(round?: bigint): Promise<Offense[]>;
|
|
113
|
-
/** Returns all
|
|
114
|
-
|
|
102
|
+
/** Returns all offenses stored */
|
|
103
|
+
getOffenses(): Promise<Offense[]>;
|
|
115
104
|
/**
|
|
116
105
|
* Returns the round to be slashed given the current round by applying the slash offset.
|
|
117
106
|
* During round N, we cannot slash the validators from the epochs of the same round, since the round is not over,
|
|
@@ -122,4 +111,4 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
|
|
|
122
111
|
*/
|
|
123
112
|
private getSlashedRound;
|
|
124
113
|
}
|
|
125
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
114
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hlcl9jbGllbnQuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zbGFzaGVyX2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXRHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUc3RCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsS0FBSyxPQUFPLEVBRVosS0FBSyxtQkFBbUIsRUFDeEIsS0FBSywyQkFBMkIsRUFJakMsTUFBTSx3QkFBd0IsQ0FBQztBQUdoQyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFaEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM5QyxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLEtBQUssNEJBQTRCLEVBQ2pDLEtBQUssOEJBQThCLEVBQ3BDLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLEtBQUsseUJBQXlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RixPQUFPLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzVFLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkUsT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTVDLDhGQUE4RjtBQUM5RixN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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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"}
|