@aztec/slasher 2.0.0-rc.8 → 2.0.2-rc.2

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 (32) hide show
  1. package/dest/empire_slasher_client.d.ts +3 -2
  2. package/dest/empire_slasher_client.d.ts.map +1 -1
  3. package/dest/empire_slasher_client.js +4 -3
  4. package/dest/factory/create_implementation.js +6 -4
  5. package/dest/slash_offenses_collector.d.ts.map +1 -1
  6. package/dest/slash_offenses_collector.js +1 -2
  7. package/dest/slasher_client_facade.d.ts.map +1 -1
  8. package/dest/slasher_client_facade.js +1 -0
  9. package/dest/tally_slasher_client.d.ts +3 -2
  10. package/dest/tally_slasher_client.d.ts.map +1 -1
  11. package/dest/tally_slasher_client.js +4 -3
  12. package/dest/test/dummy_watcher.d.ts +11 -0
  13. package/dest/test/dummy_watcher.d.ts.map +1 -0
  14. package/dest/test/dummy_watcher.js +14 -0
  15. package/dest/watcher.d.ts +2 -0
  16. package/dest/watcher.d.ts.map +1 -1
  17. package/dest/watchers/attestations_block_watcher.d.ts +5 -2
  18. package/dest/watchers/attestations_block_watcher.d.ts.map +1 -1
  19. package/dest/watchers/attestations_block_watcher.js +30 -21
  20. package/dest/watchers/epoch_prune_watcher.d.ts +5 -6
  21. package/dest/watchers/epoch_prune_watcher.d.ts.map +1 -1
  22. package/dest/watchers/epoch_prune_watcher.js +15 -3
  23. package/package.json +9 -9
  24. package/src/empire_slasher_client.ts +3 -3
  25. package/src/factory/create_implementation.ts +5 -0
  26. package/src/slash_offenses_collector.ts +1 -2
  27. package/src/slasher_client_facade.ts +1 -0
  28. package/src/tally_slasher_client.ts +3 -3
  29. package/src/test/dummy_watcher.ts +21 -0
  30. package/src/watcher.ts +3 -0
  31. package/src/watchers/attestations_block_watcher.ts +37 -25
  32. package/src/watchers/epoch_prune_watcher.ts +22 -7
