@lodestar/beacon-node 1.44.0-dev.552cdce8d0 → 1.44.0-dev.985999b30c
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/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +8 -1
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +1 -1
- 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/produceBlock/produceBlockBody.d.ts +4 -0
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +48 -2
- 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/execution/engine/interface.d.ts +1 -0
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/types.d.ts +2 -0
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +2 -0
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +2 -1
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/package.json +14 -14
- package/src/api/impl/validator/index.ts +9 -1
- package/src/chain/blocks/importExecutionPayload.ts +1 -0
- package/src/chain/errors/executionPayloadBid.ts +4 -1
- package/src/chain/forkChoice/index.ts +14 -4
- package/src/chain/produceBlock/produceBlockBody.ts +75 -7
- 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/execution/engine/interface.ts +1 -0
- package/src/execution/engine/types.ts +4 -0
- package/src/network/processor/gossipHandlers.ts +3 -1
- 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
|
@@ -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
|
|
|
@@ -88,6 +88,7 @@ export type PayloadAttributes = {
|
|
|
88
88
|
withdrawals?: capella.Withdrawal[];
|
|
89
89
|
parentBeaconBlockRoot?: Uint8Array;
|
|
90
90
|
slotNumber?: number; // EIP-7843
|
|
91
|
+
targetGasLimit?: number; // GLOAS (PayloadAttributesV4, execution-apis#796)
|
|
91
92
|
};
|
|
92
93
|
|
|
93
94
|
export type VersionedHashes = Uint8Array[];
|
|
@@ -245,6 +245,8 @@ export type PayloadAttributesRpc = {
|
|
|
245
245
|
parentBeaconBlockRoot?: DATA;
|
|
246
246
|
/** QUANTITY, 64 Bits - value for the slot number field of the new payload (EIP-7843) */
|
|
247
247
|
slotNumber?: QUANTITY;
|
|
248
|
+
/** QUANTITY, 64 Bits - target value for the gasLimit field of the new payload (GLOAS, execution-apis#796) */
|
|
249
|
+
targetGasLimit?: QUANTITY;
|
|
248
250
|
};
|
|
249
251
|
|
|
250
252
|
export type ClientVersionRpc = {
|
|
@@ -425,6 +427,7 @@ export function serializePayloadAttributes(data: PayloadAttributes): PayloadAttr
|
|
|
425
427
|
withdrawals: data.withdrawals?.map(serializeWithdrawal),
|
|
426
428
|
parentBeaconBlockRoot: data.parentBeaconBlockRoot ? bytesToData(data.parentBeaconBlockRoot) : undefined,
|
|
427
429
|
slotNumber: data.slotNumber !== undefined ? numToQuantity(data.slotNumber) : undefined,
|
|
430
|
+
targetGasLimit: data.targetGasLimit !== undefined ? numToQuantity(data.targetGasLimit) : undefined,
|
|
428
431
|
};
|
|
429
432
|
}
|
|
430
433
|
|
|
@@ -442,6 +445,7 @@ export function deserializePayloadAttributes(data: PayloadAttributesRpc): Payloa
|
|
|
442
445
|
withdrawals: data.withdrawals?.map((withdrawal) => deserializeWithdrawal(withdrawal)),
|
|
443
446
|
parentBeaconBlockRoot: data.parentBeaconBlockRoot ? dataToBytes(data.parentBeaconBlockRoot, 32) : undefined,
|
|
444
447
|
slotNumber: data.slotNumber !== undefined ? quantityToNum(data.slotNumber) : undefined,
|
|
448
|
+
targetGasLimit: data.targetGasLimit !== undefined ? quantityToNum(data.targetGasLimit) : undefined,
|
|
445
449
|
};
|
|
446
450
|
}
|
|
447
451
|
|
|
@@ -1215,7 +1215,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1215
1215
|
}: GossipHandlerParamGeneric<GossipType.execution_payload_bid>) => {
|
|
1216
1216
|
const {serializedData} = gossipData;
|
|
1217
1217
|
const executionPayloadBid = sszDeserialize(topic, serializedData);
|
|
1218
|
-
await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
|
|
1218
|
+
const {proposerIndex} = await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
|
|
1219
1219
|
|
|
1220
1220
|
// Handle valid payload bid by storing in a bid pool
|
|
1221
1221
|
try {
|
|
@@ -1225,6 +1225,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1225
1225
|
logger.error("Error adding to executionPayloadBid pool", {}, e as Error);
|
|
1226
1226
|
}
|
|
1227
1227
|
|
|
1228
|
+
chain.validatorMonitor?.registerExecutionPayloadBid(OpSource.gossip, proposerIndex, executionPayloadBid.message);
|
|
1229
|
+
|
|
1228
1230
|
chain.emitter.emit(routes.events.EventType.executionPayloadBid, {
|
|
1229
1231
|
version: config.getForkName(executionPayloadBid.message.slot),
|
|
1230
1232
|
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
|
-
}
|