@lodestar/validator 1.51.0-dev.c99cf49add → 1.51.0-dev.e1237a8b1d
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/lib/services/attestationDuties.d.ts.map +1 -1
- package/lib/services/attestationDuties.js +12 -4
- package/lib/services/attestationDuties.js.map +1 -1
- package/lib/services/chainHeaderTracker.d.ts.map +1 -1
- package/lib/services/chainHeaderTracker.js +6 -1
- package/lib/services/chainHeaderTracker.js.map +1 -1
- package/lib/services/emitter.d.ts +10 -1
- package/lib/services/emitter.d.ts.map +1 -1
- package/lib/services/emitter.js +4 -0
- package/lib/services/emitter.js.map +1 -1
- package/lib/services/externalSignerSync.d.ts.map +1 -1
- package/lib/services/externalSignerSync.js +1 -1
- package/lib/services/externalSignerSync.js.map +1 -1
- package/lib/services/inclusionList.d.ts +25 -0
- package/lib/services/inclusionList.d.ts.map +1 -0
- package/lib/services/inclusionList.js +101 -0
- package/lib/services/inclusionList.js.map +1 -0
- package/lib/services/inclusionListDuties.d.ts +59 -0
- package/lib/services/inclusionListDuties.d.ts.map +1 -0
- package/lib/services/inclusionListDuties.js +252 -0
- package/lib/services/inclusionListDuties.js.map +1 -0
- package/lib/services/indices.js +1 -1
- package/lib/services/indices.js.map +1 -1
- package/lib/services/ptcDuties.d.ts.map +1 -1
- package/lib/services/ptcDuties.js +5 -3
- package/lib/services/ptcDuties.js.map +1 -1
- package/lib/services/syncCommitteeDuties.d.ts.map +1 -1
- package/lib/services/syncCommitteeDuties.js +10 -5
- package/lib/services/syncCommitteeDuties.js.map +1 -1
- package/lib/services/validatorStore.d.ts +8 -2
- package/lib/services/validatorStore.d.ts.map +1 -1
- package/lib/services/validatorStore.js +29 -3
- package/lib/services/validatorStore.js.map +1 -1
- package/lib/slashingProtection/attestation/index.d.ts +1 -0
- package/lib/slashingProtection/attestation/index.d.ts.map +1 -1
- package/lib/slashingProtection/attestation/index.js +77 -44
- package/lib/slashingProtection/attestation/index.js.map +1 -1
- package/lib/slashingProtection/block/index.d.ts.map +1 -1
- package/lib/slashingProtection/block/index.js.map +1 -1
- package/lib/slashingProtection/index.d.ts +3 -1
- package/lib/slashingProtection/index.d.ts.map +1 -1
- package/lib/slashingProtection/index.js +48 -5
- package/lib/slashingProtection/index.js.map +1 -1
- package/lib/slashingProtection/utils.js +1 -1
- package/lib/slashingProtection/utils.js.map +1 -1
- package/lib/types.d.ts +1 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/util/externalSignerClient.d.ts +6 -2
- package/lib/util/externalSignerClient.d.ts.map +1 -1
- package/lib/util/externalSignerClient.js +4 -0
- package/lib/util/externalSignerClient.js.map +1 -1
- package/lib/validator.d.ts +4 -1
- package/lib/validator.d.ts.map +1 -1
- package/lib/validator.js +7 -1
- package/lib/validator.js.map +1 -1
- package/package.json +15 -16
- package/src/services/attestationDuties.ts +18 -4
- package/src/services/chainHeaderTracker.ts +8 -1
- package/src/services/emitter.ts +10 -0
- package/src/services/externalSignerSync.ts +1 -1
- package/src/services/inclusionList.ts +140 -0
- package/src/services/inclusionListDuties.ts +306 -0
- package/src/services/indices.ts +1 -1
- package/src/services/ptcDuties.ts +6 -3
- package/src/services/syncCommitteeDuties.ts +13 -5
- package/src/services/validatorStore.ts +44 -4
- package/src/slashingProtection/attestation/index.ts +82 -46
- package/src/slashingProtection/block/index.ts +1 -0
- package/src/slashingProtection/index.ts +51 -7
- package/src/slashingProtection/utils.ts +1 -1
- package/src/types.ts +1 -1
- package/src/util/externalSignerClient.ts +8 -1
- package/src/validator.ts +18 -0
|
@@ -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,
|
|
@@ -26,7 +26,7 @@ export {InvalidAttestationError, InvalidAttestationErrorCode} from "./attestatio
|
|
|
26
26
|
export {InvalidBlockError, InvalidBlockErrorCode} from "./block/index.js";
|
|
27
27
|
export type {Interchange, InterchangeFormat} from "./interchange/index.js";
|
|
28
28
|
export {InterchangeError, InterchangeErrorErrorCode} from "./interchange/index.js";
|
|
29
|
-
export type {ISlashingProtection, InterchangeFormatVersion,
|
|
29
|
+
export type {ISlashingProtection, InterchangeFormatVersion, SlashingProtectionAttestation, SlashingProtectionBlock};
|
|
30
30
|
/**
|
|
31
31
|
* Handles slashing protection for validator proposer and attester duties as well as slashing protection
|
|
32
32
|
* during a validator interchange import/export process.
|
|
@@ -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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
|
|
@@ -40,7 +40,7 @@ export function stringToNum(str: string): number {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export function minEpoch(epochs: Epoch[]): Epoch | null {
|
|
43
|
-
return epochs.length > 0 ? epochs.reduce((minEpoch, epoch) => (minEpoch
|
|
43
|
+
return epochs.length > 0 ? epochs.reduce((minEpoch, epoch) => Math.min(minEpoch, epoch)) : null;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export function uniqueVectorArr(buffers: Uint8Array[]): Uint8Array[] {
|
package/src/types.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
Slot,
|
|
13
13
|
altair,
|
|
14
14
|
gloas,
|
|
15
|
+
heze,
|
|
15
16
|
phase0,
|
|
16
17
|
ssz,
|
|
17
18
|
sszTypesFor,
|
|
@@ -37,6 +38,7 @@ export enum SignableMessageType {
|
|
|
37
38
|
PAYLOAD_ATTESTATION_MESSAGE = "PAYLOAD_ATTESTATION_MESSAGE",
|
|
38
39
|
PROPOSER_PREFERENCES = "PROPOSER_PREFERENCES",
|
|
39
40
|
BUILDER_REQUEST_AUTH = "BUILDER_REQUEST_AUTH",
|
|
41
|
+
INCLUSION_LIST = "INCLUSION_LIST",
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
const AggregationSlotType = new ContainerType({
|
|
@@ -89,7 +91,8 @@ export type SignableMessage =
|
|
|
89
91
|
| {type: SignableMessageType.EXECUTION_PAYLOAD_ENVELOPE; data: gloas.ExecutionPayloadEnvelope}
|
|
90
92
|
| {type: SignableMessageType.PAYLOAD_ATTESTATION_MESSAGE; data: gloas.PayloadAttestationData}
|
|
91
93
|
| {type: SignableMessageType.PROPOSER_PREFERENCES; data: gloas.ProposerPreferences}
|
|
92
|
-
| {type: SignableMessageType.BUILDER_REQUEST_AUTH; data: gloas.BuilderRequestAuth}
|
|
94
|
+
| {type: SignableMessageType.BUILDER_REQUEST_AUTH; data: gloas.BuilderRequestAuth}
|
|
95
|
+
| {type: SignableMessageType.INCLUSION_LIST; data: heze.InclusionList};
|
|
93
96
|
|
|
94
97
|
const requiresForkInfo: Record<SignableMessageType, boolean> = {
|
|
95
98
|
[SignableMessageType.AGGREGATION_SLOT]: true,
|
|
@@ -108,6 +111,7 @@ const requiresForkInfo: Record<SignableMessageType, boolean> = {
|
|
|
108
111
|
[SignableMessageType.PAYLOAD_ATTESTATION_MESSAGE]: true,
|
|
109
112
|
[SignableMessageType.PROPOSER_PREFERENCES]: true,
|
|
110
113
|
[SignableMessageType.BUILDER_REQUEST_AUTH]: false,
|
|
114
|
+
[SignableMessageType.INCLUSION_LIST]: true,
|
|
111
115
|
};
|
|
112
116
|
|
|
113
117
|
type Web3SignerSerializedRequest = {
|
|
@@ -319,6 +323,9 @@ function serializerSignableMessagePayload(config: BeaconConfig, payload: Signabl
|
|
|
319
323
|
},
|
|
320
324
|
};
|
|
321
325
|
}
|
|
326
|
+
|
|
327
|
+
case SignableMessageType.INCLUSION_LIST:
|
|
328
|
+
return {inclusion_list: ssz.heze.InclusionList.toJson(payload.data)};
|
|
322
329
|
}
|
|
323
330
|
}
|
|
324
331
|
|
package/src/validator.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {ChainHeaderTracker} from "./services/chainHeaderTracker.js";
|
|
|
27
27
|
import {DoppelgangerService} from "./services/doppelgangerService.js";
|
|
28
28
|
import {ValidatorEventEmitter} from "./services/emitter.js";
|
|
29
29
|
import {ExternalSignerOptions, pollExternalSignerPubkeys} from "./services/externalSignerSync.js";
|
|
30
|
+
import {InclusionListService} from "./services/inclusionList.js";
|
|
30
31
|
import {IndicesService} from "./services/indices.js";
|
|
31
32
|
import {pollBuilderValidatorRegistration, pollPrepareBeaconProposer} from "./services/prepareBeaconProposer.js";
|
|
32
33
|
import {ProposalPreferencesService} from "./services/proposalPreferences.js";
|
|
@@ -53,6 +54,7 @@ export type ValidatorModules = {
|
|
|
53
54
|
blockProposingService: BlockProposingService;
|
|
54
55
|
attestationService: AttestationService;
|
|
55
56
|
ptcService: PtcService;
|
|
57
|
+
inclusionListService: InclusionListService;
|
|
56
58
|
syncCommitteeService: SyncCommitteeService;
|
|
57
59
|
config: BeaconConfig;
|
|
58
60
|
api: ApiClient;
|
|
@@ -109,6 +111,7 @@ export class Validator {
|
|
|
109
111
|
private readonly blockProposingService: BlockProposingService;
|
|
110
112
|
private readonly attestationService: AttestationService;
|
|
111
113
|
private readonly ptcService: PtcService;
|
|
114
|
+
private readonly inclusionListService: InclusionListService;
|
|
112
115
|
private readonly syncCommitteeService: SyncCommitteeService;
|
|
113
116
|
private readonly config: BeaconConfig;
|
|
114
117
|
private readonly api: ApiClient;
|
|
@@ -128,6 +131,7 @@ export class Validator {
|
|
|
128
131
|
blockProposingService,
|
|
129
132
|
attestationService,
|
|
130
133
|
ptcService,
|
|
134
|
+
inclusionListService,
|
|
131
135
|
syncCommitteeService,
|
|
132
136
|
config,
|
|
133
137
|
api,
|
|
@@ -145,6 +149,7 @@ export class Validator {
|
|
|
145
149
|
this.blockProposingService = blockProposingService;
|
|
146
150
|
this.attestationService = attestationService;
|
|
147
151
|
this.ptcService = ptcService;
|
|
152
|
+
this.inclusionListService = inclusionListService;
|
|
148
153
|
this.syncCommitteeService = syncCommitteeService;
|
|
149
154
|
this.config = config;
|
|
150
155
|
this.api = api;
|
|
@@ -312,6 +317,17 @@ export class Validator {
|
|
|
312
317
|
metrics
|
|
313
318
|
);
|
|
314
319
|
|
|
320
|
+
const inclusionListService = new InclusionListService(
|
|
321
|
+
config,
|
|
322
|
+
loggerVc,
|
|
323
|
+
api,
|
|
324
|
+
clock,
|
|
325
|
+
validatorStore,
|
|
326
|
+
chainHeaderTracker,
|
|
327
|
+
syncingStatusTracker,
|
|
328
|
+
emitter
|
|
329
|
+
);
|
|
330
|
+
|
|
315
331
|
const syncCommitteeService = new SyncCommitteeService(
|
|
316
332
|
config,
|
|
317
333
|
loggerVc,
|
|
@@ -347,6 +363,7 @@ export class Validator {
|
|
|
347
363
|
blockProposingService,
|
|
348
364
|
attestationService,
|
|
349
365
|
ptcService,
|
|
366
|
+
inclusionListService,
|
|
350
367
|
syncCommitteeService,
|
|
351
368
|
config,
|
|
352
369
|
api,
|
|
@@ -433,6 +450,7 @@ export class Validator {
|
|
|
433
450
|
this.blockProposingService.removeDutiesForKey(pubkey);
|
|
434
451
|
this.attestationService.removeDutiesForKey(pubkey);
|
|
435
452
|
this.ptcService.removeDutiesForKey(pubkey);
|
|
453
|
+
this.inclusionListService.removeDutiesForKey(pubkey);
|
|
436
454
|
this.syncCommitteeService.removeDutiesForKey(pubkey);
|
|
437
455
|
}
|
|
438
456
|
|