@@ -1,4 +1,4 @@
1
- import { EmpireSlashingProposerContract, RollupContract } from '@aztec/ethereum';
1
+ import { EmpireSlashingProposerContract, RollupContract, SlasherContract } from '@aztec/ethereum';
2
2
  import { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import type { DateProvider } from '@aztec/foundation/timer';
4
4
  import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
@@ -84,6 +84,7 @@ export declare class EmpireSlasherClient implements ProposerSlashActionProvider,
84
84
  private settings;
85
85
  private slashFactoryContract;
86
86
  private slashingProposer;
87
+ private slasher;
87
88
  private rollup;
88
89
  private dateProvider;
89
90
  private offensesStore;
@@ -94,7 +95,7 @@ export declare class EmpireSlasherClient implements ProposerSlashActionProvider,
94
95
  private overridePayloadActive;
95
96
  private offensesCollector;
96
97
  private roundMonitor;
97
- constructor(config: EmpireSlasherConfig, settings: EmpireSlasherSettings, slashFactoryContract: SlashFactoryContract, slashingProposer: EmpireSlashingProposerContract, rollup: RollupContract, watchers: Watcher[], dateProvider: DateProvider, offensesStore: SlasherOffensesStore, payloadsStore: SlasherPayloadsStore, log?: import("@aztec/foundation/log").Logger);
98
+ constructor(config: EmpireSlasherConfig, settings: EmpireSlasherSettings, slashFactoryContract: SlashFactoryContract, slashingProposer: EmpireSlashingProposerContract, slasher: SlasherContract, rollup: RollupContract, watchers: Watcher[], dateProvider: DateProvider, offensesStore: SlasherOffensesStore, payloadsStore: SlasherPayloadsStore, log?: import("@aztec/foundation/log").Logger);
98
99
  start(): Promise<void>;
99
100
  /**
100
101
  * Allows consumers to stop the instance of the slasher client.
@@ -1 +1 @@
1
- {"version":3,"file":"empire_slasher_client.d.ts","sourceRoot":"","sources":["../src/empire_slasher_client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"empire_slasher_client.d.ts","sourceRoot":"","sources":["../src/empire_slasher_client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlG,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACL,KAAK,OAAO,EAGZ,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAChC,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAQvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAA0B,KAAK,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAE5G,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,gDAAgD;AAChD,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAEhD,qGAAqG;AACrG,MAAM,MAAM,qBAAqB,GAAG;IAClC,8BAA8B,EAAE,MAAM,CAAC;IACvC,+BAA+B,EAAE,MAAM,CAAC;IACxC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B,GAAG,IAAI,CACN,iBAAiB,EACjB,eAAe,GAAG,uBAAuB,GAAG,eAAe,GAAG,cAAc,GAAG,cAAc,GAAG,sBAAsB,CACvH,GACC,8BAA8B,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,qBAAa,mBAAoB,YAAW,2BAA2B,EAAE,sBAAsB;IAS3F,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IAlBb,SAAS,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,CAAM;IAEtD,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,YAAY,CAAoB;gBAG9B,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,qBAAqB,EAC/B,oBAAoB,EAAE,oBAAoB,EAC1C,gBAAgB,EAAE,8BAA8B,EAChD,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,cAAc,EAC9B,QAAQ,EAAE,OAAO,EAAE,EACX,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,oBAAoB,EACnC,aAAa,EAAE,oBAAoB,EACnC,GAAG,yCAAiC;IAOjC,KAAK;IA+ClB;;;OAGG;IACU,IAAI;IAoBjB,iCAAiC;IAC1B,SAAS,IAAI,mBAAmB;IAIvC;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC;IAU3C,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIvD;;;OAGG;cACa,cAAc,CAAC,KAAK,EAAE,MAAM;IAM5C;;;OAGG;cACa,wBAAwB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM;IA8BlF;;;OAGG;IACH,SAAS,CAAC,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM;IASnE;;;;OAIG;cACa,uBAAuB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU;IAsBxG;;;;OAIG;IACU,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAoBvE,0CAA0C;IACnC,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAI/C,uFAAuF;cACvE,yCAAyC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAU5F;;;;;OAKG;IACH,SAAS,CAAC,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,SAAS,CAAC,GAAG,MAAM;IAK9F;;;;OAIG;IACU,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IASnF,uFAAuF;cACvE,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IA4CrG,uEAAuE;cACvD,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAqG5F;;;;;;OAMG;cACa,gBAAgB,CAC9B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,MAAM,EACb,6BAA6B,CAAC,EAAE,OAAO,EAAE,GACxC,OAAO,CAAC,OAAO,CAAC;IAkEnB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAK/B,6EAA6E;IAC7E,OAAO,CAAC,wBAAwB;IAShC,wDAAwD;IACxD,OAAO,CAAC,sBAAsB;IAI9B,wDAAwD;IACxD,OAAO,CAAC,sBAAsB;CAG/B"}
@@ -65,6 +65,7 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
65
65
  settings;
66
66
  slashFactoryContract;
67
67
  slashingProposer;
68
+ slasher;
68
69
  rollup;
69
70
  dateProvider;
70
71
  offensesStore;
@@ -75,11 +76,12 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
75
76
  overridePayloadActive;
76
77
  offensesCollector;
77
78
  roundMonitor;
78
- constructor(config, settings, slashFactoryContract, slashingProposer, rollup, watchers, dateProvider, offensesStore, payloadsStore, log = createLogger('slasher:empire')){
79
+ constructor(config, settings, slashFactoryContract, slashingProposer, slasher, rollup, watchers, dateProvider, offensesStore, payloadsStore, log = createLogger('slasher:empire')){
79
80
  this.config = config;
80
81
  this.settings = settings;
81
82
  this.slashFactoryContract = slashFactoryContract;
82
83
  this.slashingProposer = slashingProposer;
84
+ this.slasher = slasher;
83
85
  this.rollup = rollup;
84
86
  this.dateProvider = dateProvider;
85
87
  this.offensesStore = offensesStore;
@@ -310,8 +312,7 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
310
312
  continue;
311
313
  }
312
314
  // Check if the slash payload is vetoed
313
- const slasherContract = await this.rollup.getSlasherContract();
314
- const isVetoed = await slasherContract.isPayloadVetoed(payload.payload);
315
+ const isVetoed = await this.slasher.isPayloadVetoed(payload.payload);
315
316
  if (isVetoed) {
316
317
  this.log.info(`Payload ${payload.payload} from round ${payload.round} is vetoed, skipping execution`);
317
318
  toRemove.push(payload);
@@ -25,7 +25,7 @@ async function createEmpireSlasher(config, rollup, slashingProposer, slashFactor
25
25
  if (slashingProposer.type !== 'empire') {
26
26
  throw new Error('Slashing proposer contract is not of type Empire');
27
27
  }
28
- const [slashingExecutionDelayInRounds, slashingPayloadLifetimeInRounds, slashingRoundSize, slashingQuorumSize, epochDuration, proofSubmissionEpochs, l1GenesisTime, slotDuration, l1StartBlock] = await Promise.all([
28
+ const [slashingExecutionDelayInRounds, slashingPayloadLifetimeInRounds, slashingRoundSize, slashingQuorumSize, epochDuration, proofSubmissionEpochs, l1GenesisTime, slotDuration, l1StartBlock, slasher] = await Promise.all([
29
29
  slashingProposer.getExecutionDelayInRounds(),
30
30
  slashingProposer.getLifetimeInRounds(),
31
31
  slashingProposer.getRoundSize(),
@@ -34,7 +34,8 @@ async function createEmpireSlasher(config, rollup, slashingProposer, slashFactor
34
34
  rollup.getProofSubmissionEpochs(),
35
35
  rollup.getL1GenesisTime(),
36
36
  rollup.getSlotDuration(),
37
- rollup.getL1StartBlock()
37
+ rollup.getL1StartBlock(),
38
+ rollup.getSlasherContract()
38
39
  ]);
39
40
  const settings = {
40
41
  slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
@@ -56,16 +57,17 @@ async function createEmpireSlasher(config, rollup, slashingProposer, slashFactor
56
57
  ...settings,
57
58
  slashOffenseExpirationRounds: config.slashOffenseExpirationRounds
58
59
  });
59
- return new EmpireSlasherClient(config, settings, slashFactoryContract, slashingProposer, rollup, watchers, dateProvider, offensesStore, payloadsStore, logger);
60
+ return new EmpireSlasherClient(config, settings, slashFactoryContract, slashingProposer, slasher, rollup, watchers, dateProvider, offensesStore, payloadsStore, logger);
60
61
  }
61
62
  async function createTallySlasher(config, rollup, slashingProposer, watchers, dateProvider, epochCache, kvStore, logger = createLogger('slasher')) {
62
63
  if (slashingProposer.type !== 'tally') {
63
64
  throw new Error('Slashing proposer contract is not of type tally');
64
65
  }
65
66
  const settings = await getTallySlasherSettings(rollup, slashingProposer);
67
+ const slasher = await rollup.getSlasherContract();
66
68
  const offensesStore = new SlasherOffensesStore(kvStore, {
67
69
  ...settings,
68
70
  slashOffenseExpirationRounds: config.slashOffenseExpirationRounds
69
71
  });
70
- return new TallySlasherClient(config, settings, slashingProposer, rollup, watchers, epochCache, dateProvider, offensesStore, logger);
72
+ return new TallySlasherClient(config, settings, slashingProposer, slasher, rollup, watchers, epochCache, dateProvider, offensesStore, logger);
71
73
  }
@@ -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;gBAGpC,MAAM,EAAE,4BAA4B,EACpC,QAAQ,EAAE,8BAA8B,EACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,aAAa,EAAE,oBAAoB,EACnC,GAAG,yCAA6C;IAG5D,KAAK;IAeL,IAAI;IAWX;;;;OAIG;IACU,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE;IA+BtD;;;OAGG;IACU,cAAc,CAAC,KAAK,EAAE,MAAM;IAQzC;;;OAGG;IACI,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE;IAKlD,8GAA8G;IAC9G,OAAO,CAAC,iBAAiB;CAI1B"}
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;gBAGpC,MAAM,EAAE,4BAA4B,EACpC,QAAQ,EAAE,8BAA8B,EACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,aAAa,EAAE,oBAAoB,EACnC,GAAG,yCAA6C;IAG5D,KAAK;IAeL,IAAI;IAWX;;;;OAIG;IACU,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE;IA+BtD;;;OAGG;IACU,cAAc,CAAC,KAAK,EAAE,MAAM;IAOzC;;;OAGG;IACI,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE;IAKlD,8GAA8G;IAC9G,OAAO,CAAC,iBAAiB;CAI1B"}
@@ -73,10 +73,9 @@ import { WANT_TO_SLASH_EVENT } from './watcher.js';
73
73
  * Triggered on a time basis when we enter a new slashing round.
74
74
  * Clears expired offenses from stores.
75
75
  */ async handleNewRound(round) {
76
- this.log.verbose(`Clearing expired offenses for new slashing round ${round}`);
77
76
  const cleared = await this.offensesStore.clearExpiredOffenses(round);
78
77
  if (cleared && cleared > 0) {
79
- this.log.verbose(`Cleared ${cleared} expired offenses`);
78
+ this.log.debug(`Cleared ${cleared} expired offenses for round ${round}`);
80
79
  }
81
80
  }
82
81
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"slasher_client_facade.d.ts","sourceRoot":"","sources":["../src/slasher_client_facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG9F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,sBAAsB;IAK9D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IAZhB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,OAAO,CAA2B;gBAGhC,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG;QAAE,oBAAoB,EAAE,MAAM,CAAA;KAAE,EAC1E,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,UAAU,EACpB,mBAAmB,EAAE,UAAU,GAAG,SAAS,EAC3C,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,gBAAgB,EACzB,MAAM,yCAA0B;IAG7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAWtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,SAAS,IAAI,aAAa;IAI1B,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAKlD,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIhD,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAI1D,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIxC,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAI7E,OAAO,CAAC,mBAAmB;YAcb,mBAAmB;CAMlC"}
1
+ {"version":3,"file":"slasher_client_facade.d.ts","sourceRoot":"","sources":["../src/slasher_client_facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG9F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,sBAAsB;IAK9D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IAZhB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,OAAO,CAA2B;gBAGhC,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG;QAAE,oBAAoB,EAAE,MAAM,CAAA;KAAE,EAC1E,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,UAAU,EACpB,mBAAmB,EAAE,UAAU,GAAG,SAAS,EAC3C,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,gBAAgB,EACzB,MAAM,yCAA0B;IAG7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAWtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,SAAS,IAAI,aAAa;IAI1B,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAMlD,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIhD,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAI1D,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIxC,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAI7E,OAAO,CAAC,mBAAmB;YAcb,mBAAmB;CAMlC"}
@@ -50,6 +50,7 @@ import { createSlasherImplementation } from './factory/create_implementation.js'
50
50
  ...config
51
51
  };
52
52
  this.client?.updateConfig(config);
53
+ this.watchers.forEach((watcher)=>watcher.updateConfig?.(config));
53
54
  }
