@aztec/slasher 4.0.0-nightly.20250907 → 4.0.0-nightly.20260108

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.
Files changed (65) hide show
  1. package/README.md +60 -11
  2. package/dest/config.d.ts +1 -1
  3. package/dest/config.d.ts.map +1 -1
  4. package/dest/config.js +8 -2
  5. package/dest/empire_slasher_client.d.ts +8 -6
  6. package/dest/empire_slasher_client.d.ts.map +1 -1
  7. package/dest/empire_slasher_client.js +11 -5
  8. package/dest/factory/create_facade.d.ts +3 -2
  9. package/dest/factory/create_facade.d.ts.map +1 -1
  10. package/dest/factory/create_implementation.d.ts +3 -3
  11. package/dest/factory/create_implementation.d.ts.map +1 -1
  12. package/dest/factory/create_implementation.js +6 -4
  13. package/dest/factory/get_settings.d.ts +2 -2
  14. package/dest/factory/get_settings.d.ts.map +1 -1
  15. package/dest/factory/index.d.ts +1 -1
  16. package/dest/index.d.ts +1 -1
  17. package/dest/null_slasher_client.d.ts +3 -2
  18. package/dest/null_slasher_client.d.ts.map +1 -1
  19. package/dest/slash_offenses_collector.d.ts +1 -1
  20. package/dest/slash_offenses_collector.d.ts.map +1 -1
  21. package/dest/slash_offenses_collector.js +1 -2
  22. package/dest/slash_round_monitor.d.ts +5 -4
  23. package/dest/slash_round_monitor.d.ts.map +1 -1
  24. package/dest/slasher_client_facade.d.ts +4 -3
  25. package/dest/slasher_client_facade.d.ts.map +1 -1
  26. package/dest/slasher_client_facade.js +1 -0
  27. package/dest/slasher_client_interface.d.ts +3 -2
  28. package/dest/slasher_client_interface.d.ts.map +1 -1
  29. package/dest/stores/offenses_store.d.ts +1 -1
  30. package/dest/stores/offenses_store.d.ts.map +1 -1
  31. package/dest/stores/offenses_store.js +1 -1
  32. package/dest/stores/payloads_store.d.ts +2 -2
  33. package/dest/stores/payloads_store.d.ts.map +1 -1
  34. package/dest/stores/schema_version.d.ts +1 -1
  35. package/dest/tally_slasher_client.d.ts +14 -8
  36. package/dest/tally_slasher_client.d.ts.map +1 -1
  37. package/dest/tally_slasher_client.js +57 -12
  38. package/dest/test/dummy_watcher.d.ts +11 -0
  39. package/dest/test/dummy_watcher.d.ts.map +1 -0
  40. package/dest/test/dummy_watcher.js +14 -0
  41. package/dest/watcher.d.ts +3 -1
  42. package/dest/watcher.d.ts.map +1 -1
  43. package/dest/watchers/attestations_block_watcher.d.ts +6 -3
  44. package/dest/watchers/attestations_block_watcher.d.ts.map +1 -1
  45. package/dest/watchers/attestations_block_watcher.js +37 -22
  46. package/dest/watchers/epoch_prune_watcher.d.ts +8 -7
  47. package/dest/watchers/epoch_prune_watcher.d.ts.map +1 -1
  48. package/dest/watchers/epoch_prune_watcher.js +48 -37
  49. package/package.json +13 -12
  50. package/src/config.ts +8 -2
  51. package/src/empire_slasher_client.ts +15 -8
  52. package/src/factory/create_facade.ts +2 -1
  53. package/src/factory/create_implementation.ts +6 -1
  54. package/src/factory/get_settings.ts +1 -1
  55. package/src/null_slasher_client.ts +2 -1
  56. package/src/slash_offenses_collector.ts +1 -2
  57. package/src/slash_round_monitor.ts +3 -2
  58. package/src/slasher_client_facade.ts +4 -2
  59. package/src/slasher_client_interface.ts +2 -1
  60. package/src/stores/offenses_store.ts +1 -1
  61. package/src/tally_slasher_client.ts +80 -17
  62. package/src/test/dummy_watcher.ts +21 -0
  63. package/src/watcher.ts +4 -1
  64. package/src/watchers/attestations_block_watcher.ts +44 -26
  65. package/src/watchers/epoch_prune_watcher.ts +67 -55
@@ -1,4 +1,4 @@
1
- import { createLogger } from '@aztec/aztec.js';
1
+ import { createLogger } from '@aztec/aztec.js/log';
2
2
  import { deserializeOffense, getRoundForOffense, serializeOffense } from '@aztec/stdlib/slashing';
3
3
  export const SCHEMA_VERSION = 1;
