@lodestar/validator 1.50.0-rc.0 → 1.51.0-dev.13ce72c336

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 (38) hide show
  1. package/lib/services/attestation.d.ts.map +1 -1
  2. package/lib/services/attestation.js +1 -2
  3. package/lib/services/attestation.js.map +1 -1
  4. package/lib/services/block.d.ts.map +1 -1
  5. package/lib/services/block.js +1 -1
  6. package/lib/services/block.js.map +1 -1
  7. package/lib/services/blockDuties.d.ts.map +1 -1
  8. package/lib/services/blockDuties.js +3 -1
  9. package/lib/services/blockDuties.js.map +1 -1
  10. package/lib/services/ptc.d.ts.map +1 -1
  11. package/lib/services/ptc.js +3 -2
  12. package/lib/services/ptc.js.map +1 -1
  13. package/lib/services/syncCommittee.js +1 -1
  14. package/lib/services/syncCommittee.js.map +1 -1
  15. package/lib/slashingProtection/attestation/index.d.ts +1 -0
  16. package/lib/slashingProtection/attestation/index.d.ts.map +1 -1
  17. package/lib/slashingProtection/attestation/index.js +77 -44
  18. package/lib/slashingProtection/attestation/index.js.map +1 -1
  19. package/lib/slashingProtection/index.d.ts +2 -0
  20. package/lib/slashingProtection/index.d.ts.map +1 -1
  21. package/lib/slashingProtection/index.js +48 -5
  22. package/lib/slashingProtection/index.js.map +1 -1
  23. package/lib/util/externalSignerClient.d.ts +1 -2
  24. package/lib/util/externalSignerClient.d.ts.map +1 -1
  25. package/lib/util/externalSignerClient.js.map +1 -1
  26. package/lib/validator.d.ts.map +1 -1
  27. package/lib/validator.js +4 -3
  28. package/lib/validator.js.map +1 -1
  29. package/package.json +12 -12
  30. package/src/services/attestation.ts +1 -2
  31. package/src/services/block.ts +6 -3
  32. package/src/services/blockDuties.ts +3 -1
  33. package/src/services/ptc.ts +6 -2
  34. package/src/services/syncCommittee.ts +1 -1
  35. package/src/slashingProtection/attestation/index.ts +81 -46
  36. package/src/slashingProtection/index.ts +50 -6
  37. package/src/util/externalSignerClient.ts +2 -2
  38. package/src/validator.ts +13 -3
@@ -1,8 +1,8 @@
1
1
  import {GENESIS_EPOCH} from "@lodestar/params";
2
2
  import {BLSPubkey, Epoch, Root} from "@lodestar/types";
3
- import {Logger, toPubkeyHex} from "@lodestar/utils";
3
+ import {Logger, defer, toPubkeyHex} from "@lodestar/utils";
4
4
  import {uniqueVectorArr} from "../slashingProtection/utils.js";
