@aztec/validator-client 0.0.1-commit.29c6b1a3 → 0.0.1-commit.2eb6648a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/validator.ts CHANGED
@@ -18,7 +18,7 @@ import { RunningPromise } from '@aztec/foundation/running-promise';
18
18
  import { sleep } from '@aztec/foundation/sleep';
19
19
  import { DateProvider } from '@aztec/foundation/timer';
20
20
  import type { KeystoreManager } from '@aztec/node-keystore';
21
- import type { P2P, PeerId } from '@aztec/p2p';
21
+ import type { DuplicateProposalInfo, P2P, PeerId } from '@aztec/p2p';
22
22
  import { AuthRequest, AuthResponse, BlockProposalValidator, ReqRespSubProtocol } from '@aztec/p2p';
23
23
  import { OffenseType, WANT_TO_SLASH_EVENT, type Watcher, type WatcherEmitter } from '@aztec/slasher';
24
24
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -309,6 +309,11 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
309
309
  ): Promise<CheckpointAttestation[] | undefined> => this.attestToCheckpointProposal(checkpoint, proposalSender);
310
310
  this.p2pClient.registerCheckpointProposalHandler(checkpointHandler);
311
311
 
312
+ // Duplicate proposal handler - triggers slashing for equivocation
313
+ this.p2pClient.registerDuplicateProposalCallback((info: DuplicateProposalInfo) => {
314
+ this.handleDuplicateProposal(info);
315
+ });
316
+
312
317
  const myAddresses = this.getValidatorAddresses();
313
318
  this.p2pClient.registerThisValidatorAddresses(myAddresses);
314
319
 
@@ -518,7 +523,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
518
523
  attestors: EthAddress[] = [],
519
524
  ): Promise<CheckpointAttestation[]> {
520
525
  const attestations = await this.validationService.attestToCheckpointProposal(proposal, attestors);
521
- await this.p2pClient.addCheckpointAttestations(attestations);
526
+ await this.p2pClient.addOwnCheckpointAttestations(attestations);
522
527
  return attestations;
523
528
  }
524
529
 
@@ -601,6 +606,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
601
606
  previousCheckpointOutHashes,
602
607
  fork,
603
608
  blocks,
609
+ this.log.getBindings(),
604
610
  );
605
611
 
606
612
  // Complete the checkpoint to get computed values
@@ -720,6 +726,30 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
720
726
  ]);
721
727
  }
722
728
 
729
+ /**
730
+ * Handle detection of a duplicate proposal (equivocation).
731
+ * Emits a slash event when a proposer sends multiple proposals for the same position.
732
+ */
733
+ private handleDuplicateProposal(info: DuplicateProposalInfo): void {
734
+ const { slot, proposer, type } = info;
735
+
736
+ this.log.warn(`Triggering slash event for duplicate ${type} proposal from ${proposer.toString()} at slot ${slot}`, {
737
+ proposer: proposer.toString(),
738
+ slot,
739
+ type,
740
+ });
741
+
742
+ // Emit slash event
743
+ this.emit(WANT_TO_SLASH_EVENT, [
744
+ {
745
+ validator: proposer,
746
+ amount: this.config.slashDuplicateProposalPenalty,
747
+ offenseType: OffenseType.DUPLICATE_PROPOSAL,
748
+ epochOrSlot: BigInt(slot),
749
+ },
750
+ ]);
751
+ }
752
+
723
753
  async createBlockProposal(
724
754
  blockHeader: BlockHeader,
725
755
  indexWithinCheckpoint: IndexWithinCheckpoint,