@lodestar/beacon-node 1.45.0-dev.d16fa2b13a → 1.45.0-dev.d5aff60d6c
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 +2 -3
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +5 -13
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +6 -41
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +4 -23
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/validation/block.js +3 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +6 -12
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +2 -7
- package/lib/sync/unknownBlock.js.map +1 -1
- package/package.json +14 -14
- package/src/api/impl/beacon/blocks/index.ts +2 -3
- package/src/chain/blocks/utils/chainSegment.ts +5 -16
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +1 -1
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +1 -1
- package/src/chain/errors/blockError.ts +7 -41
- package/src/chain/validation/block.ts +3 -3
- package/src/network/processor/gossipHandlers.ts +6 -12
- package/src/sync/unknownBlock.ts +2 -8
|
@@ -86,22 +86,11 @@ export function assertLinearChainSegment(
|
|
|
86
86
|
// Maybe the previous slot's FULL envelope was orphaned — try falling back.
|
|
87
87
|
// If even prevExecHash doesn't match, the segment is non-linear.
|
|
88
88
|
if (bidParentHash !== prevExecHash) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
? {
|
|
95
|
-
code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN,
|
|
96
|
-
parentRoot: toRootHex(block.message.parentRoot),
|
|
97
|
-
parentBlockHash: bidParentHash,
|
|
98
|
-
}
|
|
99
|
-
: {
|
|
100
|
-
code: BlockErrorCode.NON_LINEAR_PAYLOAD_ROOTS,
|
|
101
|
-
parentBlockHash: bidParentHash,
|
|
102
|
-
expectedBlockHash: currentExecHash,
|
|
103
|
-
}
|
|
104
|
-
);
|
|
89
|
+
throw new BlockError(block, {
|
|
90
|
+
code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN,
|
|
91
|
+
parentRoot: toRootHex(block.message.parentRoot),
|
|
92
|
+
parentBlockHash: bidParentHash,
|
|
93
|
+
});
|
|
105
94
|
}
|
|
106
95
|
if (lastFullSlot !== null && payloadEnvelopes !== null) {
|
|
107
96
|
const orphanedInput = payloadEnvelopes.get(lastFullSlot);
|
|
@@ -201,7 +201,7 @@ export async function verifyBlockExecutionPayload(
|
|
|
201
201
|
invalidateFromParentBlockHash: toRootHex(executionPayloadEnabled.parentHash),
|
|
202
202
|
};
|
|
203
203
|
const execError = new BlockError(block, {
|
|
204
|
-
code: BlockErrorCode.
|
|
204
|
+
code: BlockErrorCode.EXECUTION_ENGINE_ERROR,
|
|
205
205
|
execStatus: execResult.status,
|
|
206
206
|
errorMessage: execResult.validationError ?? "",
|
|
207
207
|
});
|
|
@@ -94,7 +94,7 @@ export function verifyBlocksSanityChecks(
|
|
|
94
94
|
const parentRoot = toRootHex(block.message.parentRoot);
|
|
95
95
|
const parentBlockDefaultStatus = chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
96
96
|
if (!parentBlockDefaultStatus) {
|
|
97
|
-
throw new BlockError(block, {code: BlockErrorCode.
|
|
97
|
+
throw new BlockError(block, {code: BlockErrorCode.PARENT_UNKNOWN, parentRoot});
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
parentBlock = parentBlockDefaultStatus;
|
|
@@ -8,10 +8,8 @@ import {GossipActionError} from "./gossipValidation.js";
|
|
|
8
8
|
export enum BlockErrorCode {
|
|
9
9
|
/** The prestate cannot be fetched */
|
|
10
10
|
PRESTATE_MISSING = "BLOCK_ERROR_PRESTATE_MISSING",
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
PARENT_BLOCK_UNKNOWN = "BLOCK_ERROR_PARENT_BLOCK_UNKNOWN",
|
|
11
|
+
/** The parent block was unknown. */
|
|
12
|
+
PARENT_UNKNOWN = "BLOCK_ERROR_PARENT_UNKNOWN",
|
|
15
13
|
/** The block slot is greater than the present slot. */
|
|
16
14
|
FUTURE_SLOT = "BLOCK_ERROR_FUTURE_SLOT",
|
|
17
15
|
/** The block state_root does not match the generated state. */
|
|
@@ -40,10 +38,7 @@ export enum BlockErrorCode {
|
|
|
40
38
|
NOT_FINALIZED_DESCENDANT = "BLOCK_ERROR_NOT_FINALIZED_DESCENDANT",
|
|
41
39
|
/** The provided block is from an later slot than its parent. */
|
|
42
40
|
NOT_LATER_THAN_PARENT = "BLOCK_ERROR_NOT_LATER_THAN_PARENT",
|
|
43
|
-
/**
|
|
44
|
-
* A block in the middle of a chain segment does not set its parentRoot to the previous block's root
|
|
45
|
-
* (broken parent-root link inside the segment).
|
|
46
|
-
*/
|
|
41
|
+
/** At least one block in the chain segment did not have it's parent root set to the root of the prior block. */
|
|
47
42
|
NON_LINEAR_PARENT_ROOTS = "BLOCK_ERROR_NON_LINEAR_PARENT_ROOTS",
|
|
48
43
|
/** The slots of the blocks in the chain segment were not strictly increasing. */
|
|
49
44
|
NON_LINEAR_SLOTS = "BLOCK_ERROR_NON_LINEAR_SLOTS",
|
|
@@ -66,12 +61,6 @@ export enum BlockErrorCode {
|
|
|
66
61
|
TRANSACTIONS_TOO_BIG = "BLOCK_ERROR_TRANSACTIONS_TOO_BIG",
|
|
67
62
|
/** Execution engine is unavailable, syncing, or api call errored. Peers must not be downscored on this code */
|
|
68
63
|
EXECUTION_ENGINE_ERROR = "BLOCK_ERROR_EXECUTION_ERROR",
|
|
69
|
-
/**
|
|
70
|
-
* Execution engine returned a definitive INVALID verdict on the payload. Unlike
|
|
71
|
-
* EXECUTION_ENGINE_ERROR this is evidence about the data itself, not a local malfunction, so
|
|
72
|
-
* whoever served the block MAY be downscored. Mirrors PayloadErrorCode.EXECUTION_ENGINE_INVALID.
|
|
73
|
-
*/
|
|
74
|
-
EXECUTION_ENGINE_INVALID = "BLOCK_ERROR_EXECUTION_INVALID",
|
|
75
64
|
/** The blobs are unavailable */
|
|
76
65
|
DATA_UNAVAILABLE = "BLOCK_ERROR_DATA_UNAVAILABLE",
|
|
77
66
|
/** Block contains too many kzg commitments */
|
|
@@ -82,16 +71,8 @@ export enum BlockErrorCode {
|
|
|
82
71
|
TOO_MANY_BLOCK_OPERATIONS = "BLOCK_ERROR_TOO_MANY_BLOCK_OPERATIONS",
|
|
83
72
|
/** The parent block's execution payload has been verified as invalid */
|
|
84
73
|
PARENT_EXECUTION_INVALID = "BLOCK_ERROR_PARENT_EXECUTION_INVALID",
|
|
85
|
-
/**
|
|
86
|
-
* [gloas] The first block of a chain segment references a parent execution payload
|
|
87
|
-
* (bid.parent_block_hash) unknown to fork-choice (segment boundary).
|
|
88
|
-
*/
|
|
74
|
+
/** The block's parent execution payload (defined by bid.parent_block_hash) has not been seen */
|
|
89
75
|
PARENT_PAYLOAD_UNKNOWN = "BLOCK_ERROR_PARENT_PAYLOAD_UNKNOWN",
|
|
90
|
-
/**
|
|
91
|
-
* [gloas] A block in the middle of a chain segment has a bid.parent_block_hash that does not chain onto the
|
|
92
|
-
* previous block's execution payload (broken payload link inside the segment).
|
|
93
|
-
*/
|
|
94
|
-
NON_LINEAR_PAYLOAD_ROOTS = "BLOCK_ERROR_NON_LINEAR_PAYLOAD_ROOTS",
|
|
95
76
|
/** An execution payload envelope in the chain segment references a block root that does not match its slot's block */
|
|
96
77
|
ENVELOPE_BLOCK_ROOT_MISMATCH = "BLOCK_ERROR_ENVELOPE_BLOCK_ROOT_MISMATCH",
|
|
97
78
|
}
|
|
@@ -101,18 +82,9 @@ type ExecutionErrorStatus = Exclude<
|
|
|
101
82
|
ExecutionPayloadStatus.VALID | ExecutionPayloadStatus.ACCEPTED | ExecutionPayloadStatus.SYNCING
|
|
102
83
|
>;
|
|
103
84
|
|
|
104
|
-
/**
|
|
105
|
-
* Statuses where the execution engine could NOT render a verdict on the payload: it is unreachable
|
|
106
|
-
* (UNAVAILABLE), errored (ELERROR), or returned a malformed/client-specific response
|
|
107
|
-
* (INVALID_BLOCK_HASH, dropped from engine_newPayloadV2+). None of these are evidence about the
|
|
108
|
-
* data, so peers must not be downscored on them. A definitive INVALID carries
|
|
109
|
-
* BlockErrorCode.EXECUTION_ENGINE_INVALID instead.
|
|
110
|
-
*/
|
|
111
|
-
type ExecutionEngineErrorStatus = Exclude<ExecutionErrorStatus, ExecutionPayloadStatus.INVALID>;
|
|
112
|
-
|
|
113
85
|
export type BlockErrorType =
|
|
114
86
|
| {code: BlockErrorCode.PRESTATE_MISSING; error: Error}
|
|
115
|
-
| {code: BlockErrorCode.
|
|
87
|
+
| {code: BlockErrorCode.PARENT_UNKNOWN; parentRoot: RootHex}
|
|
116
88
|
| {code: BlockErrorCode.FUTURE_SLOT; blockSlot: Slot; currentSlot: Slot}
|
|
117
89
|
| {code: BlockErrorCode.STATE_ROOT_MISMATCH}
|
|
118
90
|
| {code: BlockErrorCode.GENESIS_BLOCK}
|
|
@@ -144,19 +116,13 @@ export type BlockErrorType =
|
|
|
144
116
|
| {code: BlockErrorCode.TOO_MUCH_GAS_USED; gasUsed: number; gasLimit: number}
|
|
145
117
|
| {code: BlockErrorCode.SAME_PARENT_HASH; blockHash: RootHex}
|
|
146
118
|
| {code: BlockErrorCode.TRANSACTIONS_TOO_BIG; size: number; max: number}
|
|
147
|
-
| {code: BlockErrorCode.EXECUTION_ENGINE_ERROR; execStatus:
|
|
148
|
-
| {
|
|
149
|
-
code: BlockErrorCode.EXECUTION_ENGINE_INVALID;
|
|
150
|
-
execStatus: ExecutionPayloadStatus.INVALID;
|
|
151
|
-
errorMessage: string;
|
|
152
|
-
}
|
|
119
|
+
| {code: BlockErrorCode.EXECUTION_ENGINE_ERROR; execStatus: ExecutionErrorStatus; errorMessage: string}
|
|
153
120
|
| {code: BlockErrorCode.DATA_UNAVAILABLE}
|
|
154
121
|
| {code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS; blobKzgCommitmentsLen: number; commitmentLimit: number}
|
|
155
122
|
| {code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH; bidParentRoot: RootHex; blockParentRoot: RootHex}
|
|
156
123
|
| {code: BlockErrorCode.TOO_MANY_BLOCK_OPERATIONS; name: string; count: number; limit: number}
|
|
157
124
|
| {code: BlockErrorCode.PARENT_EXECUTION_INVALID; parentRoot: RootHex}
|
|
158
|
-
| {code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN; parentRoot: RootHex; parentBlockHash: RootHex}
|
|
159
|
-
| {code: BlockErrorCode.NON_LINEAR_PAYLOAD_ROOTS; parentBlockHash: RootHex; expectedBlockHash: RootHex};
|
|
125
|
+
| {code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN; parentRoot: RootHex; parentBlockHash: RootHex};
|
|
160
126
|
|
|
161
127
|
export class BlockGossipError extends GossipActionError<BlockErrorType> {}
|
|
162
128
|
|
|
@@ -104,8 +104,8 @@ export async function validateGossipBlock(
|
|
|
104
104
|
// 2. The parent is unknown to us, we probably want to download it since it might actually
|
|
105
105
|
// descend from the finalized root.
|
|
106
106
|
// (Non-Lighthouse): Since we prune all blocks non-descendant from finalized checking the `db.block` database won't be useful to guard
|
|
107
|
-
// against known bad fork blocks, so we throw
|
|
108
|
-
throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.
|
|
107
|
+
// against known bad fork blocks, so we throw PARENT_UNKNOWN for cases (1) and (2)
|
|
108
|
+
throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.PARENT_UNKNOWN, parentRoot});
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// [IGNORE] The block's parent (defined by `block.parent_root`) passes all validation
|
|
@@ -244,7 +244,7 @@ export async function validateGossipBlock(
|
|
|
244
244
|
const blockState = await chain.regen
|
|
245
245
|
.getPreState(block, {dontTransferCache: true}, RegenCaller.validateGossipBlock)
|
|
246
246
|
.catch(() => {
|
|
247
|
-
throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.
|
|
247
|
+
throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.PARENT_UNKNOWN, parentRoot});
|
|
248
248
|
});
|
|
249
249
|
|
|
250
250
|
// in forky condition, make sure to populate ShufflingCache with regened state
|
|
@@ -176,7 +176,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
176
176
|
|
|
177
177
|
// optimistically add gossip block to the seen cache
|
|
178
178
|
// if validation fails, we will NOT forward this gossip block to peers
|
|
179
|
-
// - if
|
|
179
|
+
// - if PARENT_UNKNOWN error, blockInput will then be queued inside BlockInputSync. If the gossip block is really invalid, it will be pruned there
|
|
180
180
|
// - if other validator errors, blockInput will stay in the seen cache and will be pruned on finalization
|
|
181
181
|
const blockInput = chain.seenBlockInputCache.getByBlock({
|
|
182
182
|
block: signedBlock,
|
|
@@ -187,7 +187,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
187
187
|
});
|
|
188
188
|
|
|
189
189
|
// Optimistically seed the payload-envelope cache too, mirroring seenBlockInputCache above.
|
|
190
|
-
// This ensures we have PayloadEnvelopeInput, even through "
|
|
190
|
+
// This ensures we have PayloadEnvelopeInput, even through "PARENT_UNKNOWN" error
|
|
191
191
|
// see https://github.com/ChainSafe/lodestar/issues/9475
|
|
192
192
|
if (isForkPostGloas(fork)) {
|
|
193
193
|
chain.seenPayloadEnvelopeInputCache.add({
|
|
@@ -227,8 +227,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
227
227
|
if (e instanceof BlockGossipError) {
|
|
228
228
|
logger.debug("Gossip block has error", {slot, root: blockShortHex, code: e.type.code});
|
|
229
229
|
if (
|
|
230
|
-
(e.type.code === BlockErrorCode.
|
|
231
|
-
e.type.code === BlockErrorCode.PARENT_PAYLOAD_UNKNOWN) &&
|
|
230
|
+
(e.type.code === BlockErrorCode.PARENT_UNKNOWN || e.type.code === BlockErrorCode.PARENT_PAYLOAD_UNKNOWN) &&
|
|
232
231
|
blockInput
|
|
233
232
|
) {
|
|
234
233
|
chain.emitter.emit(ChainEvent.blockUnknownParent, {
|
|
@@ -662,19 +661,14 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
662
661
|
break;
|
|
663
662
|
}
|
|
664
663
|
// ALREADY_KNOWN should not happen with ignoreIfKnown=true above
|
|
665
|
-
//
|
|
664
|
+
// PARENT_UNKNOWN should not happen, we handled this in validateBeaconBlock() function above
|
|
666
665
|
case BlockErrorCode.ALREADY_KNOWN:
|
|
667
|
-
case BlockErrorCode.
|
|
666
|
+
case BlockErrorCode.PARENT_UNKNOWN:
|
|
668
667
|
case BlockErrorCode.PRESTATE_MISSING:
|
|
669
668
|
case BlockErrorCode.EXECUTION_ENGINE_ERROR:
|
|
670
|
-
// Errors might indicate an issue with our node or the connected EL client
|
|
669
|
+
// Errors might indicate an issue with our node or the connected EL client
|
|
671
670
|
logLevel = LogLevel.error;
|
|
672
671
|
break;
|
|
673
|
-
case BlockErrorCode.EXECUTION_ENGINE_INVALID:
|
|
674
|
-
// the peer served a bad block
|
|
675
|
-
core.reportPeer(peerIdStr, PeerAction.LowToleranceError, "ExecutionEngineInvalid");
|
|
676
|
-
logLevel = LogLevel.warn;
|
|
677
|
-
break;
|
|
678
672
|
default:
|
|
679
673
|
// TODO: Should it use PeerId or string?
|
|
680
674
|
core.reportPeer(peerIdStr, PeerAction.LowToleranceError, "BadGossipBlock");
|
package/src/sync/unknownBlock.ts
CHANGED
|
@@ -819,7 +819,7 @@ export class BlockInputSync {
|
|
|
819
819
|
// case BlockErrorCode.ALREADY_KNOWN:
|
|
820
820
|
// case BlockErrorCode.GENESIS_BLOCK:
|
|
821
821
|
|
|
822
|
-
case BlockErrorCode.
|
|
822
|
+
case BlockErrorCode.PARENT_UNKNOWN:
|
|
823
823
|
case BlockErrorCode.PRESTATE_MISSING:
|
|
824
824
|
// Should not happen, mark as downloaded to try again latter
|
|
825
825
|
this.logger.debug("Attempted to process block but its parent was still unknown", errorData, res.err);
|
|
@@ -841,16 +841,10 @@ export class BlockInputSync {
|
|
|
841
841
|
|
|
842
842
|
case BlockErrorCode.EXECUTION_ENGINE_ERROR:
|
|
843
843
|
// Removing the block(s) without penalizing the peers, hoping for EL to
|
|
844
|
-
// recover on a latter download + verify attempt
|
|
844
|
+
// recover on a latter download + verify attempt
|
|
845
845
|
this.removeAllDescendants(pendingBlock);
|
|
846
846
|
break;
|
|
847
847
|
|
|
848
|
-
case BlockErrorCode.EXECUTION_ENGINE_INVALID:
|
|
849
|
-
// the peer served a bad block
|
|
850
|
-
this.logger.debug("Execution engine rejected block from unknown parent sync", errorData, res.err);
|
|
851
|
-
this.removeAndDownScoreAllDescendants(pendingBlock);
|
|
852
|
-
break;
|
|
853
|
-
|
|
854
848
|
default:
|
|
855
849
|
// Block is not correct with respect to our chain. Log error loudly
|
|
856
850
|
this.logger.debug("Error processing block from unknown parent sync", errorData, res.err);
|