@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
|
@@ -220,12 +220,6 @@ export function getBeaconBlockApi({
|
|
|
220
220
|
// Block has already been seen, e.g. via gossip racing the publish API. Benign.
|
|
221
221
|
chain.logger.debug("Ignoring already-known block during publishing", valLogMeta);
|
|
222
222
|
return;
|
|
223
|
-
case BlockErrorCode.REPEAT_PROPOSAL:
|
|
224
|
-
// The proposer already produced a block for this slot. For a solo setup this is a
|
|
225
|
-
// notable signal (duplicate-proposal attempt). For fallback / DVT setups it is
|
|
226
|
-
// expected on every block where another node published first.
|
|
227
|
-
chain.logger.warn("Ignoring repeat-proposal block during publishing", valLogMeta);
|
|
228
|
-
return;
|
|
229
223
|
}
|
|
230
224
|
}
|
|
231
225
|
|
|
@@ -407,7 +401,7 @@ export function getBeaconBlockApi({
|
|
|
407
401
|
for (let i = 0; i < dataColumnSidecars.length; i++) {
|
|
408
402
|
// + 1 because we publish to beacon_block first
|
|
409
403
|
const {sentPeers, alreadyPublished} = sentPeersArr[i + 1] as {sentPeers: number; alreadyPublished: boolean};
|
|
410
|
-
// sent peers could be 0
|
|
404
|
+
// sent peers could be 0, data_column_sidecar opts out of the zero peers publish error, see gossipTopicAllowPublishToZeroPeers
|
|
411
405
|
metrics?.dataColumns.sentPeersPerSubnet.observe(sentPeers);
|
|
412
406
|
// A duplicate publish (alreadyPublished=true) means the column is already propagating on the network —
|
|
413
407
|
// expected in self-build flows where peers gossip columns back to us before we publish the envelope.
|
|
@@ -1032,6 +1026,7 @@ export function getBeaconBlockApi({
|
|
|
1032
1026
|
},
|
|
1033
1027
|
|
|
1034
1028
|
async publishExecutionPayloadBid({signedExecutionPayloadBid}) {
|
|
1029
|
+
const seenTimestampSec = Date.now() / 1000;
|
|
1035
1030
|
const bid = signedExecutionPayloadBid.message;
|
|
1036
1031
|
const slot = bid.slot;
|
|
1037
1032
|
const fork = config.getForkName(slot);
|
|
@@ -1042,6 +1037,9 @@ export function getBeaconBlockApi({
|
|
|
1042
1037
|
|
|
1043
1038
|
await validateApiExecutionPayloadBid(chain, signedExecutionPayloadBid);
|
|
1044
1039
|
|
|
1040
|
+
const elapsedSec = chain.clock.secFromSlot(slot, seenTimestampSec);
|
|
1041
|
+
metrics?.gossipExecutionPayloadBid.elapsedTimeTillReceived.observe({source: OpSource.api}, elapsedSec);
|
|
1042
|
+
|
|
1045
1043
|
try {
|
|
1046
1044
|
const insertOutcome = chain.executionPayloadBidPool.add(signedExecutionPayloadBid);
|
|
1047
1045
|
metrics?.opPool.executionPayloadBidPool.apiInsertOutcome.inc({insertOutcome});
|
|
@@ -25,6 +25,7 @@ import {validateApiPayloadAttestationMessage} from "../../../../chain/validation
|
|
|
25
25
|
import {validateApiProposerSlashing} from "../../../../chain/validation/proposerSlashing.js";
|
|
26
26
|
import {validateApiSyncCommittee} from "../../../../chain/validation/syncCommittee.js";
|
|
27
27
|
import {validateApiVoluntaryExit} from "../../../../chain/validation/voluntaryExit.js";
|
|
28
|
+
import {OpSource} from "../../../../chain/validatorMonitor.js";
|
|
28
29
|
import {validateGossipFnRetryUnknownRoot} from "../../../../network/processor/gossipHandlers.js";
|
|
29
30
|
import {ApiError, FailureList, IndexedError} from "../../errors.js";
|
|
30
31
|
import {ApiModules} from "../../types.js";
|
|
@@ -99,7 +100,9 @@ export function getBeaconPoolApi({
|
|
|
99
100
|
const {indexedAttestation, subnet, attDataRootHex, committeeIndex, validatorCommitteeIndex, committeeSize} =
|
|
100
101
|
await validateGossipFnRetryUnknownRoot(validateFn, network, chain, slot, beaconBlockRoot);
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
try {
|
|
104
|
+
// `is_aggregator` only covers aggregating what we receive on the subnet via gossip, not what
|
|
105
|
+
// a validator client hands us directly, see https://github.com/ChainSafe/lodestar/issues/7548
|
|
103
106
|
const insertOutcome = chain.attestationPool.add(
|
|
104
107
|
committeeIndex,
|
|
105
108
|
attestation,
|
|
@@ -109,6 +112,10 @@ export function getBeaconPoolApi({
|
|
|
109
112
|
priority
|
|
110
113
|
);
|
|
111
114
|
metrics?.opPool.attestationPool.apiInsertOutcome.inc({insertOutcome});
|
|
115
|
+
} catch (e) {
|
|
116
|
+
// The pool is a local optimization, failing to insert must not stop us from publishing a
|
|
117
|
+
// validated attestation, which the route requires us to do. Same handling as the gossip path
|
|
118
|
+
logger.debug("Error adding unaggregated attestation to pool", {subnet}, e as Error);
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
if (isForkPostElectra(fork)) {
|
|
@@ -211,6 +218,7 @@ export function getBeaconPoolApi({
|
|
|
211
218
|
},
|
|
212
219
|
|
|
213
220
|
async submitPayloadAttestationMessages({payloadAttestationMessages}) {
|
|
221
|
+
const seenTimestampSec = Date.now() / 1000;
|
|
214
222
|
const failures: FailureList = [];
|
|
215
223
|
|
|
216
224
|
await Promise.all(
|
|
@@ -226,6 +234,9 @@ export function getBeaconPoolApi({
|
|
|
226
234
|
beaconBlockRoot
|
|
227
235
|
);
|
|
228
236
|
|
|
237
|
+
const delaySec = chain.clock.secFromSlot(slot, seenTimestampSec);
|
|
238
|
+
metrics?.gossipPayloadAttestationMessage.elapsedTimeTillReceived.observe({source: OpSource.api}, delaySec);
|
|
239
|
+
|
|
229
240
|
const insertOutcome = chain.payloadAttestationPool.add(
|
|
230
241
|
payloadAttestationMessage,
|
|
231
242
|
attDataRootHex,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import {type PubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
|
|
1
2
|
import {routes} from "@lodestar/api";
|
|
2
3
|
import {CheckpointWithHex, IForkChoice} from "@lodestar/fork-choice";
|
|
3
4
|
import {GENESIS_SLOT} from "@lodestar/params";
|
|
4
|
-
import {IBeaconStateView, IBeaconStateViewGloas
|
|
5
|
+
import {IBeaconStateView, IBeaconStateViewGloas} from "@lodestar/state-transition";
|
|
5
6
|
import {
|
|
6
7
|
BLSPubkey,
|
|
7
8
|
BuilderIndex,
|
|
@@ -4,7 +4,8 @@ import {ApiModules} from "../types.js";
|
|
|
4
4
|
|
|
5
5
|
export function getEventsApi({
|
|
6
6
|
chain,
|
|
7
|
-
|
|
7
|
+
logger,
|
|
8
|
+
}: Pick<ApiModules, "chain" | "config" | "logger">): ApplicationMethods<routes.events.Endpoints> {
|
|
8
9
|
return {
|
|
9
10
|
async eventstream({topics, signal, onEvent}) {
|
|
10
11
|
const onAbortFns: (() => void)[] = [];
|
|
@@ -12,9 +13,16 @@ export function getEventsApi({
|
|
|
12
13
|
for (const topic of topics) {
|
|
13
14
|
// biome-ignore lint/suspicious/noExplicitAny: We need to use `any` type here
|
|
14
15
|
const handler = (data: any): void => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
try {
|
|
17
|
+
// TS only relates `{type, message}` to the `BeaconEvent` discriminated union while
|
|
18
|
+
// `EventType` stays within its ~25-member cap; without the cast, adding events trips TS2345.
|
|
19
|
+
onEvent({type: topic, message: data} as routes.events.BeaconEvent);
|
|
20
|
+
} catch (e) {
|
|
21
|
+
// `chain.emitter` emits synchronously, a throwing listener would propagate the error to
|
|
22
|
+
// whoever emitted the event, e.g. a gossip handler, and skip the remaining listeners.
|
|
23
|
+
// A single misbehaving event or client must not affect the node or other subscribers.
|
|
24
|
+
logger.warn("Error sending event to client", {topic}, e as Error);
|
|
25
|
+
}
|
|
18
26
|
};
|
|
19
27
|
|
|
20
28
|
chain.emitter.on(topic, handler);
|
|
@@ -895,7 +895,7 @@ export function getValidatorApi(
|
|
|
895
895
|
// TODO GLOAS: add external builder api support when it is implemented
|
|
896
896
|
const isBuildingOnFull = chain.forkChoice.shouldBuildOnFull(parentBlock, slot);
|
|
897
897
|
const bidParentBlockHash = isBuildingOnFull ? parentBlock.executionPayloadBlockHash : parentBlock.parentBlockHash;
|
|
898
|
-
const circuitBreakerActive = chain.builderCircuitBreaker.isActive(slot);
|
|
898
|
+
const circuitBreakerActive = chain.builderCircuitBreaker.isActive(slot, parentBlock);
|
|
899
899
|
// Keep a builder bid as fallback unless the circuit breaker is active
|
|
900
900
|
const builderBid = circuitBreakerActive
|
|
901
901
|
? null
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {ForkName} from "@lodestar/params";
|
|
1
2
|
import {
|
|
2
3
|
BeaconStateTransitionMetrics,
|
|
3
4
|
EpochTransitionStep,
|
|
@@ -45,6 +46,27 @@ export function createHistoricalStateTransitionMetrics(
|
|
|
45
46
|
labelNames: ["step"],
|
|
46
47
|
buckets: [0.01, 0.05, 0.1, 0.2, 0.5, 0.75, 1],
|
|
47
48
|
}),
|
|
49
|
+
forkUpgradeTime: metricsRegister.histogram<{fork: ForkName}>({
|
|
50
|
+
name: "lodestar_historical_state_stfn_fork_upgrade_seconds",
|
|
51
|
+
help: "Time to upgrade the state at a fork boundary in seconds",
|
|
52
|
+
labelNames: ["fork"],
|
|
53
|
+
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30],
|
|
54
|
+
}),
|
|
55
|
+
onboardBuildersTime: metricsRegister.histogram({
|
|
56
|
+
name: "lodestar_historical_state_stfn_gloas_onboard_builders_seconds",
|
|
57
|
+
help: "Time spent in onboardBuildersFromPendingDeposits at the gloas fork transition",
|
|
58
|
+
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30],
|
|
59
|
+
}),
|
|
60
|
+
onboardBuildersDeposits: metricsRegister.gauge<{outcome: "onboarded" | "topup" | "kept" | "dropped"}>({
|
|
61
|
+
name: "lodestar_historical_state_stfn_gloas_onboard_builders_deposits",
|
|
62
|
+
help: "Pending deposits handled at the gloas fork transition, by outcome",
|
|
63
|
+
labelNames: ["outcome"],
|
|
64
|
+
}),
|
|
65
|
+
onboardBuildersSignatureChecks: metricsRegister.gauge<{source: "cache" | "verified"}>({
|
|
66
|
+
name: "lodestar_historical_state_stfn_gloas_onboard_builders_signature_checks",
|
|
67
|
+
help: "Builder deposit signature checks at the gloas fork transition, by whether the pre-verify cache served them",
|
|
68
|
+
labelNames: ["source"],
|
|
69
|
+
}),
|
|
48
70
|
processBlockTime: metricsRegister.histogram({
|
|
49
71
|
name: "lodestar_historical_state_stfn_process_block_seconds",
|
|
50
72
|
help: "Time to process a single block in seconds",
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
RootCache,
|
|
23
23
|
computeEpochAtSlot,
|
|
24
24
|
computeTimeAtSlot,
|
|
25
|
-
isStartSlotOfEpoch,
|
|
26
25
|
isStatePostAltair,
|
|
27
26
|
isStatePostBellatrix,
|
|
28
27
|
} from "@lodestar/state-transition";
|
|
@@ -404,11 +403,7 @@ export async function importBlock(
|
|
|
404
403
|
notOverrideFcuReason = NotReorgedReason.NotProposerOfNextSlot;
|
|
405
404
|
}
|
|
406
405
|
} catch (e) {
|
|
407
|
-
|
|
408
|
-
notOverrideFcuReason = NotReorgedReason.AtEpochBoundary;
|
|
409
|
-
} else {
|
|
410
|
-
this.logger.warn("Unable to get beacon proposer. Do not override fcu.", {proposalSlot}, e as Error);
|
|
411
|
-
}
|
|
406
|
+
this.logger.warn("Unable to get beacon proposer. Do not override fcu.", {proposalSlot}, e as Error);
|
|
412
407
|
}
|
|
413
408
|
|
|
414
409
|
if (shouldOverrideFcu) {
|
|
@@ -58,11 +58,12 @@ export type PayloadErrorType =
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
export class PayloadError extends Error {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
constructor(
|
|
62
|
+
readonly payloadInput: PayloadEnvelopeInput,
|
|
63
|
+
readonly type: PayloadErrorType,
|
|
64
|
+
message?: string
|
|
65
|
+
) {
|
|
64
66
|
super(message ?? type.code);
|
|
65
|
-
this.type = type;
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -125,7 +126,7 @@ export async function importExecutionPayload(
|
|
|
125
126
|
// 2. Get ProtoBlock for parent root lookup
|
|
126
127
|
const protoBlock = this.forkChoice.getBlockHexDefaultStatus(blockRootHex);
|
|
127
128
|
if (!protoBlock) {
|
|
128
|
-
throw new PayloadError({
|
|
129
|
+
throw new PayloadError(payloadInput, {
|
|
129
130
|
code: PayloadErrorCode.BLOCK_NOT_IN_FORK_CHOICE,
|
|
130
131
|
blockRootHex,
|
|
131
132
|
});
|
|
@@ -140,13 +141,13 @@ export async function importExecutionPayload(
|
|
|
140
141
|
);
|
|
141
142
|
|
|
142
143
|
if (blockState == null) {
|
|
143
|
-
throw new PayloadError({
|
|
144
|
+
throw new PayloadError(payloadInput, {
|
|
144
145
|
code: PayloadErrorCode.MISS_BLOCK_STATE,
|
|
145
146
|
blockRootHex: protoBlock.blockRoot,
|
|
146
147
|
});
|
|
147
148
|
}
|
|
148
149
|
if (!isStatePostGloas(blockState)) {
|
|
149
|
-
throw new PayloadError({
|
|
150
|
+
throw new PayloadError(payloadInput, {
|
|
150
151
|
code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
|
|
151
152
|
message: `Expected gloas+ state for payload import, got fork=${blockState.forkName}`,
|
|
152
153
|
});
|
|
@@ -161,6 +162,7 @@ export async function importExecutionPayload(
|
|
|
161
162
|
});
|
|
162
163
|
} catch (e) {
|
|
163
164
|
throw new PayloadError(
|
|
165
|
+
payloadInput,
|
|
164
166
|
{
|
|
165
167
|
code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
|
|
166
168
|
message: (e as Error).message,
|
|
@@ -184,7 +186,6 @@ export async function importExecutionPayload(
|
|
|
184
186
|
: verifyExecutionPayloadEnvelopeSignature(
|
|
185
187
|
this.config,
|
|
186
188
|
blockState,
|
|
187
|
-
this.pubkeyCache,
|
|
188
189
|
signedEnvelope,
|
|
189
190
|
payloadInput.proposerIndex,
|
|
190
191
|
this.bls
|
|
@@ -193,7 +194,7 @@ export async function importExecutionPayload(
|
|
|
193
194
|
|
|
194
195
|
// 4b. Check signature verification result
|
|
195
196
|
if (!signatureValid) {
|
|
196
|
-
throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
|
|
197
|
+
throw new PayloadError(payloadInput, {code: PayloadErrorCode.INVALID_SIGNATURE});
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
// 4c. Handle EL response
|
|
@@ -202,7 +203,7 @@ export async function importExecutionPayload(
|
|
|
202
203
|
break;
|
|
203
204
|
|
|
204
205
|
case ExecutionPayloadStatus.INVALID:
|
|
205
|
-
throw new PayloadError({
|
|
206
|
+
throw new PayloadError(payloadInput, {
|
|
206
207
|
code: PayloadErrorCode.EXECUTION_ENGINE_INVALID,
|
|
207
208
|
execStatus: execResult.status,
|
|
208
209
|
errorMessage: execResult.validationError ?? "",
|
|
@@ -215,7 +216,7 @@ export async function importExecutionPayload(
|
|
|
215
216
|
case ExecutionPayloadStatus.INVALID_BLOCK_HASH:
|
|
216
217
|
case ExecutionPayloadStatus.ELERROR:
|
|
217
218
|
case ExecutionPayloadStatus.UNAVAILABLE:
|
|
218
|
-
throw new PayloadError({
|
|
219
|
+
throw new PayloadError(payloadInput, {
|
|
219
220
|
code: PayloadErrorCode.EXECUTION_ENGINE_ERROR,
|
|
220
221
|
execStatus: execResult.status,
|
|
221
222
|
errorMessage: execResult.validationError ?? "",
|
|
@@ -8,7 +8,7 @@ import {BlockError, BlockErrorCode, isBlockErrorAborted} from "../errors/index.j
|
|
|
8
8
|
import {BlockProcessOpts} from "../options.js";
|
|
9
9
|
import {IBlockInput} from "./blockInput/types.js";
|
|
10
10
|
import {importBlock} from "./importBlock.js";
|
|
11
|
-
import {importExecutionPayload} from "./importExecutionPayload.js";
|
|
11
|
+
import {PayloadError, importExecutionPayload} from "./importExecutionPayload.js";
|
|
12
12
|
import {PayloadEnvelopeInput} from "./payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
13
13
|
import {FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
|
|
14
14
|
import {assertLinearChainSegment} from "./utils/chainSegment.js";
|
|
@@ -164,13 +164,21 @@ export async function processBlocks(
|
|
|
164
164
|
return; // Ignore
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
// above functions should only throw BlockError
|
|
168
|
-
const err =
|
|
167
|
+
// above functions should only throw BlockError, or PayloadError from the gloas payload import
|
|
168
|
+
const err = getBlockOrPayloadError(e, blocks[0].getBlock());
|
|
169
169
|
|
|
170
170
|
// TODO: De-duplicate with logic above
|
|
171
171
|
// ChainEvent.errorBlock
|
|
172
|
-
if (!(err instanceof BlockError)) {
|
|
173
|
-
this.logger.debug("
|
|
172
|
+
if (!(err instanceof BlockError) && !(err instanceof PayloadError)) {
|
|
173
|
+
this.logger.debug("Neither BlockError nor PayloadError received", {}, err);
|
|
174
|
+
} else if (err instanceof PayloadError) {
|
|
175
|
+
if (!opts.disableOnBlockError) {
|
|
176
|
+
this.logger.debug(
|
|
177
|
+
"Payload error",
|
|
178
|
+
{slot: err.payloadInput.slot, blockRoot: err.payloadInput.blockRootHex},
|
|
179
|
+
err
|
|
180
|
+
);
|
|
181
|
+
}
|
|
174
182
|
} else if (!opts.disableOnBlockError) {
|
|
175
183
|
this.logger.debug("Block error", {slot: err.signedBlock.message.slot}, err);
|
|
176
184
|
|
|
@@ -201,11 +209,15 @@ export async function processBlocks(
|
|
|
201
209
|
}
|
|
202
210
|
}
|
|
203
211
|
|
|
204
|
-
function
|
|
212
|
+
function getBlockOrPayloadError(e: unknown, block: SignedBeaconBlock): BlockError | PayloadError {
|
|
205
213
|
if (e instanceof BlockError) {
|
|
206
214
|
return e;
|
|
207
215
|
}
|
|
208
216
|
|
|
217
|
+
if (e instanceof PayloadError) {
|
|
218
|
+
return e;
|
|
219
|
+
}
|
|
220
|
+
|
|
209
221
|
if (e instanceof Error) {
|
|
210
222
|
const blockError = new BlockError(block, {code: BlockErrorCode.BEACON_CHAIN_ERROR, error: e});
|
|
211
223
|
blockError.stack = e.stack;
|
|
@@ -44,22 +44,31 @@ export async function verifyBlocksStateTransitionOnly(
|
|
|
44
44
|
// STFN - per_slot_processing() + per_block_processing()
|
|
45
45
|
// NOTE: `regen.getPreState()` should have dialed forward the state already caching checkpoint states
|
|
46
46
|
const useBlsBatchVerify = !opts?.disableBlsBatchVerify;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
let postState: IBeaconStateView;
|
|
48
|
+
try {
|
|
49
|
+
postState = preState.stateTransition(
|
|
50
|
+
block,
|
|
51
|
+
{
|
|
52
|
+
// NOTE: Assume valid for now while sending payload to execution engine in parallel
|
|
53
|
+
// Latter verifyBlocksInEpoch() will make sure that payload is indeed valid
|
|
54
|
+
executionPayloadStatus: ExecutionPayloadStatus.valid,
|
|
55
|
+
dataAvailabilityStatus,
|
|
56
|
+
// false because it's verified below with better error typing
|
|
57
|
+
verifyStateRoot: false,
|
|
58
|
+
// if block is trusted don't verify proposer or op signature
|
|
59
|
+
verifyProposer: !useBlsBatchVerify && !validSignatures && !validProposerSignature,
|
|
60
|
+
verifySignatures: !useBlsBatchVerify && !validSignatures,
|
|
61
|
+
dontTransferCache: false,
|
|
62
|
+
},
|
|
63
|
+
{metrics, validatorMonitor}
|
|
64
|
+
);
|
|
65
|
+
} catch (e) {
|
|
66
|
+
throw new BlockError(block, {
|
|
67
|
+
code: BlockErrorCode.PER_BLOCK_PROCESSING_ERROR,
|
|
68
|
+
blockRoot: blocks[i].blockRootHex,
|
|
69
|
+
error: e as Error,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
63
72
|
|
|
64
73
|
const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
|
|
65
74
|
source: StateHashTreeRootSource.blockTransition,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {
|
|
3
3
|
type IBeaconStateViewGloas,
|
|
4
|
-
type PubkeyCache,
|
|
5
4
|
computeTimeAtSlot,
|
|
6
5
|
getExecutionPayloadEnvelopeSignatureSet,
|
|
7
6
|
} from "@lodestar/state-transition";
|
|
@@ -119,17 +118,10 @@ export function verifyExecutionPayloadEnvelope(
|
|
|
119
118
|
export async function verifyExecutionPayloadEnvelopeSignature(
|
|
120
119
|
config: BeaconConfig,
|
|
121
120
|
state: IBeaconStateViewGloas,
|
|
122
|
-
pubkeyCache: PubkeyCache,
|
|
123
121
|
signedEnvelope: gloas.SignedExecutionPayloadEnvelope,
|
|
124
122
|
proposerIndex: number,
|
|
125
123
|
bls: IBlsVerifier
|
|
126
124
|
): Promise<boolean> {
|
|
127
|
-
const signatureSet = getExecutionPayloadEnvelopeSignatureSet(
|
|
128
|
-
config,
|
|
129
|
-
pubkeyCache,
|
|
130
|
-
state,
|
|
131
|
-
signedEnvelope,
|
|
132
|
-
proposerIndex
|
|
133
|
-
);
|
|
125
|
+
const signatureSet = getExecutionPayloadEnvelopeSignatureSet(config, state, signedEnvelope, proposerIndex);
|
|
134
126
|
return bls.verifySignatureSets([signatureSet]);
|
|
135
127
|
}
|
package/src/chain/bls/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type {IBlsVerifier} from "./interface.js";
|
|
1
|
+
export type {IBlsVerifier, SameMessageSignatureSet} from "./interface.js";
|
|
2
2
|
export type {BlsMultiThreadWorkerPoolModules, JobQueueItemType} from "./multithread/index.js";
|
|
3
3
|
export {BlsMultiThreadWorkerPool} from "./multithread/index.js";
|
|
4
4
|
export {BlsSingleThreadVerifier} from "./singleThread.js";
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {PublicKey} from "@chainsafe/blst";
|
|
2
1
|
import {ISignatureSet} from "@lodestar/state-transition";
|
|
3
2
|
|
|
3
|
+
export type SameMessageSignatureSet = {
|
|
4
|
+
index: number;
|
|
5
|
+
signature: Uint8Array;
|
|
6
|
+
};
|
|
7
|
+
|
|
4
8
|
export type VerifySignatureOpts = {
|
|
5
9
|
/**
|
|
6
10
|
* A batchable set MAY be verified with more sets to reduce the verification costs.
|
|
@@ -53,8 +57,8 @@ export interface IBlsVerifier {
|
|
|
53
57
|
* - only support `batchable` option
|
|
54
58
|
*/
|
|
55
59
|
verifySignatureSetsSameMessage(
|
|
56
|
-
sets:
|
|
57
|
-
|
|
60
|
+
sets: SameMessageSignatureSet[],
|
|
61
|
+
message: Uint8Array,
|
|
58
62
|
opts?: Omit<VerifySignatureOpts, "verifyOnMainThread">
|
|
59
63
|
): Promise<boolean[]>;
|
|
60
64
|
|