54
55
  getSlashPayloads() {
55
56
  return this.client?.getSlashPayloads() ?? Promise.reject(new Error('Slasher client not initialized'));
@@ -1,5 +1,5 @@
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
3
  import type { DateProvider } from '@aztec/foundation/timer';
4
4
  import type { Prettify } from '@aztec/foundation/types';
5
5
  import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
@@ -58,6 +58,7 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
58
58
  private config;
59
59
  private settings;
60
60
  private tallySlashingProposer;
61
+ private slasher;
61
62
  private rollup;
62
63
  private epochCache;
63
64
  private dateProvider;
@@ -66,7 +67,7 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
66
67
  protected unwatchCallbacks: (() => void)[];
67
68
  protected roundMonitor: SlashRoundMonitor;
68
69
  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);
70
+ constructor(config: TallySlasherClientConfig, settings: TallySlasherSettings, tallySlashingProposer: TallySlashingProposerContract, slasher: SlasherContract, rollup: RollupContract, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, offensesStore: SlasherOffensesStore, log?: import("@aztec/aztec.js").Logger);
70
71
  start(): Promise<void>;
71
72
  /**
72
73
  * Stop the tally slasher client
@@ -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":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAI3G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EACL,KAAK,OAAO,EAEZ,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EAGvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,EACjC,KAAK,8BAA8B,EACpC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,oGAAoG;AACpG,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CACzC,yBAAyB,GACvB,8BAA8B,GAAG;IAC/B,wBAAwB,EAAE,MAAM,CAAC;IACjC,8BAA8B,EAAE,MAAM,CAAC;IACvC,yBAAyB,EAAE,MAAM,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,wCAAwC;IACxC,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CACJ,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,4BAA4B,GACjE,IAAI,CAAC,aAAa,EAAE,uBAAuB,GAAG,sBAAsB,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,kBAAmB,YAAW,2BAA2B,EAAE,sBAAsB;IAM1F,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,qBAAqB;IAC7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IAdb,SAAS,CAAC,gBAAgB,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAM;IAChD,SAAS,CAAC,YAAY,EAAE,iBAAiB,CAAC;IAC1C,SAAS,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;gBAG1C,MAAM,EAAE,wBAAwB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,qBAAqB,EAAE,6BAA6B,EACpD,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,cAAc,EAC9B,QAAQ,EAAE,OAAO,EAAE,EACX,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,oBAAoB,EACnC,GAAG,mCAAoC;IAMpC,KAAK;IAuBlB;;OAEG;IACU,IAAI;IAejB,iCAAiC;IAC1B,SAAS,IAAI,aAAa;IAIjC,8CAA8C;IACvC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC;IAIlD,6FAA6F;cAC7E,cAAc,CAAC,KAAK,EAAE,MAAM;IAK5C,gGAAgG;cAChF,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG;IAKvF;;;;OAIG;IACU,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IASnF,mFAAmF;cACnE,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAkEnG,0FAA0F;cAC1E,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAkFnG,mFAAmF;IACnF,OAAO,CAAC,kCAAkC;IAQ1C;;;OAGG;IACI,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIvD;;;;;OAKG;IACU,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IASvE,0CAA0C;IACnC,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAI/C;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;CAIxB"}
@@ -40,6 +40,7 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
40
40
  config;
41
41
  settings;
42
42
  tallySlashingProposer;
43
+ slasher;
43
44
  rollup;
44
45
  epochCache;
45
46
  dateProvider;
@@ -48,10 +49,11 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
48
49
  unwatchCallbacks;
49
50
  roundMonitor;
50
51
  offensesCollector;
51
- constructor(config, settings, tallySlashingProposer, rollup, watchers, epochCache, dateProvider, offensesStore, log = createLogger('slasher:consensus')){
52
+ constructor(config, settings, tallySlashingProposer, slasher, rollup, watchers, epochCache, dateProvider, offensesStore, log = createLogger('slasher:consensus')){
52
53
  this.config = config;
53
54
  this.settings = settings;
54
55
  this.tallySlashingProposer = tallySlashingProposer;
56
+ this.slasher = slasher;
55
57
  this.rollup = rollup;
56
58
  this.epochCache = epochCache;
57
59
  this.dateProvider = dateProvider;
@@ -156,8 +158,7 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
156
158
  }
157
159
  // Check if the slash payload is vetoed
158
160
  const payload = await this.tallySlashingProposer.getPayload(executableRound);
159
- const slasherContract = await this.rollup.getSlasherContract();
160
- const isVetoed = await slasherContract.isPayloadVetoed(payload.address);
161
+ const isVetoed = await this.slasher.isPayloadVetoed(payload.address);
161
162
  if (isVetoed) {
162
163
  this.log.warn(`Round ${executableRound} payload is vetoed (skipping execution)`, {
163
164
  payloadAddress: payload.address.toString(),
@@ -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=dummy_watcher.d.ts.map
@@ -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;iCAE1D,UAAU,cAAc;AAA3E,qBAAa,YAAa,SAAQ,iBAA2C,YAAW,OAAO;IACtF,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC;IAE5C,KAAK;IAIL,IAAI;IAIJ,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE;CAG5C"}
@@ -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
21
  //# sourceMappingURL=watcher.d.ts.map
@@ -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,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;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;
@@ -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;AAGhD,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;6CAQhD,UAAU,cAAc;AANvF;;;;;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;gBAGQ,aAAa,EAAE,yBAAyB,EACxC,UAAU,EAAE,UAAU,EAC9B,MAAM,EAAE,8BAA8B;IAOjC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,8BAA8B,CAAC;IAK/D,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,8 +1,13 @@
1
+ import { merge, pick } from '@aztec/foundation/collection';
1
2
  import { createLogger } from '@aztec/foundation/log';
2
3
  import { L2BlockSourceEvents } from '@aztec/stdlib/block';
3
4
  import { OffenseType } from '@aztec/stdlib/slashing';
4
5
  import EventEmitter from 'node:events';
5
6
  import { WANT_TO_SLASH_EVENT } from '../watcher.js';
7
+ const AttestationsBlockWatcherConfigKeys = [
8
+ 'slashAttestDescendantOfInvalidPenalty',
9
+ 'slashProposeInvalidAttestationsPenalty'
10
+ ];
6
11
  /**
7
12
  * This watcher is responsible for detecting invalid blocks and creating slashing arguments for offenders.
8
13
  * An invalid block is one that doesn't have enough attestations or has incorrect attestations.
@@ -11,26 +16,30 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
11
16
  */ export class AttestationsBlockWatcher extends EventEmitter {
12
17
  l2BlockSource;
13
18
  epochCache;
14
- config;
15
19
  log;
16
20
  // Only keep track of the last N invalid blocks
17
21
  maxInvalidBlocks;
18
22
  // All invalid archive roots seen
19
23
  invalidArchiveRoots;
24
+ config;
20
25
  boundHandleInvalidBlock;
21
26
  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)=>{
27
+ super(), this.l2BlockSource = l2BlockSource, this.epochCache = epochCache, this.log = createLogger('attestations-block-watcher'), this.maxInvalidBlocks = 100, this.invalidArchiveRoots = new Set(), this.boundHandleInvalidBlock = (event)=>{
23
28
  try {
24
29
  this.handleInvalidBlock(event);
25
30
  } catch (err) {
26
31
  this.log.error('Error handling invalid block', err, {
27
- ...event.validationResult.block.block.toBlockInfo(),
28
- ...event.validationResult.block.l1,
32
+ ...event.validationResult,
29
33
  reason: event.validationResult.reason
30
34
  });
31
35
  }
32
36
  };
33
- this.log.info('InvalidBlockWatcher initialized');
37
+ this.config = pick(config, ...AttestationsBlockWatcherConfigKeys);
38
+ this.log.info('AttestationsBlockWatcher initialized');
39
+ }
40
+ updateConfig(newConfig) {
41
+ this.config = merge(this.config, pick(newConfig, ...AttestationsBlockWatcherConfigKeys));
42
+ this.log.verbose('AttestationsBlockWatcher config updated', this.config);
34
43
  }
