@lodestar/beacon-node 1.47.0-dev.d9c16ea16f → 1.47.0-dev.da8dfeabda
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 +10 -3
- package/lib/api/impl/events/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +12 -22
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/impl/validator/utils.d.ts +5 -0
- package/lib/api/impl/validator/utils.d.ts.map +1 -1
- package/lib/api/impl/validator/utils.js +18 -12
- package/lib/api/impl/validator/utils.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 +15 -7
- 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 +3 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +8 -5
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +2 -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/produceBlock/produceBlockBody.d.ts +2 -0
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +6 -1
- package/lib/chain/produceBlock/produceBlockBody.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/seenCache/seenBlockProposers.d.ts +5 -1
- package/lib/chain/seenCache/seenBlockProposers.d.ts.map +1 -1
- package/lib/chain/seenCache/seenBlockProposers.js +10 -3
- package/lib/chain/seenCache/seenBlockProposers.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/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +21 -7
- package/lib/chain/validation/block.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 +32 -5
- 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 +10 -4
- package/src/api/impl/validator/index.ts +22 -27
- package/src/api/impl/validator/utils.ts +30 -15
- 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 +19 -7
- 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 +9 -5
- package/src/chain/errors/blockError.ts +9 -3
- 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/produceBlock/produceBlockBody.ts +13 -0
- package/src/chain/seenCache/seenAttesters.ts +31 -5
- package/src/chain/seenCache/seenBlockProposers.ts +13 -3
- package/src/chain/validation/attestation.ts +1 -7
- package/src/chain/validation/attesterSlashing.ts +1 -8
- package/src/chain/validation/block.ts +21 -7
- 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 +35 -3
- 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
package/src/sync/range/chain.ts
CHANGED
|
@@ -358,9 +358,10 @@ export class SyncChain {
|
|
|
358
358
|
// If a batch exceeds it's retry limit, maybe downscore peers.
|
|
359
359
|
// shouldDownscoreOnBatchError() functions enforces that all BatchErrorCode values are covered
|
|
360
360
|
if (e instanceof BatchError) {
|
|
361
|
-
const shouldReportPeer = shouldReportPeerOnBatchError(e.type.code);
|
|
361
|
+
const shouldReportPeer = shouldReportPeerOnBatchError(e.type.code, this.batches.get(e.type.startEpoch));
|
|
362
362
|
if (shouldReportPeer) {
|
|
363
|
-
|
|
363
|
+
// Only the peers actually at fault are reported, never the whole peerset.
|
|
364
|
+
for (const peer of shouldReportPeer.peers) {
|
|
364
365
|
this.reportPeer(peer, shouldReportPeer.action, shouldReportPeer.reason);
|
|
365
366
|
}
|
|
366
367
|
}
|
|
@@ -768,8 +769,11 @@ export class SyncChain {
|
|
|
768
769
|
|
|
769
770
|
// The last batch attempt is right, all others are wrong. Penalize other peers
|
|
770
771
|
const attemptOk = batch.validationSuccess();
|
|
771
|
-
for (const attempt of batch.
|
|
772
|
+
for (const attempt of batch.getPeerAttributableAttempts()) {
|
|
772
773
|
if (attempt.hash !== attemptOk.hash) {
|
|
774
|
+
// attempt.peers contains block/column/envelope peers.
|
|
775
|
+
// And if there is one bad envelope we will downscore block and column peers to
|
|
776
|
+
// TODO: resolve this
|
|
773
777
|
for (const badAttemptPeer of attempt.peers) {
|
|
774
778
|
if (attemptOk.peers.find((goodPeer) => goodPeer === badAttemptPeer)) {
|
|
775
779
|
// The same peer corrected its previous attempt
|
|
@@ -830,21 +834,32 @@ export class SyncChain {
|
|
|
830
834
|
* If peer should not be downscored, returns null.
|
|
831
835
|
*/
|
|
832
836
|
export function shouldReportPeerOnBatchError(
|
|
833
|
-
code: BatchErrorCode
|
|
834
|
-
|
|
837
|
+
code: BatchErrorCode,
|
|
838
|
+
batch: Batch | undefined
|
|
839
|
+
): {action: PeerAction.LowToleranceError; reason: string; peers: PeerIdStr[]} | null {
|
|
835
840
|
switch (code) {
|
|
836
|
-
//
|
|
837
|
-
//
|
|
838
|
-
// We drop the chain and report all peers.
|
|
839
|
-
// There are some edge cases with forks that could cause this situation, but it's unlikely.
|
|
841
|
+
// A batch could not be processed after max retry limit. Report
|
|
842
|
+
// only the peers that served a peer-attributable failed attempt.
|
|
840
843
|
case BatchErrorCode.MAX_PROCESSING_ATTEMPTS:
|
|
841
|
-
|
|
844
|
+
case BatchErrorCode.MAX_EXECUTION_ENGINE_ERROR_ATTEMPTS: {
|
|
845
|
+
// penalize both the processing-error and execution-error peers
|
|
846
|
+
const attributablePeers = [
|
|
847
|
+
...new Set(batch?.getPeerAttributableAttempts().flatMap((attempt) => attempt.peers) ?? []),
|
|
848
|
+
];
|
|
849
|
+
if (attributablePeers.length === 0) {
|
|
850
|
+
return null;
|
|
851
|
+
}
|
|
852
|
+
const reason =
|
|
853
|
+
code === BatchErrorCode.MAX_PROCESSING_ATTEMPTS
|
|
854
|
+
? "SyncChainMaxProcessingAttempts"
|
|
855
|
+
: "SyncChainMaxExecutionEngineErrorAttempts";
|
|
856
|
+
return {action: PeerAction.LowToleranceError, reason, peers: attributablePeers};
|
|
857
|
+
}
|
|
842
858
|
|
|
843
859
|
// TODO: Should peers be reported for MAX_DOWNLOAD_ATTEMPTS?
|
|
844
860
|
case BatchErrorCode.MAX_DOWNLOAD_ATTEMPTS:
|
|
845
861
|
case BatchErrorCode.INVALID_COUNT:
|
|
846
862
|
case BatchErrorCode.WRONG_STATUS:
|
|
847
|
-
case BatchErrorCode.MAX_EXECUTION_ENGINE_ERROR_ATTEMPTS:
|
|
848
863
|
return null;
|
|
849
864
|
}
|
|
850
865
|
}
|
package/src/sync/types.ts
CHANGED
|
@@ -77,7 +77,9 @@ export type PendingPayloadInput = {
|
|
|
77
77
|
export type PendingPayloadRootHex = {
|
|
78
78
|
status: PendingPayloadInputStatus.pending | PendingPayloadInputStatus.fetching;
|
|
79
79
|
rootHex: RootHex;
|
|
80
|
-
//
|
|
80
|
+
// Trusted slot only (fork choice / validated data), may be missing until resolved. NOT the gossip
|
|
81
|
+
// message slot from ChainEvent.unknownEnvelopeBlockRoot, which is untrusted and not necessarily the
|
|
82
|
+
// payload/block slot. See BlockInputSync.resolvePayloadSlot.
|
|
81
83
|
slot?: Slot;
|
|
82
84
|
timeAddedSec: number;
|
|
83
85
|
timeSyncedSec?: number;
|
package/src/sync/unknownBlock.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
-
import {
|
|
3
|
+
import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
4
|
+
import {ForkSeq, isForkPostGloas} from "@lodestar/params";
|
|
4
5
|
import {RequestError, RequestErrorCode} from "@lodestar/reqresp";
|
|
5
6
|
import {computeTimeAtSlot} from "@lodestar/state-transition";
|
|
6
7
|
import {RootHex, Slot, gloas} from "@lodestar/types";
|
|
@@ -154,6 +155,7 @@ export class BlockInputSync {
|
|
|
154
155
|
this.chain.emitter.on(ChainEvent.incompleteBlockInput, this.onIncompleteBlockInput);
|
|
155
156
|
this.chain.emitter.on(ChainEvent.incompletePayloadEnvelope, this.onIncompletePayloadEnvelope);
|
|
156
157
|
this.chain.emitter.on(ChainEvent.blockUnknownParent, this.onUnknownParent);
|
|
158
|
+
this.chain.emitter.on(ChainEvent.forkChoiceFinalized, this.pruneFinalized);
|
|
157
159
|
this.chain.emitter.on(routes.events.EventType.block, this.onBlockImported);
|
|
158
160
|
this.chain.emitter.on(routes.events.EventType.executionPayload, this.onPayloadImported);
|
|
159
161
|
this.network.events.on(NetworkEvent.peerConnected, this.onPeerConnected);
|
|
@@ -170,6 +172,7 @@ export class BlockInputSync {
|
|
|
170
172
|
this.chain.emitter.off(ChainEvent.incompleteBlockInput, this.onIncompleteBlockInput);
|
|
171
173
|
this.chain.emitter.off(ChainEvent.incompletePayloadEnvelope, this.onIncompletePayloadEnvelope);
|
|
172
174
|
this.chain.emitter.off(ChainEvent.blockUnknownParent, this.onUnknownParent);
|
|
175
|
+
this.chain.emitter.off(ChainEvent.forkChoiceFinalized, this.pruneFinalized);
|
|
173
176
|
this.chain.emitter.off(routes.events.EventType.block, this.onBlockImported);
|
|
174
177
|
this.chain.emitter.off(routes.events.EventType.executionPayload, this.onPayloadImported);
|
|
175
178
|
this.network.events.off(NetworkEvent.peerConnected, this.onPeerConnected);
|
|
@@ -215,7 +218,7 @@ export class BlockInputSync {
|
|
|
215
218
|
|
|
216
219
|
private onUnknownEnvelopeBlockRoot = (data: ChainEventData[ChainEvent.unknownEnvelopeBlockRoot]): void => {
|
|
217
220
|
try {
|
|
218
|
-
this.addByPayloadRootHex(data.rootHex, data.peer, data.
|
|
221
|
+
this.addByPayloadRootHex(data.rootHex, data.peer, this.resolvePayloadSlot(data.rootHex));
|
|
219
222
|
this.triggerUnknownBlockSearch();
|
|
220
223
|
this.metrics?.blockInputSync.requests.inc({type: PendingBlockType.UNKNOWN_PAYLOAD_BLOCK_ROOT});
|
|
221
224
|
this.metrics?.blockInputSync.payloadSource.inc({source: data.source});
|
|
@@ -258,7 +261,7 @@ export class BlockInputSync {
|
|
|
258
261
|
}
|
|
259
262
|
|
|
260
263
|
if (missingDependency.kind === "parentPayload") {
|
|
261
|
-
this.addByPayloadRootHex(missingDependency.rootHex, data.peer);
|
|
264
|
+
this.addByPayloadRootHex(missingDependency.rootHex, data.peer, missingDependency.slot);
|
|
262
265
|
} else if (missingDependency.kind === "parentBlock") {
|
|
263
266
|
this.addByRootHex(missingDependency.rootHex, data.peer);
|
|
264
267
|
}
|
|
@@ -284,6 +287,61 @@ export class BlockInputSync {
|
|
|
284
287
|
this.triggerUnknownBlockSearch();
|
|
285
288
|
};
|
|
286
289
|
|
|
290
|
+
/**
|
|
291
|
+
* Drop pending payloads and blocks that fell below the finalized slot.
|
|
292
|
+
* See https://github.com/ChainSafe/lodestar/issues/9800
|
|
293
|
+
*/
|
|
294
|
+
private pruneFinalized = (checkpoint: CheckpointWithHex): void => {
|
|
295
|
+
// Use the actual finalized block slot, not computeStartSlotAtEpoch(checkpoint.epoch)
|
|
296
|
+
// because the payload at the finalized block is not finalized
|
|
297
|
+
const finalizedSlot = this.chain.forkChoice.getFinalizedBlock().slot;
|
|
298
|
+
|
|
299
|
+
let deletedPayloads = 0;
|
|
300
|
+
let unresolvedSlotPayloads = 0;
|
|
301
|
+
for (const [rootHex, payload] of this.pendingPayloads) {
|
|
302
|
+
// Last-effort resolve for a slot-less PendingPayloadRootHex, and store it back for later passes.
|
|
303
|
+
if (!isPendingPayloadInput(payload) && !isPendingPayloadEnvelope(payload) && payload.slot === undefined) {
|
|
304
|
+
payload.slot = this.resolvePayloadSlot(rootHex);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const slot = getPayloadSyncCacheItemSlot(payload);
|
|
308
|
+
if (typeof slot !== "number") {
|
|
309
|
+
unresolvedSlotPayloads++;
|
|
310
|
+
this.logger.debug("BlockInputSync.pruneFinalized: pending payload with unresolved slot", {
|
|
311
|
+
root: rootHex,
|
|
312
|
+
finalizedSlot,
|
|
313
|
+
});
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (slot < finalizedSlot) {
|
|
318
|
+
this.pendingPayloads.delete(rootHex);
|
|
319
|
+
deletedPayloads++;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
let deletedBlocks = 0;
|
|
324
|
+
for (const [rootHex, block] of this.pendingBlocks) {
|
|
325
|
+
const slot = getBlockInputSyncCacheItemSlot(block);
|
|
326
|
+
if (typeof slot === "number" && slot < finalizedSlot) {
|
|
327
|
+
this.pendingBlocks.delete(rootHex);
|
|
328
|
+
deletedBlocks++;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (deletedPayloads > 0 || deletedBlocks > 0) {
|
|
333
|
+
this.metrics?.blockInputSync.removedBlocks.inc(deletedPayloads + deletedBlocks);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
this.logger.debug("BlockInputSync.pruneFinalized dropped pre-finalized pending items", {
|
|
337
|
+
finalizedSlot,
|
|
338
|
+
finalizedRoot: checkpoint.rootHex,
|
|
339
|
+
deletedPayloads,
|
|
340
|
+
deletedBlocks,
|
|
341
|
+
unresolvedSlotPayloads,
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
|
|
287
345
|
private addByRootHex = (rootHex: RootHex, peerIdStr?: PeerIdStr): boolean => {
|
|
288
346
|
let pendingBlock = this.pendingBlocks.get(rootHex);
|
|
289
347
|
let added = false;
|
|
@@ -382,6 +440,29 @@ export class BlockInputSync {
|
|
|
382
440
|
return added;
|
|
383
441
|
};
|
|
384
442
|
|
|
443
|
+
/**
|
|
444
|
+
* Resolve the block slot for a payload root.
|
|
445
|
+
*/
|
|
446
|
+
private resolvePayloadSlot(rootHex: RootHex): Slot | undefined {
|
|
447
|
+
// a pending block of the same root
|
|
448
|
+
const pendingBlock = this.pendingBlocks.get(rootHex);
|
|
449
|
+
if (pendingBlock) {
|
|
450
|
+
const pendingBlockSlot = getBlockInputSyncCacheItemSlot(pendingBlock);
|
|
451
|
+
if (typeof pendingBlockSlot === "number") {
|
|
452
|
+
return pendingBlockSlot;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// the block is in fork choice
|
|
457
|
+
const forkChoiceSlot = this.chain.forkChoice.getBlockHexDefaultStatus(rootHex)?.slot;
|
|
458
|
+
if (forkChoiceSlot !== undefined) {
|
|
459
|
+
return forkChoiceSlot;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// a seen payload envelope input
|
|
463
|
+
return this.chain.seenPayloadEnvelopeInputCache.get(rootHex)?.slot;
|
|
464
|
+
}
|
|
465
|
+
|
|
385
466
|
private addByPayloadInput = (
|
|
386
467
|
payloadInput: PayloadEnvelopeInput,
|
|
387
468
|
peerIdStr?: PeerIdStr,
|
|
@@ -436,10 +517,12 @@ export class BlockInputSync {
|
|
|
436
517
|
blockInput: IBlockInput
|
|
437
518
|
):
|
|
438
519
|
| {kind: "ready"}
|
|
439
|
-
| {kind: "block" | "parentBlock"
|
|
520
|
+
| {kind: "block" | "parentBlock"; rootHex: RootHex}
|
|
521
|
+
| {kind: "parentPayload"; rootHex: RootHex; slot: Slot}
|
|
440
522
|
| {kind: "invalidParentPayload"; parentRootHex: RootHex; parentBlockHashHex: RootHex} {
|
|
441
523
|
const parentRootHex = blockInput.parentRootHex;
|
|
442
|
-
|
|
524
|
+
const parentBlock = this.chain.forkChoice.getBlockHexDefaultStatus(parentRootHex);
|
|
525
|
+
if (!parentBlock) {
|
|
443
526
|
return {kind: "parentBlock", rootHex: parentRootHex};
|
|
444
527
|
}
|
|
445
528
|
|
|
@@ -464,13 +547,13 @@ export class BlockInputSync {
|
|
|
464
547
|
const parentPayloadInput = this.chain.seenPayloadEnvelopeInputCache.get(parentRootHex);
|
|
465
548
|
if (parentPayloadInput) {
|
|
466
549
|
if (parentPayloadInput.getBlockHashHex() === parentBlockHashHex) {
|
|
467
|
-
return {kind: "parentPayload", rootHex: parentRootHex};
|
|
550
|
+
return {kind: "parentPayload", rootHex: parentRootHex, slot: parentBlock.slot};
|
|
468
551
|
}
|
|
469
552
|
|
|
470
553
|
return {kind: "invalidParentPayload", parentRootHex, parentBlockHashHex};
|
|
471
554
|
}
|
|
472
555
|
|
|
473
|
-
return {kind: "parentPayload", rootHex: parentRootHex};
|
|
556
|
+
return {kind: "parentPayload", rootHex: parentRootHex, slot: parentBlock.slot};
|
|
474
557
|
}
|
|
475
558
|
|
|
476
559
|
private advancePendingBlock(pendingBlock: PendingBlockInput): AdvancePendingBlockResult {
|
|
@@ -493,9 +576,9 @@ export class BlockInputSync {
|
|
|
493
576
|
}
|
|
494
577
|
|
|
495
578
|
case "parentPayload": {
|
|
496
|
-
let added = this.addByPayloadRootHex(missingDependency.rootHex);
|
|
579
|
+
let added = this.addByPayloadRootHex(missingDependency.rootHex, undefined, missingDependency.slot);
|
|
497
580
|
for (const peerIdStr of pendingBlock.peerIdStrings) {
|
|
498
|
-
added = this.addByPayloadRootHex(missingDependency.rootHex, peerIdStr) || added;
|
|
581
|
+
added = this.addByPayloadRootHex(missingDependency.rootHex, peerIdStr, missingDependency.slot) || added;
|
|
499
582
|
}
|
|
500
583
|
return added ? "queued_parent_payload" : "blocked";
|
|
501
584
|
}
|
|
@@ -764,9 +847,10 @@ export class BlockInputSync {
|
|
|
764
847
|
// this prevents unbundling attack
|
|
765
848
|
// see https://lighthouse-blog.sigmaprime.io/mev-unbundling-rpc.html
|
|
766
849
|
const {slot: blockSlot, proposerIndex} = pendingBlock.blockInput.getBlock().message;
|
|
850
|
+
const blockRootHex = pendingBlock.blockInput.blockRootHex;
|
|
767
851
|
const logCtx = {
|
|
768
852
|
slot: blockSlot,
|
|
769
|
-
root:
|
|
853
|
+
root: blockRootHex,
|
|
770
854
|
delaySec: this.chain.clock.secFromSlot(blockSlot),
|
|
771
855
|
};
|
|
772
856
|
this.logger.verbose("Processing downloaded block", logCtx);
|
|
@@ -780,7 +864,7 @@ export class BlockInputSync {
|
|
|
780
864
|
// eligible for proposer boost to prevent unbundling attack
|
|
781
865
|
this.logger.verbose("Avoid proposer boost for this block of known proposer", {
|
|
782
866
|
slot: blockSlot,
|
|
783
|
-
root:
|
|
867
|
+
root: blockRootHex,
|
|
784
868
|
proposerIndex,
|
|
785
869
|
});
|
|
786
870
|
await sleep(proposerBoostWindowMs);
|
|
@@ -807,12 +891,24 @@ export class BlockInputSync {
|
|
|
807
891
|
if (!res.err) {
|
|
808
892
|
this.logger.verbose("Processed block from unknown sync", logCtx);
|
|
809
893
|
// no need to update status to "processed", delete anyway
|
|
810
|
-
this.pendingBlocks.delete(
|
|
894
|
+
this.pendingBlocks.delete(blockRootHex);
|
|
895
|
+
|
|
896
|
+
if (isForkPostGloas(fork)) {
|
|
897
|
+
const payloadInput = this.chain.seenPayloadEnvelopeInputCache.get(blockRootHex);
|
|
898
|
+
if (!payloadInput) {
|
|
899
|
+
this.logger.warn("PayloadEnvelopeInput not seeded during unknown sync processReadyBlock()", logCtx);
|
|
900
|
+
} else {
|
|
901
|
+
// Similar to the gossip path: immediately attempt fetch of data columns from the execution engine.
|
|
902
|
+
// The bid already carries the kzg commitments, so there is no reason to wait for the payload to arrive.
|
|
903
|
+
this.chain.getBlobsTracker.triggerGetBlobs(payloadInput);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
811
907
|
// Re-enter the scheduler so descendants blocked on either parent blocks or parent payloads
|
|
812
908
|
// are advanced through the same dependency checks as every other pending item.
|
|
813
909
|
this.triggerUnknownBlockSearch();
|
|
814
910
|
} else {
|
|
815
|
-
const errorData = {slot: pendingBlock.blockInput.slot, root:
|
|
911
|
+
const errorData = {slot: pendingBlock.blockInput.slot, root: blockRootHex};
|
|
816
912
|
if (res.err instanceof BlockError) {
|
|
817
913
|
switch (res.err.type.code) {
|
|
818
914
|
// This cases are already handled with `{ignoreIfKnown: true}`
|
|
@@ -915,6 +1011,7 @@ export class BlockInputSync {
|
|
|
915
1011
|
const pendingPayloadByRoot: PendingPayloadRootHex = {
|
|
916
1012
|
status: PendingPayloadInputStatus.pending,
|
|
917
1013
|
rootHex,
|
|
1014
|
+
slot: pendingPayload.envelope.message.payload.slotNumber,
|
|
918
1015
|
timeAddedSec: pendingPayload.timeAddedSec,
|
|
919
1016
|
peerIdStrings: new Set(pendingPayload.peerIdStrings),
|
|
920
1017
|
};
|
|
@@ -954,6 +1051,10 @@ export class BlockInputSync {
|
|
|
954
1051
|
return;
|
|
955
1052
|
}
|
|
956
1053
|
|
|
1054
|
+
if (!isPendingPayloadInput(payload) && payload.slot === undefined) {
|
|
1055
|
+
payload.slot = this.resolvePayloadSlot(rootHex);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
957
1058
|
const payloadSlot = getPayloadSyncCacheItemSlot(payload);
|
|
958
1059
|
const logCtx = {
|
|
959
1060
|
slot: payloadSlot,
|
|
@@ -969,7 +1070,13 @@ export class BlockInputSync {
|
|
|
969
1070
|
const res = await wrapError(this.fetchPayloadInput(payload));
|
|
970
1071
|
if (!res.err) {
|
|
971
1072
|
const pendingPayload = res.result;
|
|
972
|
-
|
|
1073
|
+
const resultRootHex = getPayloadSyncCacheItemRootHex(pendingPayload);
|
|
1074
|
+
// finalization may have deleted this entry while we were awaiting the network, do not resurrect it via the set below
|
|
1075
|
+
if (!this.pendingPayloads.has(resultRootHex)) {
|
|
1076
|
+
this.logger.verbose("Dropping downloaded payload, entry pruned during fetch", logCtx);
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
this.pendingPayloads.set(resultRootHex, pendingPayload);
|
|
973
1080
|
|
|
974
1081
|
if (isPendingPayloadEnvelope(pendingPayload)) {
|
|
975
1082
|
await this.reconcilePayloadEnvelope(pendingPayload);
|
|
@@ -1097,9 +1204,11 @@ export class BlockInputSync {
|
|
|
1097
1204
|
);
|
|
1098
1205
|
}
|
|
1099
1206
|
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1207
|
+
const reason =
|
|
1208
|
+
pendingColumns.size > 0
|
|
1209
|
+
? `cannot find peer with needed columns=${prettyPrintIndices(Array.from(pendingColumns))}`
|
|
1210
|
+
: "no peer available to download pending payload";
|
|
1211
|
+
throw Error(`Error fetching payload by root slot=${slot} root=${rootHex} after ${i}: ${reason}`);
|
|
1103
1212
|
}
|
|
1104
1213
|
|
|
1105
1214
|
const {peerId, client: peerClient} = peerMeta;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { PublicKey } from "@chainsafe/blst";
|
|
2
|
-
export type SignatureSetDeserialized = {
|
|
3
|
-
publicKey: PublicKey;
|
|
4
|
-
message: Uint8Array;
|
|
5
|
-
signature: Uint8Array;
|
|
6
|
-
};
|
|
7
|
-
/**
|
|
8
|
-
* Verify signatures sets with batch verification or regular core verify depending on the set count.
|
|
9
|
-
* Abstracted in a separate file to be consumed by the threaded pool and the main thread implementation.
|
|
10
|
-
*/
|
|
11
|
-
export declare function verifySignatureSetsMaybeBatch(sets: SignatureSetDeserialized[]): boolean;
|
|
12
|
-
//# sourceMappingURL=maybeBatch.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"maybeBatch.d.ts","sourceRoot":"","sources":["../../../src/chain/bls/maybeBatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAuD,MAAM,iBAAiB,CAAC;AAIhG,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,UAAU,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,wBAAwB,EAAE,GAAG,OAAO,CA8BvF"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Signature, verify, verifyMultipleAggregateSignatures } from "@chainsafe/blst";
|
|
2
|
-
const MIN_SET_COUNT_TO_BATCH = 2;
|
|
3
|
-
/**
|
|
4
|
-
* Verify signatures sets with batch verification or regular core verify depending on the set count.
|
|
5
|
-
* Abstracted in a separate file to be consumed by the threaded pool and the main thread implementation.
|
|
6
|
-
*/
|
|
7
|
-
export function verifySignatureSetsMaybeBatch(sets) {
|
|
8
|
-
try {
|
|
9
|
-
if (sets.length >= MIN_SET_COUNT_TO_BATCH) {
|
|
10
|
-
return verifyMultipleAggregateSignatures(sets.map((s) => ({
|
|
11
|
-
pk: s.publicKey,
|
|
12
|
-
msg: s.message,
|
|
13
|
-
// true = validate signature
|
|
14
|
-
sig: Signature.fromBytes(s.signature, true),
|
|
15
|
-
})));
|
|
16
|
-
}
|
|
17
|
-
// .every on an empty array returns true
|
|
18
|
-
if (sets.length === 0) {
|
|
19
|
-
throw Error("Empty signature set");
|
|
20
|
-
}
|
|
21
|
-
// If too few signature sets verify them without batching
|
|
22
|
-
return sets.every((set) => {
|
|
23
|
-
// true = validate signature
|
|
24
|
-
const sig = Signature.fromBytes(set.signature, true);
|
|
25
|
-
return verify(set.message, set.publicKey, sig);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
catch (_) {
|
|
29
|
-
// A signature could be malformed, in that case fromBytes throws error
|
|
30
|
-
// blst-ts `verifyMultipleSignatures` is also a fallible operation if mul_n_aggregate fails
|
|
31
|
-
// see https://github.com/ChainSafe/blst-ts/blob/b1ba6333f664b08e5c50b2b0d18c4f079203962b/src/lib.ts#L291
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=maybeBatch.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"maybeBatch.js","sourceRoot":"","sources":["../../../src/chain/bls/maybeBatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,SAAS,EAAE,MAAM,EAAE,iCAAiC,EAAC,MAAM,iBAAiB,CAAC;AAEhG,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAQjC;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAAC,IAAgC;IAC5E,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,MAAM,IAAI,sBAAsB,EAAE,CAAC;YAC1C,OAAO,iCAAiC,CACtC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACf,EAAE,EAAE,CAAC,CAAC,SAAS;gBACf,GAAG,EAAE,CAAC,CAAC,OAAO;gBACd,4BAA4B;gBAC5B,GAAG,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC;aAC5C,CAAC,CAAC,CACJ,CAAC;QACJ,CAAC;QAED,wCAAwC;QACxC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACrC,CAAC;QAED,yDAAyD;QACzD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACxB,4BAA4B;YAC5B,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACrD,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,sEAAsE;QACtE,2FAA2F;QAC3F,yGAAyG;QACzG,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import {PublicKey, Signature, verify, verifyMultipleAggregateSignatures} from "@chainsafe/blst";
|
|
2
|
-
|
|
3
|
-
const MIN_SET_COUNT_TO_BATCH = 2;
|
|
4
|
-
|
|
5
|
-
export type SignatureSetDeserialized = {
|
|
6
|
-
publicKey: PublicKey;
|
|
7
|
-
message: Uint8Array;
|
|
8
|
-
signature: Uint8Array;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Verify signatures sets with batch verification or regular core verify depending on the set count.
|
|
13
|
-
* Abstracted in a separate file to be consumed by the threaded pool and the main thread implementation.
|
|
14
|
-
*/
|
|
15
|
-
export function verifySignatureSetsMaybeBatch(sets: SignatureSetDeserialized[]): boolean {
|
|
16
|
-
try {
|
|
17
|
-
if (sets.length >= MIN_SET_COUNT_TO_BATCH) {
|
|
18
|
-
return verifyMultipleAggregateSignatures(
|
|
19
|
-
sets.map((s) => ({
|
|
20
|
-
pk: s.publicKey,
|
|
21
|
-
msg: s.message,
|
|
22
|
-
// true = validate signature
|
|
23
|
-
sig: Signature.fromBytes(s.signature, true),
|
|
24
|
-
}))
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// .every on an empty array returns true
|
|
29
|
-
if (sets.length === 0) {
|
|
30
|
-
throw Error("Empty signature set");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// If too few signature sets verify them without batching
|
|
34
|
-
return sets.every((set) => {
|
|
35
|
-
// true = validate signature
|
|
36
|
-
const sig = Signature.fromBytes(set.signature, true);
|
|
37
|
-
return verify(set.message, set.publicKey, sig);
|
|
38
|
-
});
|
|
39
|
-
} catch (_) {
|
|
40
|
-
// A signature could be malformed, in that case fromBytes throws error
|
|
41
|
-
// blst-ts `verifyMultipleSignatures` is also a fallible operation if mul_n_aggregate fails
|
|
42
|
-
// see https://github.com/ChainSafe/blst-ts/blob/b1ba6333f664b08e5c50b2b0d18c4f079203962b/src/lib.ts#L291
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
}
|