@lodestar/validator 1.39.0-dev.882891d89c → 1.39.0-dev.90334173dc
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/attestation.d.ts +0 -11
- package/lib/services/attestation.d.ts.map +1 -1
- package/lib/services/attestation.js +1 -75
- package/lib/services/attestation.js.map +1 -1
- package/lib/services/attestationDuties.d.ts +8 -0
- package/lib/services/attestationDuties.d.ts.map +1 -1
- package/lib/services/attestationDuties.js +60 -2
- package/lib/services/attestationDuties.js.map +1 -1
- package/lib/services/syncCommittee.d.ts +0 -10
- package/lib/services/syncCommittee.d.ts.map +1 -1
- package/lib/services/syncCommittee.js +0 -67
- package/lib/services/syncCommittee.js.map +1 -1
- package/lib/services/syncCommitteeDuties.d.ts +9 -0
- package/lib/services/syncCommitteeDuties.d.ts.map +1 -1
- package/lib/services/syncCommitteeDuties.js +64 -2
- package/lib/services/syncCommitteeDuties.js.map +1 -1
- package/lib/util/externalSignerClient.d.ts +2 -6
- package/lib/util/externalSignerClient.d.ts.map +1 -1
- package/lib/util/externalSignerClient.js +21 -7
- package/lib/util/externalSignerClient.js.map +1 -1
- package/package.json +17 -15
- package/src/services/attestation.ts +3 -100
- package/src/services/attestationDuties.ts +79 -2
- package/src/services/syncCommittee.ts +2 -93
- package/src/services/syncCommitteeDuties.ts +85 -3
- package/src/util/externalSignerClient.ts +28 -10
|
@@ -26,6 +26,7 @@ export class SyncCommitteeDutiesService {
|
|
|
26
26
|
config;
|
|
27
27
|
logger;
|
|
28
28
|
api;
|
|
29
|
+
clock;
|
|
29
30
|
validatorStore;
|
|
30
31
|
opts;
|
|
31
32
|
/** Maps a validator public key to their duties for each slot */
|
|
@@ -34,6 +35,7 @@ export class SyncCommitteeDutiesService {
|
|
|
34
35
|
this.config = config;
|
|
35
36
|
this.logger = logger;
|
|
36
37
|
this.api = api;
|
|
38
|
+
this.clock = clock;
|
|
37
39
|
this.validatorStore = validatorStore;
|
|
38
40
|
this.opts = opts;
|
|
39
41
|
// Running this task every epoch is safe since a re-org of many epochs is very unlikely
|
|
@@ -76,6 +78,15 @@ export class SyncCommitteeDutiesService {
|
|
|
76
78
|
selectionProofs: await this.getSelectionProofs(slot, dutyAtPeriod.duty),
|
|
77
79
|
});
|
|
78
80
|
}
|
|
81
|
+
if (this.opts?.distributedAggregationSelection) {
|
|
82
|
+
// Validator in distributed cluster only has a key share, not the full private key.
|
|
83
|
+
// The partial selection proofs must be exchanged for combined selection proofs by
|
|
84
|
+
// calling submitSyncCommitteeSelections on the distributed validator middleware client.
|
|
85
|
+
// This will run in parallel to other sync committee tasks but must be finished before starting
|
|
86
|
+
// sync committee contributions as it is required to correctly determine if validator is aggregator
|
|
87
|
+
// and to produce a ContributionAndProof that can be threshold aggregated by the middleware client.
|
|
88
|
+
this.runDistributedAggregationSelectionTasks(duties, slot).catch((e) => this.logger.debug("Error on sync committee aggregation selection", { slot }, e));
|
|
89
|
+
}
|
|
79
90
|
}
|
|
80
91
|
return duties;
|
|
81
92
|
}
|
|
@@ -228,8 +239,8 @@ export class SyncCommitteeDutiesService {
|
|
|
228
239
|
if (this.opts?.distributedAggregationSelection) {
|
|
229
240
|
// Validator in distributed cluster only has a key share, not the full private key.
|
|
230
241
|
// Passing a partial selection proof to `is_sync_committee_aggregator` would produce incorrect result.
|
|
231
|
-
//
|
|
232
|
-
// distributed validator middleware client
|
|
242
|
+
// For all duties in the slot, aggregators are determined by exchanging partial for combined selection
|
|
243
|
+
// proofs retrieved from distributed validator middleware client at beginning of every slot.
|
|
233
244
|
dutiesAndProofs.push({
|
|
234
245
|
selectionProof: null,
|
|
235
246
|
partialSelectionProof: selectionProof,
|
|
@@ -255,5 +266,56 @@ export class SyncCommitteeDutiesService {
|
|
|
255
266
|
}
|
|
256
267
|
}
|
|
257
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Performs additional sync committee contribution tasks required if validator is part of distributed cluster
|
|
271
|
+
*
|
|
272
|
+
* 1. Exchange partial for combined selection proofs
|
|
273
|
+
* 2. Determine validators that should produce sync committee contribution
|
|
274
|
+
* 3. Mutate duty objects to set selection proofs for aggregators
|
|
275
|
+
*/
|
|
276
|
+
async runDistributedAggregationSelectionTasks(duties, slot) {
|
|
277
|
+
if (duties.length === 0) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const partialSelections = [];
|
|
281
|
+
for (const { duty, selectionProofs } of duties) {
|
|
282
|
+
const validatorSelections = selectionProofs.map(({ subcommitteeIndex, partialSelectionProof }) => ({
|
|
283
|
+
validatorIndex: duty.validatorIndex,
|
|
284
|
+
slot,
|
|
285
|
+
subcommitteeIndex,
|
|
286
|
+
selectionProof: partialSelectionProof,
|
|
287
|
+
}));
|
|
288
|
+
partialSelections.push(...validatorSelections);
|
|
289
|
+
}
|
|
290
|
+
this.logger.debug("Submitting partial sync committee selection proofs", { slot, count: partialSelections.length });
|
|
291
|
+
const res = await this.api.validator.submitSyncCommitteeSelections({ selections: partialSelections }, {
|
|
292
|
+
// Exit sync committee contributions flow if there is no response until CONTRIBUTION_DUE_BPS of the slot.
|
|
293
|
+
// Note that the sync committee contributions flow is not explicitly exited but rather will be skipped
|
|
294
|
+
// due to the fact that calculation of `is_sync_committee_aggregator` in SyncCommitteeDutiesService is not done
|
|
295
|
+
// and selectionProof is set to null, meaning no validator will be considered an aggregator.
|
|
296
|
+
timeoutMs: this.config.getSyncContributionDueMs(this.config.getForkName(slot)) - this.clock.msFromSlot(slot),
|
|
297
|
+
});
|
|
298
|
+
const combinedSelections = res.value();
|
|
299
|
+
this.logger.debug("Received combined sync committee selection proofs", { slot, count: combinedSelections.length });
|
|
300
|
+
for (const dutyAndProofs of duties) {
|
|
301
|
+
const { validatorIndex, subnets } = dutyAndProofs.duty;
|
|
302
|
+
for (const subnet of subnets) {
|
|
303
|
+
const logCtxValidator = { slot, index: subnet, validatorIndex };
|
|
304
|
+
const combinedSelection = combinedSelections.find((s) => s.validatorIndex === validatorIndex && s.slot === slot && s.subcommitteeIndex === subnet);
|
|
305
|
+
if (!combinedSelection) {
|
|
306
|
+
this.logger.debug("Did not receive combined sync committee selection proof", logCtxValidator);
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
const isAggregator = isSyncCommitteeAggregator(combinedSelection.selectionProof);
|
|
310
|
+
if (isAggregator) {
|
|
311
|
+
const selectionProofObject = dutyAndProofs.selectionProofs.find((p) => p.subcommitteeIndex === subnet);
|
|
312
|
+
if (selectionProofObject) {
|
|
313
|
+
// Update selection proof by mutating proof objects in duty object
|
|
314
|
+
selectionProofObject.selectionProof = combinedSelection.selectionProof;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
258
320
|
}
|
|
259
321
|
//# sourceMappingURL=syncCommitteeDuties.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncCommitteeDuties.js","sourceRoot":"","sources":["../../src/services/syncCommitteeDuties.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,gCAAgC,EAAE,0BAA0B,EAAC,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAC,WAAW,EAAC,MAAM,iBAAiB,CAAC;AAK5C,OAAO,EAAC,6BAA6B,EAAC,MAAM,YAAY,CAAC;AAGzD,mFAAmF;AACnF,MAAM,yBAAyB,GAAG,CAAC,CAAC;AACpC;;;;;;;;;;GAUG;AACH,MAAM,4BAA4B,GAAG,CAAC,CAAC;AACvC,oFAAoF;AACpF,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAyCzC;;;GAGG;AACH,MAAM,OAAO,0BAA0B;IAKlB;IACA;IACA;
|
|
1
|
+
{"version":3,"file":"syncCommitteeDuties.js","sourceRoot":"","sources":["../../src/services/syncCommitteeDuties.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ContainerType, ValueOf } from "@chainsafe/ssz";
|
|
2
2
|
import { BeaconConfig } from "@lodestar/config";
|
|
3
3
|
import { ForkPreBellatrix } from "@lodestar/params";
|
|
4
|
-
import { AggregateAndProof, BeaconBlock, BlindedBeaconBlock, Epoch, Root, Slot, altair,
|
|
4
|
+
import { AggregateAndProof, BeaconBlock, BlindedBeaconBlock, Epoch, Root, Slot, altair, phase0 } from "@lodestar/types";
|
|
5
5
|
import { ValidatorRegistrationV1 } from "@lodestar/types/bellatrix";
|
|
6
6
|
import { PubkeyHex } from "../types.js";
|
|
7
7
|
export declare enum SignableMessageType {
|
|
@@ -16,8 +16,7 @@ export declare enum SignableMessageType {
|
|
|
16
16
|
SYNC_COMMITTEE_MESSAGE = "SYNC_COMMITTEE_MESSAGE",
|
|
17
17
|
SYNC_COMMITTEE_SELECTION_PROOF = "SYNC_COMMITTEE_SELECTION_PROOF",
|
|
18
18
|
SYNC_COMMITTEE_CONTRIBUTION_AND_PROOF = "SYNC_COMMITTEE_CONTRIBUTION_AND_PROOF",
|
|
19
|
-
VALIDATOR_REGISTRATION = "VALIDATOR_REGISTRATION"
|
|
20
|
-
BLS_TO_EXECUTION_CHANGE = "BLS_TO_EXECUTION_CHANGE"
|
|
19
|
+
VALIDATOR_REGISTRATION = "VALIDATOR_REGISTRATION"
|
|
21
20
|
}
|
|
22
21
|
declare const DepositType: ContainerType<{
|
|
23
22
|
pubkey: import("@chainsafe/ssz").ByteVectorType;
|
|
@@ -73,9 +72,6 @@ export type SignableMessage = {
|
|
|
73
72
|
} | {
|
|
74
73
|
type: SignableMessageType.VALIDATOR_REGISTRATION;
|
|
75
74
|
data: ValidatorRegistrationV1;
|
|
76
|
-
} | {
|
|
77
|
-
type: SignableMessageType.BLS_TO_EXECUTION_CHANGE;
|
|
78
|
-
data: capella.BLSToExecutionChange;
|
|
79
75
|
};
|
|
80
76
|
/**
|
|
81
77
|
* Return public keys from the server.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"externalSignerClient.d.ts","sourceRoot":"","sources":["../../src/util/externalSignerClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,OAAO,EAAC,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAC9C,OAAO,
|
|
1
|
+
{"version":3,"file":"externalSignerClient.d.ts","sourceRoot":"","sources":["../../src/util/externalSignerClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ContainerType } from "@chainsafe/ssz";
|
|
2
|
-
import { ForkSeq } from "@lodestar/params";
|
|
2
|
+
import { ForkName, ForkSeq, isForkPostDeneb } from "@lodestar/params";
|
|
3
3
|
import { blindedOrFullBlockToHeader, computeEpochAtSlot } from "@lodestar/state-transition";
|
|
4
4
|
import { ssz, sszTypesFor, } from "@lodestar/types";
|
|
5
5
|
import { fetch, toHex, toRootHex } from "@lodestar/utils";
|
|
@@ -17,7 +17,6 @@ export var SignableMessageType;
|
|
|
17
17
|
SignableMessageType["SYNC_COMMITTEE_SELECTION_PROOF"] = "SYNC_COMMITTEE_SELECTION_PROOF";
|
|
18
18
|
SignableMessageType["SYNC_COMMITTEE_CONTRIBUTION_AND_PROOF"] = "SYNC_COMMITTEE_CONTRIBUTION_AND_PROOF";
|
|
19
19
|
SignableMessageType["VALIDATOR_REGISTRATION"] = "VALIDATOR_REGISTRATION";
|
|
20
|
-
SignableMessageType["BLS_TO_EXECUTION_CHANGE"] = "BLS_TO_EXECUTION_CHANGE";
|
|
21
20
|
})(SignableMessageType || (SignableMessageType = {}));
|
|
22
21
|
const AggregationSlotType = new ContainerType({
|
|
23
22
|
slot: ssz.Slot,
|
|
@@ -52,7 +51,6 @@ const requiresForkInfo = {
|
|
|
52
51
|
[SignableMessageType.SYNC_COMMITTEE_SELECTION_PROOF]: true,
|
|
53
52
|
[SignableMessageType.SYNC_COMMITTEE_CONTRIBUTION_AND_PROOF]: true,
|
|
54
53
|
[SignableMessageType.VALIDATOR_REGISTRATION]: false,
|
|
55
|
-
[SignableMessageType.BLS_TO_EXECUTION_CHANGE]: true,
|
|
56
54
|
};
|
|
57
55
|
var MediaType;
|
|
58
56
|
(function (MediaType) {
|
|
@@ -76,12 +74,12 @@ export async function externalSignerPostSignature(config, externalSignerUrl, pub
|
|
|
76
74
|
requestObj.type = signableMessage.type;
|
|
77
75
|
requestObj.signingRoot = toRootHex(signingRoot);
|
|
78
76
|
if (requiresForkInfo[signableMessage.type]) {
|
|
79
|
-
const forkInfo = config.
|
|
77
|
+
const forkInfo = getForkInfoForSigning(config, signingSlot, signableMessage.type);
|
|
80
78
|
requestObj.fork_info = {
|
|
81
79
|
fork: {
|
|
82
80
|
previous_version: toHex(forkInfo.prevVersion),
|
|
83
81
|
current_version: toHex(forkInfo.version),
|
|
84
|
-
epoch: String(
|
|
82
|
+
epoch: String(forkInfo.epoch),
|
|
85
83
|
},
|
|
86
84
|
genesis_validators_root: toRootHex(config.genesisValidatorsRoot),
|
|
87
85
|
};
|
|
@@ -179,8 +177,24 @@ function serializerSignableMessagePayload(config, payload) {
|
|
|
179
177
|
return { contribution_and_proof: ssz.altair.ContributionAndProof.toJson(payload.data) };
|
|
180
178
|
case SignableMessageType.VALIDATOR_REGISTRATION:
|
|
181
179
|
return { validator_registration: ssz.bellatrix.ValidatorRegistrationV1.toJson(payload.data) };
|
|
182
|
-
case SignableMessageType.BLS_TO_EXECUTION_CHANGE:
|
|
183
|
-
return { BLS_TO_EXECUTION_CHANGE: ssz.capella.BLSToExecutionChange.toJson(payload.data) };
|
|
184
180
|
}
|
|
185
181
|
}
|
|
182
|
+
function getForkInfoForSigning(config, signingSlot, messageType) {
|
|
183
|
+
const forkInfo = config.getForkInfo(signingSlot);
|
|
184
|
+
if (messageType === SignableMessageType.VOLUNTARY_EXIT && isForkPostDeneb(forkInfo.name)) {
|
|
185
|
+
// Always uses Capella fork post-Deneb (EIP-7044)
|
|
186
|
+
const capellaFork = config.forks[ForkName.capella];
|
|
187
|
+
return {
|
|
188
|
+
version: capellaFork.version,
|
|
189
|
+
prevVersion: capellaFork.prevVersion,
|
|
190
|
+
epoch: capellaFork.epoch,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
// Use the fork at the signing slot by default
|
|
194
|
+
return {
|
|
195
|
+
version: forkInfo.version,
|
|
196
|
+
prevVersion: forkInfo.prevVersion,
|
|
197
|
+
epoch: computeEpochAtSlot(signingSlot),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
186
200
|
//# sourceMappingURL=externalSignerClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"externalSignerClient.js","sourceRoot":"","sources":["../../src/util/externalSignerClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAEtD,OAAO,
|
|
1
|
+
{"version":3,"file":"externalSignerClient.js","sourceRoot":"","sources":["../../src/util/externalSignerClient.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lodestar/validator",
|
|
3
|
-
"version": "1.39.0-dev.
|
|
3
|
+
"version": "1.39.0-dev.90334173dc",
|
|
4
4
|
"description": "A Typescript implementation of the validator client",
|
|
5
5
|
"author": "ChainSafe Systems",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -24,18 +24,18 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"clean": "rm -rf lib && rm -f *.tsbuildinfo",
|
|
26
26
|
"build": "tsc -p tsconfig.build.json",
|
|
27
|
-
"build:release": "
|
|
28
|
-
"build:watch": "
|
|
27
|
+
"build:release": "pnpm clean && pnpm run build",
|
|
28
|
+
"build:watch": "pnpm run build --watch",
|
|
29
29
|
"check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"",
|
|
30
30
|
"check-types": "tsc",
|
|
31
31
|
"lint": "biome check src/ test/",
|
|
32
|
-
"lint:fix": "
|
|
32
|
+
"lint:fix": "pnpm run lint --write",
|
|
33
33
|
"test:unit": "vitest run --project unit --project unit-minimal",
|
|
34
|
-
"test": "
|
|
34
|
+
"test": "pnpm test:unit && pnpm test:e2e",
|
|
35
35
|
"test:spec": "vitest run --project spec-minimal",
|
|
36
36
|
"test:e2e": "vitest run --project e2e --project e2e-mainnet",
|
|
37
37
|
"download-spec-tests": "node --loader=ts-node/esm test/spec/downloadTests.ts",
|
|
38
|
-
"check-readme": "
|
|
38
|
+
"check-readme": "pnpm exec ts-node ../../scripts/check_readme.ts"
|
|
39
39
|
},
|
|
40
40
|
"repository": {
|
|
41
41
|
"type": "git",
|
|
@@ -50,19 +50,21 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@chainsafe/blst": "^2.2.0",
|
|
52
52
|
"@chainsafe/ssz": "^1.2.2",
|
|
53
|
-
"@lodestar/api": "1.39.0-dev.
|
|
54
|
-
"@lodestar/config": "1.39.0-dev.
|
|
55
|
-
"@lodestar/db": "1.39.0-dev.
|
|
56
|
-
"@lodestar/params": "1.39.0-dev.
|
|
57
|
-
"@lodestar/state-transition": "1.39.0-dev.
|
|
58
|
-
"@lodestar/types": "1.39.0-dev.
|
|
59
|
-
"@lodestar/utils": "1.39.0-dev.
|
|
53
|
+
"@lodestar/api": "^1.39.0-dev.90334173dc",
|
|
54
|
+
"@lodestar/config": "^1.39.0-dev.90334173dc",
|
|
55
|
+
"@lodestar/db": "^1.39.0-dev.90334173dc",
|
|
56
|
+
"@lodestar/params": "^1.39.0-dev.90334173dc",
|
|
57
|
+
"@lodestar/state-transition": "^1.39.0-dev.90334173dc",
|
|
58
|
+
"@lodestar/types": "^1.39.0-dev.90334173dc",
|
|
59
|
+
"@lodestar/utils": "^1.39.0-dev.90334173dc",
|
|
60
60
|
"strict-event-emitter-types": "^2.0.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@lodestar/
|
|
63
|
+
"@lodestar/logger": "^1.39.0-dev.90334173dc",
|
|
64
|
+
"@lodestar/spec-test-util": "^1.39.0-dev.90334173dc",
|
|
65
|
+
"@lodestar/test-utils": "^1.39.0-dev.90334173dc",
|
|
64
66
|
"bigint-buffer": "^1.1.5",
|
|
65
67
|
"rimraf": "^4.4.1"
|
|
66
68
|
},
|
|
67
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "70ad2460adbb8c8ebd26f4575a7b5ee86c70759e"
|
|
68
70
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {ApiClient
|
|
1
|
+
import {ApiClient} from "@lodestar/api";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
3
|
import {ForkName, isForkPostElectra} from "@lodestar/params";
|
|
4
|
-
import {computeEpochAtSlot
|
|
5
|
-
import {
|
|
4
|
+
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
5
|
+
import {SignedAggregateAndProof, SingleAttestation, Slot, phase0, ssz} from "@lodestar/types";
|
|
6
6
|
import {prettyBytes, sleep, toRootHex} from "@lodestar/utils";
|
|
7
7
|
import {Metrics} from "../metrics.js";
|
|
8
8
|
import {PubkeyHex} from "../types.js";
|
|
@@ -75,18 +75,6 @@ export class AttestationService {
|
|
|
75
75
|
}
|
|
76
76
|
const fork = this.config.getForkName(slot);
|
|
77
77
|
|
|
78
|
-
if (this.opts?.distributedAggregationSelection) {
|
|
79
|
-
// Validator in distributed cluster only has a key share, not the full private key.
|
|
80
|
-
// The partial selection proofs must be exchanged for combined selection proofs by
|
|
81
|
-
// calling submitBeaconCommitteeSelections on the distributed validator middleware client.
|
|
82
|
-
// This will run in parallel to other attestation tasks but must be finished before starting
|
|
83
|
-
// attestation aggregation as it is required to correctly determine if validator is aggregator
|
|
84
|
-
// and to produce a AggregateAndProof that can be threshold aggregated by the middleware client.
|
|
85
|
-
this.runDistributedAggregationSelectionTasks(fork, duties, slot, signal).catch((e) =>
|
|
86
|
-
this.logger.error("Error on attestation aggregation selection", {slot}, e)
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
78
|
// A validator should create and broadcast the attestation to the associated attestation subnet when either
|
|
91
79
|
// (a) the validator has received a valid block from the expected block proposer for the assigned slot or
|
|
92
80
|
// (b) ATTESTATION_DUE_BPS of the slot has transpired -- whichever comes first.
|
|
@@ -274,89 +262,4 @@ export class AttestationService {
|
|
|
274
262
|
}
|
|
275
263
|
}
|
|
276
264
|
}
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Performs additional attestation aggregation tasks required if validator is part of distributed cluster
|
|
280
|
-
*
|
|
281
|
-
* 1. Exchange partial for combined selection proofs
|
|
282
|
-
* 2. Determine validators that should aggregate attestations
|
|
283
|
-
* 3. Mutate duty objects to set selection proofs for aggregators
|
|
284
|
-
* 4. Resubscribe validators as aggregators on beacon committee subnets
|
|
285
|
-
*
|
|
286
|
-
* See https://docs.google.com/document/d/1q9jOTPcYQa-3L8luRvQJ-M0eegtba4Nmon3dpO79TMk/mobilebasic
|
|
287
|
-
*/
|
|
288
|
-
private async runDistributedAggregationSelectionTasks(
|
|
289
|
-
fork: ForkName,
|
|
290
|
-
duties: AttDutyAndProof[],
|
|
291
|
-
slot: number,
|
|
292
|
-
signal: AbortSignal
|
|
293
|
-
): Promise<void> {
|
|
294
|
-
const partialSelections: routes.validator.BeaconCommitteeSelection[] = duties.map(
|
|
295
|
-
({duty, partialSelectionProof}) => ({
|
|
296
|
-
validatorIndex: duty.validatorIndex,
|
|
297
|
-
slot,
|
|
298
|
-
selectionProof: partialSelectionProof as BLSSignature,
|
|
299
|
-
})
|
|
300
|
-
);
|
|
301
|
-
|
|
302
|
-
this.logger.debug("Submitting partial beacon committee selection proofs", {slot, count: partialSelections.length});
|
|
303
|
-
|
|
304
|
-
const res = await Promise.race([
|
|
305
|
-
this.api.validator.submitBeaconCommitteeSelections({selections: partialSelections}),
|
|
306
|
-
// Exit attestation aggregation flow if there is no response after ATTESTATION_DUE_BPS of the slot as
|
|
307
|
-
// beacon node would likely not have enough time to prepare an aggregate attestation.
|
|
308
|
-
// Note that the aggregations flow is not explicitly exited but rather will be skipped
|
|
309
|
-
// due to the fact that calculation of `is_aggregator` in AttestationDutiesService is not done
|
|
310
|
-
// and selectionProof is set to null, meaning no validator will be considered an aggregator.
|
|
311
|
-
sleep(this.config.getAttestationDueMs(fork) - this.clock.msFromSlot(slot), signal),
|
|
312
|
-
]);
|
|
313
|
-
|
|
314
|
-
if (!res) {
|
|
315
|
-
throw new Error("Failed to receive combined selection proofs before ATTESTATION_DUE_BPS of the slot");
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
const combinedSelections = res.value();
|
|
319
|
-
this.logger.debug("Received combined beacon committee selection proofs", {slot, count: combinedSelections.length});
|
|
320
|
-
|
|
321
|
-
const beaconCommitteeSubscriptions: routes.validator.BeaconCommitteeSubscription[] = [];
|
|
322
|
-
|
|
323
|
-
for (const dutyAndProof of duties) {
|
|
324
|
-
const {validatorIndex, committeeIndex, committeeLength, committeesAtSlot} = dutyAndProof.duty;
|
|
325
|
-
const logCtxValidator = {slot, index: committeeIndex, validatorIndex};
|
|
326
|
-
|
|
327
|
-
const combinedSelection = combinedSelections.find((s) => s.validatorIndex === validatorIndex && s.slot === slot);
|
|
328
|
-
|
|
329
|
-
if (!combinedSelection) {
|
|
330
|
-
this.logger.warn("Did not receive combined beacon committee selection proof", logCtxValidator);
|
|
331
|
-
continue;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
const isAggregator = isAggregatorFromCommitteeLength(committeeLength, combinedSelection.selectionProof);
|
|
335
|
-
|
|
336
|
-
if (isAggregator) {
|
|
337
|
-
// Update selection proof by mutating duty object
|
|
338
|
-
dutyAndProof.selectionProof = combinedSelection.selectionProof;
|
|
339
|
-
|
|
340
|
-
// Only push subnet subscriptions with `isAggregator=true` as all validators
|
|
341
|
-
// with duties for slot are already subscribed to subnets with `isAggregator=false`.
|
|
342
|
-
beaconCommitteeSubscriptions.push({
|
|
343
|
-
validatorIndex,
|
|
344
|
-
committeesAtSlot,
|
|
345
|
-
committeeIndex,
|
|
346
|
-
slot,
|
|
347
|
-
isAggregator,
|
|
348
|
-
});
|
|
349
|
-
this.logger.debug("Resubscribing validator as aggregator on beacon committee subnet", logCtxValidator);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// If there are any subscriptions with aggregators, push them out to the beacon node.
|
|
354
|
-
if (beaconCommitteeSubscriptions.length > 0) {
|
|
355
|
-
(await this.api.validator.prepareBeaconCommitteeSubnet({subscriptions: beaconCommitteeSubscriptions})).assertOk();
|
|
356
|
-
this.logger.debug("Resubscribed validators as aggregators on beacon committee subnets", {
|
|
357
|
-
slot,
|
|
358
|
-
count: beaconCommitteeSubscriptions.length,
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
265
|
}
|
|
@@ -204,6 +204,17 @@ export class AttestationDutiesService {
|
|
|
204
204
|
for (const epoch of [currentEpoch, nextEpoch]) {
|
|
205
205
|
const epochDuties = this.dutiesByIndexByEpoch.get(epoch)?.dutiesByIndex;
|
|
206
206
|
if (epochDuties) {
|
|
207
|
+
if (this.opts?.distributedAggregationSelection) {
|
|
208
|
+
// Validator in distributed cluster only has a key share, not the full private key.
|
|
209
|
+
// The partial selection proofs must be exchanged for combined selection proofs by
|
|
210
|
+
// calling submitBeaconCommitteeSelections on the distributed validator middleware client.
|
|
211
|
+
// This is required to correctly determine if validator is aggregator and to produce
|
|
212
|
+
// a AggregateAndProof that can be threshold aggregated by the middleware client.
|
|
213
|
+
await this.runDistributedAggregationSelectionTasks(Array.from(epochDuties.values()), epoch).catch((e) =>
|
|
214
|
+
this.logger.debug("Error on attestation aggregation selection", {epoch}, e)
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
207
218
|
for (const {duty, selectionProof} of epochDuties.values()) {
|
|
208
219
|
if (indexSet.has(duty.validatorIndex)) {
|
|
209
220
|
beaconCommitteeSubscriptions.push({
|
|
@@ -367,6 +378,12 @@ export class AttestationDutiesService {
|
|
|
367
378
|
const epochDuties = this.dutiesByIndexByEpoch.get(dutyEpoch)?.dutiesByIndex;
|
|
368
379
|
|
|
369
380
|
if (epochDuties) {
|
|
381
|
+
if (this.opts?.distributedAggregationSelection) {
|
|
382
|
+
await this.runDistributedAggregationSelectionTasks(Array.from(epochDuties.values()), dutyEpoch).catch((e) =>
|
|
383
|
+
this.logger.debug("Error on attestation aggregation selection after duties reorg", logContext, e)
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
370
387
|
for (const {duty, selectionProof} of epochDuties.values()) {
|
|
371
388
|
beaconCommitteeSubscriptions.push({
|
|
372
389
|
validatorIndex: duty.validatorIndex,
|
|
@@ -403,8 +420,8 @@ export class AttestationDutiesService {
|
|
|
403
420
|
if (this.opts?.distributedAggregationSelection) {
|
|
404
421
|
// Validator in distributed cluster only has a key share, not the full private key.
|
|
405
422
|
// Passing a partial selection proof to `is_aggregator` would produce incorrect result.
|
|
406
|
-
//
|
|
407
|
-
//
|
|
423
|
+
// Before subscribing to beacon committee subnets, aggregators are determined by exchanging
|
|
424
|
+
// partial for combined selection proofs retrieved from distributed validator middleware client.
|
|
408
425
|
return {duty, selectionProof: null, partialSelectionProof: selectionProof};
|
|
409
426
|
}
|
|
410
427
|
|
|
@@ -427,4 +444,64 @@ export class AttestationDutiesService {
|
|
|
427
444
|
}
|
|
428
445
|
}
|
|
429
446
|
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Performs additional attestation aggregation tasks required if validator is part of distributed cluster
|
|
450
|
+
*
|
|
451
|
+
* 1. Exchange partial for combined selection proofs
|
|
452
|
+
* 2. Determine validators that should aggregate attestations
|
|
453
|
+
* 3. Mutate duty objects to set selection proofs for aggregators
|
|
454
|
+
*/
|
|
455
|
+
private async runDistributedAggregationSelectionTasks(duties: AttDutyAndProof[], epoch: Epoch): Promise<void> {
|
|
456
|
+
if (duties.length === 0) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const partialSelections: routes.validator.BeaconCommitteeSelection[] = duties.map(
|
|
461
|
+
({duty, partialSelectionProof}) => ({
|
|
462
|
+
validatorIndex: duty.validatorIndex,
|
|
463
|
+
slot: duty.slot,
|
|
464
|
+
selectionProof: partialSelectionProof as BLSSignature,
|
|
465
|
+
})
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
this.logger.debug("Submitting partial beacon committee selection proofs", {epoch, count: partialSelections.length});
|
|
469
|
+
|
|
470
|
+
const res = await this.api.validator.submitBeaconCommitteeSelections({selections: partialSelections});
|
|
471
|
+
|
|
472
|
+
const combinedSelections = new Map<ValidatorIndex, routes.validator.BeaconCommitteeSelection>();
|
|
473
|
+
for (const selection of res.value()) {
|
|
474
|
+
combinedSelections.set(selection.validatorIndex, selection);
|
|
475
|
+
}
|
|
476
|
+
this.logger.debug("Received combined beacon committee selection proofs", {epoch, count: combinedSelections.size});
|
|
477
|
+
|
|
478
|
+
for (const dutyAndProof of duties) {
|
|
479
|
+
const {slot, validatorIndex, committeeIndex, committeeLength} = dutyAndProof.duty;
|
|
480
|
+
const logCtxValidator = {slot, index: committeeIndex, validatorIndex};
|
|
481
|
+
|
|
482
|
+
const combinedSelection = combinedSelections.get(validatorIndex);
|
|
483
|
+
|
|
484
|
+
if (!combinedSelection) {
|
|
485
|
+
this.logger.debug("Did not receive combined beacon committee selection proof", logCtxValidator);
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (combinedSelection.slot !== slot) {
|
|
490
|
+
this.logger.debug("Received combined beacon committee selection proof for different slot", {
|
|
491
|
+
expected: slot,
|
|
492
|
+
actual: combinedSelection.slot,
|
|
493
|
+
index: committeeIndex,
|
|
494
|
+
validatorIndex,
|
|
495
|
+
});
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const isAggregator = isAggregatorFromCommitteeLength(committeeLength, combinedSelection.selectionProof);
|
|
500
|
+
|
|
501
|
+
if (isAggregator) {
|
|
502
|
+
// Update selection proof by mutating duty object
|
|
503
|
+
dutyAndProof.selectionProof = combinedSelection.selectionProof;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
430
507
|
}
|