@lodestar/beacon-node 1.44.0-dev.6ef8199cfa → 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.
Files changed (42) hide show
  1. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  2. package/lib/chain/blocks/importExecutionPayload.js +1 -1
  3. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  4. package/lib/chain/errors/executionPayloadBid.d.ts +6 -1
  5. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  6. package/lib/chain/errors/executionPayloadBid.js +1 -0
  7. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  8. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  9. package/lib/chain/forkChoice/index.js +14 -4
  10. package/lib/chain/forkChoice/index.js.map +1 -1
  11. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  12. package/lib/chain/produceBlock/produceBlockBody.js +19 -8
  13. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  14. package/lib/chain/validation/executionPayloadBid.d.ts +7 -3
  15. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  16. package/lib/chain/validation/executionPayloadBid.js +24 -8
  17. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  18. package/lib/chain/validatorMonitor.d.ts +1 -0
  19. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  20. package/lib/chain/validatorMonitor.js +16 -0
  21. package/lib/chain/validatorMonitor.js.map +1 -1
  22. package/lib/execution/builder/index.d.ts +1 -2
  23. package/lib/execution/builder/index.d.ts.map +1 -1
  24. package/lib/execution/builder/index.js +0 -1
  25. package/lib/execution/builder/index.js.map +1 -1
  26. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  27. package/lib/network/processor/gossipHandlers.js +2 -1
  28. package/lib/network/processor/gossipHandlers.js.map +1 -1
  29. package/package.json +14 -14
  30. package/src/chain/blocks/importExecutionPayload.ts +1 -0
  31. package/src/chain/errors/executionPayloadBid.ts +4 -1
  32. package/src/chain/forkChoice/index.ts +14 -4
  33. package/src/chain/produceBlock/produceBlockBody.ts +25 -16
  34. package/src/chain/validation/executionPayloadBid.ts +30 -12
  35. package/src/chain/validatorMonitor.ts +18 -0
  36. package/src/execution/builder/index.ts +1 -4
  37. package/src/network/processor/gossipHandlers.ts +3 -1
  38. package/lib/execution/builder/utils.d.ts +0 -5
  39. package/lib/execution/builder/utils.d.ts.map +0 -1
  40. package/lib/execution/builder/utils.js +0 -17
  41. package/lib/execution/builder/utils.js.map +0 -1
  42. 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<void> {
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<void> {
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<void> {
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
- // [REJECT] `bid.gas_limit == proposer_preferences.target_gas_limit`.
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
- if (bidGasLimit !== proposerPreferences.message.targetGasLimit) {
134
- throw new ExecutionPayloadBidError(GossipAction.REJECT, {
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
- expectedGasLimit: proposerPreferences.message.targetGasLimit,
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
 
@@ -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,5 +0,0 @@
1
- /**
2
- * Calculates expected gas limit based on parent gas limit and target gas limit
3
- */
4
- export declare function getExpectedGasLimit(parentGasLimit: number, targetGasLimit: number): number;
5
- //# sourceMappingURL=utils.d.ts.map
@@ -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
- }