5
- import {LodestarValidatorDatabaseController} from "../types.js";
5
+ import {LodestarValidatorDatabaseController, PubkeyHex} from "../types.js";
6
6
  import {
7
7
  AttestationByTargetRepository,
8
8
  AttestationLowerBoundRepository,
@@ -34,6 +34,8 @@ export type {ISlashingProtection, InterchangeFormatVersion, SlashingProtectionBl
34
34
  export class SlashingProtection implements ISlashingProtection {
35
35
  private blockService: SlashingProtectionBlockService;
36
36
  private attestationService: SlashingProtectionAttestationService;
37
+ private readonly importing = new Map<PubkeyHex, Promise<void>>();
38
+ private lastImport: Promise<void> | null = null;
37
39
 
38
40
  constructor(protected db: LodestarValidatorDatabaseController) {
39
41
  const blockBySlotRepository = new BlockBySlotRepository(db);
@@ -51,10 +53,26 @@ export class SlashingProtection implements ISlashingProtection {
51
53
  }
52
54
 
53
55
  async checkAndInsertBlockProposal(pubKey: BLSPubkey, block: SlashingProtectionBlock): Promise<void> {
56
+ if (this.importing.size !== 0) {
57
+ const pubkeyHex = toPubkeyHex(pubKey);
58
+ let importing = this.importing.get(pubkeyHex);
59
+ while (importing !== undefined) {
60
+ await importing;
61
+ importing = this.importing.get(pubkeyHex);
62
+ }
63
+ }
54
64
  await this.blockService.checkAndInsertBlockProposal(pubKey, block);
55
65
  }
56
66
 
57
67
  async checkAndInsertAttestation(pubKey: BLSPubkey, attestation: SlashingProtectionAttestation): Promise<void> {
68
+ if (this.importing.size !== 0) {
69
+ const pubkeyHex = toPubkeyHex(pubKey);
70
+ let importing = this.importing.get(pubkeyHex);
71
+ while (importing !== undefined) {
72
+ await importing;
73
+ importing = this.importing.get(pubkeyHex);
74
+ }
75
+ }
58
76
  await this.attestationService.checkAndInsertAttestation(pubKey, attestation);
59
77
  }
60
78
 
@@ -84,10 +102,36 @@ export class SlashingProtection implements ISlashingProtection {
84
102
  }
85
103
  }
86
104
  }
87
- for (const validator of data) {
88
- logger?.info("Importing slashing protection", {pubkey: toPubkeyHex(validator.pubkey)});
89
- await this.blockService.importBlocks(validator.pubkey, validator.signedBlocks);
90
- await this.attestationService.importAttestations(validator.pubkey, validator.signedAttestations);
105
+
106
+ // Checks for keys in the file wait for the whole import, a key that is already signing must not sign against
107
+ // a history the import is still extending. Imports run one after another so a later one cannot release a key early.
108
+ const pubkeyHexes = data.map((validator) => toPubkeyHex(validator.pubkey));
109
+ const previous = this.lastImport;
110
+ const {promise, resolve} = defer<void>();
111
+ this.lastImport = promise;
112
+ for (const pubkeyHex of pubkeyHexes) {
113
+ this.importing.set(pubkeyHex, promise);
114
+ }
115
+
116
+ try {
117
+ if (previous !== null) {
118
+ await previous;
119
+ }
120
+ for (const validator of data) {
121
+ logger?.info("Importing slashing protection", {pubkey: toPubkeyHex(validator.pubkey)});
122
+ await this.blockService.importBlocks(validator.pubkey, validator.signedBlocks);
123
+ await this.attestationService.importAttestations(validator.pubkey, validator.signedAttestations);
124
+ }
125
+ } finally {
126
+ resolve();
127
+ if (this.lastImport === promise) {
128
+ this.lastImport = null;
129
+ }
130
+ for (const pubkeyHex of pubkeyHexes) {
131
+ if (this.importing.get(pubkeyHex) === promise) {
132
+ this.importing.delete(pubkeyHex);
133
+ }
134
+ }
91
135
  }
92
136
  }
93
137
 
@@ -1,6 +1,6 @@
1
1
  import {ContainerType, ValueOf} from "@chainsafe/ssz";
2
2
  import {BeaconConfig} from "@lodestar/config";
3
- import {ForkName, ForkPostGloas, ForkPreBellatrix, ForkSeq, isForkPostDeneb} from "@lodestar/params";
3
+ import {ForkName, ForkPostGloas, ForkSeq, isForkPostDeneb} from "@lodestar/params";
4
4
  import {blindedOrFullBlockToHeader, computeEpochAtSlot} from "@lodestar/state-transition";
5
5
  import {
6
6
  AggregateAndProof,
@@ -78,7 +78,7 @@ export type SignableMessage =
78
78
  | {type: SignableMessageType.AGGREGATE_AND_PROOF; data: phase0.AggregateAndProof}
79
79
  | {type: SignableMessageType.AGGREGATE_AND_PROOF_V2; data: AggregateAndProof}
80
80
  | {type: SignableMessageType.ATTESTATION; data: phase0.AttestationData}
81
- | {type: SignableMessageType.BLOCK_V2; data: BeaconBlock<ForkPreBellatrix> | BlindedBeaconBlock}
81
+ | {type: SignableMessageType.BLOCK_V2; data: BeaconBlock | BlindedBeaconBlock}
82
82
  | {type: SignableMessageType.DEPOSIT; data: ValueOf<typeof DepositType>}
83
83
  | {type: SignableMessageType.RANDAO_REVEAL; data: {epoch: Epoch}}
84
84
  | {type: SignableMessageType.VOLUNTARY_EXIT; data: phase0.VoluntaryExit}
package/src/validator.ts CHANGED
@@ -6,7 +6,14 @@ import {
6
6
  assertEqualParams,
7
7
  createBeaconConfig,
8
8
  } from "@lodestar/config";
9
- import {Clock, ClockOptions, IClock, computeEpochAtSlot, getCurrentSlot} from "@lodestar/state-transition";
9
+ import {
10
+ Clock,
11
+ ClockOptions,
12
+ IClock,
13
+ computeEpochAtSlot,
14
+ getCurrentSlot,
15
+ getSlotDurations,
16
+ } from "@lodestar/state-transition";
10
17
  import {BLSPubkey, phase0, ssz} from "@lodestar/types";
11
18
  import {Genesis} from "@lodestar/types/phase0";
12
19
  import {Logger, prettyGweiToEth, toPrintableUrl, toRootHex} from "@lodestar/utils";
@@ -202,7 +209,9 @@ export class Validator {
202
209
  globalInit: {
203
210
  signal: controller.signal,
204
211
  ...globalInit,
205
- timeoutMs: globalInit?.timeoutMs ?? config.SLOT_DURATION_MS,
212
+ timeoutMs:
213
+ globalInit?.timeoutMs ??
214
+ Math.min(...getSlotDurations(config).map(([, slotDurationMs]) => slotDurationMs)),
206
215
  },
207
216
  },
208
217
  {config, logger, metrics: metrics?.restApiClient}
@@ -366,7 +375,8 @@ export class Validator {
366
375
  urls: urls.map(toPrintableUrl).toString(),
367
376
  requestWireFormat: globalInit?.requestWireFormat ?? defaultInit.requestWireFormat,
368
377
  responseWireFormat: globalInit?.responseWireFormat ?? defaultInit.responseWireFormat,
369
- requestTimeoutMs: globalInit?.timeoutMs ?? config.SLOT_DURATION_MS,
378
+ requestTimeoutMs:
379
+ globalInit?.timeoutMs ?? Math.min(...getSlotDurations(config).map(([, slotDurationMs]) => slotDurationMs)),
370
380
  });
371
381
  } else {
372
382
  api = clientOrUrls;