@lodestar/beacon-node 1.40.0-dev.9defa5c09b → 1.40.0-dev.b87b37f4d0
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 +15 -9
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +24 -0
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/rest/base.d.ts.map +1 -1
- package/lib/api/rest/base.js +2 -2
- package/lib/api/rest/base.js.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.d.ts +2 -0
- package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.js +7 -3
- package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +2 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +28 -0
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +38 -3
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/importBlock.js +1 -1
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +1 -1
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +1 -2
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +8 -0
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +3 -1
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +5 -3
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
- package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
- package/lib/chain/bls/multithread/jobItem.js +2 -2
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/singleThread.d.ts +4 -2
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +4 -2
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.d.ts +2 -2
- package/lib/chain/bls/utils.d.ts.map +1 -1
- package/lib/chain/bls/utils.js +9 -6
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/chain.d.ts +1 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +19 -31
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +2 -2
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/lightClient/index.d.ts.map +1 -1
- package/lib/chain/lightClient/index.js +1 -2
- package/lib/chain/lightClient/index.js.map +1 -1
- package/lib/chain/options.d.ts +0 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +0 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +1 -1
- package/lib/chain/regen/queued.d.ts +1 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +2 -0
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +4 -1
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +3 -3
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/serializeState.d.ts.map +1 -1
- package/lib/chain/serializeState.js +2 -1
- package/lib/chain/serializeState.js.map +1 -1
- package/lib/chain/stateCache/index.d.ts +0 -2
- package/lib/chain/stateCache/index.d.ts.map +1 -1
- package/lib/chain/stateCache/index.js +0 -2
- package/lib/chain/stateCache/index.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +2 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +3 -0
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/aggregateAndProof.js +3 -4
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts +2 -2
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +4 -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/blobSidecar.d.ts.map +1 -1
- package/lib/chain/validation/blobSidecar.js +4 -4
- package/lib/chain/validation/blobSidecar.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +2 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +4 -4
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +4 -3
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +2 -3
- package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.js +8 -3
- package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.js +3 -3
- package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/selectionProof.d.ts +2 -3
- package/lib/chain/validation/signatureSets/selectionProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/selectionProof.js +8 -3
- package/lib/chain/validation/signatureSets/selectionProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.js +3 -3
- package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
- package/lib/chain/validation/syncCommittee.js +1 -1
- package/lib/chain/validation/syncCommittee.js.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -5
- package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +1 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +7 -4
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/network/core/networkCore.d.ts +3 -0
- package/lib/network/core/networkCore.d.ts.map +1 -1
- package/lib/network/core/networkCore.js +9 -0
- package/lib/network/core/networkCore.js.map +1 -1
- package/lib/network/core/networkCoreWorker.js +3 -0
- package/lib/network/core/networkCoreWorker.js.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -0
- package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
- package/lib/network/core/networkCoreWorkerHandler.js +9 -0
- package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
- package/lib/network/core/types.d.ts +3 -0
- package/lib/network/core/types.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.d.ts +34 -0
- package/lib/network/gossip/gossipsub.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.js +123 -0
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/network.d.ts +3 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +9 -0
- package/lib/network/network.js.map +1 -1
- package/lib/network/options.d.ts +6 -0
- package/lib/network/options.d.ts.map +1 -1
- package/lib/network/options.js.map +1 -1
- package/lib/network/peers/peerManager.d.ts.map +1 -1
- package/lib/network/peers/peerManager.js +9 -0
- package/lib/network/peers/peerManager.js.map +1 -1
- package/lib/network/processor/gossipHandlers.js +1 -1
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/sync/backfill/backfill.d.ts.map +1 -1
- package/lib/sync/backfill/backfill.js +3 -4
- package/lib/sync/backfill/backfill.js.map +1 -1
- package/lib/sync/backfill/verify.d.ts +1 -2
- package/lib/sync/backfill/verify.d.ts.map +1 -1
- package/lib/sync/backfill/verify.js +2 -2
- package/lib/sync/backfill/verify.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +2 -2
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +1 -2
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/package.json +16 -16
- package/src/api/impl/beacon/blocks/index.ts +31 -19
- package/src/api/impl/lodestar/index.ts +29 -0
- package/src/api/impl/validator/index.ts +2 -1
- package/src/api/rest/base.ts +4 -4
- package/src/chain/ColumnReconstructionTracker.ts +8 -4
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +2 -1
- package/src/chain/blocks/blockInput/blockInput.ts +47 -4
- package/src/chain/blocks/importBlock.ts +1 -1
- package/src/chain/blocks/verifyBlock.ts +0 -1
- package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +1 -2
- package/src/chain/blocks/writeBlockInputToDb.ts +9 -0
- package/src/chain/bls/multithread/index.ts +7 -4
- package/src/chain/bls/multithread/jobItem.ts +7 -3
- package/src/chain/bls/singleThread.ts +5 -3
- package/src/chain/bls/utils.ts +15 -7
- package/src/chain/chain.ts +24 -35
- package/src/chain/initState.ts +2 -2
- package/src/chain/lightClient/index.ts +1 -2
- package/src/chain/options.ts +0 -2
- package/src/chain/regen/interface.ts +1 -1
- package/src/chain/regen/queued.ts +1 -2
- package/src/chain/regen/regen.ts +6 -1
- package/src/chain/seenCache/seenGossipBlockInput.ts +3 -3
- package/src/chain/serializeState.ts +2 -1
- package/src/chain/stateCache/index.ts +0 -2
- package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
- package/src/chain/validation/aggregateAndProof.ts +3 -4
- package/src/chain/validation/attestation.ts +9 -13
- package/src/chain/validation/attesterSlashing.ts +1 -6
- package/src/chain/validation/blobSidecar.ts +3 -8
- package/src/chain/validation/block.ts +2 -3
- package/src/chain/validation/dataColumnSidecar.ts +3 -8
- package/src/chain/validation/executionPayloadBid.ts +5 -4
- package/src/chain/validation/payloadAttestationMessage.ts +1 -1
- package/src/chain/validation/proposerSlashing.ts +1 -6
- package/src/chain/validation/signatureSets/aggregateAndProof.ts +9 -14
- package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -4
- package/src/chain/validation/signatureSets/selectionProof.ts +9 -9
- package/src/chain/validation/signatureSets/syncCommittee.ts +2 -4
- package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -3
- package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -4
- package/src/chain/validation/syncCommittee.ts +1 -1
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -5
- package/src/chain/validation/voluntaryExit.ts +1 -1
- package/src/chain/validatorMonitor.ts +10 -5
- package/src/network/core/networkCore.ts +12 -0
- package/src/network/core/networkCoreWorker.ts +3 -0
- package/src/network/core/networkCoreWorkerHandler.ts +9 -0
- package/src/network/core/types.ts +6 -0
- package/src/network/gossip/gossipsub.ts +147 -1
- package/src/network/network.ts +12 -0
- package/src/network/options.ts +6 -0
- package/src/network/peers/peerManager.ts +11 -0
- package/src/network/processor/gossipHandlers.ts +1 -1
- package/src/sync/backfill/backfill.ts +3 -4
- package/src/sync/backfill/verify.ts +2 -3
- package/src/sync/utils/downloadByRange.ts +2 -2
- package/src/sync/utils/downloadByRoot.ts +1 -2
- package/lib/chain/stateCache/blockStateCacheImpl.d.ts +0 -54
- package/lib/chain/stateCache/blockStateCacheImpl.d.ts.map +0 -1
- package/lib/chain/stateCache/blockStateCacheImpl.js +0 -130
- package/lib/chain/stateCache/blockStateCacheImpl.js.map +0 -1
- package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts +0 -60
- package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts.map +0 -1
- package/lib/chain/stateCache/inMemoryCheckpointsCache.js +0 -156
- package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +0 -1
- package/lib/util/bytes.d.ts +0 -3
- package/lib/util/bytes.d.ts.map +0 -1
- package/lib/util/bytes.js +0 -11
- package/lib/util/bytes.js.map +0 -1
- package/src/chain/stateCache/blockStateCacheImpl.ts +0 -149
- package/src/chain/stateCache/inMemoryCheckpointsCache.ts +0 -192
- package/src/util/bytes.ts +0 -11
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
-
import {CachedBeaconStateAllForks,
|
|
2
|
+
import {CachedBeaconStateAllForks, getBlockSignatureSets} from "@lodestar/state-transition";
|
|
3
3
|
import {IndexedAttestation, SignedBeaconBlock} from "@lodestar/types";
|
|
4
4
|
import {Logger} from "@lodestar/utils";
|
|
5
5
|
import {Metrics} from "../../metrics/metrics.js";
|
|
@@ -17,7 +17,6 @@ import {ImportBlockOpts} from "./types.js";
|
|
|
17
17
|
*/
|
|
18
18
|
export async function verifyBlocksSignatures(
|
|
19
19
|
config: BeaconConfig,
|
|
20
|
-
index2pubkey: Index2PubkeyCache,
|
|
21
20
|
bls: IBlsVerifier,
|
|
22
21
|
logger: Logger,
|
|
23
22
|
metrics: Metrics | null,
|
|
@@ -42,16 +41,9 @@ export async function verifyBlocksSignatures(
|
|
|
42
41
|
: //
|
|
43
42
|
// Verify signatures per block to track which block is invalid
|
|
44
43
|
bls.verifySignatureSets(
|
|
45
|
-
getBlockSignatureSets(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
currentSyncCommitteeIndexed,
|
|
49
|
-
block,
|
|
50
|
-
indexedAttestationsByBlock[i],
|
|
51
|
-
{
|
|
52
|
-
skipProposerSignature: opts.validProposerSignature,
|
|
53
|
-
}
|
|
54
|
-
)
|
|
44
|
+
getBlockSignatureSets(config, currentSyncCommitteeIndexed, block, indexedAttestationsByBlock[i], {
|
|
45
|
+
skipProposerSignature: opts.validProposerSignature,
|
|
46
|
+
})
|
|
55
47
|
);
|
|
56
48
|
|
|
57
49
|
// getBlockSignatureSets() takes 45ms in benchmarks for 2022Q2 mainnet blocks (100 sigs). When syncing a 32 blocks
|
|
@@ -5,9 +5,8 @@ import {
|
|
|
5
5
|
StateHashTreeRootSource,
|
|
6
6
|
stateTransition,
|
|
7
7
|
} from "@lodestar/state-transition";
|
|
8
|
-
import {ErrorAborted, Logger} from "@lodestar/utils";
|
|
8
|
+
import {ErrorAborted, Logger, byteArrayEquals} from "@lodestar/utils";
|
|
9
9
|
import {Metrics} from "../../metrics/index.js";
|
|
10
|
-
import {byteArrayEquals} from "../../util/bytes.js";
|
|
11
10
|
import {nextEventLoop} from "../../util/eventLoop.js";
|
|
12
11
|
import {BlockError, BlockErrorCode} from "../errors/index.js";
|
|
13
12
|
import {BlockProcessOpts} from "../options.js";
|
|
@@ -44,6 +44,15 @@ export async function writeBlockInputToDb(this: BeaconChain, blocksInputs: IBloc
|
|
|
44
44
|
|
|
45
45
|
// NOTE: Old data is pruned on archive
|
|
46
46
|
if (isBlockInputColumns(blockInput)) {
|
|
47
|
+
if (!blockInput.hasComputedAllData()) {
|
|
48
|
+
// Supernodes may only have a subset of the data columns by the time the block begins to be imported
|
|
49
|
+
// because full data availability can be assumed after NUMBER_OF_COLUMNS / 2 columns are available.
|
|
50
|
+
// Here, however, all data columns must be fully available/reconstructed before persisting to the DB.
|
|
51
|
+
await blockInput.waitForComputedAllData(BLOB_AVAILABILITY_TIMEOUT).catch(() => {
|
|
52
|
+
this.logger.debug("Failed to wait for computed all data", {slot, blockRoot: blockRootHex});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
47
56
|
const {custodyColumns} = this.custodyConfig;
|
|
48
57
|
const blobsLen = (block.message as fulu.BeaconBlock).body.blobKzgCommitments.length;
|
|
49
58
|
let dataColumnsLen: number;
|
|
@@ -7,7 +7,7 @@ import {Worker, spawn} from "@chainsafe/threads";
|
|
|
7
7
|
self = undefined;
|
|
8
8
|
|
|
9
9
|
import {PublicKey} from "@chainsafe/blst";
|
|
10
|
-
import {ISignatureSet} from "@lodestar/state-transition";
|
|
10
|
+
import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
|
|
11
11
|
import {Logger} from "@lodestar/utils";
|
|
12
12
|
import {Metrics} from "../../../metrics/index.js";
|
|
13
13
|
import {LinkedList} from "../../../util/array.js";
|
|
@@ -34,6 +34,7 @@ const workerDir = process.env.NODE_ENV === "test" ? "../../../../lib/chain/bls/m
|
|
|
34
34
|
export type BlsMultiThreadWorkerPoolModules = {
|
|
35
35
|
logger: Logger;
|
|
36
36
|
metrics: Metrics | null;
|
|
37
|
+
index2pubkey: Index2PubkeyCache;
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
export type BlsMultiThreadWorkerPoolOptions = {
|
|
@@ -113,6 +114,7 @@ type WorkerDescriptor = {
|
|
|
113
114
|
export class BlsMultiThreadWorkerPool implements IBlsVerifier {
|
|
114
115
|
private readonly logger: Logger;
|
|
115
116
|
private readonly metrics: Metrics | null;
|
|
117
|
+
private readonly index2pubkey: Index2PubkeyCache;
|
|
116
118
|
|
|
117
119
|
private readonly workers: WorkerDescriptor[];
|
|
118
120
|
private readonly jobs = new LinkedList<JobQueueItem>();
|
|
@@ -128,9 +130,10 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
|
|
|
128
130
|
private workersBusy = 0;
|
|
129
131
|
|
|
130
132
|
constructor(options: BlsMultiThreadWorkerPoolOptions, modules: BlsMultiThreadWorkerPoolModules) {
|
|
131
|
-
const {logger, metrics} = modules;
|
|
133
|
+
const {logger, metrics, index2pubkey} = modules;
|
|
132
134
|
this.logger = logger;
|
|
133
135
|
this.metrics = metrics;
|
|
136
|
+
this.index2pubkey = index2pubkey;
|
|
134
137
|
this.blsVerifyAllMultiThread = options.blsVerifyAllMultiThread ?? false;
|
|
135
138
|
|
|
136
139
|
// Use compressed for herumi for now.
|
|
@@ -170,7 +173,7 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
|
|
|
170
173
|
try {
|
|
171
174
|
return verifySignatureSetsMaybeBatch(
|
|
172
175
|
sets.map((set) => ({
|
|
173
|
-
publicKey: getAggregatedPubkey(set),
|
|
176
|
+
publicKey: getAggregatedPubkey(set, this.index2pubkey),
|
|
174
177
|
message: set.signingRoot.valueOf(),
|
|
175
178
|
signature: set.signature,
|
|
176
179
|
}))
|
|
@@ -395,7 +398,7 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
|
|
|
395
398
|
try {
|
|
396
399
|
// Note: This can throw, must be handled per-job.
|
|
397
400
|
// Pubkey and signature aggregation is defered here
|
|
398
|
-
workReq = await jobItemWorkReq(job, this.metrics);
|
|
401
|
+
workReq = await jobItemWorkReq(job, this.index2pubkey, this.metrics);
|
|
399
402
|
} catch (e) {
|
|
400
403
|
this.metrics?.blsThreadPool.errorAggregateSignatureSetsCount.inc({type: job.type});
|
|
401
404
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {PublicKey, asyncAggregateWithRandomness} from "@chainsafe/blst";
|
|
2
|
-
import {ISignatureSet, SignatureSetType} from "@lodestar/state-transition";
|
|
2
|
+
import {ISignatureSet, Index2PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
|
|
3
3
|
import {Metrics} from "../../../metrics/metrics.js";
|
|
4
4
|
import {LinkedList} from "../../../util/array.js";
|
|
5
5
|
import {VerifySignatureOpts} from "../interface.js";
|
|
@@ -48,14 +48,18 @@ export function jobItemSigSets(job: JobQueueItem): number {
|
|
|
48
48
|
* Prepare BlsWorkReq from JobQueueItem
|
|
49
49
|
* WARNING: May throw with untrusted user input
|
|
50
50
|
*/
|
|
51
|
-
export async function jobItemWorkReq(
|
|
51
|
+
export async function jobItemWorkReq(
|
|
52
|
+
job: JobQueueItem,
|
|
53
|
+
index2pubkey: Index2PubkeyCache,
|
|
54
|
+
metrics: Metrics | null
|
|
55
|
+
): Promise<BlsWorkReq> {
|
|
52
56
|
switch (job.type) {
|
|
53
57
|
case JobQueueItemType.default:
|
|
54
58
|
return {
|
|
55
59
|
opts: job.opts,
|
|
56
60
|
sets: job.sets.map((set) => ({
|
|
57
61
|
// this can throw, handled in the consumer code
|
|
58
|
-
publicKey: getAggregatedPubkey(set, metrics).toBytes(),
|
|
62
|
+
publicKey: getAggregatedPubkey(set, index2pubkey, metrics).toBytes(),
|
|
59
63
|
signature: set.signature,
|
|
60
64
|
message: set.signingRoot,
|
|
61
65
|
})),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {PublicKey, Signature, aggregatePublicKeys, aggregateSignatures, verify} from "@chainsafe/blst";
|
|
2
|
-
import {ISignatureSet} from "@lodestar/state-transition";
|
|
2
|
+
import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
|
|
3
3
|
import {Metrics} from "../../metrics/index.js";
|
|
4
4
|
import {IBlsVerifier} from "./interface.js";
|
|
5
5
|
import {verifySignatureSetsMaybeBatch} from "./maybeBatch.js";
|
|
@@ -7,16 +7,18 @@ import {getAggregatedPubkey, getAggregatedPubkeysCount} from "./utils.js";
|
|
|
7
7
|
|
|
8
8
|
export class BlsSingleThreadVerifier implements IBlsVerifier {
|
|
9
9
|
private readonly metrics: Metrics | null;
|
|
10
|
+
private readonly index2pubkey: Index2PubkeyCache;
|
|
10
11
|
|
|
11
|
-
constructor({metrics = null}: {metrics: Metrics | null}) {
|
|
12
|
+
constructor({metrics = null, index2pubkey}: {metrics: Metrics | null; index2pubkey: Index2PubkeyCache}) {
|
|
12
13
|
this.metrics = metrics;
|
|
14
|
+
this.index2pubkey = index2pubkey;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
async verifySignatureSets(sets: ISignatureSet[]): Promise<boolean> {
|
|
16
18
|
this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
|
|
17
19
|
|
|
18
20
|
const setsAggregated = sets.map((set) => ({
|
|
19
|
-
publicKey: getAggregatedPubkey(set),
|
|
21
|
+
publicKey: getAggregatedPubkey(set, this.index2pubkey, this.metrics),
|
|
20
22
|
message: set.signingRoot,
|
|
21
23
|
signature: set.signature,
|
|
22
24
|
}));
|
package/src/chain/bls/utils.ts
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import {PublicKey, aggregatePublicKeys} from "@chainsafe/blst";
|
|
2
|
-
import {ISignatureSet, SignatureSetType} from "@lodestar/state-transition";
|
|
2
|
+
import {ISignatureSet, Index2PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
|
|
3
3
|
import {Metrics} from "../../metrics/metrics.js";
|
|
4
4
|
|
|
5
|
-
export function getAggregatedPubkey(
|
|
5
|
+
export function getAggregatedPubkey(
|
|
6
|
+
signatureSet: ISignatureSet,
|
|
7
|
+
index2pubkey: Index2PubkeyCache,
|
|
8
|
+
metrics: Metrics | null = null
|
|
9
|
+
): PublicKey {
|
|
6
10
|
switch (signatureSet.type) {
|
|
7
11
|
case SignatureSetType.single:
|
|
8
12
|
return signatureSet.pubkey;
|
|
9
13
|
|
|
14
|
+
case SignatureSetType.indexed:
|
|
15
|
+
return index2pubkey[signatureSet.index];
|
|
16
|
+
|
|
10
17
|
case SignatureSetType.aggregate: {
|
|
11
18
|
const timer = metrics?.blsThreadPool.pubkeysAggregationMainThreadDuration.startTimer();
|
|
12
|
-
const pubkeys =
|
|
19
|
+
const pubkeys = signatureSet.indices.map((i) => index2pubkey[i]);
|
|
20
|
+
const aggregated = aggregatePublicKeys(pubkeys);
|
|
13
21
|
timer?.();
|
|
14
|
-
return
|
|
22
|
+
return aggregated;
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
default:
|
|
@@ -20,11 +28,11 @@ export function getAggregatedPubkey(signatureSet: ISignatureSet, metrics: Metric
|
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
export function getAggregatedPubkeysCount(signatureSets: ISignatureSet[]): number {
|
|
23
|
-
let
|
|
31
|
+
let pubkeysCount = 0;
|
|
24
32
|
for (const set of signatureSets) {
|
|
25
33
|
if (set.type === SignatureSetType.aggregate) {
|
|
26
|
-
|
|
34
|
+
pubkeysCount += set.indices.length;
|
|
27
35
|
}
|
|
28
36
|
}
|
|
29
|
-
return
|
|
37
|
+
return pubkeysCount;
|
|
30
38
|
}
|
package/src/chain/chain.ts
CHANGED
|
@@ -107,12 +107,10 @@ import {SeenAttestationDatas} from "./seenCache/seenAttestationData.js";
|
|
|
107
107
|
import {SeenBlockAttesters} from "./seenCache/seenBlockAttesters.js";
|
|
108
108
|
import {SeenBlockInput} from "./seenCache/seenGossipBlockInput.js";
|
|
109
109
|
import {ShufflingCache} from "./shufflingCache.js";
|
|
110
|
-
import {BlockStateCacheImpl} from "./stateCache/blockStateCacheImpl.js";
|
|
111
110
|
import {DbCPStateDatastore, checkpointToDatastoreKey} from "./stateCache/datastore/db.js";
|
|
112
111
|
import {FileCPStateDatastore} from "./stateCache/datastore/file.js";
|
|
113
112
|
import {CPStateDatastore} from "./stateCache/datastore/types.js";
|
|
114
113
|
import {FIFOBlockStateCache} from "./stateCache/fifoBlockStateCache.js";
|
|
115
|
-
import {InMemoryCheckpointStateCache} from "./stateCache/inMemoryCheckpointsCache.js";
|
|
116
114
|
import {PersistentCheckpointStateCache} from "./stateCache/persistentCheckpointsCache.js";
|
|
117
115
|
import {CheckpointStateCache} from "./stateCache/types.js";
|
|
118
116
|
import {ValidatorMonitor} from "./validatorMonitor.js";
|
|
@@ -142,7 +140,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
142
140
|
readonly logger: Logger;
|
|
143
141
|
readonly metrics: Metrics | null;
|
|
144
142
|
readonly validatorMonitor: ValidatorMonitor | null;
|
|
145
|
-
readonly bufferPool: BufferPool
|
|
143
|
+
readonly bufferPool: BufferPool;
|
|
146
144
|
|
|
147
145
|
readonly anchorStateLatestBlockSlot: Slot;
|
|
148
146
|
|
|
@@ -278,8 +276,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
278
276
|
const emitter = new ChainEventEmitter();
|
|
279
277
|
// by default, verify signatures on both main threads and worker threads
|
|
280
278
|
const bls = opts.blsVerifyAllMainThread
|
|
281
|
-
? new BlsSingleThreadVerifier({metrics})
|
|
282
|
-
: new BlsMultiThreadWorkerPool(opts, {logger, metrics});
|
|
279
|
+
? new BlsSingleThreadVerifier({metrics, index2pubkey})
|
|
280
|
+
: new BlsMultiThreadWorkerPool(opts, {logger, metrics, index2pubkey});
|
|
283
281
|
|
|
284
282
|
if (!clock) clock = new Clock({config, genesisTime: this.genesisTime, signal});
|
|
285
283
|
|
|
@@ -339,32 +337,22 @@ export class BeaconChain implements IBeaconChain {
|
|
|
339
337
|
this.index2pubkey = index2pubkey;
|
|
340
338
|
|
|
341
339
|
const fileDataStore = opts.nHistoricalStatesFileDataStore ?? true;
|
|
342
|
-
const blockStateCache = this.opts
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
this.
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
clock,
|
|
359
|
-
blockStateCache,
|
|
360
|
-
bufferPool: this.bufferPool,
|
|
361
|
-
datastore: this.cpStateDatastore,
|
|
362
|
-
},
|
|
363
|
-
this.opts
|
|
364
|
-
);
|
|
365
|
-
} else {
|
|
366
|
-
checkpointStateCache = new InMemoryCheckpointStateCache({metrics});
|
|
367
|
-
}
|
|
340
|
+
const blockStateCache = new FIFOBlockStateCache(this.opts, {metrics});
|
|
341
|
+
this.bufferPool = new BufferPool(anchorState.type.tree_serializedSize(anchorState.node), metrics);
|
|
342
|
+
|
|
343
|
+
this.cpStateDatastore = fileDataStore ? new FileCPStateDatastore(dataDir) : new DbCPStateDatastore(this.db);
|
|
344
|
+
const checkpointStateCache: CheckpointStateCache = new PersistentCheckpointStateCache(
|
|
345
|
+
{
|
|
346
|
+
config,
|
|
347
|
+
metrics,
|
|
348
|
+
logger,
|
|
349
|
+
clock,
|
|
350
|
+
blockStateCache,
|
|
351
|
+
bufferPool: this.bufferPool,
|
|
352
|
+
datastore: this.cpStateDatastore,
|
|
353
|
+
},
|
|
354
|
+
this.opts
|
|
355
|
+
);
|
|
368
356
|
|
|
369
357
|
const {checkpoint} = computeAnchorCheckpoint(config, anchorState);
|
|
370
358
|
blockStateCache.add(anchorState);
|
|
@@ -387,6 +375,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
387
375
|
forkChoice,
|
|
388
376
|
blockStateCache,
|
|
389
377
|
checkpointStateCache,
|
|
378
|
+
seenBlockInputCache: this.seenBlockInputCache,
|
|
390
379
|
db,
|
|
391
380
|
metrics,
|
|
392
381
|
validatorMonitor,
|
|
@@ -1368,13 +1357,13 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1368
1357
|
// TODO: Improve using regen here
|
|
1369
1358
|
const {blockRoot, stateRoot, slot} = this.forkChoice.getHead();
|
|
1370
1359
|
const headState = this.regen.getStateSync(stateRoot);
|
|
1371
|
-
const
|
|
1372
|
-
if (
|
|
1373
|
-
throw Error(`Head block ${slot}
|
|
1360
|
+
const blockResult = await this.getBlockByRoot(blockRoot);
|
|
1361
|
+
if (blockResult == null) {
|
|
1362
|
+
throw Error(`Head block for ${slot} is not available in cache or database`);
|
|
1374
1363
|
}
|
|
1375
1364
|
|
|
1376
1365
|
if (headState) {
|
|
1377
|
-
this.opPool.pruneAll(
|
|
1366
|
+
this.opPool.pruneAll(blockResult.block, headState);
|
|
1378
1367
|
}
|
|
1379
1368
|
|
|
1380
1369
|
if (headState === null) {
|
package/src/chain/initState.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {ChainForkConfig} from "@lodestar/config";
|
|
|
2
2
|
import {ZERO_HASH} from "@lodestar/params";
|
|
3
3
|
import {BeaconStateAllForks, computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
4
4
|
import {SignedBeaconBlock, ssz} from "@lodestar/types";
|
|
5
|
-
import {Logger, toHex, toRootHex} from "@lodestar/utils";
|
|
5
|
+
import {Logger, byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
|
|
6
6
|
import {GENESIS_SLOT} from "../constants/index.js";
|
|
7
7
|
import {IBeaconDb} from "../db/index.js";
|
|
8
8
|
import {Metrics} from "../metrics/index.js";
|
|
@@ -26,7 +26,7 @@ export async function persistAnchorState(
|
|
|
26
26
|
|
|
27
27
|
const latestBlockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(latestBlockHeader);
|
|
28
28
|
|
|
29
|
-
if (
|
|
29
|
+
if (!byteArrayEquals(blockRoot, latestBlockRoot)) {
|
|
30
30
|
throw Error(
|
|
31
31
|
`Genesis block root ${toRootHex(blockRoot)} does not match genesis state latest block root ${toRootHex(latestBlockRoot)}`
|
|
32
32
|
);
|
|
@@ -46,12 +46,11 @@ import {
|
|
|
46
46
|
ssz,
|
|
47
47
|
sszTypesFor,
|
|
48
48
|
} from "@lodestar/types";
|
|
49
|
-
import {Logger, MapDef, pruneSetToMax, toRootHex} from "@lodestar/utils";
|
|
49
|
+
import {Logger, MapDef, byteArrayEquals, pruneSetToMax, toRootHex} from "@lodestar/utils";
|
|
50
50
|
import {ZERO_HASH} from "../../constants/index.js";
|
|
51
51
|
import {IBeaconDb} from "../../db/index.js";
|
|
52
52
|
import {NUM_WITNESS, NUM_WITNESS_ELECTRA} from "../../db/repositories/lightclientSyncCommitteeWitness.js";
|
|
53
53
|
import {Metrics} from "../../metrics/index.js";
|
|
54
|
-
import {byteArrayEquals} from "../../util/bytes.js";
|
|
55
54
|
import {IClock} from "../../util/clock.js";
|
|
56
55
|
import {ChainEventEmitter} from "../emitter.js";
|
|
57
56
|
import {LightClientServerError, LightClientServerErrorCode} from "../errors/lightClientError.js";
|
package/src/chain/options.ts
CHANGED
|
@@ -45,7 +45,6 @@ export type IChainOptions = BlockProcessOpts &
|
|
|
45
45
|
broadcastValidationStrictness?: string;
|
|
46
46
|
minSameMessageSignatureSetsToBatch: number;
|
|
47
47
|
archiveDateEpochs?: number;
|
|
48
|
-
nHistoricalStates?: boolean;
|
|
49
48
|
nHistoricalStatesFileDataStore?: boolean;
|
|
50
49
|
};
|
|
51
50
|
|
|
@@ -119,7 +118,6 @@ export const defaultChainOptions: IChainOptions = {
|
|
|
119
118
|
// batching too much may block the I/O thread so if useWorker=false, suggest this value to be 32
|
|
120
119
|
// since this batch attestation work is designed to work with useWorker=true, make this the lowest value
|
|
121
120
|
minSameMessageSignatureSetsToBatch: 2,
|
|
122
|
-
nHistoricalStates: true,
|
|
123
121
|
// as of Feb 2025, this option turned out to be very useful:
|
|
124
122
|
// - it allows to share a persisted checkpoint state to other nodes
|
|
125
123
|
// - users can prune the persisted checkpoint state files manually to save disc space
|
|
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
|
|
|
2
2
|
import {ProtoBlock} from "@lodestar/fork-choice";
|
|
3
3
|
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
|
|
4
4
|
import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
|
|
5
|
-
import {CheckpointHex} from "../stateCache/
|
|
5
|
+
import {CheckpointHex} from "../stateCache/types.js";
|
|
6
6
|
|
|
7
7
|
export enum RegenCaller {
|
|
8
8
|
getDuties = "getDuties",
|
|
@@ -5,8 +5,7 @@ import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
|
|
|
5
5
|
import {Logger, toRootHex} from "@lodestar/utils";
|
|
6
6
|
import {Metrics} from "../../metrics/index.js";
|
|
7
7
|
import {JobItemQueue} from "../../util/queue/index.js";
|
|
8
|
-
import {CheckpointHex} from "../stateCache/
|
|
9
|
-
import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
|
|
8
|
+
import {BlockStateCache, CheckpointHex, CheckpointStateCache} from "../stateCache/types.js";
|
|
10
9
|
import {RegenError, RegenErrorCode} from "./errors.js";
|
|
11
10
|
import {
|
|
12
11
|
IStateRegenerator,
|
package/src/chain/regen/regen.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {Metrics} from "../../metrics/index.js";
|
|
|
18
18
|
import {nextEventLoop} from "../../util/eventLoop.js";
|
|
19
19
|
import {getCheckpointFromState} from "../blocks/utils/checkpoint.js";
|
|
20
20
|
import {ChainEvent, ChainEventEmitter} from "../emitter.js";
|
|
21
|
+
import {SeenBlockInput} from "../seenCache/seenGossipBlockInput.js";
|
|
21
22
|
import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
|
|
22
23
|
import {ValidatorMonitor} from "../validatorMonitor.js";
|
|
23
24
|
import {RegenError, RegenErrorCode} from "./errors.js";
|
|
@@ -28,6 +29,7 @@ export type RegenModules = {
|
|
|
28
29
|
forkChoice: IForkChoice;
|
|
29
30
|
blockStateCache: BlockStateCache;
|
|
30
31
|
checkpointStateCache: CheckpointStateCache;
|
|
32
|
+
seenBlockInputCache: SeenBlockInput;
|
|
31
33
|
config: ChainForkConfig;
|
|
32
34
|
emitter: ChainEventEmitter;
|
|
33
35
|
logger: Logger;
|
|
@@ -191,7 +193,10 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
191
193
|
const protoBlocksAsc = blocksToReplay.reverse();
|
|
192
194
|
for (const [i, protoBlock] of protoBlocksAsc.entries()) {
|
|
193
195
|
replaySlots[i] = protoBlock.slot;
|
|
194
|
-
|
|
196
|
+
const blockInput = this.modules.seenBlockInputCache.get(protoBlock.blockRoot);
|
|
197
|
+
blockPromises[i] = blockInput?.hasBlock()
|
|
198
|
+
? Promise.resolve(blockInput.getBlock())
|
|
199
|
+
: this.modules.db.block.get(fromHex(protoBlock.blockRoot));
|
|
195
200
|
}
|
|
196
201
|
|
|
197
202
|
const logCtx = {stateRoot, caller, replaySlots: replaySlots.join(",")};
|
|
@@ -3,7 +3,7 @@ import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
|
3
3
|
import {ForkName, ForkPostFulu, ForkPreGloas, isForkPostDeneb, isForkPostFulu, isForkPostGloas} from "@lodestar/params";
|
|
4
4
|
import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
5
5
|
import {BLSSignature, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
6
|
-
import {LodestarError, Logger, pruneSetToMax} from "@lodestar/utils";
|
|
6
|
+
import {LodestarError, Logger, byteArrayEquals, pruneSetToMax} from "@lodestar/utils";
|
|
7
7
|
import {Metrics} from "../../metrics/metrics.js";
|
|
8
8
|
import {IClock} from "../../util/clock.js";
|
|
9
9
|
import {CustodyConfig} from "../../util/dataColumns.js";
|
|
@@ -344,7 +344,7 @@ export class SeenBlockInput {
|
|
|
344
344
|
return false;
|
|
345
345
|
}
|
|
346
346
|
// Only consider verified if the signature matches
|
|
347
|
-
return
|
|
347
|
+
return byteArrayEquals(cachedSignature, signature);
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
/**
|
|
@@ -379,7 +379,7 @@ export class SeenBlockInput {
|
|
|
379
379
|
let itemsToDelete = this.blockInputs.size - MAX_BLOCK_INPUT_CACHE_SIZE;
|
|
380
380
|
|
|
381
381
|
if (itemsToDelete > 0) {
|
|
382
|
-
const sorted = [...this.blockInputs.entries()].sort((a, b) =>
|
|
382
|
+
const sorted = [...this.blockInputs.entries()].sort((a, b) => a[1].slot - b[1].slot);
|
|
383
383
|
for (const [rootHex] of sorted) {
|
|
384
384
|
this.blockInputs.delete(rootHex);
|
|
385
385
|
itemsToDelete--;
|
|
@@ -20,7 +20,8 @@ export async function serializeState<T>(
|
|
|
20
20
|
stateBytes = bufferWithKey.buffer;
|
|
21
21
|
const dataView = new DataView(stateBytes.buffer, stateBytes.byteOffset, stateBytes.byteLength);
|
|
22
22
|
state.serializeToBytes({uint8Array: stateBytes, dataView}, 0);
|
|
23
|
-
|
|
23
|
+
// Await to ensure buffer is not released back to pool until processFn completes
|
|
24
|
+
return await processFn(stateBytes);
|
|
24
25
|
}
|
|
25
26
|
// release the buffer back to the pool automatically
|
|
26
27
|
}
|
|
@@ -31,7 +31,7 @@ type PersistentCheckpointStateCacheModules = {
|
|
|
31
31
|
signal?: AbortSignal;
|
|
32
32
|
datastore: CPStateDatastore;
|
|
33
33
|
blockStateCache: BlockStateCache;
|
|
34
|
-
bufferPool?: BufferPool
|
|
34
|
+
bufferPool?: BufferPool;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
/** checkpoint serialized as a string */
|
|
@@ -119,7 +119,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
119
119
|
private readonly maxEpochsOnDisk: number;
|
|
120
120
|
private readonly datastore: CPStateDatastore;
|
|
121
121
|
private readonly blockStateCache: BlockStateCache;
|
|
122
|
-
private readonly bufferPool?: BufferPool
|
|
122
|
+
private readonly bufferPool?: BufferPool;
|
|
123
123
|
|
|
124
124
|
constructor(
|
|
125
125
|
{
|
|
@@ -851,6 +851,10 @@ export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
|
|
|
851
851
|
};
|
|
852
852
|
}
|
|
853
853
|
|
|
854
|
+
export function toCheckpointKey(cp: CheckpointHex): string {
|
|
855
|
+
return `${cp.rootHex}:${cp.epoch}`;
|
|
856
|
+
}
|
|
857
|
+
|
|
854
858
|
function toCacheKey(cp: CheckpointHex | phase0.Checkpoint): CacheKey {
|
|
855
859
|
if (isCheckpointHex(cp)) {
|
|
856
860
|
return `${cp.rootHex}_${cp.epoch}`;
|
|
@@ -239,16 +239,15 @@ async function validateAggregateAndProof(
|
|
|
239
239
|
// by the validator with index aggregate_and_proof.aggregator_index.
|
|
240
240
|
// [REJECT] The aggregator signature, signed_aggregate_and_proof.signature, is valid.
|
|
241
241
|
// [REJECT] The signature of aggregate is valid.
|
|
242
|
-
const aggregator = chain.index2pubkey[aggregateAndProof.aggregatorIndex];
|
|
243
242
|
const signingRoot = cachedAttData ? cachedAttData.signingRoot : getAttestationDataSigningRoot(chain.config, attData);
|
|
244
243
|
const indexedAttestationSignatureSet = createAggregateSignatureSetFromComponents(
|
|
245
|
-
indexedAttestation.attestingIndices
|
|
244
|
+
indexedAttestation.attestingIndices,
|
|
246
245
|
signingRoot,
|
|
247
246
|
indexedAttestation.signature
|
|
248
247
|
);
|
|
249
248
|
const signatureSets = [
|
|
250
|
-
getSelectionProofSignatureSet(chain.config, attSlot,
|
|
251
|
-
getAggregateAndProofSignatureSet(chain.config, attEpoch,
|
|
249
|
+
getSelectionProofSignatureSet(chain.config, attSlot, aggregatorIndex, signedAggregateAndProof),
|
|
250
|
+
getAggregateAndProofSignatureSet(chain.config, attEpoch, aggregatorIndex, signedAggregateAndProof),
|
|
252
251
|
indexedAttestationSignatureSet,
|
|
253
252
|
];
|
|
254
253
|
// no need to write to SeenAttestationDatas
|
|
@@ -14,13 +14,13 @@ import {
|
|
|
14
14
|
} from "@lodestar/params";
|
|
15
15
|
import {
|
|
16
16
|
EpochShuffling,
|
|
17
|
+
IndexedSignatureSet,
|
|
17
18
|
ShufflingError,
|
|
18
19
|
ShufflingErrorCode,
|
|
19
|
-
SingleSignatureSet,
|
|
20
20
|
computeEpochAtSlot,
|
|
21
21
|
computeSigningRoot,
|
|
22
22
|
computeStartSlotAtEpoch,
|
|
23
|
-
|
|
23
|
+
createIndexedSignatureSetFromComponents,
|
|
24
24
|
} from "@lodestar/state-transition";
|
|
25
25
|
import {
|
|
26
26
|
CommitteeIndex,
|
|
@@ -90,7 +90,7 @@ export type GossipAttestation = {
|
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
export type Step0Result = AttestationValidationResult & {
|
|
93
|
-
signatureSet:
|
|
93
|
+
signatureSet: IndexedSignatureSet;
|
|
94
94
|
validatorIndex: number;
|
|
95
95
|
};
|
|
96
96
|
|
|
@@ -125,7 +125,7 @@ export async function validateGossipAttestationsSameAttData(
|
|
|
125
125
|
// step1: verify signatures of all valid attestations
|
|
126
126
|
// map new index to index in resultOrErrors
|
|
127
127
|
const newIndexToOldIndex = new Map<number, number>();
|
|
128
|
-
const signatureSets:
|
|
128
|
+
const signatureSets: IndexedSignatureSet[] = [];
|
|
129
129
|
let newIndex = 0;
|
|
130
130
|
const step0Results: Step0Result[] = [];
|
|
131
131
|
for (const [i, resultOrError] of step0ResultOrErrors.entries()) {
|
|
@@ -143,7 +143,7 @@ export async function validateGossipAttestationsSameAttData(
|
|
|
143
143
|
if (batchableBls) {
|
|
144
144
|
// all signature sets should have same signing root since we filtered in network processor
|
|
145
145
|
signatureValids = await chain.bls.verifySignatureSetsSameMessage(
|
|
146
|
-
signatureSets.map((set) => ({publicKey: set.
|
|
146
|
+
signatureSets.map((set) => ({publicKey: chain.index2pubkey[set.index], signature: set.signature})),
|
|
147
147
|
signatureSets[0].signingRoot
|
|
148
148
|
);
|
|
149
149
|
} else {
|
|
@@ -498,7 +498,7 @@ async function validateAttestationNoSignatureCheck(
|
|
|
498
498
|
|
|
499
499
|
// [REJECT] The signature of attestation is valid.
|
|
500
500
|
const attestingIndices = [validatorIndex];
|
|
501
|
-
let signatureSet:
|
|
501
|
+
let signatureSet: IndexedSignatureSet;
|
|
502
502
|
let attDataRootHex: RootHex;
|
|
503
503
|
const signature = attestationOrCache.attestation
|
|
504
504
|
? attestationOrCache.attestation.signature
|
|
@@ -513,18 +513,14 @@ async function validateAttestationNoSignatureCheck(
|
|
|
513
513
|
|
|
514
514
|
if (attestationOrCache.cache) {
|
|
515
515
|
// there could be up to 6% of cpu time to compute signing root if we don't clone the signature set
|
|
516
|
-
signatureSet =
|
|
517
|
-
|
|
516
|
+
signatureSet = createIndexedSignatureSetFromComponents(
|
|
517
|
+
validatorIndex,
|
|
518
518
|
attestationOrCache.cache.signingRoot,
|
|
519
519
|
signature
|
|
520
520
|
);
|
|
521
521
|
attDataRootHex = attestationOrCache.cache.attDataRootHex;
|
|
522
522
|
} else {
|
|
523
|
-
signatureSet =
|
|
524
|
-
chain.index2pubkey[validatorIndex],
|
|
525
|
-
getSigningRoot(),
|
|
526
|
-
signature
|
|
527
|
-
);
|
|
523
|
+
signatureSet = createIndexedSignatureSetFromComponents(validatorIndex, getSigningRoot(), signature);
|
|
528
524
|
|
|
529
525
|
// add cached attestation data before verifying signature
|
|
530
526
|
attDataRootHex = toRootHex(ssz.phase0.AttestationData.hashTreeRoot(attData));
|
|
@@ -58,12 +58,7 @@ export async function validateAttesterSlashing(
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
const signatureSets = getAttesterSlashingSignatureSets(
|
|
62
|
-
chain.config,
|
|
63
|
-
chain.index2pubkey,
|
|
64
|
-
state.slot,
|
|
65
|
-
attesterSlashing
|
|
66
|
-
);
|
|
61
|
+
const signatureSets = getAttesterSlashingSignatureSets(chain.config, state.slot, attesterSlashing);
|
|
67
62
|
if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
|
|
68
63
|
throw new AttesterSlashingError(GossipAction.REJECT, {
|
|
69
64
|
code: AttesterSlashingErrorCode.INVALID,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
getBlockHeaderProposerSignatureSetByParentStateSlot,
|
|
13
13
|
} from "@lodestar/state-transition";
|
|
14
14
|
import {BlobIndex, Root, Slot, SubnetID, deneb, ssz} from "@lodestar/types";
|
|
15
|
-
import {toRootHex, verifyMerkleBranch} from "@lodestar/utils";
|
|
15
|
+
import {byteArrayEquals, toRootHex, verifyMerkleBranch} from "@lodestar/utils";
|
|
16
16
|
import {kzg} from "../../util/kzg.js";
|
|
17
17
|
import {BlobSidecarErrorCode, BlobSidecarGossipError, BlobSidecarValidationError} from "../errors/blobSidecarError.js";
|
|
18
18
|
import {GossipAction} from "../errors/gossipValidation.js";
|
|
@@ -139,7 +139,6 @@ export async function validateGossipBlobSidecar(
|
|
|
139
139
|
if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blobSlot, blockHex, signature)) {
|
|
140
140
|
const signatureSet = getBlockHeaderProposerSignatureSetByParentStateSlot(
|
|
141
141
|
chain.config,
|
|
142
|
-
chain.index2pubkey,
|
|
143
142
|
blockState.slot,
|
|
144
143
|
blobSidecar.signedBlockHeader
|
|
145
144
|
);
|
|
@@ -227,7 +226,7 @@ export async function validateBlockBlobSidecars(
|
|
|
227
226
|
const firstSidecarSignedBlockHeader = blobSidecars[0].signedBlockHeader;
|
|
228
227
|
const firstSidecarBlockHeader = firstSidecarSignedBlockHeader.message;
|
|
229
228
|
const firstBlockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(firstSidecarBlockHeader);
|
|
230
|
-
if (
|
|
229
|
+
if (!byteArrayEquals(blockRoot, firstBlockRoot)) {
|
|
231
230
|
throw new BlobSidecarValidationError(
|
|
232
231
|
{
|
|
233
232
|
code: BlobSidecarErrorCode.INCORRECT_BLOCK,
|
|
@@ -244,11 +243,7 @@ export async function validateBlockBlobSidecars(
|
|
|
244
243
|
const blockRootHex = toRootHex(blockRoot);
|
|
245
244
|
const signature = firstSidecarSignedBlockHeader.signature;
|
|
246
245
|
if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blockSlot, blockRootHex, signature)) {
|
|
247
|
-
const signatureSet = getBlockHeaderProposerSignatureSetByHeaderSlot(
|
|
248
|
-
chain.config,
|
|
249
|
-
chain.index2pubkey,
|
|
250
|
-
firstSidecarSignedBlockHeader
|
|
251
|
-
);
|
|
246
|
+
const signatureSet = getBlockHeaderProposerSignatureSetByHeaderSlot(chain.config, firstSidecarSignedBlockHeader);
|
|
252
247
|
|
|
253
248
|
if (
|
|
254
249
|
!(await chain.bls.verifySignatureSets([signatureSet], {
|