4
4
  export class SlasherOffensesStore {
@@ -9,7 +9,7 @@ export declare class SlasherPayloadsStore {
9
9
  /** Map from `round:payload` to votes */
10
10
  private roundPayloadVotes;
11
11
  constructor(kvStore: AztecAsyncKVStore, settings?: {
12
- slashingPayloadLifetimeInRounds?: number;
12
+ slashingPayloadLifetimeInRounds?: number | undefined;
13
13
  } | undefined);
14
14
  getPayloadsForRound(round: bigint): Promise<SlashPayloadRound[]>;
15
15
  getPayloadAtRound(payloadAddress: EthAddress, round: bigint): Promise<SlashPayloadRound | undefined>;
@@ -26,4 +26,4 @@ export declare class SlasherPayloadsStore {
26
26
  getPayload(payloadAddress: EthAddress | string): Promise<SlashPayload | undefined>;
27
27
  hasPayload(payload: EthAddress): Promise<boolean>;
28
28
  }
29
- //# sourceMappingURL=payloads_store.d.ts.map
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bG9hZHNfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZXMvcGF5bG9hZHNfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sRUFDTCxLQUFLLFlBQVksRUFDakIsS0FBSyxpQkFBaUIsRUFHdkIsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxxQkFBYSxvQkFBb0I7SUFRN0IsT0FBTyxDQUFDLE9BQU87SUFDZixPQUFPLENBQUMsUUFBUSxDQUFDO0lBUm5CLCtDQUErQztJQUMvQyxPQUFPLENBQUMsUUFBUSxDQUFnQztJQUVoRCx3Q0FBd0M7SUFDeEMsT0FBTyxDQUFDLGlCQUFpQixDQUFnQztJQUV6RCxZQUNVLE9BQU8sRUFBRSxpQkFBaUIsRUFDMUIsUUFBUSxDQUFDOztpQkFFaEIsRUFJRjtJQUVZLG1CQUFtQixDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FVNUU7SUFFWSxpQkFBaUIsQ0FBQyxjQUFjLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxDQVdoSDtZQUVhLGdCQUFnQjtJQVk5QixPQUFPLENBQUMsV0FBVztJQUluQixPQUFPLENBQUMsa0JBQWtCO0lBSTFCLE9BQU8sQ0FBQywrQkFBK0I7SUFNdkM7O09BRUc7SUFDVSxvQkFBb0IsQ0FBQyxZQUFZLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FvQ3JFO0lBRVkscUJBQXFCLENBQUMsY0FBYyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FNN0Y7SUFFWSxVQUFVLENBQUMsT0FBTyxFQUFFLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FPakU7SUFFWSxVQUFVLENBQUMsY0FBYyxFQUFFLFVBQVUsR0FBRyxNQUFNLEdBQUcsT0FBTyxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUMsQ0FJOUY7SUFFWSxVQUFVLENBQUMsT0FBTyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBRzdEO0NBQ0YifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"payloads_store.d.ts","sourceRoot":"","sources":["../../src/stores/payloads_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAGvB,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,oBAAoB;IAQ7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ,CAAC;IARnB,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,wCAAwC;IACxC,OAAO,CAAC,iBAAiB,CAAgC;gBAG/C,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,CAAC,EAAE;QACjB,+BAA+B,CAAC,EAAE,MAAM,CAAC;KAC1C,YAAA;IAMU,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAYhE,iBAAiB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;YAanG,gBAAgB;IAY9B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,+BAA+B;IAMvC;;OAEG;IACU,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCzD,qBAAqB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQjF,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IASrD,UAAU,CAAC,cAAc,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAMlF,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;CAI/D"}
1
+ {"version":3,"file":"payloads_store.d.ts","sourceRoot":"","sources":["../../src/stores/payloads_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAGvB,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,oBAAoB;IAQ7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ,CAAC;IARnB,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,wCAAwC;IACxC,OAAO,CAAC,iBAAiB,CAAgC;IAEzD,YACU,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,CAAC;;iBAEhB,EAIF;IAEY,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAU5E;IAEY,iBAAiB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAWhH;YAEa,gBAAgB;IAY9B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,+BAA+B;IAMvC;;OAEG;IACU,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCrE;IAEY,qBAAqB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM7F;IAEY,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjE;IAEY,UAAU,CAAC,cAAc,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAI9F;IAEY,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7D;CACF"}
@@ -1,2 +1,2 @@
1
1
  export declare const SCHEMA_VERSION = 1;
2
- //# sourceMappingURL=schema_version.d.ts.map
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hX3ZlcnNpb24uZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZXMvc2NoZW1hX3ZlcnNpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZUFBTyxNQUFNLGNBQWMsSUFBSSxDQUFDIn0=
@@ -1,5 +1,6 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
- import { RollupContract, TallySlashingProposerContract } from '@aztec/ethereum/contracts';
2
+ import { RollupContract, SlasherContract, TallySlashingProposerContract } from '@aztec/ethereum/contracts';
3
+ import { SlotNumber } from '@aztec/foundation/branded-types';
3
4
  import type { DateProvider } from '@aztec/foundation/timer';
4
5
  import type { Prettify } from '@aztec/foundation/types';
5
6
  import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
@@ -21,7 +22,7 @@ export type TallySlasherSettings = Prettify<SlashRoundMonitorSettings & SlashOff
21
22
  /** Committee size for block proposal */
22
23
  targetCommitteeSize: number;
23
24
  }>;
24
- export type TallySlasherClientConfig = SlashOffensesCollectorConfig & Pick<SlasherConfig, 'slashValidatorsAlways' | 'slashValidatorsNever'>;
25
+ export type TallySlasherClientConfig = SlashOffensesCollectorConfig & Pick<SlasherConfig, 'slashValidatorsAlways' | 'slashValidatorsNever' | 'slashExecuteRoundsLookBack'>;
25
26
  /**
26
27
  * The Tally Slasher client is responsible for managing slashable offenses using
27
28
  * the consensus-based slashing model where proposers vote on individual validator offenses.
@@ -58,6 +59,7 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
58
59
  private config;
59
60
  private settings;
60
61
  private tallySlashingProposer;
62
+ private slasher;
61
63
  private rollup;
62
64
  private epochCache;
63
65
  private dateProvider;
@@ -66,7 +68,7 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
66
68
  protected unwatchCallbacks: (() => void)[];
67
69
  protected roundMonitor: SlashRoundMonitor;
68
70
  protected offensesCollector: SlashOffensesCollector;
69
- constructor(config: TallySlasherClientConfig, settings: TallySlasherSettings, tallySlashingProposer: TallySlashingProposerContract, rollup: RollupContract, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, offensesStore: SlasherOffensesStore, log?: import("@aztec/aztec.js").Logger);
71
+ constructor(config: TallySlasherClientConfig, settings: TallySlasherSettings, tallySlashingProposer: TallySlashingProposerContract, slasher: SlasherContract, rollup: RollupContract, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, offensesStore: SlasherOffensesStore, log?: import("@aztec/foundation/log").Logger);
70
72
  start(): Promise<void>;
71
73
  /**
72
74
  * Stop the tally slasher client
@@ -85,11 +87,15 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
85
87
  * @param slotNumber - The current slot number
86
88
  * @returns The actions to take
87
89
  */
88
- getProposerActions(slotNumber: bigint): Promise<ProposerSlashAction[]>;
89
- /** Returns an execute slash action if there are any rounds ready to be executed */
90
- protected getExecuteSlashAction(slotNumber: bigint): Promise<ProposerSlashAction | undefined>;
90
+ getProposerActions(slotNumber: SlotNumber): Promise<ProposerSlashAction[]>;
91
+ /**
92
+ * Returns an execute slash action if there are any rounds ready to be executed.
93
+ * Returns the oldest slash action if there are multiple rounds pending execution.
94
+ */
95
+ protected getExecuteSlashAction(slotNumber: SlotNumber): Promise<ProposerSlashAction | undefined>;
96
+ private tryGetRoundExecuteAction;
91
97
  /** Returns a vote action based on offenses from the target round (with offset applied) */
92
- protected getVoteOffensesAction(slotNumber: bigint): Promise<ProposerSlashAction | undefined>;
98
+ protected getVoteOffensesAction(slotNumber: SlotNumber): Promise<ProposerSlashAction | undefined>;
93
99
  /** Returns the committees that were active during the timespan of a given round */
94
100
  private collectCommitteesActiveDuringRound;
95
101
  /**
@@ -116,4 +122,4 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
116
122
  */
117
123
  private getSlashedRound;
118
124
  }
119
- //# sourceMappingURL=tally_slasher_client.d.ts.map
125
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFsbHlfc2xhc2hlcl9jbGllbnQuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90YWxseV9zbGFzaGVyX2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSw2QkFBNkIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUk3RCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsS0FBSyxPQUFPLEVBRVosS0FBSyxtQkFBbUIsRUFDeEIsS0FBSywyQkFBMkIsRUFDaEMsS0FBSyxpQkFBaUIsRUFHdkIsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFaEMsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixLQUFLLDRCQUE0QixFQUNqQyxLQUFLLDhCQUE4QixFQUNwQyxNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxLQUFLLHlCQUF5QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDN0YsT0FBTyxLQUFLLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM1RSxPQUFPLEtBQUssRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU1QyxvR0FBb0c7QUFDcEcsTUFBTSxNQUFNLG9C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
@@ -1 +1 @@
1
- {"version":3,"file":"tally_slasher_client.d.ts","sourceRoot":"","sources":["../src/tally_slasher_client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tally_slasher_client.d.ts","sourceRoot":"","sources":["../src/tally_slasher_client.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { EthAddress } from '@aztec/aztec.js';
1
+ import { EthAddress } from '@aztec/aztec.js/addresses';
2
+ import { maxBigint } from '@aztec/foundation/bigint';
2
3
  import { compactArray, partition, times } from '@aztec/foundation/collection';
3
4
  import { createLogger } from '@aztec/foundation/log';
4
5
  import { sleep } from '@aztec/foundation/sleep';
@@ -40,6 +41,7 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
40
41
  config;
41
42
  settings;
42
43
  tallySlashingProposer;
44
+ slasher;
43
45
  rollup;
44
46
  epochCache;
45
47
  dateProvider;
@@ -48,10 +50,11 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
48
50
  unwatchCallbacks;
49
51
  roundMonitor;
50
52
  offensesCollector;
51
- constructor(config, settings, tallySlashingProposer, rollup, watchers, epochCache, dateProvider, offensesStore, log = createLogger('slasher:consensus')){
53
+ constructor(config, settings, tallySlashingProposer, slasher, rollup, watchers, epochCache, dateProvider, offensesStore, log = createLogger('slasher:consensus')){
52
54
  this.config = config;
53
55
  this.settings = settings;
54
56
  this.tallySlashingProposer = tallySlashingProposer;
57
+ this.slasher = slasher;
55
58
  this.rollup = rollup;
56
59
  this.epochCache = epochCache;
57
60
  this.dateProvider = dateProvider;
@@ -118,18 +121,57 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
118
121
  voteAction
119
122
  ]);
120
123
  }
121
- /** Returns an execute slash action if there are any rounds ready to be executed */ async getExecuteSlashAction(slotNumber) {
124
+ /**
125
+ * Returns an execute slash action if there are any rounds ready to be executed.
126
+ * Returns the oldest slash action if there are multiple rounds pending execution.
127
+ */ async getExecuteSlashAction(slotNumber) {
122
128
  const { round: currentRound } = this.roundMonitor.getRoundForSlot(slotNumber);
123
129
  const slashingExecutionDelayInRounds = BigInt(this.settings.slashingExecutionDelayInRounds);
124
130
  const executableRound = currentRound - slashingExecutionDelayInRounds - 1n;
125
- if (executableRound < 0n) {
131
+ const lookBack = BigInt(this.config.slashExecuteRoundsLookBack);
132
+ const slashingLifetimeInRounds = BigInt(this.settings.slashingLifetimeInRounds);
133
+ // Compute the oldest executable round considering both lookBack and lifetimeInRounds
134
+ // A round is only executable if currentRound <= round + lifetimeInRounds
135
+ // So the oldest round we can execute is: currentRound - lifetimeInRounds
136
+ const oldestByLifetime = maxBigint(0n, currentRound - slashingLifetimeInRounds);
137
+ const oldestByLookBack = maxBigint(0n, executableRound - lookBack);
138
+ const oldestExecutableRound = maxBigint(oldestByLifetime, oldestByLookBack);
139
+ // Check if slashing is enabled at all
140
+ if (!await this.slasher.isSlashingEnabled()) {
141
+ this.log.warn(`Slashing is disabled in the Slasher contract (skipping execution)`);
126
142
  return undefined;
127
143
  }
128
- let logData = {
144
+ this.log.debug(`Checking slashing rounds ${oldestExecutableRound} to ${executableRound} to execute`, {
145
+ slotNumber,
129
146
  currentRound,
147
+ oldestExecutableRound,
148
+ oldestByLifetime,
149
+ oldestByLookBack,
150
+ executableRound,
151
+ slashingExecutionDelayInRounds,
152
+ lookBack,
153
+ slashingLifetimeInRounds
154
+ });
155
+ // Iterate over all rounds, starting from the oldest, until we find one that is executable
156
+ for(let roundToCheck = oldestExecutableRound; roundToCheck <= executableRound; roundToCheck++){
157
+ const action = await this.tryGetRoundExecuteAction(roundToCheck, slotNumber);
158
+ if (action) {
159
+ return action;
160
+ }
161
+ }
162
+ // And return nothing if none are found
163
+ return undefined;
164
+ }
165
+ /**
166
+ * Checks if a given round is executable and returns an execute-slash action for it if so.
167
+ * Assumes round number has already been checked against lifetime and execution delay.
168
+ * @param executableRound - The round to check for execution
169
+ */ async tryGetRoundExecuteAction(executableRound, slotNumber) {
170
+ let logData = {
130
171
  executableRound,
131
172
  slotNumber
132
173
  };
174
+ this.log.debug(`Testing if slashing round ${executableRound} is executable`, logData);
133
175
  try {
134
176
  const roundInfo = await this.tallySlashingProposer.getRound(executableRound);
135
177
  logData = {
@@ -139,9 +181,6 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
139
181
  if (roundInfo.isExecuted) {
140
182
  this.log.verbose(`Round ${executableRound} has already been executed`, logData);
141
183
  return undefined;
142
- } else if (!roundInfo.readyToExecute) {
143
- this.log.verbose(`Round ${executableRound} is not ready to execute yet`, logData);
144
- return undefined;
145
184
  } else if (roundInfo.voteCount === 0n) {
146
185
  this.log.debug(`Round ${executableRound} received no votes`, logData);
147
186
  return undefined;
@@ -149,6 +188,13 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
149
188
  this.log.verbose(`Round ${executableRound} does not have enough votes to execute`, logData);
150
189
  return undefined;
151
190
  }
191
+ // Check if round is ready to execute at the given slot
192
+ const isReadyToExecute = await this.tallySlashingProposer.isRoundReadyToExecute(executableRound, slotNumber);
193
+ if (!isReadyToExecute) {
194
+ this.log.warn(`Round ${executableRound} is not ready to execute at slot ${slotNumber} according to contract check`, logData);
195
+ return undefined;
196
+ }
197
+ // Check if the round yields any slashing at all
152
198
  const { actions: slashActions, committees } = await this.tallySlashingProposer.getTally(executableRound);
153
199
  if (slashActions.length === 0) {
154
200
  this.log.verbose(`Round ${executableRound} does not resolve in any slashing`, logData);
@@ -156,8 +202,7 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
156
202
  }
157
203
  // Check if the slash payload is vetoed
158
204
  const payload = await this.tallySlashingProposer.getPayload(executableRound);
159
- const slasherContract = await this.rollup.getSlasherContract();
160
- const isVetoed = await slasherContract.isPayloadVetoed(payload.address);
205
+ const isVetoed = await this.slasher.isPayloadVetoed(payload.address);
161
206
  if (isVetoed) {
162
207
  this.log.warn(`Round ${executableRound} payload is vetoed (skipping execution)`, {
163
208
  payloadAddress: payload.address.toString(),
@@ -183,8 +228,8 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
183
228
  };
184
229
  } catch (error) {
185
230
  this.log.error(`Error checking round to execute ${executableRound}`, error);
231
+ return undefined;
186
232
  }
187
- return undefined;
188
233
  }
189
234
  /** Returns a vote action based on offenses from the target round (with offset applied) */ async getVoteOffensesAction(slotNumber) {
190
235
  // Compute what round we are in based on the slot number and what round will be slashed
@@ -239,7 +284,7 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
239
284
  });
240
285
  const committees = await this.collectCommitteesActiveDuringRound(slashedRound);
241
286
  const epochsForCommittees = getEpochsForRound(slashedRound, this.settings);
242
- const votes = getSlashConsensusVotesFromOffenses(offensesToSlash, committees, epochsForCommittees, this.settings);
287
+ const votes = getSlashConsensusVotesFromOffenses(offensesToSlash, committees, epochsForCommittees.map((e)=>BigInt(e)), this.settings);
243
288
  if (votes.every((v)=>v === 0)) {
244
289
  this.log.warn(`Computed votes for offenses are all zero. Skipping vote.`, {
245
290
  slotNumber,
@@ -0,0 +1,11 @@
1
+ import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
2
+ import { type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js';
3
+ declare const DummyWatcher_base: new () => WatcherEmitter;
4
+ export declare class DummyWatcher extends DummyWatcher_base implements Watcher {
5
+ updateConfig(_config: Partial<SlasherConfig>): void;
6
+ start(): Promise<void>;
7
+ stop(): Promise<void>;
8
+ triggerSlash(args: WantToSlashArgs[]): void;
9
+ }
10
+ export {};
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHVtbXlfd2F0Y2hlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QvZHVtbXlfd2F0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUlyRSxPQUFPLEVBQXVCLEtBQUssZUFBZSxFQUFFLEtBQUssT0FBTyxFQUFFLEtBQUssY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUU3RyxxQkFBYSxZQUFhLFNBQVEsaUJBQTJDLFlBQVcsT0FBTztJQUN0RixZQUFZLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsUUFBSTtJQUVoRCxLQUFLLGtCQUVYO0lBRU0sSUFBSSxrQkFFVjtJQUVNLFlBQVksQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFLFFBRTFDO0NBQ0YifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dummy_watcher.d.ts","sourceRoot":"","sources":["../../src/test/dummy_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAIrE,OAAO,EAAuB,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;;AAE7G,qBAAa,YAAa,SAAQ,iBAA2C,YAAW,OAAO;IACtF,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,QAAI;IAEhD,KAAK,kBAEX;IAEM,IAAI,kBAEV;IAEM,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,QAE1C;CACF"}
@@ -0,0 +1,14 @@
1
+ import EventEmitter from 'node:events';
2
+ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
3
+ export class DummyWatcher extends EventEmitter {
4
+ updateConfig(_config) {}
5
+ start() {
6
+ return Promise.resolve();
7
+ }
8
+ stop() {
9
+ return Promise.resolve();
10
+ }
11
+ triggerSlash(args) {
12
+ this.emit(WANT_TO_SLASH_EVENT, args);
13
+ }
14
+ }
package/dest/watcher.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { EthAddress } from '@aztec/foundation/eth-address';
2
2
  import type { TypedEventEmitter } from '@aztec/foundation/types';
3
3
  import { OffenseType } from '@aztec/stdlib/slashing';
4
+ import type { SlasherConfig } from './config.js';
4
5
  export declare const WANT_TO_SLASH_EVENT: "want-to-slash";
5
6
  export interface WantToSlashArgs {
6
7
  validator: EthAddress;
@@ -15,5 +16,6 @@ export type WatcherEmitter = TypedEventEmitter<WatcherEventMap>;
15
16
  export type Watcher = WatcherEmitter & {
16
17
  start?: () => Promise<void>;
17
18
  stop?: () => Promise<void>;
19
+ updateConfig: (config: Partial<SlasherConfig>) => void;
18
20
  };
19
- //# sourceMappingURL=watcher.d.ts.map
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0Y2hlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dhdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXJELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVqRCxlQUFPLE1BQU0sbUJBQW1CLGlCQUEyQixDQUFDO0FBRTVELE1BQU0sV0FBVyxlQUFlO0lBQzlCLFNBQVMsRUFBRSxVQUFVLENBQUM7SUFDdEIsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLFdBQVcsRUFBRSxXQUFXLENBQUM7SUFDekIsV0FBVyxFQUFFLE1BQU0sQ0FBQztDQUNyQjtBQUdELE1BQU0sV0FBVyxlQUFlO0lBQzlCLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxlQUFlLEVBQUUsS0FBSyxJQUFJLENBQUM7Q0FDMUQ7QUFFRCxNQUFNLE1BQU0sY0FBYyxHQUFHLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBRWhFLE1BQU0sTUFBTSxPQUFPLEdBQUcsY0FBYyxHQUFHO0lBQ3JDLEtBQUssQ0FBQyxFQUFFLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLElBQUksQ0FBQyxFQUFFLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNCLFlBQVksRUFBRSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssSUFBSSxDQUFDO0NBQ3hELENBQUMifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,eAAO,MAAM,mBAAmB,EAAG,eAAwB,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,UAAU,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,eAAe;IAC9B,CAAC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAEhE,MAAM,MAAM,OAAO,GAAG,cAAc,GAAG;IACrC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC"}
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,mBAAmB,iBAA2B,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,UAAU,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,eAAe;IAC9B,CAAC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAEhE,MAAM,MAAM,OAAO,GAAG,cAAc,GAAG;IACrC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC;CACxD,CAAC"}
@@ -2,6 +2,8 @@ import { EpochCache } from '@aztec/epoch-cache';
2
2
  import { type L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
3
3
  import type { SlasherConfig } from '../config.js';
4
4
  import { type Watcher, type WatcherEmitter } from '../watcher.js';
5
+ declare const AttestationsBlockWatcherConfigKeys: readonly ["slashAttestDescendantOfInvalidPenalty", "slashProposeInvalidAttestationsPenalty"];
6
+ type AttestationsBlockWatcherConfig = Pick<SlasherConfig, (typeof AttestationsBlockWatcherConfigKeys)[number]>;
5
7
  declare const AttestationsBlockWatcher_base: new () => WatcherEmitter;
6
8
  /**
7
9
  * This watcher is responsible for detecting invalid blocks and creating slashing arguments for offenders.
@@ -12,12 +14,13 @@ declare const AttestationsBlockWatcher_base: new () => WatcherEmitter;
12
14
  export declare class AttestationsBlockWatcher extends AttestationsBlockWatcher_base implements Watcher {
13
15
  private l2BlockSource;
14
16
  private epochCache;
15
- private config;
16
17
  private log;
17
18
  private maxInvalidBlocks;
18
19
  private invalidArchiveRoots;
20
+ private config;
19
21
  private boundHandleInvalidBlock;
20
- constructor(l2BlockSource: L2BlockSourceEventEmitter, epochCache: EpochCache, config: Pick<SlasherConfig, 'slashAttestDescendantOfInvalidPenalty' | 'slashProposeInvalidAttestationsPenalty'>);
22
+ constructor(l2BlockSource: L2BlockSourceEventEmitter, epochCache: EpochCache, config: AttestationsBlockWatcherConfig);
23
+ updateConfig(newConfig: Partial<AttestationsBlockWatcherConfig>): void;
21
24
  start(): Promise<void>;
22
25
  stop(): Promise<void>;
23
26
  private handleInvalidBlock;
@@ -27,4 +30,4 @@ export declare class AttestationsBlockWatcher extends AttestationsBlockWatcher_b
27
30
  private addInvalidBlock;
28
31
  }
29
32
  export {};
30
- //# sourceMappingURL=attestations_block_watcher.d.ts.map
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZXN0YXRpb25zX2Jsb2NrX3dhdGNoZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93YXRjaGVycy9hdHRlc3RhdGlvbnNfYmxvY2tfd2F0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFJaEQsT0FBTyxFQUdMLEtBQUsseUJBQXlCLEVBRy9CLE1BQU0scUJBQXFCLENBQUM7QUFLN0IsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ2xELE9BQU8sRUFBNkMsS0FBSyxPQUFPLEVBQUUsS0FBSyxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFN0csUUFBQSxNQUFNLGtDQUFrQyw4RkFHOUIsQ0FBQztBQUVYLEtBQUssOEJBQThCLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLE9BQU8sa0NBQWtDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDOztBQUUvRzs7Ozs7R0FLRztBQUNILHFCQUFhLHdCQUF5QixTQUFRLDZCQUEyQyxZQUFXLE9BQU87SUF1QnZHLE9BQU8sQ0FBQyxhQUFhO0lBQ3JCLE9BQU8sQ0FBQyxVQUFVO0lBdkJwQixPQUFPLENBQUMsR0FBRyxDQUFzRDtJQUdqRSxPQUFPLENBQUMsZ0JBQWdCLENBQU87SUFHL0IsT0FBTyxDQUFDLG1CQUFtQixDQUEwQjtJQUVyRCxPQUFPLENBQUMsTUFBTSxDQUFpQztJQUUvQyxPQUFPLENBQUMsdUJBQXVCLENBUzdCO0lBRUYsWUFDVSxhQUFhLEVBQUUseUJBQXlCLEVBQ3hDLFVBQVUsRUFBRSxVQUFVLEVBQzlCLE1BQU0sRUFBRSw4QkFBOEIsRUFLdkM7SUFFTSxZQUFZLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyw4QkFBOEIsQ0FBQyxRQUdyRTtJQUVNLEtBQUssa0JBR1g7SUFFTSxJQUFJLGtCQU1WO0lBRUQsT0FBTyxDQUFDLGtCQUFrQjtJQXlCMUIsT0FBTyxDQUFDLCtCQUErQjtJQXdCdkMsT0FBTyxDQUFDLGFBQWE7SUFpQ3JCLE9BQU8sQ0FBQyxnQ0FBZ0M7SUFheEMsT0FBTyxDQUFDLGVBQWU7Q0FTeEIifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"attestations_block_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/attestations_block_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAEL,KAAK,yBAAyB,EAI/B,MAAM,qBAAqB,CAAC;AAK7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;6CAQ9C,UAAU,cAAc;AANvF;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,6BAA2C,YAAW,OAAO;IAsBvG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IAvBhB,OAAO,CAAC,GAAG,CAAsD;IAGjE,OAAO,CAAC,gBAAgB,CAAO;IAG/B,OAAO,CAAC,mBAAmB,CAA0B;IAErD,OAAO,CAAC,uBAAuB,CAU7B;gBAGQ,aAAa,EAAE,yBAAyB,EACxC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,IAAI,CAClB,aAAa,EACb,uCAAuC,GAAG,wCAAwC,CACnF;IAMI,KAAK;IAKL,IAAI;IAQX,OAAO,CAAC,kBAAkB;IAyB1B,OAAO,CAAC,+BAA+B;IAwBvC,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,gCAAgC;IAaxC,OAAO,CAAC,eAAe;CASxB"}
1
+ {"version":3,"file":"attestations_block_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/attestations_block_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIhD,OAAO,EAGL,KAAK,yBAAyB,EAG/B,MAAM,qBAAqB,CAAC;AAK7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7G,QAAA,MAAM,kCAAkC,8FAG9B,CAAC;AAEX,KAAK,8BAA8B,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,kCAAkC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;;AAE/G;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,6BAA2C,YAAW,OAAO;IAuBvG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,UAAU;IAvBpB,OAAO,CAAC,GAAG,CAAsD;IAGjE,OAAO,CAAC,gBAAgB,CAAO;IAG/B,OAAO,CAAC,mBAAmB,CAA0B;IAErD,OAAO,CAAC,MAAM,CAAiC;IAE/C,OAAO,CAAC,uBAAuB,CAS7B;IAEF,YACU,aAAa,EAAE,yBAAyB,EACxC,UAAU,EAAE,UAAU,EAC9B,MAAM,EAAE,8BAA8B,EAKvC;IAEM,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,8BAA8B,CAAC,QAGrE;IAEM,KAAK,kBAGX;IAEM,IAAI,kBAMV;IAED,OAAO,CAAC,kBAAkB;IAyB1B,OAAO,CAAC,+BAA+B;IAwBvC,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,gCAAgC;IAaxC,OAAO,CAAC,eAAe;CASxB"}
@@ -1,8 +1,14 @@
1
+ import { SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { merge, pick } from '@aztec/foundation/collection';
1
3
  import { createLogger } from '@aztec/foundation/log';
2
4
  import { L2BlockSourceEvents } from '@aztec/stdlib/block';
3
5
  import { OffenseType } from '@aztec/stdlib/slashing';
4
6
  import EventEmitter from 'node:events';
5
7
  import { WANT_TO_SLASH_EVENT } from '../watcher.js';
8
+ const AttestationsBlockWatcherConfigKeys = [
9
+ 'slashAttestDescendantOfInvalidPenalty',
10
+ 'slashProposeInvalidAttestationsPenalty'
11
+ ];
6
12
  /**
7
13
  * This watcher is responsible for detecting invalid blocks and creating slashing arguments for offenders.
8
14
  * An invalid block is one that doesn't have enough attestations or has incorrect attestations.
@@ -11,26 +17,30 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
11
17
  */ export class AttestationsBlockWatcher extends EventEmitter {
12
18
  l2BlockSource;
13
19
  epochCache;
14
- config;
15
20
  log;
16
21
  // Only keep track of the last N invalid blocks
17
22
  maxInvalidBlocks;
18
23
  // All invalid archive roots seen
19
24
  invalidArchiveRoots;
25
+ config;
20
26
  boundHandleInvalidBlock;
21
27
  constructor(l2BlockSource, epochCache, config){
22
- super(), this.l2BlockSource = l2BlockSource, this.epochCache = epochCache, this.config = config, this.log = createLogger('attestations-block-watcher'), this.maxInvalidBlocks = 100, this.invalidArchiveRoots = new Set(), this.boundHandleInvalidBlock = (event)=>{
28
+ super(), this.l2BlockSource = l2BlockSource, this.epochCache = epochCache, this.log = createLogger('attestations-block-watcher'), this.maxInvalidBlocks = 100, this.invalidArchiveRoots = new Set(), this.boundHandleInvalidBlock = (event)=>{
23
29
  try {
24
30
  this.handleInvalidBlock(event);
25
31
  } catch (err) {
26
32
  this.log.error('Error handling invalid block', err, {
27
- ...event.validationResult.block.block.toBlockInfo(),
28
- ...event.validationResult.block.l1,
33
+ ...event.validationResult,
29
34
  reason: event.validationResult.reason
30
35
  });
31
36
  }
32
37
  };
33
- this.log.info('InvalidBlockWatcher initialized');
38
+ this.config = pick(config, ...AttestationsBlockWatcherConfigKeys);
39
+ this.log.info('AttestationsBlockWatcher initialized');
40
+ }
41
+ updateConfig(newConfig) {
42
+ this.config = merge(this.config, pick(newConfig, ...AttestationsBlockWatcherConfigKeys));
43
+ this.log.verbose('AttestationsBlockWatcher config updated', this.config);
34
44
  }
35
45
  start() {
36
46
  this.l2BlockSource.on(L2BlockSourceEvents.InvalidAttestationsBlockDetected, this.boundHandleInvalidBlock);
@@ -42,14 +52,14 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
42
52
  }
43
53
  handleInvalidBlock(event) {
44
54
  const { validationResult } = event;
45
- const block = validationResult.block.block;
55
+ const block = validationResult.block;
46
56
  // Check if we already have processed this block, archiver may emit the same event multiple times
47
- if (this.invalidArchiveRoots.has(block.archive.root.toString())) {
48
- this.log.trace(`Already processed invalid block ${block.number}`);
57
+ if (this.invalidArchiveRoots.has(block.archive.toString())) {
58
+ this.log.trace(`Already processed invalid block ${block.blockNumber}`);
49
59
  return;
50
60
  }
51
- this.log.verbose(`Detected invalid block ${block.number}`, {
52
- ...block.toBlockInfo(),
61
+ this.log.verbose(`Detected invalid block ${block.blockNumber}`, {
62
+ ...block,
53
63
  reason: validationResult.valid === false ? validationResult.reason : 'unknown'
54
64
  });
55
65
  // Store the invalid block
@@ -61,11 +71,11 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
61
71
  }
62
72
  slashAttestorsOnAncestorInvalid(validationResult) {
63
73
  const block = validationResult.block;
64
- const parentArchive = block.block.header.lastArchive.root.toString();
65
- if (this.invalidArchiveRoots.has(block.block.header.lastArchive.root.toString())) {
66
- const attestors = validationResult.attestations.map((a)=>a.getSender());
67
- this.log.info(`Want to slash attestors of block ${block.block.number} built on invalid block`, {
68
- ...block.block.toBlockInfo(),
74
+ const parentArchive = block.lastArchive.toString();
75
+ if (this.invalidArchiveRoots.has(parentArchive)) {
76
+ const attestors = validationResult.attestors;
77
+ this.log.info(`Want to slash attestors of block ${block.blockNumber} built on invalid block`, {
78
+ ...block,
69
79
  ...attestors,
70
80
  parentArchive
71
81
  });
@@ -73,15 +83,20 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
73
83
  validator: attestor,
74
84
  amount: this.config.slashAttestDescendantOfInvalidPenalty,
75
85
  offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID,
76
- epochOrSlot: block.block.slot
86
+ epochOrSlot: BigInt(SlotNumber(block.slotNumber))
77
87
  })));
78
88
  }
79
89
  }
80
90
  slashProposer(validationResult) {
81
91
  const { reason, block } = validationResult;
82
- const blockNumber = block.block.number;
83
- const slot = block.block.header.getSlot();
84
- const proposer = this.epochCache.getProposerFromEpochCommittee(validationResult, slot);
92
+ const blockNumber = block.blockNumber;
93
+ const slot = block.slotNumber;
94
+ const epochCommitteeInfo = {
95
+ committee: validationResult.committee,
96
+ seed: validationResult.seed,
97
+ epoch: validationResult.epoch
98
+ };
99
+ const proposer = this.epochCache.getProposerFromEpochCommittee(epochCommitteeInfo, slot);
85
100
  if (!proposer) {
86
101
  this.log.warn(`No proposer found for block ${blockNumber} at slot ${slot}`);
87
102
  return;
@@ -92,10 +107,10 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
92
107
  validator: proposer,
93
108
  amount,
94
109
  offenseType: offense,
95
- epochOrSlot: block.block.slot
110
+ epochOrSlot: BigInt(slot)
96
111
  };
97
112
  this.log.info(`Want to slash proposer of block ${blockNumber} due to ${reason}`, {
98
- ...block.block.toBlockInfo(),
113
+ ...block,
99
114
  ...args
100
115
  });
101
116
  this.emit(WANT_TO_SLASH_EVENT, [
@@ -116,7 +131,7 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
116
131
  }
117
132
  }
118
133
  addInvalidBlock(block) {
119
- this.invalidArchiveRoots.add(block.block.archive.root.toString());
134
+ this.invalidArchiveRoots.add(block.archive.toString());
120
135
  // Prune old entries if we exceed the maximum
121
136
  if (this.invalidArchiveRoots.size > this.maxInvalidBlocks) {
122
137
  const oldestKey = this.invalidArchiveRoots.keys().next().value;
@@ -1,12 +1,10 @@
1
1
  import { EpochCache } from '@aztec/epoch-cache';
2
2
  import { L2Block, type L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
3
- import type { IFullNodeBlockBuilder, ITxProvider, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
3
+ import type { IFullNodeBlockBuilder, ITxProvider, MerkleTreeWriteOperations, SlasherConfig } from '@aztec/stdlib/interfaces/server';
4
4
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
5
5
  import { type Watcher, type WatcherEmitter } from '../watcher.js';
6
- type EpochPruneWatcherPenalties = {
7
- slashPrunePenalty: bigint;
8
- slashDataWithholdingPenalty: bigint;
9
- };
6
+ declare const EpochPruneWatcherPenaltiesConfigKeys: readonly ["slashPrunePenalty", "slashDataWithholdingPenalty"];
7
+ type EpochPruneWatcherPenalties = Pick<SlasherConfig, (typeof EpochPruneWatcherPenaltiesConfigKeys)[number]>;
10
8
  declare const EpochPruneWatcher_base: new () => WatcherEmitter;
11
9
  /**
12
10
  * This watcher is responsible for detecting chain prunes and creating slashing arguments for the committee.
@@ -20,17 +18,20 @@ export declare class EpochPruneWatcher extends EpochPruneWatcher_base implements
20
18
  private epochCache;
21
19
  private txProvider;
22
20
  private blockBuilder;
23
- private penalties;
24
21
  private log;
25
22
  private boundHandlePruneL2Blocks;
23
+ private penalties;
26
24
  constructor(l2BlockSource: L2BlockSourceEventEmitter, l1ToL2MessageSource: L1ToL2MessageSource, epochCache: EpochCache, txProvider: Pick<ITxProvider, 'getAvailableTxs'>, blockBuilder: IFullNodeBlockBuilder, penalties: EpochPruneWatcherPenalties);
27
25
  start(): Promise<void>;
28
26
  stop(): Promise<void>;
27
+ updateConfig(config: Partial<SlasherConfig>): void;
29
28
  private handlePruneL2Blocks;
29
+ private emitSlashForEpoch;
30
+ private processPruneL2Blocks;
30
31
  validateBlocks(blocks: L2Block[]): Promise<void>;
31
32
  validateBlock(blockFromL1: L2Block, fork: MerkleTreeWriteOperations): Promise<void>;
32
33
  private getValidatorsForEpoch;
33
34
  private validatorsToSlashingArgs;
34
35
  }
35
36
  export {};
36
- //# sourceMappingURL=epoch_prune_watcher.d.ts.map
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfcHJ1bmVfd2F0Y2hlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dhdGNoZXJzL2Vwb2NoX3BydW5lX3dhdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBSWhELE9BQU8sRUFFTCxPQUFPLEVBRVAsS0FBSyx5QkFBeUIsRUFFL0IsTUFBTSxxQkFBcUIsQ0FBQztBQUU3QixPQUFPLEtBQUssRUFDVixxQkFBcUIsRUFDckIsV0FBVyxFQUNYLHlCQUF5QixFQUN6QixhQUFhLEVBQ2QsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBV25FLE9BQU8sRUFBNkMsS0FBSyxPQUFPLEVBQUUsS0FBSyxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFN0csUUFBQSxNQUFNLG9DQUFvQywrREFBZ0UsQ0FBQztBQUUzRyxLQUFLLDBCQUEwQixHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxPQUFPLG9DQUFvQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzs7QUFFN0c7Ozs7O0dBS0c7QUFDSCxxQkFBYSxpQkFBa0IsU0FBUSxzQkFBMkMsWUFBVyxPQUFPO0lBU2hHLE9BQU8sQ0FBQyxhQUFhO0lBQ3JCLE9BQU8sQ0FBQyxtQkFBbUI7SUFDM0IsT0FBTyxDQUFDLFVBQVU7SUFDbEIsT0FBTyxDQUFDLFVBQVU7SUFDbEIsT0FBTyxDQUFDLFlBQVk7SUFadEIsT0FBTyxDQUFDLEdBQUcsQ0FBK0M7SUFHMUQsT0FBTyxDQUFDLHdCQUF3QixDQUF1QztJQUV2RSxPQUFPLENBQUMsU0FBUyxDQUE2QjtJQUU5QyxZQUNVLGFBQWEsRUFBRSx5QkFBeUIsRUFDeEMsbUJBQW1CLEVBQUUsbUJBQW1CLEVBQ3hDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDLEVBQ2hELFlBQVksRUFBRSxxQkFBcUIsRUFDM0MsU0FBUyxFQUFFLDBCQUEwQixFQU90QztJQUVNLEtBQUssa0JBR1g7SUFFTSxJQUFJLGtCQUdWO0lBRU0sWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUd4RDtJQUVELE9BQU8sQ0FBQyxtQkFBbUI7WUFPYixpQkFBaUI7WUFXakIsb0JBQW9CO0lBd0JyQixjQUFjLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FZNUQ7SUFFWSxhQUFhLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUseUJBQXlCLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQStCL0Y7WUFFYSxxQkFBcUI7SUFTbkMsT0FBTyxDQUFDLHdCQUF3QjtDQWdCakMifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"epoch_prune_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/epoch_prune_watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAEL,OAAO,EAEP,KAAK,yBAAyB,EAE/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACrH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAWnE,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7G,KAAK,0BAA0B,GAAG;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2BAA2B,EAAE,MAAM,CAAC;CACrC,CAAC;sCAQsD,UAAU,cAAc;AANhF;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,sBAA2C,YAAW,OAAO;IAOhG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,SAAS;IAXnB,OAAO,CAAC,GAAG,CAA+C;IAG1D,OAAO,CAAC,wBAAwB,CAAuC;gBAG7D,aAAa,EAAE,yBAAyB,EACxC,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAChD,YAAY,EAAE,qBAAqB,EACnC,SAAS,EAAE,0BAA0B;IAQxC,KAAK;IAKL,IAAI;IAKX,OAAO,CAAC,mBAAmB;IA6Cd,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAchD,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;YAgClF,qBAAqB;IASnC,OAAO,CAAC,wBAAwB;CAgBjC"}
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;AAIhD,OAAO,EAEL,OAAO,EAEP,KAAK,yBAAyB,EAE/B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EACV,qBAAqB,EACrB,WAAW,EACX,yBAAyB,EACzB,aAAa,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAWnE,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,YAAY;IAZtB,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,YAAY,EAAE,qBAAqB,EAC3C,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,GAAG,OAAO,CAAC,IAAI,CAAC,CAY5D;IAEY,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B/F;YAEa,qBAAqB;IASnC,OAAO,CAAC,wBAAwB;CAgBjC"}