35
44
  start() {
36
45
  this.l2BlockSource.on(L2BlockSourceEvents.InvalidAttestationsBlockDetected, this.boundHandleInvalidBlock);
@@ -42,14 +51,14 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
42
51
  }
43
52
  handleInvalidBlock(event) {
44
53
  const { validationResult } = event;
45
- const block = validationResult.block.block;
54
+ const block = validationResult.block;
46
55
  // 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}`);
56
+ if (this.invalidArchiveRoots.has(block.archive.toString())) {
57
+ this.log.trace(`Already processed invalid block ${block.blockNumber}`);
49
58
  return;
50
59
  }
51
- this.log.verbose(`Detected invalid block ${block.number}`, {
52
- ...block.toBlockInfo(),
60
+ this.log.verbose(`Detected invalid block ${block.blockNumber}`, {
61
+ ...block,
53
62
  reason: validationResult.valid === false ? validationResult.reason : 'unknown'
54
63
  });
55
64
  // Store the invalid block
@@ -61,11 +70,11 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
61
70
  }
62
71
  slashAttestorsOnAncestorInvalid(validationResult) {
63
72
  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(),
73
+ const parentArchive = block.lastArchive.toString();
74
+ if (this.invalidArchiveRoots.has(parentArchive)) {
75
+ const attestors = validationResult.attestors;
76
+ this.log.info(`Want to slash attestors of block ${block.blockNumber} built on invalid block`, {
77
+ ...block,
69
78
  ...attestors,
70
79
  parentArchive
71
80
  });
@@ -73,14 +82,14 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
73
82
  validator: attestor,
74
83
  amount: this.config.slashAttestDescendantOfInvalidPenalty,
75
84
  offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID,
76
- epochOrSlot: block.block.slot
85
+ epochOrSlot: BigInt(block.slotNumber)
77
86
  })));
78
87
  }
79
88
  }
