@lodestar/beacon-node 1.44.0-dev.6ef8199cfa → 1.44.0-dev.b506aab66d
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/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +1 -1
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +1 -1
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +4 -2
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +6 -1
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +1 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +14 -4
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +2 -1
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +25 -11
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts +7 -3
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +24 -8
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +1 -0
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +16 -0
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/execution/builder/index.d.ts +1 -2
- package/lib/execution/builder/index.d.ts.map +1 -1
- package/lib/execution/builder/index.js +0 -1
- package/lib/execution/builder/index.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +1 -1
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +4 -3
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +11 -3
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/package.json +14 -14
- package/src/api/impl/beacon/pool/index.ts +2 -1
- package/src/chain/blocks/importBlock.ts +2 -1
- package/src/chain/blocks/importExecutionPayload.ts +7 -1
- package/src/chain/errors/executionPayloadBid.ts +4 -1
- package/src/chain/forkChoice/index.ts +14 -4
- package/src/chain/prepareNextSlot.ts +2 -1
- package/src/chain/produceBlock/produceBlockBody.ts +31 -19
- package/src/chain/validation/executionPayloadBid.ts +30 -12
- package/src/chain/validatorMonitor.ts +18 -0
- package/src/execution/builder/index.ts +1 -4
- package/src/metrics/metrics/lodestar.ts +4 -3
- package/src/network/processor/gossipHandlers.ts +15 -3
- package/lib/execution/builder/utils.d.ts +0 -5
- package/lib/execution/builder/utils.d.ts.map +0 -1
- package/lib/execution/builder/utils.js +0 -17
- package/lib/execution/builder/utils.js.map +0 -1
- package/src/execution/builder/utils.ts +0 -19
|
@@ -140,9 +140,11 @@ export function initializeForkChoiceFromFinalizedState(
|
|
|
140
140
|
executionPayloadBlockHash: isStatePostGloas(state)
|
|
141
141
|
? toRootHex(state.latestBlockHash)
|
|
142
142
|
: toRootHex(state.latestExecutionPayloadHeader.blockHash),
|
|
143
|
-
// TODO GLOAS: executionPayloadNumber
|
|
144
|
-
// latestExecutionPayloadHeader). Using 0 as unavailable fallback
|
|
143
|
+
// TODO GLOAS: executionPayloadNumber/GasLimit are not tracked in BeaconState post-gloas
|
|
144
|
+
// (EIP-7732 removed latestExecutionPayloadHeader). Using 0 as unavailable fallback —
|
|
145
|
+
// see initializeForkChoiceFromUnfinalizedState for the same caveat on validation.
|
|
145
146
|
executionPayloadNumber: isStatePostGloas(state) ? 0 : state.payloadBlockNumber,
|
|
147
|
+
executionPayloadGasLimit: isStatePostGloas(state) ? 0 : state.latestExecutionPayloadHeader.gasLimit,
|
|
146
148
|
executionStatus: blockHeader.slot === GENESIS_SLOT ? ExecutionStatus.Valid : ExecutionStatus.Syncing,
|
|
147
149
|
}
|
|
148
150
|
: {executionPayloadBlockHash: null, executionStatus: ExecutionStatus.PreMerge}),
|
|
@@ -232,9 +234,17 @@ export function initializeForkChoiceFromUnfinalizedState(
|
|
|
232
234
|
executionPayloadBlockHash: isStatePostGloas(unfinalizedState)
|
|
233
235
|
? toRootHex(unfinalizedState.latestBlockHash)
|
|
234
236
|
: toRootHex(unfinalizedState.latestExecutionPayloadHeader.blockHash),
|
|
235
|
-
// TODO GLOAS: executionPayloadNumber
|
|
236
|
-
// latestExecutionPayloadHeader). Using 0 as unavailable fallback until
|
|
237
|
+
// TODO GLOAS: executionPayloadNumber/GasLimit are not tracked in BeaconState post-gloas
|
|
238
|
+
// (EIP-7732 removed latestExecutionPayloadHeader). Using 0 as unavailable fallback until
|
|
239
|
+
// a solution is found. The 0 doesn't gate validation in practice: at boot the head's
|
|
240
|
+
// PENDING variant's `executionPayloadBlockHash` is the *parent's* payload hash (per the
|
|
241
|
+
// PENDING/EMPTY convention), so gossip bids that reference the head's *own* payload
|
|
242
|
+
// hash won't match this variant anyway and will IGNORE until `onExecutionPayload`
|
|
243
|
+
// upgrades the head to FULL with real values.
|
|
237
244
|
executionPayloadNumber: isStatePostGloas(unfinalizedState) ? 0 : unfinalizedState.payloadBlockNumber,
|
|
245
|
+
executionPayloadGasLimit: isStatePostGloas(unfinalizedState)
|
|
246
|
+
? 0
|
|
247
|
+
: unfinalizedState.latestExecutionPayloadHeader.gasLimit,
|
|
238
248
|
executionStatus: blockHeader.slot === GENESIS_SLOT ? ExecutionStatus.Valid : ExecutionStatus.Syncing,
|
|
239
249
|
}
|
|
240
250
|
: {executionPayloadBlockHash: null, executionStatus: ExecutionStatus.PreMerge}),
|
|
@@ -169,7 +169,8 @@ export class PrepareNextSlotScheduler {
|
|
|
169
169
|
// Apply parent payload once here as it's reused by EL prep and SSE emit below
|
|
170
170
|
let stateAfterParentPayload: IBeaconStateViewBellatrix = updatedPrepareState;
|
|
171
171
|
if (isStatePostGloas(updatedPrepareState)) {
|
|
172
|
-
|
|
172
|
+
// Spec: should_build_on_full(store, head) — see produceBlockBody.ts for context.
|
|
173
|
+
if (this.chain.forkChoice.shouldBuildOnFull(updatedHead)) {
|
|
173
174
|
parentBlockHash = updatedPrepareState.latestExecutionPayloadBid.blockHash;
|
|
174
175
|
// Skip applying parent payload unless we're proposing the next slot or have to emit payload_attributes events
|
|
175
176
|
if (feeRecipient !== undefined || this.chain.opts.emitPayloadAttributes === true) {
|
|
@@ -18,9 +18,9 @@ import {
|
|
|
18
18
|
G2_POINT_AT_INFINITY,
|
|
19
19
|
IBeaconStateView,
|
|
20
20
|
type IBeaconStateViewBellatrix,
|
|
21
|
-
type IBeaconStateViewGloas,
|
|
22
21
|
computeEpochAtSlot,
|
|
23
22
|
computeTimeAtSlot,
|
|
23
|
+
getExpectedGasLimit,
|
|
24
24
|
isStatePostBellatrix,
|
|
25
25
|
isStatePostCapella,
|
|
26
26
|
isStatePostGloas,
|
|
@@ -53,13 +53,7 @@ import {
|
|
|
53
53
|
import {Logger, byteArrayEquals, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
54
54
|
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
55
55
|
import {numToQuantity} from "../../execution/engine/utils.js";
|
|
56
|
-
import {
|
|
57
|
-
IExecutionBuilder,
|
|
58
|
-
IExecutionEngine,
|
|
59
|
-
PayloadAttributes,
|
|
60
|
-
PayloadId,
|
|
61
|
-
getExpectedGasLimit,
|
|
62
|
-
} from "../../execution/index.js";
|
|
56
|
+
import {IExecutionBuilder, IExecutionEngine, PayloadAttributes, PayloadId} from "../../execution/index.js";
|
|
63
57
|
import {getShufflingDependentRoot} from "../../util/dependentRoot.js";
|
|
64
58
|
import {fromGraffitiBytes} from "../../util/graffiti.js";
|
|
65
59
|
import {kzg} from "../../util/kzg.js";
|
|
@@ -226,8 +220,11 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
226
220
|
let parentExecutionRequests: electra.ExecutionRequests;
|
|
227
221
|
// Apply parent payload once here as it's reused by EL prep and voluntary exit filtering below
|
|
228
222
|
let stateAfterParentPayload: IBeaconStateViewBellatrix = currentState;
|
|
229
|
-
|
|
230
|
-
|
|
223
|
+
// Spec: should_build_on_full(store, head). `parentBlock` is the proposer's head
|
|
224
|
+
// (set by chain.getProposerHead(slot)). Returns false when the PTC majority
|
|
225
|
+
// signalled the blob data is not available, forcing a build on EMPTY (reorg).
|
|
226
|
+
const isBuildingOnFull = this.forkChoice.shouldBuildOnFull(parentBlock);
|
|
227
|
+
if (isBuildingOnFull) {
|
|
231
228
|
parentBlockHash = currentState.latestExecutionPayloadBid.blockHash;
|
|
232
229
|
parentExecutionRequests = await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot);
|
|
233
230
|
stateAfterParentPayload = currentState.withParentPayloadApplied(parentExecutionRequests);
|
|
@@ -306,7 +303,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
306
303
|
// Drop voluntary exits that parent_execution_requests have invalidated (e.g. a withdrawal
|
|
307
304
|
// request initiating an exit on the same validator). Op pool selected against the unapplied
|
|
308
305
|
// state, so re-validate against the post-apply state to avoid producing an invalid block.
|
|
309
|
-
if (
|
|
306
|
+
if (isBuildingOnFull && commonBlockBody.voluntaryExits.length > 0) {
|
|
310
307
|
gloasBody.voluntaryExits = commonBlockBody.voluntaryExits.filter((signedVoluntaryExit) =>
|
|
311
308
|
stateAfterParentPayload.isValidVoluntaryExit(signedVoluntaryExit, false)
|
|
312
309
|
);
|
|
@@ -331,6 +328,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
331
328
|
fetchedTime,
|
|
332
329
|
executionBlockHash: toRootHex(executionPayload.blockHash),
|
|
333
330
|
blobs: blobsBundle.commitments.length,
|
|
331
|
+
gasLimit: executionPayload.gasLimit,
|
|
334
332
|
});
|
|
335
333
|
|
|
336
334
|
Object.assign(logMeta, {
|
|
@@ -869,9 +867,9 @@ function preparePayloadAttributes(
|
|
|
869
867
|
(payloadAttributes as gloas.SSEPayloadAttributes["payloadAttributes"]).slotNumber = prepareSlot;
|
|
870
868
|
(payloadAttributes as gloas.SSEPayloadAttributes["payloadAttributes"]).targetGasLimit = getProposerTargetGasLimit(
|
|
871
869
|
chain,
|
|
872
|
-
prepareState,
|
|
873
870
|
prepareSlot,
|
|
874
|
-
parentBlockRoot
|
|
871
|
+
parentBlockRoot,
|
|
872
|
+
parentBlockHash
|
|
875
873
|
);
|
|
876
874
|
}
|
|
877
875
|
|
|
@@ -886,14 +884,20 @@ function preparePayloadAttributes(
|
|
|
886
884
|
* (same `(slot, dependent_root)` lookup as gossip bid validation). When no matching
|
|
887
885
|
* preferences are pooled, target the parent payload's gas limit so the gas limit stays
|
|
888
886
|
* unchanged (`is_gas_limit_target_compatible` then requires `gas_limit == parent_gas_limit`).
|
|
887
|
+
*
|
|
888
|
+
* The parent payload's gas_limit is read from fork choice — the variant matching
|
|
889
|
+
* `(parentBlockRoot, parentBlockHash)` carries the correct value for both FULL parents
|
|
890
|
+
* (FULL.executionPayloadGasLimit = delivered payload's gas_limit) and EMPTY parents
|
|
891
|
+
* (EMPTY.executionPayloadGasLimit = inherited grandparent's gas_limit).
|
|
889
892
|
*/
|
|
890
893
|
function getProposerTargetGasLimit(
|
|
891
894
|
chain: {forkChoice: IForkChoice; proposerPreferencesPool: ProposerPreferencesPool},
|
|
892
|
-
state: IBeaconStateViewGloas,
|
|
893
895
|
prepareSlot: Slot,
|
|
894
|
-
parentBlockRoot: Root
|
|
896
|
+
parentBlockRoot: Root,
|
|
897
|
+
parentBlockHash: Bytes32
|
|
895
898
|
): number {
|
|
896
|
-
const
|
|
899
|
+
const parentBlockRootHex = toRootHex(parentBlockRoot);
|
|
900
|
+
const parentBlock = chain.forkChoice.getBlockHexDefaultStatus(parentBlockRootHex);
|
|
897
901
|
const dependentRootHex = (() => {
|
|
898
902
|
if (parentBlock === null) {
|
|
899
903
|
return null;
|
|
@@ -911,9 +915,17 @@ function getProposerTargetGasLimit(
|
|
|
911
915
|
})();
|
|
912
916
|
|
|
913
917
|
const pref = dependentRootHex !== null ? chain.proposerPreferencesPool.get(prepareSlot, dependentRootHex) : null;
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
918
|
+
if (pref !== null) {
|
|
919
|
+
return pref.message.targetGasLimit;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
const parentPayloadVariant = chain.forkChoice.getBlockHexAndBlockHash(parentBlockRootHex, toRootHex(parentBlockHash));
|
|
923
|
+
if (parentPayloadVariant === null || parentPayloadVariant.executionPayloadBlockHash === null) {
|
|
924
|
+
throw new Error(
|
|
925
|
+
`Cannot resolve parent payload gas_limit for proposer targetGasLimit fallback parentBlockRoot=${parentBlockRootHex} parentBlockHash=${toRootHex(parentBlockHash)}`
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
return parentPayloadVariant.executionPayloadGasLimit;
|
|
917
929
|
}
|
|
918
930
|
|
|
919
931
|
export async function produceCommonBlockBody<T extends BlockType>(
|
|
@@ -4,9 +4,10 @@ import {
|
|
|
4
4
|
createSingleSignatureSetFromComponents,
|
|
5
5
|
getExecutionPayloadBidSigningRoot,
|
|
6
6
|
isActiveBuilder,
|
|
7
|
+
isGasLimitTargetCompatible,
|
|
7
8
|
isStatePostGloas,
|
|
8
9
|
} from "@lodestar/state-transition";
|
|
9
|
-
import {gloas} from "@lodestar/types";
|
|
10
|
+
import {ValidatorIndex, gloas} from "@lodestar/types";
|
|
10
11
|
import {byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
|
|
11
12
|
import {getShufflingDependentRoot} from "../../util/dependentRoot.js";
|
|
12
13
|
import {ExecutionPayloadBidError, ExecutionPayloadBidErrorCode, GossipAction} from "../errors/index.js";
|
|
@@ -16,21 +17,21 @@ import {RegenCaller} from "../regen/index.js";
|
|
|
16
17
|
export async function validateApiExecutionPayloadBid(
|
|
17
18
|
chain: IBeaconChain,
|
|
18
19
|
signedExecutionPayloadBid: gloas.SignedExecutionPayloadBid
|
|
19
|
-
): Promise<
|
|
20
|
+
): Promise<{proposerIndex: ValidatorIndex}> {
|
|
20
21
|
return validateExecutionPayloadBid(chain, signedExecutionPayloadBid);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export async function validateGossipExecutionPayloadBid(
|
|
24
25
|
chain: IBeaconChain,
|
|
25
26
|
signedExecutionPayloadBid: gloas.SignedExecutionPayloadBid
|
|
26
|
-
): Promise<
|
|
27
|
+
): Promise<{proposerIndex: ValidatorIndex}> {
|
|
27
28
|
return validateExecutionPayloadBid(chain, signedExecutionPayloadBid);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
async function validateExecutionPayloadBid(
|
|
31
32
|
chain: IBeaconChain,
|
|
32
33
|
signedExecutionPayloadBid: gloas.SignedExecutionPayloadBid
|
|
33
|
-
): Promise<
|
|
34
|
+
): Promise<{proposerIndex: ValidatorIndex}> {
|
|
34
35
|
const bid = signedExecutionPayloadBid.message;
|
|
35
36
|
const parentBlockRootHex = toRootHex(bid.parentBlockRoot);
|
|
36
37
|
const parentBlockHashHex = toRootHex(bid.parentBlockHash);
|
|
@@ -128,14 +129,33 @@ async function validateExecutionPayloadBid(
|
|
|
128
129
|
});
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
// [
|
|
132
|
+
// [IGNORE] `bid.parent_block_hash` is the block hash of a known execution payload in fork
|
|
133
|
+
// choice. Looks up the variant of `bid.parent_block_root` whose payload hash matches
|
|
134
|
+
// `bid.parent_block_hash` — works for both FULL parents (FULL variant carries the delivered
|
|
135
|
+
// payload's hash) and EMPTY parents (EMPTY/PENDING variants carry the inherited parent
|
|
136
|
+
// payload's hash, since the new block doesn't have its own payload). Variant carries the
|
|
137
|
+
// executed payload's gas_limit, which we use as `parent_gas_limit` below.
|
|
138
|
+
const parentPayloadVariant = chain.forkChoice.getBlockHexAndBlockHash(parentBlockRootHex, parentBlockHashHex);
|
|
139
|
+
if (parentPayloadVariant === null || parentPayloadVariant.executionPayloadBlockHash === null) {
|
|
140
|
+
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|
|
141
|
+
code: ExecutionPayloadBidErrorCode.UNKNOWN_PARENT_BLOCK_HASH,
|
|
142
|
+
parentBlockHash: parentBlockHashHex,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// [IGNORE] `is_gas_limit_target_compatible(parent_gas_limit, bid.gas_limit, target_gas_limit)`,
|
|
147
|
+
// where `parent_gas_limit` is the `gas_limit` of the parent execution payload and
|
|
148
|
+
// `target_gas_limit` is `proposer_preferences.target_gas_limit`.
|
|
132
149
|
const bidGasLimit = Number(bid.gasLimit);
|
|
133
|
-
|
|
134
|
-
|
|
150
|
+
const parentGasLimit = parentPayloadVariant.executionPayloadGasLimit;
|
|
151
|
+
const targetGasLimit = proposerPreferences.message.targetGasLimit;
|
|
152
|
+
if (!isGasLimitTargetCompatible(parentGasLimit, bidGasLimit, targetGasLimit)) {
|
|
153
|
+
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|
|
135
154
|
code: ExecutionPayloadBidErrorCode.PROPOSER_PREFERENCES_GAS_LIMIT_MISMATCH,
|
|
136
155
|
builderIndex: bid.builderIndex,
|
|
137
156
|
bidGasLimit,
|
|
138
|
-
|
|
157
|
+
parentGasLimit,
|
|
158
|
+
targetGasLimit,
|
|
139
159
|
});
|
|
140
160
|
}
|
|
141
161
|
|
|
@@ -183,10 +203,6 @@ async function validateExecutionPayloadBid(
|
|
|
183
203
|
});
|
|
184
204
|
}
|
|
185
205
|
|
|
186
|
-
// [IGNORE] `bid.parent_block_hash` is the block hash of a known execution
|
|
187
|
-
// payload in fork choice.
|
|
188
|
-
// TODO GLOAS: implement this
|
|
189
|
-
|
|
190
206
|
// [REJECT] `signed_execution_payload_bid.signature` is valid with respect to the `bid.builder_index`.
|
|
191
207
|
const signatureSet = createSingleSignatureSetFromComponents(
|
|
192
208
|
PublicKey.fromBytes(builder.pubkey),
|
|
@@ -204,4 +220,6 @@ async function validateExecutionPayloadBid(
|
|
|
204
220
|
|
|
205
221
|
// Valid
|
|
206
222
|
chain.seenExecutionPayloadBids.add(bid.slot, bid.builderIndex);
|
|
223
|
+
|
|
224
|
+
return {proposerIndex: proposerPreferences.message.validatorIndex};
|
|
207
225
|
}
|
|
@@ -66,6 +66,7 @@ export type ValidatorMonitor = {
|
|
|
66
66
|
delaySec: Seconds,
|
|
67
67
|
envelope: gloas.SignedExecutionPayloadEnvelope
|
|
68
68
|
): void;
|
|
69
|
+
registerExecutionPayloadBid(src: OpSource, proposerIndex: ValidatorIndex, bid: gloas.ExecutionPayloadBid): void;
|
|
69
70
|
registerImportedBlock(block: BeaconBlock, data: {proposerBalanceDelta: number}): void;
|
|
70
71
|
onPoolSubmitUnaggregatedAttestation(
|
|
71
72
|
seenTimestampSec: number,
|
|
@@ -459,6 +460,23 @@ export function createValidatorMonitor(
|
|
|
459
460
|
// TODO GLOAS: implement execution payload envelope monitoring
|
|
460
461
|
},
|
|
461
462
|
|
|
463
|
+
registerExecutionPayloadBid(src, proposerIndex, bid) {
|
|
464
|
+
if (!validators.has(proposerIndex)) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
log("Received an execution payload bid for monitored proposer", {
|
|
468
|
+
slot: bid.slot,
|
|
469
|
+
proposerIndex,
|
|
470
|
+
src,
|
|
471
|
+
builderIndex: bid.builderIndex,
|
|
472
|
+
gasLimit: bid.gasLimit,
|
|
473
|
+
value: bid.value.toString(),
|
|
474
|
+
parentBlockRoot: toRootHex(bid.parentBlockRoot),
|
|
475
|
+
parentBlockHash: toRootHex(bid.parentBlockHash),
|
|
476
|
+
blockHash: toRootHex(bid.blockHash),
|
|
477
|
+
});
|
|
478
|
+
},
|
|
479
|
+
|
|
462
480
|
registerImportedBlock(block, {proposerBalanceDelta}) {
|
|
463
481
|
const validator = validators.get(block.proposerIndex);
|
|
464
482
|
if (validator) {
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {Logger} from "@lodestar/logger";
|
|
3
3
|
import {Metrics} from "../../metrics/metrics.js";
|
|
4
|
-
import {IExecutionBuilder} from "./interface.js";
|
|
5
|
-
|
|
6
|
-
export {getExpectedGasLimit} from "./utils.js";
|
|
7
|
-
|
|
8
4
|
import {ExecutionBuilderHttp, ExecutionBuilderHttpOpts, defaultExecutionBuilderHttpOpts} from "./http.js";
|
|
5
|
+
import {IExecutionBuilder} from "./interface.js";
|
|
9
6
|
|
|
10
7
|
export {ExecutionBuilderHttp, defaultExecutionBuilderHttpOpts};
|
|
11
8
|
|
|
@@ -987,10 +987,11 @@ export function createLodestarMetrics(
|
|
|
987
987
|
}),
|
|
988
988
|
},
|
|
989
989
|
importPayload: {
|
|
990
|
-
|
|
991
|
-
name: "
|
|
992
|
-
help: "
|
|
990
|
+
elapsedTimeTillImported: register.histogram<{source: PayloadEnvelopeInputSource}>({
|
|
991
|
+
name: "lodestar_import_payload_elapsed_time_till_imported_seconds",
|
|
992
|
+
help: "Time elapsed between slot time and the time execution payload envelope is imported (added to fork choice)",
|
|
993
993
|
labelNames: ["source"],
|
|
994
|
+
buckets: [1, 2, 3, 6, 9, 12],
|
|
994
995
|
}),
|
|
995
996
|
columnsBySource: register.gauge<{source: PayloadEnvelopeInputSource}>({
|
|
996
997
|
name: "lodestar_import_payload_columns_by_source_total",
|
|
@@ -1117,7 +1117,16 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1117
1117
|
}
|
|
1118
1118
|
|
|
1119
1119
|
const slot = envelope.payload.slotNumber;
|
|
1120
|
-
const delaySec =
|
|
1120
|
+
const delaySec = chain.clock.secFromSlot(slot, seenTimestampSec);
|
|
1121
|
+
|
|
1122
|
+
logger.debug("Received gossip payload envelope", {
|
|
1123
|
+
currentSlot: chain.clock.currentSlot,
|
|
1124
|
+
peerId: peerIdStr,
|
|
1125
|
+
slot,
|
|
1126
|
+
blockRoot: toRootHex(envelope.beaconBlockRoot),
|
|
1127
|
+
delaySec,
|
|
1128
|
+
});
|
|
1129
|
+
|
|
1121
1130
|
metrics?.gossipExecutionPayloadEnvelope.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
|
|
1122
1131
|
chain.validatorMonitor?.registerExecutionPayloadEnvelope(OpSource.gossip, delaySec, signedEnvelope);
|
|
1123
1132
|
|
|
@@ -1206,7 +1215,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1206
1215
|
chain.forkChoice.notifyPtcMessages(
|
|
1207
1216
|
toRootHex(payloadAttestationMessage.data.beaconBlockRoot),
|
|
1208
1217
|
validationResult.validatorCommitteeIndices,
|
|
1209
|
-
payloadAttestationMessage.data.payloadPresent
|
|
1218
|
+
payloadAttestationMessage.data.payloadPresent,
|
|
1219
|
+
payloadAttestationMessage.data.blobDataAvailable
|
|
1210
1220
|
);
|
|
1211
1221
|
},
|
|
1212
1222
|
[GossipType.execution_payload_bid]: async ({
|
|
@@ -1215,7 +1225,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1215
1225
|
}: GossipHandlerParamGeneric<GossipType.execution_payload_bid>) => {
|
|
1216
1226
|
const {serializedData} = gossipData;
|
|
1217
1227
|
const executionPayloadBid = sszDeserialize(topic, serializedData);
|
|
1218
|
-
await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
|
|
1228
|
+
const {proposerIndex} = await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
|
|
1219
1229
|
|
|
1220
1230
|
// Handle valid payload bid by storing in a bid pool
|
|
1221
1231
|
try {
|
|
@@ -1225,6 +1235,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1225
1235
|
logger.error("Error adding to executionPayloadBid pool", {}, e as Error);
|
|
1226
1236
|
}
|
|
1227
1237
|
|
|
1238
|
+
chain.validatorMonitor?.registerExecutionPayloadBid(OpSource.gossip, proposerIndex, executionPayloadBid.message);
|
|
1239
|
+
|
|
1228
1240
|
chain.emitter.emit(routes.events.EventType.executionPayloadBid, {
|
|
1229
1241
|
version: config.getForkName(executionPayloadBid.message.slot),
|
|
1230
1242
|
data: executionPayloadBid,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/execution/builder/utils.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAU1F"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* From https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md
|
|
3
|
-
*/
|
|
4
|
-
const gasLimitAdjustmentFactor = 1024;
|
|
5
|
-
/**
|
|
6
|
-
* Calculates expected gas limit based on parent gas limit and target gas limit
|
|
7
|
-
*/
|
|
8
|
-
export function getExpectedGasLimit(parentGasLimit, targetGasLimit) {
|
|
9
|
-
const maxGasLimitDifference = Math.max(Math.floor(parentGasLimit / gasLimitAdjustmentFactor) - 1, 0);
|
|
10
|
-
if (targetGasLimit > parentGasLimit) {
|
|
11
|
-
const gasDiff = targetGasLimit - parentGasLimit;
|
|
12
|
-
return parentGasLimit + Math.min(gasDiff, maxGasLimitDifference);
|
|
13
|
-
}
|
|
14
|
-
const gasDiff = parentGasLimit - targetGasLimit;
|
|
15
|
-
return parentGasLimit - Math.min(gasDiff, maxGasLimitDifference);
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/execution/builder/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAEtC;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,cAAsB,EAAE,cAAsB,EAAU;IAC1F,MAAM,qBAAqB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,wBAAwB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAErG,IAAI,cAAc,GAAG,cAAc,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,cAAc,GAAG,cAAc,CAAC;QAChD,OAAO,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,cAAc,GAAG,cAAc,CAAC;IAChD,OAAO,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;AAAA,CAClE"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* From https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md
|
|
3
|
-
*/
|
|
4
|
-
const gasLimitAdjustmentFactor = 1024;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Calculates expected gas limit based on parent gas limit and target gas limit
|
|
8
|
-
*/
|
|
9
|
-
export function getExpectedGasLimit(parentGasLimit: number, targetGasLimit: number): number {
|
|
10
|
-
const maxGasLimitDifference = Math.max(Math.floor(parentGasLimit / gasLimitAdjustmentFactor) - 1, 0);
|
|
11
|
-
|
|
12
|
-
if (targetGasLimit > parentGasLimit) {
|
|
13
|
-
const gasDiff = targetGasLimit - parentGasLimit;
|
|
14
|
-
return parentGasLimit + Math.min(gasDiff, maxGasLimitDifference);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const gasDiff = parentGasLimit - targetGasLimit;
|
|
18
|
-
return parentGasLimit - Math.min(gasDiff, maxGasLimitDifference);
|
|
19
|
-
}
|