@lodestar/validator 1.51.0-dev.4fa9ea1184 → 1.51.0-dev.5619357e93
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 +28 -2
- package/lib/services/validatorStore.js.map +1 -1
- package/lib/slashingProtection/attestation/index.d.ts.map +1 -1
- 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 +1 -1
- package/lib/slashingProtection/index.d.ts.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 +14 -14
- 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 +42 -2
- package/src/slashingProtection/attestation/index.ts +1 -0
- package/src/slashingProtection/block/index.ts +1 -0
- package/src/slashingProtection/index.ts +1 -1
- 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
|
-
import {SecretKey} from "@chainsafe/lodestar-z/blst";
|
|
2
1
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
2
|
import {routes} from "@lodestar/api";
|
|
4
3
|
import {BuilderConfigData, BuilderEntryConfig} from "@lodestar/api/keymanager";
|
|
5
4
|
import {BeaconConfig} from "@lodestar/config";
|
|
5
|
+
import {SecretKey} from "@lodestar/native/blst";
|
|
6
6
|
import {
|
|
7
7
|
DOMAIN_AGGREGATE_AND_PROOF,
|
|
8
8
|
DOMAIN_APPLICATION_BUILDER,
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
DOMAIN_BEACON_PROPOSER,
|
|
12
12
|
DOMAIN_BUILDER_REQUEST_AUTH,
|
|
13
13
|
DOMAIN_CONTRIBUTION_AND_PROOF,
|
|
14
|
+
DOMAIN_INCLUSION_LIST_COMMITTEE,
|
|
14
15
|
DOMAIN_PROPOSER_PREFERENCES,
|
|
15
16
|
DOMAIN_PTC_ATTESTER,
|
|
16
17
|
DOMAIN_RANDAO,
|
|
@@ -46,6 +47,7 @@ import {
|
|
|
46
47
|
altair,
|
|
47
48
|
bellatrix,
|
|
48
49
|
gloas,
|
|
50
|
+
heze,
|
|
49
51
|
phase0,
|
|
50
52
|
ssz,
|
|
51
53
|
} from "@lodestar/types";
|
|
@@ -633,7 +635,8 @@ export class ValidatorStore {
|
|
|
633
635
|
removeSigner(pubkeyHex: PubkeyHex): boolean {
|
|
634
636
|
this.doppelgangerService?.unregisterValidator(pubkeyHex);
|
|
635
637
|
|
|
636
|
-
|
|
638
|
+
this.indicesService.removeForKey(pubkeyHex);
|
|
639
|
+
return this.validators.delete(pubkeyHex);
|
|
637
640
|
}
|
|
638
641
|
|
|
639
642
|
/** Return true if there is at least 1 pubkey registered */
|
|
@@ -954,6 +957,38 @@ export class ValidatorStore {
|
|
|
954
957
|
};
|
|
955
958
|
}
|
|
956
959
|
|
|
960
|
+
async signInclusionList(
|
|
961
|
+
duty: routes.validator.InclusionListDuty,
|
|
962
|
+
inclusionList: heze.InclusionList
|
|
963
|
+
): Promise<heze.SignedInclusionList> {
|
|
964
|
+
if (duty.slot !== inclusionList.slot) {
|
|
965
|
+
throw Error(
|
|
966
|
+
`Inconsistent duties during signing: duty.slot ${duty.slot} != inclusionList.slot ${inclusionList.slot}`
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
if (duty.validatorIndex !== inclusionList.validatorIndex) {
|
|
970
|
+
throw Error(
|
|
971
|
+
`Inconsistent duties during signing: duty.validatorIndex ${duty.validatorIndex} != inclusionList.validatorIndex ${inclusionList.validatorIndex}`
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
this.assertDoppelgangerSafe(duty.pubkey);
|
|
976
|
+
|
|
977
|
+
const signingSlot = inclusionList.slot;
|
|
978
|
+
const domain = this.config.getDomain(signingSlot, DOMAIN_INCLUSION_LIST_COMMITTEE);
|
|
979
|
+
const signingRoot = computeSigningRoot(ssz.heze.InclusionList, inclusionList, domain);
|
|
980
|
+
|
|
981
|
+
const signableMessage: SignableMessage = {
|
|
982
|
+
type: SignableMessageType.INCLUSION_LIST,
|
|
983
|
+
data: inclusionList,
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
return {
|
|
987
|
+
message: inclusionList,
|
|
988
|
+
signature: await this.getSignature(duty.pubkey, signingRoot, signingSlot, signableMessage),
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
|
|
957
992
|
async signAttestationSelectionProof(pubkey: BLSPubkeyMaybeHex, slot: Slot): Promise<BLSSignature> {
|
|
958
993
|
const signingSlot = slot;
|
|
959
994
|
const domain = this.config.getDomain(slot, DOMAIN_SELECTION_PROOF);
|
|
@@ -1214,6 +1249,11 @@ export class ValidatorStore {
|
|
|
1214
1249
|
}
|
|
1215
1250
|
}
|
|
1216
1251
|
|
|
1252
|
+
/**
|
|
1253
|
+
* Required before signing a message that is slashable or that the beacon node counts as validator
|
|
1254
|
+
* liveness (see `validatorSeenAtEpoch`), otherwise doppelganger detection would flag our own messages.
|
|
1255
|
+
* Skip it for anything else.
|
|
1256
|
+
*/
|
|
1217
1257
|
private assertDoppelgangerSafe(pubKey: PubkeyHex | BLSPubkey): void {
|
|
1218
1258
|
const pubkeyHex = typeof pubKey === "string" ? pubKey : toPubkeyHex(pubKey);
|
|
1219
1259
|
if (!this.isDoppelgangerSafe(pubkeyHex)) {
|
|
@@ -6,6 +6,7 @@ import {ZERO_ROOT, isEqualNonZeroRoot, isEqualRoot, minEpoch} from "../utils.js"
|
|
|
6
6
|
import {AttestationByTargetRepository} from "./attestationByTargetRepository.js";
|
|
7
7
|
import {AttestationLowerBoundRepository} from "./attestationLowerBoundRepository.js";
|
|
8
8
|
import {InvalidAttestationError, InvalidAttestationErrorCode} from "./errors.js";
|
|
9
|
+
|
|
9
10
|
export {
|
|
10
11
|
AttestationByTargetRepository,
|
|
11
12
|
AttestationLowerBoundRepository,
|
|
@@ -4,6 +4,7 @@ import {SlashingProtectionBlock} from "../types.js";
|
|
|
4
4
|
import {ZERO_ROOT, isEqualNonZeroRoot, isEqualRoot} from "../utils.js";
|
|
5
5
|
import {BlockBySlotRepository} from "./blockBySlotRepository.js";
|
|
6
6
|
import {InvalidBlockError, InvalidBlockErrorCode} from "./errors.js";
|
|
7
|
+
|
|
7
8
|
export {BlockBySlotRepository, InvalidBlockError, InvalidBlockErrorCode};
|
|
8
9
|
|
|
9
10
|
enum SafeStatus {
|
|
@@ -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.
|
|
@@ -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
|
|