80
89
  slashProposer(validationResult) {
81
90
  const { reason, block } = validationResult;
82
- const blockNumber = block.block.number;
83
- const slot = block.block.header.getSlot();
91
+ const blockNumber = block.blockNumber;
92
+ const slot = BigInt(block.slotNumber);
84
93
  const proposer = this.epochCache.getProposerFromEpochCommittee(validationResult, slot);
85
94
  if (!proposer) {
86
95
  this.log.warn(`No proposer found for block ${blockNumber} at slot ${slot}`);
@@ -92,10 +101,10 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
92
101
  validator: proposer,
93
102
  amount,
94
103
  offenseType: offense,
95
- epochOrSlot: block.block.slot
104
+ epochOrSlot: slot
96
105
  };
97
106
  this.log.info(`Want to slash proposer of block ${blockNumber} due to ${reason}`, {
98
- ...block.block.toBlockInfo(),
107
+ ...block,
99
108
  ...args
100
109
  });
101
110
  this.emit(WANT_TO_SLASH_EVENT, [
@@ -116,7 +125,7 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
116
125
  }
117
126
  }
118
127
  addInvalidBlock(block) {
119
- this.invalidArchiveRoots.add(block.block.archive.root.toString());
128
+ this.invalidArchiveRoots.add(block.archive.toString());
120
129
  // Prune old entries if we exceed the maximum
121
130
  if (this.invalidArchiveRoots.size > this.maxInvalidBlocks) {
122
131
  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,12 +18,13 @@ 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;
30
29
  validateBlocks(blocks: L2Block[]): Promise<void>;
31
30
  validateBlock(blockFromL1: L2Block, fork: MerkleTreeWriteOperations): Promise<void>;
@@ -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":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAEL,OAAO,EAEP,KAAK,yBAAyB,EAE/B,MAAM,qBAAqB,CAAC;AAC7B,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;sCAQrD,UAAU,cAAc;AANhF;;;;;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;gBAGpC,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;IAShC,KAAK;IAKL,IAAI;IAKJ,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAKzD,OAAO,CAAC,mBAAmB;IA+Cd,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,9 +1,14 @@
1
+ import { merge, pick } from '@aztec/foundation/collection';
1
2
  import { createLogger } from '@aztec/foundation/log';
2
3
  import { L2BlockSourceEvents } from '@aztec/stdlib/block';
3
4
  import { OffenseType } from '@aztec/stdlib/slashing';
4
5
  import { ReExFailedTxsError, ReExStateMismatchError, TransactionsNotAvailableError, ValidatorError } from '@aztec/stdlib/validators';
5
6
  import EventEmitter from 'node:events';
6
7
  import { WANT_TO_SLASH_EVENT } from '../watcher.js';
8
+ const EpochPruneWatcherPenaltiesConfigKeys = [
9
+ 'slashPrunePenalty',
10
+ 'slashDataWithholdingPenalty'
11
+ ];
7
12
  /**
8
13
  * This watcher is responsible for detecting chain prunes and creating slashing arguments for the committee.
9
14
  * It only wants to slash if:
@@ -15,12 +20,13 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
15
20
  epochCache;
16
21
  txProvider;
17
22
  blockBuilder;
18
- penalties;
19
23
  log;
20
24
  // Store bound function reference for proper listener removal
21
25
  boundHandlePruneL2Blocks;
26
+ penalties;
22
27
  constructor(l2BlockSource, l1ToL2MessageSource, epochCache, txProvider, blockBuilder, penalties){
23
- super(), this.l2BlockSource = l2BlockSource, this.l1ToL2MessageSource = l1ToL2MessageSource, this.epochCache = epochCache, this.txProvider = txProvider, this.blockBuilder = blockBuilder, this.penalties = penalties, this.log = createLogger('epoch-prune-watcher'), this.boundHandlePruneL2Blocks = this.handlePruneL2Blocks.bind(this);
28
+ super(), this.l2BlockSource = l2BlockSource, this.l1ToL2MessageSource = l1ToL2MessageSource, this.epochCache = epochCache, this.txProvider = txProvider, this.blockBuilder = blockBuilder, this.log = createLogger('epoch-prune-watcher'), this.boundHandlePruneL2Blocks = this.handlePruneL2Blocks.bind(this);
29
+ this.penalties = pick(penalties, ...EpochPruneWatcherPenaltiesConfigKeys);
24
30
  this.log.verbose(`EpochPruneWatcher initialized with penalties: valid epoch pruned=${penalties.slashPrunePenalty} data withholding=${penalties.slashDataWithholdingPenalty}`);
25
31
  }
26
32
  start() {
@@ -31,6 +37,10 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
31
37
  this.l2BlockSource.removeListener(L2BlockSourceEvents.L2PruneDetected, this.boundHandlePruneL2Blocks);
32
38
  return Promise.resolve();
33
39
  }
40
+ updateConfig(config) {
41
+ this.penalties = merge(this.penalties, pick(config, ...EpochPruneWatcherPenaltiesConfigKeys));
42
+ this.log.verbose('EpochPruneWatcher config updated', this.penalties);
43
+ }
34
44
  handlePruneL2Blocks(event) {
35
45
  const { blocks, epochNumber } = event;
36
46
  this.log.info(`Detected chain prune. Validating epoch ${epochNumber}`);
@@ -45,7 +55,9 @@ import { WANT_TO_SLASH_EVENT } from '../watcher.js';
45
55
  return result;
46
56
  }).catch(async (error)=>{
47
57
  if (error instanceof TransactionsNotAvailableError) {
48
- this.log.info(`Data for pruned epoch ${epochNumber} was not available. Will want to slash.`, error);
58
+ this.log.info(`Data for pruned epoch ${epochNumber} was not available. Will want to slash.`, {
59
+ message: error.message
60
+ });
49
61
  const validators = await this.getValidatorsForEpoch(epochNumber);
50
62
  return {
51
63
  validators,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/slasher",
3
- "version": "2.0.0-rc.8",
3
+ "version": "2.0.2-rc.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -54,20 +54,20 @@
54
54
  ]
55
55
  },
56
56
  "dependencies": {
57
- "@aztec/epoch-cache": "2.0.0-rc.8",
58
- "@aztec/ethereum": "2.0.0-rc.8",
59
- "@aztec/foundation": "2.0.0-rc.8",
60
- "@aztec/kv-store": "2.0.0-rc.8",
61
- "@aztec/l1-artifacts": "2.0.0-rc.8",
62
- "@aztec/stdlib": "2.0.0-rc.8",
63
- "@aztec/telemetry-client": "2.0.0-rc.8",
57
+ "@aztec/epoch-cache": "2.0.2-rc.2",
58
+ "@aztec/ethereum": "2.0.2-rc.2",
59
+ "@aztec/foundation": "2.0.2-rc.2",
60
+ "@aztec/kv-store": "2.0.2-rc.2",
61
+ "@aztec/l1-artifacts": "2.0.2-rc.2",
62
+ "@aztec/stdlib": "2.0.2-rc.2",
63
+ "@aztec/telemetry-client": "2.0.2-rc.2",
64
64
  "source-map-support": "^0.5.21",
65
65
  "tslib": "^2.4.0",
66
66
  "viem": "2.23.7",
67
67
  "zod": "^3.23.8"
68
68
  },
69
69
  "devDependencies": {
70
- "@aztec/aztec.js": "2.0.0-rc.8",
70
+ "@aztec/aztec.js": "2.0.2-rc.2",
71
71
  "@jest/globals": "^30.0.0",
72
72
  "@types/jest": "^30.0.0",
73
73
  "@types/node": "^22.15.17",
@@ -1,4 +1,4 @@
1
- import { EmpireSlashingProposerContract, RollupContract } from '@aztec/ethereum';
1
+ import { EmpireSlashingProposerContract, RollupContract, SlasherContract } from '@aztec/ethereum';
2
2
  import { sumBigint } from '@aztec/foundation/bigint';
3
3
  import { compactArray, filterAsync, maxBy, pick } from '@aztec/foundation/collection';
4
4
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -121,6 +121,7 @@ export class EmpireSlasherClient implements ProposerSlashActionProvider, Slasher
121
121
  private settings: EmpireSlasherSettings,
122
122
  private slashFactoryContract: SlashFactoryContract,
123
123
  private slashingProposer: EmpireSlashingProposerContract,
124
+ private slasher: SlasherContract,
124
125
  private rollup: RollupContract,
125
126
  watchers: Watcher[],
126
127
  private dateProvider: DateProvider,
@@ -404,8 +405,7 @@ export class EmpireSlasherClient implements ProposerSlashActionProvider, Slasher
404
405
  }
405
406
 
406
407
  // Check if the slash payload is vetoed
407
- const slasherContract = await this.rollup.getSlasherContract();
408
- const isVetoed = await slasherContract.isPayloadVetoed(payload.payload);
408
+ const isVetoed = await this.slasher.isPayloadVetoed(payload.payload);
409
409
 
410
410
  if (isVetoed) {
411
411
  this.log.info(`Payload ${payload.payload} from round ${payload.round} is vetoed, skipping execution`);
@@ -71,6 +71,7 @@ async function createEmpireSlasher(
71
71
  l1GenesisTime,
72
72
  slotDuration,
73
73
  l1StartBlock,
74
+ slasher,
74
75
  ] = await Promise.all([
75
76
  slashingProposer.getExecutionDelayInRounds(),
76
77
  slashingProposer.getLifetimeInRounds(),
@@ -81,6 +82,7 @@ async function createEmpireSlasher(
81
82
  rollup.getL1GenesisTime(),
82
83
  rollup.getSlotDuration(),
83
84
  rollup.getL1StartBlock(),
85
+ rollup.getSlasherContract(),
84
86
  ]);
85
87
 
86
88
  const settings: EmpireSlasherSettings = {
@@ -110,6 +112,7 @@ async function createEmpireSlasher(
110
112
  settings,
111
113
  slashFactoryContract,
112
114
  slashingProposer,
115
+ slasher!,
113
116
  rollup,
114
117
  watchers,
115
118
  dateProvider,
@@ -134,6 +137,7 @@ async function createTallySlasher(
134
137
  }
135
138
 
136
139
  const settings = await getTallySlasherSettings(rollup, slashingProposer);
140
+ const slasher = await rollup.getSlasherContract();
137
141
 
138
142
  const offensesStore = new SlasherOffensesStore(kvStore, {
139
143
  ...settings,
@@ -144,6 +148,7 @@ async function createTallySlasher(
144
148
  config,
145
149
  settings,
146
150
  slashingProposer,
151
+ slasher!,
147
152
  rollup,
148
153
  watchers,
149
154
  epochCache,
@@ -95,10 +95,9 @@ export class SlashOffensesCollector {
95
95
  * Clears expired offenses from stores.
96
96
  */
97
97
  public async handleNewRound(round: bigint) {
98
- this.log.verbose(`Clearing expired offenses for new slashing round ${round}`);
99
98
  const cleared = await this.offensesStore.clearExpiredOffenses(round);
100
99
  if (cleared && cleared > 0) {
101
- this.log.verbose(`Cleared ${cleared} expired offenses`);
100
+ this.log.debug(`Cleared ${cleared} expired offenses for round ${round}`);
102
101
  }
103
102
  }
104
103
 
@@ -58,6 +58,7 @@ export class SlasherClientFacade implements SlasherClientInterface {
58
58
  public updateConfig(config: Partial<SlasherConfig>): void {
59
59
  this.config = { ...this.config, ...config };
60
60
  this.client?.updateConfig(config);
61
+ this.watchers.forEach(watcher => watcher.updateConfig?.(config));
61
62
  }
62
63
 
63
64
  public getSlashPayloads(): Promise<SlashPayloadRound[]> {
@@ -1,6 +1,6 @@
1
1
  import { EthAddress } from '@aztec/aztec.js';
2
2
  import type { EpochCache } from '@aztec/epoch-cache';
3
- import { RollupContract, TallySlashingProposerContract } from '@aztec/ethereum/contracts';
3
+ import { RollupContract, SlasherContract, TallySlashingProposerContract } from '@aztec/ethereum/contracts';
4
4
  import { compactArray, partition, times } from '@aztec/foundation/collection';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import { sleep } from '@aztec/foundation/sleep';
@@ -88,6 +88,7 @@ export class TallySlasherClient implements ProposerSlashActionProvider, SlasherC
88
88
  private config: TallySlasherClientConfig,
89
89
  private settings: TallySlasherSettings,
90
90
  private tallySlashingProposer: TallySlashingProposerContract,
91
+ private slasher: SlasherContract,
91
92
  private rollup: RollupContract,
92
93
  watchers: Watcher[],
93
94
  private epochCache: EpochCache,
@@ -212,8 +213,7 @@ export class TallySlasherClient implements ProposerSlashActionProvider, SlasherC
212
213
 
213
214
  // Check if the slash payload is vetoed
214
215
  const payload = await this.tallySlashingProposer.getPayload(executableRound);
215
- const slasherContract = await this.rollup.getSlasherContract();
216
- const isVetoed = await slasherContract.isPayloadVetoed(payload.address);
216
+ const isVetoed = await this.slasher.isPayloadVetoed(payload.address);
217
217
  if (isVetoed) {
218
218
  this.log.warn(`Round ${executableRound} payload is vetoed (skipping execution)`, {
219
219
  payloadAddress: payload.address.toString(),
@@ -0,0 +1,21 @@
1
+ import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
2
+
3
+ import EventEmitter from 'node:events';
4
+
5
+ import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js';
6
+
7
+ export class DummyWatcher extends (EventEmitter as new () => WatcherEmitter) implements Watcher {
8
+ public updateConfig(_config: Partial<SlasherConfig>) {}
9
+
10
+ public start() {
11
+ return Promise.resolve();
12
+ }
13
+
14
+ public stop() {
15
+ return Promise.resolve();
16
+ }
17
+
18
+ public triggerSlash(args: WantToSlashArgs[]) {
19
+ this.emit(WANT_TO_SLASH_EVENT, args);
20
+ }
21
+ }
package/src/watcher.ts CHANGED
@@ -2,6 +2,8 @@ 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
4
 
5
+ import type { SlasherConfig } from './config.js';
6
+
5
7
  export const WANT_TO_SLASH_EVENT = 'want-to-slash' as const;
6
8
 
7
9
  export interface WantToSlashArgs {
@@ -21,4 +23,5 @@ export type WatcherEmitter = TypedEventEmitter<WatcherEventMap>;
21
23
  export type Watcher = WatcherEmitter & {
22
24
  start?: () => Promise<void>;
23
25
  stop?: () => Promise<void>;
26
+ updateConfig: (config: Partial<SlasherConfig>) => void;
24
27
  };
@@ -1,10 +1,11 @@
1
1
  import { EpochCache } from '@aztec/epoch-cache';
2
+ import { merge, pick } from '@aztec/foundation/collection';
2
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
3
4
  import {
4
5
  type InvalidBlockDetectedEvent,
6
+ type L2BlockInfo,
5
7
  type L2BlockSourceEventEmitter,
6
8
  L2BlockSourceEvents,
7
- PublishedL2Block,
8
9
  type ValidateBlockNegativeResult,
9
10
  } from '@aztec/stdlib/block';
10
11
  import { OffenseType } from '@aztec/stdlib/slashing';
@@ -14,6 +15,13 @@ import EventEmitter from 'node:events';
14
15
  import type { SlasherConfig } from '../config.js';
15
16
  import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js';
16
17
 
18
+ const AttestationsBlockWatcherConfigKeys = [
19
+ 'slashAttestDescendantOfInvalidPenalty',
20
+ 'slashProposeInvalidAttestationsPenalty',
21
+ ] as const;
22
+
23
+ type AttestationsBlockWatcherConfig = Pick<SlasherConfig, (typeof AttestationsBlockWatcherConfigKeys)[number]>;
24
+
17
25
  /**
18
26
  * This watcher is responsible for detecting invalid blocks and creating slashing arguments for offenders.
19
27
  * An invalid block is one that doesn't have enough attestations or has incorrect attestations.
@@ -29,13 +37,14 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher
29
37
  // All invalid archive roots seen
30
38
  private invalidArchiveRoots: Set<string> = new Set();
31
39
 
40
+ private config: AttestationsBlockWatcherConfig;
41
+
32
42
  private boundHandleInvalidBlock = (event: InvalidBlockDetectedEvent) => {
33
43
  try {
34
44
  this.handleInvalidBlock(event);
35
45
  } catch (err) {
36
46
  this.log.error('Error handling invalid block', err, {
37
- ...event.validationResult.block.block.toBlockInfo(),
38
- ...event.validationResult.block.l1,
47
+ ...event.validationResult,
39
48
  reason: event.validationResult.reason,
40
49
  });
41
50
  }
@@ -44,13 +53,16 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher
44
53
  constructor(
45
54
  private l2BlockSource: L2BlockSourceEventEmitter,
46
55
  private epochCache: EpochCache,
47
- private config: Pick<
48
- SlasherConfig,
49
- 'slashAttestDescendantOfInvalidPenalty' | 'slashProposeInvalidAttestationsPenalty'
50
- >,
56
+ config: AttestationsBlockWatcherConfig,
51
57
  ) {
52
58
  super();
53
- this.log.info('InvalidBlockWatcher initialized');
59
+ this.config = pick(config, ...AttestationsBlockWatcherConfigKeys);
60
+ this.log.info('AttestationsBlockWatcher initialized');
61
+ }
62
+
63
+ public updateConfig(newConfig: Partial<AttestationsBlockWatcherConfig>) {
64
+ this.config = merge(this.config, pick(newConfig, ...AttestationsBlockWatcherConfigKeys));
65
+ this.log.verbose('AttestationsBlockWatcher config updated', this.config);
54
66
  }
55
67
 
56
68
  public start() {
@@ -68,16 +80,16 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher
68
80
 
69
81
  private handleInvalidBlock(event: InvalidBlockDetectedEvent): void {
70
82
  const { validationResult } = event;
71
- const block = validationResult.block.block;
83
+ const block = validationResult.block;
72
84
 
73
85
  // Check if we already have processed this block, archiver may emit the same event multiple times
74
- if (this.invalidArchiveRoots.has(block.archive.root.toString())) {
75
- this.log.trace(`Already processed invalid block ${block.number}`);
86
+ if (this.invalidArchiveRoots.has(block.archive.toString())) {
87
+ this.log.trace(`Already processed invalid block ${block.blockNumber}`);
76
88
  return;
77
89
  }
78
90
 
79
- this.log.verbose(`Detected invalid block ${block.number}`, {
80
- ...block.toBlockInfo(),
91
+ this.log.verbose(`Detected invalid block ${block.blockNumber}`, {
92
+ ...block,
81
93
  reason: validationResult.valid === false ? validationResult.reason : 'unknown',
82
94
  });
83
95
 
@@ -94,11 +106,11 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher
94
106
  private slashAttestorsOnAncestorInvalid(validationResult: ValidateBlockNegativeResult) {
95
107
  const block = validationResult.block;
96
108
 
97
- const parentArchive = block.block.header.lastArchive.root.toString();
98
- if (this.invalidArchiveRoots.has(block.block.header.lastArchive.root.toString())) {
99
- const attestors = validationResult.attestations.map(a => a.getSender());
100
- this.log.info(`Want to slash attestors of block ${block.block.number} built on invalid block`, {
101
- ...block.block.toBlockInfo(),
109
+ const parentArchive = block.lastArchive.toString();
110
+ if (this.invalidArchiveRoots.has(parentArchive)) {
111
+ const attestors = validationResult.attestors;
112
+ this.log.info(`Want to slash attestors of block ${block.blockNumber} built on invalid block`, {
113
+ ...block,
102
114
  ...attestors,
103
115
  parentArchive,
104
116
  });
@@ -109,7 +121,7 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher
109
121
  validator: attestor,
110
122
  amount: this.config.slashAttestDescendantOfInvalidPenalty,
111
123
  offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID,
112
- epochOrSlot: block.block.slot,
124
+ epochOrSlot: BigInt(block.slotNumber),
113
125
  })),
114
126
  );
115
127
  }
@@ -117,8 +129,8 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher
117
129
 
118
130
  private slashProposer(validationResult: ValidateBlockNegativeResult) {
119
131
  const { reason, block } = validationResult;
120
- const blockNumber = block.block.number;
121
- const slot = block.block.header.getSlot();
132
+ const blockNumber = block.blockNumber;
133
+ const slot = BigInt(block.slotNumber);
122
134
  const proposer = this.epochCache.getProposerFromEpochCommittee(validationResult, slot);
123
135
 
124
136
  if (!proposer) {
@@ -132,11 +144,11 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher
132
144
  validator: proposer,
133
145
  amount,
134
146
  offenseType: offense,
135
- epochOrSlot: block.block.slot,
147
+ epochOrSlot: slot,
136
148
  };
137
149
 
138
150
  this.log.info(`Want to slash proposer of block ${blockNumber} due to ${reason}`, {
139
- ...block.block.toBlockInfo(),
151
+ ...block,
140
152
  ...args,
141
153
  });
142
154
 
@@ -156,8 +168,8 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher
156
168
  }
157
169
  }
158
170
 
159
- private addInvalidBlock(block: PublishedL2Block) {
160
- this.invalidArchiveRoots.add(block.block.archive.root.toString());
171
+ private addInvalidBlock(block: L2BlockInfo) {
172
+ this.invalidArchiveRoots.add(block.archive.toString());
161
173
 
162
174
  // Prune old entries if we exceed the maximum
163
175
  if (this.invalidArchiveRoots.size > this.maxInvalidBlocks) {
@@ -1,5 +1,6 @@
1
1
  import type { Tx } from '@aztec/aztec.js';
2
2
  import { EpochCache } from '@aztec/epoch-cache';
3
+ import { merge, pick } from '@aztec/foundation/collection';
3
4
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
5
  import {
5
6
  EthAddress,
@@ -8,7 +9,12 @@ import {
8
9
  type L2BlockSourceEventEmitter,
9
10
  L2BlockSourceEvents,
10
11
  } from '@aztec/stdlib/block';
11
- import type { IFullNodeBlockBuilder, ITxProvider, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
12
+ import type {
13
+ IFullNodeBlockBuilder,
14
+ ITxProvider,
15
+ MerkleTreeWriteOperations,
16
+ SlasherConfig,
17
+ } from '@aztec/stdlib/interfaces/server';
12
18
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
13
19
  import { OffenseType } from '@aztec/stdlib/slashing';
14
20
  import {
@@ -22,10 +28,9 @@ import EventEmitter from 'node:events';
22
28
 
23
29
  import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js';
24
30
 
25
- type EpochPruneWatcherPenalties = {
26
- slashPrunePenalty: bigint;
27
- slashDataWithholdingPenalty: bigint;
28
- };
31
+ const EpochPruneWatcherPenaltiesConfigKeys = ['slashPrunePenalty', 'slashDataWithholdingPenalty'] as const;
32
+
33
+ type EpochPruneWatcherPenalties = Pick<SlasherConfig, (typeof EpochPruneWatcherPenaltiesConfigKeys)[number]>;
29
34
 
30
35
  /**
31
36
  * This watcher is responsible for detecting chain prunes and creating slashing arguments for the committee.
@@ -39,15 +44,18 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
39
44
  // Store bound function reference for proper listener removal
40
45
  private boundHandlePruneL2Blocks = this.handlePruneL2Blocks.bind(this);
41
46
 
47
+ private penalties: EpochPruneWatcherPenalties;
48
+
42
49
  constructor(
43
50
  private l2BlockSource: L2BlockSourceEventEmitter,
44
51
  private l1ToL2MessageSource: L1ToL2MessageSource,
45
52
  private epochCache: EpochCache,
46
53
  private txProvider: Pick<ITxProvider, 'getAvailableTxs'>,
47
54
  private blockBuilder: IFullNodeBlockBuilder,
48
- private penalties: EpochPruneWatcherPenalties,
55
+ penalties: EpochPruneWatcherPenalties,
49
56
  ) {
50
57
  super();
58
+ this.penalties = pick(penalties, ...EpochPruneWatcherPenaltiesConfigKeys);
51
59
  this.log.verbose(
52
60
  `EpochPruneWatcher initialized with penalties: valid epoch pruned=${penalties.slashPrunePenalty} data withholding=${penalties.slashDataWithholdingPenalty}`,
53
61
  );
@@ -63,6 +71,11 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
63
71
  return Promise.resolve();
64
72
  }
65
73
 
74
+ public updateConfig(config: Partial<SlasherConfig>): void {
75
+ this.penalties = merge(this.penalties, pick(config, ...EpochPruneWatcherPenaltiesConfigKeys));
76
+ this.log.verbose('EpochPruneWatcher config updated', this.penalties);
77
+ }
78
+
66
79
  private handlePruneL2Blocks(event: L2BlockPruneEvent): void {
67
80
  const { blocks, epochNumber } = event;
68
81
  this.log.info(`Detected chain prune. Validating epoch ${epochNumber}`);
@@ -80,7 +93,9 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
80
93
  })
81
94
  .catch(async error => {
82
95
  if (error instanceof TransactionsNotAvailableError) {
83
- this.log.info(`Data for pruned epoch ${epochNumber} was not available. Will want to slash.`, error);
96
+ this.log.info(`Data for pruned epoch ${epochNumber} was not available. Will want to slash.`, {
97
+ message: error.message,
98
+ });
84
99
  const validators = await this.getValidatorsForEpoch(epochNumber);
85
100
  return {
86
101
  validators,