@lodestar/beacon-node 1.47.0-dev.0bcaaaebb5 → 1.47.0-dev.157b2b2a96
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/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +4 -7
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +12 -1
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -1
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/events/index.d.ts +1 -1
- package/lib/api/impl/events/index.d.ts.map +1 -1
- package/lib/api/impl/events/index.js +12 -3
- package/lib/api/impl/events/index.js.map +1 -1
- package/lib/api/impl/validator/index.js +1 -1
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.js +21 -0
- package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +2 -7
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +3 -2
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +11 -9
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +14 -6
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +22 -12
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/bls/index.d.ts +1 -1
- package/lib/chain/bls/index.d.ts.map +1 -1
- package/lib/chain/bls/interface.d.ts +5 -5
- package/lib/chain/bls/interface.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +5 -11
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +116 -101
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +5 -19
- package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
- package/lib/chain/bls/multithread/jobItem.js +10 -65
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/multithread/types.d.ts +29 -8
- package/lib/chain/bls/multithread/types.d.ts.map +1 -1
- package/lib/chain/bls/multithread/types.js +12 -0
- package/lib/chain/bls/multithread/types.js.map +1 -1
- package/lib/chain/bls/multithread/utils.d.ts +4 -0
- package/lib/chain/bls/multithread/utils.d.ts.map +1 -1
- package/lib/chain/bls/multithread/utils.js +10 -0
- package/lib/chain/bls/multithread/utils.js.map +1 -1
- package/lib/chain/bls/multithread/worker.js +49 -23
- package/lib/chain/bls/multithread/worker.js.map +1 -1
- package/lib/chain/bls/singleThread.d.ts +4 -10
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +8 -45
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.d.ts +4 -4
- package/lib/chain/bls/utils.d.ts.map +1 -1
- package/lib/chain/bls/utils.js +18 -19
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/builderCircuitBreaker.d.ts +6 -5
- package/lib/chain/builderCircuitBreaker.d.ts.map +1 -1
- package/lib/chain/builderCircuitBreaker.js +28 -15
- package/lib/chain/builderCircuitBreaker.js.map +1 -1
- package/lib/chain/chain.d.ts +2 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +6 -4
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +1 -0
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +6 -1
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/proposerPreferences.d.ts +6 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -1
- package/lib/chain/errors/proposerPreferences.js +1 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -1
- package/lib/chain/interface.d.ts +2 -1
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/attestationPool.d.ts +1 -1
- package/lib/chain/opPools/attestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/attestationPool.js +1 -1
- package/lib/chain/opPools/attestationPool.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +3 -3
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
- package/lib/chain/opPools/utils.d.ts +1 -1
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +1 -1
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/options.d.ts +1 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +1 -1
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/seenCache/seenAttesters.d.ts +9 -5
- package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
- package/lib/chain/seenCache/seenAttesters.js +25 -4
- package/lib/chain/seenCache/seenAttesters.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +1 -4
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +1 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +1 -2
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +5 -14
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts.map +1 -1
- package/lib/chain/validation/proposerPreferences.js +13 -4
- package/lib/chain/validation/proposerPreferences.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/execution/builder/http.d.ts +10 -7
- package/lib/execution/builder/http.d.ts.map +1 -1
- package/lib/execution/builder/http.js +11 -8
- package/lib/execution/builder/http.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +3 -3
- package/lib/metrics/metrics/beacon.d.ts.map +1 -1
- package/lib/metrics/metrics/beacon.js +9 -9
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +48 -18
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +96 -50
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +13 -0
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +37 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/libp2p/index.d.ts.map +1 -1
- package/lib/network/libp2p/index.js +10 -2
- package/lib/network/libp2p/index.js.map +1 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +22 -43
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +7 -2
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/reqresp/score.d.ts.map +1 -1
- package/lib/network/reqresp/score.js +5 -11
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/util.d.ts +0 -1
- package/lib/network/util.d.ts.map +1 -1
- package/lib/network/util.js +0 -4
- package/lib/network/util.js.map +1 -1
- package/lib/node/nodejs.d.ts +2 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/batch.d.ts +23 -5
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +61 -22
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +2 -1
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +23 -10
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +9 -0
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +110 -14
- package/lib/sync/unknownBlock.js.map +1 -1
- package/package.json +18 -18
- package/src/api/impl/beacon/blocks/index.ts +5 -7
- package/src/api/impl/beacon/pool/index.ts +12 -1
- package/src/api/impl/beacon/state/utils.ts +2 -1
- package/src/api/impl/events/index.ts +12 -4
- package/src/api/impl/validator/index.ts +1 -1
- package/src/chain/archiveStore/historicalState/metrics.ts +22 -0
- package/src/chain/blocks/importBlock.ts +1 -6
- package/src/chain/blocks/importExecutionPayload.ts +12 -11
- package/src/chain/blocks/index.ts +18 -6
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +25 -16
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +1 -9
- package/src/chain/bls/index.ts +1 -1
- package/src/chain/bls/interface.ts +7 -3
- package/src/chain/bls/multithread/index.ts +148 -120
- package/src/chain/bls/multithread/jobItem.ts +12 -82
- package/src/chain/bls/multithread/types.ts +33 -8
- package/src/chain/bls/multithread/utils.ts +11 -0
- package/src/chain/bls/multithread/worker.ts +85 -27
- package/src/chain/bls/singleThread.ts +11 -55
- package/src/chain/bls/utils.ts +23 -24
- package/src/chain/builderCircuitBreaker.ts +31 -17
- package/src/chain/chain.ts +7 -5
- package/src/chain/errors/blockError.ts +8 -2
- package/src/chain/errors/proposerPreferences.ts +7 -0
- package/src/chain/interface.ts +2 -1
- package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
- package/src/chain/opPools/attestationPool.ts +1 -1
- package/src/chain/opPools/payloadAttestationPool.ts +3 -3
- package/src/chain/opPools/syncCommitteeMessagePool.ts +1 -1
- package/src/chain/opPools/syncContributionAndProofPool.ts +1 -1
- package/src/chain/opPools/utils.ts +1 -1
- package/src/chain/options.ts +1 -1
- package/src/chain/prepareNextSlot.ts +1 -1
- package/src/chain/seenCache/seenAttesters.ts +31 -5
- package/src/chain/validation/attestation.ts +1 -7
- package/src/chain/validation/attesterSlashing.ts +1 -8
- package/src/chain/validation/executionPayloadBid.ts +1 -2
- package/src/chain/validation/executionPayloadEnvelope.ts +0 -1
- package/src/chain/validation/payloadAttestationMessage.ts +6 -17
- package/src/chain/validation/proposerPreferences.ts +15 -5
- package/src/chain/validation/proposerSlashing.ts +1 -1
- package/src/execution/builder/http.ts +11 -11
- package/src/metrics/metrics/beacon.ts +9 -9
- package/src/metrics/metrics/lodestar.ts +101 -51
- package/src/network/gossip/topic.ts +38 -0
- package/src/network/libp2p/index.ts +11 -2
- package/src/network/network.ts +27 -55
- package/src/network/processor/gossipHandlers.ts +9 -0
- package/src/network/reqresp/score.ts +5 -11
- package/src/network/util.ts +0 -5
- package/src/node/nodejs.ts +2 -1
- package/src/sync/range/batch.ts +83 -28
- package/src/sync/range/chain.ts +26 -11
- package/src/sync/types.ts +3 -1
- package/src/sync/unknownBlock.ts +126 -17
- package/lib/chain/bls/maybeBatch.d.ts +0 -12
- package/lib/chain/bls/maybeBatch.d.ts.map +0 -1
- package/lib/chain/bls/maybeBatch.js +0 -35
- package/lib/chain/bls/maybeBatch.js.map +0 -1
- package/src/chain/bls/maybeBatch.ts +0 -45
|
@@ -17,3 +17,14 @@ export function chunkifyMaximizeChunkSize<T>(arr: T[], minPerChunk: number): T[]
|
|
|
17
17
|
|
|
18
18
|
return arrArr;
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Splits an array into chunks that do not exceed a maximum size.
|
|
23
|
+
*/
|
|
24
|
+
export function chunkifyMaxChunkSize<T>(arr: T[], maxPerChunk: number): T[][] {
|
|
25
|
+
const chunks: T[][] = [];
|
|
26
|
+
for (let i = 0; i < arr.length; i += maxPerChunk) {
|
|
27
|
+
chunks.push(arr.slice(i, i + maxPerChunk));
|
|
28
|
+
}
|
|
29
|
+
return chunks;
|
|
30
|
+
}
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import worker from "node:worker_threads";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type BlsSignatureSet,
|
|
4
|
+
verifySignatureSets,
|
|
5
|
+
verifySignatureSetsSameMessage,
|
|
6
|
+
} from "@chainsafe/lodestar-z/bls-verifier";
|
|
3
7
|
import {expose} from "@chainsafe/threads/worker";
|
|
4
|
-
import {
|
|
5
|
-
|
|
8
|
+
import {
|
|
9
|
+
BlsWorkReq,
|
|
10
|
+
BlsWorkResult,
|
|
11
|
+
JobQueueItemType,
|
|
12
|
+
VerificationCall,
|
|
13
|
+
VerificationCallOperation,
|
|
14
|
+
WorkResult,
|
|
15
|
+
WorkResultCode,
|
|
16
|
+
WorkerData,
|
|
17
|
+
} from "./types.js";
|
|
6
18
|
import {chunkifyMaximizeChunkSize} from "./utils.js";
|
|
7
19
|
|
|
8
20
|
/**
|
|
@@ -27,23 +39,45 @@ expose({
|
|
|
27
39
|
|
|
28
40
|
function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
|
|
29
41
|
const [startSec, startNs] = process.hrtime();
|
|
30
|
-
const results: WorkResult<boolean>[] = [];
|
|
42
|
+
const results: WorkResult<boolean[]>[] = [];
|
|
43
|
+
const verificationCalls: VerificationCall[] = [];
|
|
31
44
|
let batchRetries = 0;
|
|
32
45
|
let batchSigsSuccess = 0;
|
|
33
46
|
|
|
34
47
|
// If there are multiple batchable sets attempt batch verification with them
|
|
35
|
-
const batchableSets: {idx: number; sets:
|
|
36
|
-
const nonBatchableSets: {
|
|
48
|
+
const batchableSets: {idx: number; sets: BlsSignatureSet[]}[] = [];
|
|
49
|
+
const nonBatchableSets: {
|
|
50
|
+
idx: number;
|
|
51
|
+
sets: BlsSignatureSet[];
|
|
52
|
+
operation: VerificationCallOperation.single | VerificationCallOperation.fallback;
|
|
53
|
+
}[] = [];
|
|
37
54
|
|
|
38
55
|
// Split sets between batchable and non-batchable preserving their original index in the req array
|
|
39
56
|
for (let i = 0; i < workReqArr.length; i++) {
|
|
40
57
|
const workReq = workReqArr[i];
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
switch (workReq.type) {
|
|
59
|
+
case JobQueueItemType.default: {
|
|
60
|
+
const {sets} = workReq;
|
|
61
|
+
if (workReq.opts.batchable) {
|
|
62
|
+
batchableSets.push({idx: i, sets});
|
|
63
|
+
} else {
|
|
64
|
+
nonBatchableSets.push({idx: i, sets, operation: VerificationCallOperation.single});
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case JobQueueItemType.sameMessage:
|
|
69
|
+
try {
|
|
70
|
+
const result = recordVerificationCall(
|
|
71
|
+
verificationCalls,
|
|
72
|
+
VerificationCallOperation.sameMessage,
|
|
73
|
+
workReq.sets.length,
|
|
74
|
+
() => verifySignatureSetsSameMessage(workReq.sets, workReq.message)
|
|
75
|
+
);
|
|
76
|
+
results[i] = {code: WorkResultCode.success, result};
|
|
77
|
+
} catch (e) {
|
|
78
|
+
results[i] = {code: WorkResultCode.error, error: e as Error};
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
47
81
|
}
|
|
48
82
|
}
|
|
49
83
|
|
|
@@ -52,7 +86,7 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
|
|
|
52
86
|
const batchableChunks = chunkifyMaximizeChunkSize(batchableSets, BATCHABLE_MIN_PER_CHUNK);
|
|
53
87
|
|
|
54
88
|
for (const batchableChunk of batchableChunks) {
|
|
55
|
-
const allSets:
|
|
89
|
+
const allSets: BlsSignatureSet[] = [];
|
|
56
90
|
for (const {sets} of batchableChunk) {
|
|
57
91
|
for (const set of sets) {
|
|
58
92
|
allSets.push(set);
|
|
@@ -61,33 +95,49 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
|
|
|
61
95
|
|
|
62
96
|
try {
|
|
63
97
|
// Attempt to verify multiple sets at once
|
|
64
|
-
const isValid =
|
|
98
|
+
const isValid = recordVerificationCall(verificationCalls, VerificationCallOperation.batch, allSets.length, () =>
|
|
99
|
+
verifySignatureSets(allSets)
|
|
100
|
+
);
|
|
65
101
|
|
|
66
102
|
if (isValid) {
|
|
67
103
|
// The entire batch is valid, return success to all
|
|
68
104
|
for (const {idx, sets} of batchableChunk) {
|
|
69
105
|
batchSigsSuccess += sets.length;
|
|
70
|
-
results[idx] = {code: WorkResultCode.success, result: isValid};
|
|
106
|
+
results[idx] = {code: WorkResultCode.success, result: [isValid]};
|
|
71
107
|
}
|
|
72
108
|
} else {
|
|
73
109
|
batchRetries++;
|
|
74
110
|
// Re-verify all sigs
|
|
75
|
-
nonBatchableSets.push(
|
|
111
|
+
nonBatchableSets.push(
|
|
112
|
+
...batchableChunk.map(({idx, sets}) => ({
|
|
113
|
+
idx,
|
|
114
|
+
sets,
|
|
115
|
+
operation: VerificationCallOperation.fallback as const,
|
|
116
|
+
}))
|
|
117
|
+
);
|
|
76
118
|
}
|
|
77
119
|
} catch (_e) {
|
|
78
120
|
// TODO: Ignore this error expecting that the same error will happen when re-verifying the set individually
|
|
79
|
-
// It's not ideal but
|
|
121
|
+
// It's not ideal but the BLS implementation may throw errors on some conditions
|
|
80
122
|
batchRetries++;
|
|
81
123
|
// Re-verify all sigs
|
|
82
|
-
nonBatchableSets.push(
|
|
124
|
+
nonBatchableSets.push(
|
|
125
|
+
...batchableChunk.map(({idx, sets}) => ({
|
|
126
|
+
idx,
|
|
127
|
+
sets,
|
|
128
|
+
operation: VerificationCallOperation.fallback as const,
|
|
129
|
+
}))
|
|
130
|
+
);
|
|
83
131
|
}
|
|
84
132
|
}
|
|
85
133
|
}
|
|
86
134
|
|
|
87
|
-
for (const {idx, sets} of nonBatchableSets) {
|
|
135
|
+
for (const {idx, sets, operation} of nonBatchableSets) {
|
|
88
136
|
try {
|
|
89
|
-
const isValid =
|
|
90
|
-
|
|
137
|
+
const isValid = recordVerificationCall(verificationCalls, operation, sets.length, () =>
|
|
138
|
+
verifySignatureSets(sets)
|
|
139
|
+
);
|
|
140
|
+
results[idx] = {code: WorkResultCode.success, result: [isValid]};
|
|
91
141
|
} catch (e) {
|
|
92
142
|
results[idx] = {code: WorkResultCode.error, error: e as Error};
|
|
93
143
|
}
|
|
@@ -99,16 +149,24 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
|
|
|
99
149
|
workerId,
|
|
100
150
|
batchRetries,
|
|
101
151
|
batchSigsSuccess,
|
|
152
|
+
verificationCalls,
|
|
102
153
|
workerStartTime: [startSec, startNs],
|
|
103
154
|
workerEndTime: [workerEndSec, workerEndNs],
|
|
104
155
|
results,
|
|
105
156
|
};
|
|
106
157
|
}
|
|
107
158
|
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
159
|
+
function recordVerificationCall<T>(
|
|
160
|
+
calls: VerificationCall[],
|
|
161
|
+
operation: VerificationCallOperation,
|
|
162
|
+
signatureSets: number,
|
|
163
|
+
verify: () => T
|
|
164
|
+
): T {
|
|
165
|
+
const startTime = process.hrtime();
|
|
166
|
+
try {
|
|
167
|
+
return verify();
|
|
168
|
+
} finally {
|
|
169
|
+
const [seconds, nanoseconds] = process.hrtime(startTime);
|
|
170
|
+
calls.push({operation, signatureSets, duration: seconds + nanoseconds / 1e9});
|
|
171
|
+
}
|
|
114
172
|
}
|
|
@@ -1,31 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {ISignatureSet
|
|
1
|
+
import {verifySignatureSetsSameMessage} from "@chainsafe/lodestar-z/bls-verifier";
|
|
2
|
+
import {ISignatureSet} from "@lodestar/state-transition";
|
|
3
3
|
import {Metrics} from "../../metrics/index.js";
|
|
4
|
-
import {IBlsVerifier} from "./interface.js";
|
|
5
|
-
import {
|
|
6
|
-
import {getAggregatedPubkey, getAggregatedPubkeysCount} from "./utils.js";
|
|
4
|
+
import {IBlsVerifier, SameMessageSignatureSet} from "./interface.js";
|
|
5
|
+
import {chunkSameMessageSignatureSets, getAggregatedPubkeysCount, verifySignatureSetsInBatches} from "./utils.js";
|
|
7
6
|
|
|
8
7
|
export class BlsSingleThreadVerifier implements IBlsVerifier {
|
|
9
8
|
private readonly metrics: Metrics | null;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
constructor({metrics = null, pubkeyCache}: {metrics: Metrics | null; pubkeyCache: PubkeyCache}) {
|
|
9
|
+
constructor({metrics = null}: {metrics: Metrics | null}) {
|
|
13
10
|
this.metrics = metrics;
|
|
14
|
-
this.pubkeyCache = pubkeyCache;
|
|
15
11
|
}
|
|
16
12
|
|
|
17
13
|
async verifySignatureSets(sets: ISignatureSet[]): Promise<boolean> {
|
|
18
14
|
this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
|
|
19
15
|
|
|
20
|
-
const setsAggregated = sets.map((set) => ({
|
|
21
|
-
publicKey: getAggregatedPubkey(set, this.pubkeyCache, this.metrics),
|
|
22
|
-
message: set.signingRoot,
|
|
23
|
-
signature: set.signature,
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
// Count time after aggregating
|
|
27
16
|
const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
|
|
28
|
-
const isValid =
|
|
17
|
+
const isValid = verifySignatureSetsInBatches(sets);
|
|
29
18
|
|
|
30
19
|
// Don't use a try/catch, only count run without exceptions
|
|
31
20
|
if (timer) {
|
|
@@ -35,46 +24,13 @@ export class BlsSingleThreadVerifier implements IBlsVerifier {
|
|
|
35
24
|
return isValid;
|
|
36
25
|
}
|
|
37
26
|
|
|
38
|
-
async verifySignatureSetsSameMessage(
|
|
39
|
-
sets: {publicKey: PublicKey; signature: Uint8Array}[],
|
|
40
|
-
message: Uint8Array
|
|
41
|
-
): Promise<boolean[]> {
|
|
27
|
+
async verifySignatureSetsSameMessage(sets: SameMessageSignatureSet[], message: Uint8Array): Promise<boolean[]> {
|
|
42
28
|
const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const signatures = sets.map((set) => {
|
|
47
|
-
try {
|
|
48
|
-
return Signature.fromBytes(set.signature, true);
|
|
49
|
-
} catch (_) {
|
|
50
|
-
// at least one set has malformed signature
|
|
51
|
-
isAllValid = false;
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
if (isAllValid) {
|
|
57
|
-
const signature = aggregateSignatures(signatures as Signature[]);
|
|
58
|
-
isAllValid = verify(message, pubkey, signature);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
let result: boolean[];
|
|
62
|
-
if (isAllValid) {
|
|
63
|
-
result = sets.map(() => true);
|
|
64
|
-
} else {
|
|
65
|
-
result = sets.map((set, i) => {
|
|
66
|
-
const sig = signatures[i];
|
|
67
|
-
if (sig === null) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
return verify(message, set.publicKey, sig);
|
|
71
|
-
});
|
|
29
|
+
const result: boolean[] = [];
|
|
30
|
+
for (const setsChunk of chunkSameMessageSignatureSets(sets)) {
|
|
31
|
+
result.push(...verifySignatureSetsSameMessage(setsChunk, message));
|
|
72
32
|
}
|
|
73
|
-
|
|
74
|
-
if (timer) {
|
|
75
|
-
timer();
|
|
76
|
-
}
|
|
77
|
-
|
|
33
|
+
timer?.();
|
|
78
34
|
return result;
|
|
79
35
|
}
|
|
80
36
|
|
package/src/chain/bls/utils.ts
CHANGED
|
@@ -1,33 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
BLS_VERIFIER_MAX_BATCH_SIZE,
|
|
3
|
+
BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE,
|
|
4
|
+
verifySignatureSets,
|
|
5
|
+
} from "@chainsafe/lodestar-z/bls-verifier";
|
|
6
|
+
import {ISignatureSet, SignatureSetType, toBlsSignatureSet} from "@lodestar/state-transition";
|
|
7
|
+
import {SameMessageSignatureSet} from "./interface.js";
|
|
4
8
|
|
|
5
|
-
export function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
): PublicKey {
|
|
10
|
-
switch (signatureSet.type) {
|
|
11
|
-
case SignatureSetType.single:
|
|
12
|
-
return signatureSet.pubkey;
|
|
9
|
+
export function verifySignatureSetsInBatches(signatureSets: ISignatureSet[]): boolean {
|
|
10
|
+
if (signatureSets.length === 0) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
for (let start = 0; start < signatureSets.length; start += BLS_VERIFIER_MAX_BATCH_SIZE) {
|
|
15
|
+
const sets = signatureSets.slice(start, start + BLS_VERIFIER_MAX_BATCH_SIZE).map(toBlsSignatureSet);
|
|
16
|
+
if (!verifySignatureSets(sets)) {
|
|
17
|
+
return false;
|
|
16
18
|
}
|
|
19
|
+
}
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const pubkeys = signatureSet.indices.map((i) => {
|
|
21
|
-
return pubkeyCache.getOrThrow(i);
|
|
22
|
-
});
|
|
23
|
-
const aggregated = aggregatePublicKeys(pubkeys);
|
|
24
|
-
timer?.();
|
|
25
|
-
return aggregated;
|
|
26
|
-
}
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
export function chunkSameMessageSignatureSets(sets: SameMessageSignatureSet[]): SameMessageSignatureSet[][] {
|
|
25
|
+
const chunks: SameMessageSignatureSet[][] = [];
|
|
26
|
+
for (let start = 0; start < sets.length; start += BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE) {
|
|
27
|
+
chunks.push(sets.slice(start, start + BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE));
|
|
30
28
|
}
|
|
29
|
+
return chunks;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
export function getAggregatedPubkeysCount(signatureSets: ISignatureSet[]): number {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {IForkChoice} from "@lodestar/fork-choice";
|
|
1
|
+
import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
2
2
|
import {Slot} from "@lodestar/types";
|
|
3
3
|
import {Logger} from "@lodestar/utils";
|
|
4
4
|
import {getFaultInspectionParams} from "../execution/builder/http.js";
|
|
@@ -15,11 +15,15 @@ export type BuilderCircuitBreakerModules = {
|
|
|
15
15
|
metrics: Metrics | null;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
/** Four observations is the minimum useful recovery sample for the default ~25% fault budget */
|
|
19
|
+
const MIN_BLOCKS_TO_DEACTIVATE = 4;
|
|
20
|
+
|
|
18
21
|
/**
|
|
19
22
|
* Post-gloas circuit breaker for builder bids. The beacon block is produced by the proposer
|
|
20
23
|
* regardless of bid source, so missed blocks are not a useful builder health signal. Instead
|
|
21
|
-
* count blocks
|
|
22
|
-
*
|
|
24
|
+
* count canonical blocks selected as EMPTY. Activate when the proportion of EMPTY blocks exceeds
|
|
25
|
+
* the fault budget, and resume selecting builder bids only when the observed blocks are within
|
|
26
|
+
* budget and meet the minimum recovery sample size.
|
|
23
27
|
*/
|
|
24
28
|
export class BuilderCircuitBreaker {
|
|
25
29
|
readonly faultInspectionWindow: number;
|
|
@@ -35,39 +39,49 @@ export class BuilderCircuitBreaker {
|
|
|
35
39
|
const {faultInspectionWindow, allowedFaults} = getFaultInspectionParams(opts);
|
|
36
40
|
this.faultInspectionWindow = faultInspectionWindow;
|
|
37
41
|
this.allowedFaults = allowedFaults;
|
|
42
|
+
this.modules.logger.info("Builder circuit breaker initialized", {faultInspectionWindow, allowedFaults});
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
/** Whether builder bids must be ignored for a block produced at clockSlot */
|
|
41
|
-
isActive(clockSlot: Slot): boolean {
|
|
42
|
-
this.update(clockSlot);
|
|
46
|
+
isActive(clockSlot: Slot, head: ProtoBlock): boolean {
|
|
47
|
+
this.update(clockSlot, head);
|
|
43
48
|
return this.active;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
update(clockSlot: Slot): void {
|
|
51
|
+
update(clockSlot: Slot, head: ProtoBlock): void {
|
|
47
52
|
if (clockSlot <= this.lastUpdatedSlot) {
|
|
48
53
|
return;
|
|
49
54
|
}
|
|
50
55
|
this.lastUpdatedSlot = clockSlot;
|
|
51
56
|
|
|
52
|
-
// Exclude clockSlot itself, its payload
|
|
53
|
-
const {
|
|
57
|
+
// Exclude clockSlot itself, its payload status may still be unresolved
|
|
58
|
+
const {full, empty} = this.modules.forkChoice.getCanonicalPayloadCounts(
|
|
54
59
|
Math.max(clockSlot - this.faultInspectionWindow, 0),
|
|
55
|
-
clockSlot - 1
|
|
60
|
+
clockSlot - 1,
|
|
61
|
+
head
|
|
56
62
|
);
|
|
57
|
-
const
|
|
63
|
+
const canonicalBlocks = full + empty;
|
|
58
64
|
|
|
59
65
|
const wasActive = this.active;
|
|
60
|
-
// Scale the fault budget by blocks
|
|
61
|
-
|
|
66
|
+
// Scale the fault budget by canonical blocks so sparse windows still trigger on high EMPTY rates
|
|
67
|
+
const exceedsFaultBudget = empty * this.faultInspectionWindow > this.allowedFaults * canonicalBlocks;
|
|
68
|
+
if (exceedsFaultBudget) {
|
|
69
|
+
this.active = true;
|
|
70
|
+
} else if (canonicalBlocks >= MIN_BLOCKS_TO_DEACTIVATE) {
|
|
71
|
+
// Require a minimum sample within the fault budget before accepting builder bids again
|
|
72
|
+
this.active = false;
|
|
73
|
+
}
|
|
62
74
|
|
|
63
75
|
this.modules.metrics?.builderCircuitBreaker.active.set(this.active ? 1 : 0);
|
|
64
|
-
this.modules.metrics?.builderCircuitBreaker.
|
|
65
|
-
this.modules.metrics?.builderCircuitBreaker.
|
|
66
|
-
this.modules.metrics?.builderCircuitBreaker.
|
|
76
|
+
this.modules.metrics?.builderCircuitBreaker.canonicalBlocks.set(canonicalBlocks);
|
|
77
|
+
this.modules.metrics?.builderCircuitBreaker.fullBlocks.set(full);
|
|
78
|
+
this.modules.metrics?.builderCircuitBreaker.emptyBlocks.set(empty);
|
|
67
79
|
|
|
68
80
|
const logCtx = {
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
clockSlot,
|
|
82
|
+
canonicalBlocks,
|
|
83
|
+
full,
|
|
84
|
+
empty,
|
|
71
85
|
faultInspectionWindow: this.faultInspectionWindow,
|
|
72
86
|
allowedFaults: this.allowedFaults,
|
|
73
87
|
};
|
package/src/chain/chain.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
|
+
import {type PubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
|
|
3
4
|
import {Type} from "@chainsafe/ssz";
|
|
4
5
|
import {routes} from "@lodestar/api";
|
|
5
6
|
import {BeaconConfig} from "@lodestar/config";
|
|
@@ -25,7 +26,6 @@ import {
|
|
|
25
26
|
EffectiveBalanceIncrements,
|
|
26
27
|
EpochShuffling,
|
|
27
28
|
IBeaconStateView,
|
|
28
|
-
PubkeyCache,
|
|
29
29
|
computeEndSlotAtEpoch,
|
|
30
30
|
computeEpochAtSlot,
|
|
31
31
|
computeStartSlotAtEpoch,
|
|
@@ -307,8 +307,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
307
307
|
const emitter = new ChainEventEmitter();
|
|
308
308
|
// by default, verify signatures on both main threads and worker threads
|
|
309
309
|
const bls = opts.blsVerifyAllMainThread
|
|
310
|
-
? new BlsSingleThreadVerifier({metrics
|
|
311
|
-
: new BlsMultiThreadWorkerPool(opts, {logger, metrics
|
|
310
|
+
? new BlsSingleThreadVerifier({metrics})
|
|
311
|
+
: new BlsMultiThreadWorkerPool(opts, {logger, metrics});
|
|
312
312
|
|
|
313
313
|
if (!clock) clock = new Clock({config, genesisTime: this.genesisTime, signal});
|
|
314
314
|
|
|
@@ -579,7 +579,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
579
579
|
// seenAggregators = single aggregator index, not participants of the aggregate
|
|
580
580
|
this.seenAggregators.isKnown(epoch, index) ||
|
|
581
581
|
// seenPayloadAttesters = single signer of payload attestation message
|
|
582
|
-
this.seenPayloadAttesters.
|
|
582
|
+
this.seenPayloadAttesters.seenAtEpoch(epoch, index) ||
|
|
583
583
|
// seenBlockProposers = single block proposer
|
|
584
584
|
this.seenBlockProposers.seenAtEpoch(epoch, index)
|
|
585
585
|
);
|
|
@@ -1090,7 +1090,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1090
1090
|
RegenCaller.produceBlock
|
|
1091
1091
|
);
|
|
1092
1092
|
const proposerIndex = state.getBeaconProposer(slot);
|
|
1093
|
-
const proposerPubKey = this.pubkeyCache.
|
|
1093
|
+
const proposerPubKey = this.pubkeyCache.getPubkeyBytesOrThrow(proposerIndex);
|
|
1094
1094
|
|
|
1095
1095
|
const {body, produceResult, executionPayloadValue, shouldOverrideBuilder} = await produceBlockBody.call(
|
|
1096
1096
|
this,
|
|
@@ -1577,6 +1577,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1577
1577
|
// syncContributionAndProofPool tracks metrics on its own
|
|
1578
1578
|
metrics.opPool.blsToExecutionChangePoolSize.set(this.opPool.blsToExecutionChangeSize);
|
|
1579
1579
|
metrics.chain.blacklistedBlocks.set(this.blacklistedBlocks.size);
|
|
1580
|
+
metrics.bls.pubkeyCacheSize.set(this.pubkeyCache.size);
|
|
1581
|
+
metrics.bls.pubkeyCacheCapacity.set(this.pubkeyCache.capacity);
|
|
1580
1582
|
|
|
1581
1583
|
const headState = this.getHeadState();
|
|
1582
1584
|
if (isStatePostElectra(headState)) {
|
|
@@ -136,7 +136,7 @@ export type BlockErrorType =
|
|
|
136
136
|
| {code: BlockErrorCode.NON_LINEAR_PARENT_ROOTS}
|
|
137
137
|
| {code: BlockErrorCode.NON_LINEAR_SLOTS}
|
|
138
138
|
| {code: BlockErrorCode.ENVELOPE_BLOCK_ROOT_MISMATCH; envelopeBlockRoot: RootHex; blockRoot: RootHex}
|
|
139
|
-
| {code: BlockErrorCode.PER_BLOCK_PROCESSING_ERROR; error: Error}
|
|
139
|
+
| {code: BlockErrorCode.PER_BLOCK_PROCESSING_ERROR; blockRoot: RootHex; error: Error}
|
|
140
140
|
| {code: BlockErrorCode.BEACON_CHAIN_ERROR; error: Error}
|
|
141
141
|
| {code: BlockErrorCode.KNOWN_BAD_BLOCK}
|
|
142
142
|
| {code: BlockErrorCode.BLACKLISTED_BLOCK}
|
|
@@ -184,13 +184,19 @@ export function isBlockErrorAborted(e: unknown): e is BlockError {
|
|
|
184
184
|
export function renderBlockErrorType(type: BlockErrorType): Record<string, string | number | null> {
|
|
185
185
|
switch (type.code) {
|
|
186
186
|
case BlockErrorCode.PRESTATE_MISSING:
|
|
187
|
-
case BlockErrorCode.PER_BLOCK_PROCESSING_ERROR:
|
|
188
187
|
case BlockErrorCode.BEACON_CHAIN_ERROR:
|
|
189
188
|
return {
|
|
190
189
|
code: type.code,
|
|
191
190
|
error: type.error.message,
|
|
192
191
|
};
|
|
193
192
|
|
|
193
|
+
case BlockErrorCode.PER_BLOCK_PROCESSING_ERROR:
|
|
194
|
+
return {
|
|
195
|
+
code: type.code,
|
|
196
|
+
blockRoot: type.blockRoot,
|
|
197
|
+
error: type.error.message,
|
|
198
|
+
};
|
|
199
|
+
|
|
194
200
|
case BlockErrorCode.INVALID_SIGNATURE:
|
|
195
201
|
return {
|
|
196
202
|
code: type.code,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import {ForkName} from "@lodestar/params";
|
|
1
2
|
import {Epoch, RootHex, Slot, ValidatorIndex} from "@lodestar/types";
|
|
2
3
|
import {GossipActionError} from "./gossipValidation.js";
|
|
3
4
|
|
|
4
5
|
export enum ProposerPreferencesErrorCode {
|
|
6
|
+
PRE_GLOAS_PROPOSAL_SLOT = "PROPOSER_PREFERENCES_ERROR_PRE_GLOAS_PROPOSAL_SLOT",
|
|
5
7
|
INVALID_EPOCH = "PROPOSER_PREFERENCES_ERROR_INVALID_EPOCH",
|
|
6
8
|
PROPOSAL_SLOT_PASSED = "PROPOSER_PREFERENCES_ERROR_PROPOSAL_SLOT_PASSED",
|
|
7
9
|
UNKNOWN_DEPENDENT_ROOT = "PROPOSER_PREFERENCES_ERROR_UNKNOWN_DEPENDENT_ROOT",
|
|
@@ -13,6 +15,11 @@ export enum ProposerPreferencesErrorCode {
|
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export type ProposerPreferencesErrorType =
|
|
18
|
+
| {
|
|
19
|
+
code: ProposerPreferencesErrorCode.PRE_GLOAS_PROPOSAL_SLOT;
|
|
20
|
+
proposalSlot: Slot;
|
|
21
|
+
proposalFork: ForkName;
|
|
22
|
+
}
|
|
16
23
|
| {
|
|
17
24
|
code: ProposerPreferencesErrorCode.INVALID_EPOCH;
|
|
18
25
|
proposalSlot: Slot;
|
package/src/chain/interface.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import {type PubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
|
|
1
2
|
import {Type} from "@chainsafe/ssz";
|
|
2
3
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
4
|
import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
4
|
-
import {EpochShuffling, IBeaconStateView
|
|
5
|
+
import {EpochShuffling, IBeaconStateView} from "@lodestar/state-transition";
|
|
5
6
|
import {
|
|
6
7
|
BeaconBlock,
|
|
7
8
|
BlindedBeaconBlock,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
1
|
+
import {Signature, aggregateSignatures} from "@chainsafe/lodestar-z/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {BeaconConfig} from "@lodestar/config";
|
|
4
4
|
import {IForkChoice} from "@lodestar/fork-choice";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
1
|
+
import {Signature, aggregateSignatures} from "@chainsafe/lodestar-z/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {ChainForkConfig} from "@lodestar/config";
|
|
4
4
|
import {MAX_COMMITTEES_PER_SLOT, isForkPostElectra} from "@lodestar/params";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
1
|
+
import {Signature, aggregateSignatures} from "@chainsafe/lodestar-z/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {ChainForkConfig} from "@lodestar/config";
|
|
4
4
|
import {MAX_COMMITTEES_PER_SLOT, MAX_PAYLOAD_ATTESTATIONS, PTC_SIZE} from "@lodestar/params";
|
|
@@ -178,8 +178,8 @@ function aggregateMessageInto(
|
|
|
178
178
|
validatorCommitteeIndices: number[],
|
|
179
179
|
aggregate: AggregateFast
|
|
180
180
|
): InsertOutcome {
|
|
181
|
-
// Gossip dedup via `seenPayloadAttesters` is keyed by (
|
|
182
|
-
// validator's message is never processed twice
|
|
181
|
+
// Gossip dedup via `seenPayloadAttesters` is keyed by (slot, validatorIndex), so the same
|
|
182
|
+
// validator's message is never processed twice for this aggregate's slot. All of its bits are set together or none.
|
|
183
183
|
// Checking the first index is sufficient.
|
|
184
184
|
if (aggregate.aggregationBits.get(validatorCommitteeIndices[0]) === true) {
|
|
185
185
|
return InsertOutcome.AlreadyKnown;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
1
|
+
import {Signature, aggregateSignatures} from "@chainsafe/lodestar-z/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {ChainForkConfig} from "@lodestar/config";
|
|
4
4
|
import {SYNC_COMMITTEE_SIZE, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
1
|
+
import {Signature, aggregateSignatures} from "@chainsafe/lodestar-z/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {ChainForkConfig} from "@lodestar/config";
|
|
4
4
|
import {SYNC_COMMITTEE_SIZE, SYNC_COMMITTEE_SUBNET_SIZE} from "@lodestar/params";
|
package/src/chain/options.ts
CHANGED
|
@@ -53,7 +53,7 @@ export type IChainOptions = BlockProcessOpts &
|
|
|
53
53
|
nativeStateView?: boolean;
|
|
54
54
|
/** Builder circuit breaker fault inspection window in slots */
|
|
55
55
|
faultInspectionWindow?: number;
|
|
56
|
-
/**
|
|
56
|
+
/** Canonical EMPTY blocks allowed per `faultInspectionWindow` observed blocks */
|
|
57
57
|
allowedFaults?: number;
|
|
58
58
|
};
|
|
59
59
|
|
|
@@ -169,7 +169,7 @@ export class PrepareNextSlotScheduler {
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
if (isForkPostGloas(fork)) {
|
|
172
|
-
this.chain.builderCircuitBreaker.update(clockSlot);
|
|
172
|
+
this.chain.builderCircuitBreaker.update(clockSlot, updatedHead);
|
|
173
173
|
} else {
|
|
174
174
|
// Update the builder status, if enabled shoot an api call to check status
|
|
175
175
|
this.chain.updateBuilderStatus(clockSlot);
|