@lodestar/builder 1.50.0-dev.033e6b7138 → 1.50.0-dev.1f38fe79fb

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.
@@ -15,6 +15,7 @@ export type BidLedgerRecord = SubmittedBid & {
15
15
  export declare enum BidLedgerErrorCode {
16
16
  INVALID_BID_VALUE = "BID_LEDGER_ERROR_INVALID_BID_VALUE",
17
17
  DUPLICATE_BID = "BID_LEDGER_ERROR_DUPLICATE_BID",
18
+ BID_TOO_OLD = "BID_LEDGER_ERROR_BID_TOO_OLD",
18
19
  REVEAL_CONFLICT = "BID_LEDGER_ERROR_REVEAL_CONFLICT",
19
20
  UNSETTLED_VALUE_OVERFLOW = "BID_LEDGER_ERROR_UNSETTLED_VALUE_OVERFLOW"
20
21
  }
@@ -26,6 +27,10 @@ export type BidLedgerErrorType = {
26
27
  slot: Slot;
27
28
  parentBlockHash: RootHex;
28
29
  parentBlockRoot: RootHex;
30
+ } | {
31
+ code: BidLedgerErrorCode.BID_TOO_OLD;
32
+ slot: Slot;
33
+ pruneCutoffSlot: Slot;
29
34
  } | {
30
35
  code: BidLedgerErrorCode.REVEAL_CONFLICT;
31
36
  blockRoot: RootHex;
@@ -43,7 +48,9 @@ export declare class BidLedgerError extends LodestarError<BidLedgerErrorType> {
43
48
  export declare class BidLedger {
44
49
  private readonly bidsBySlot;
45
50
  private readonly revealedPayloadByBlockRoot;
51
+ private pruneCutoffSlot;
46
52
  hasSubmitted(slot: Slot, parentBlockHash: RootHex, parentBlockRoot: RootHex): boolean;
53
+ assertCanRecordBid({ slot, parentBlockHash, parentBlockRoot, }: Pick<SubmittedBid, "slot" | "parentBlockHash" | "parentBlockRoot">): void;
47
54
  recordBid(bid: SubmittedBid): BidLedgerRecord;
48
55
  recordWin(identity: BidIdentity & Pick<SubmittedBid, "signedBidRoot">, blockRoot: RootHex): BidLedgerRecord | null;
49
56
  /** Release a winning bid liability only after its payment is known to be reflected in Builder balance. */
@@ -1 +1 @@
1
- {"version":3,"file":"bidLedger.d.ts","sourceRoot":"","sources":["../../src/services/bidLedger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bidLedger.d.ts","sourceRoot":"","sources":["../../src/services/bidLedger.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ export var BidLedgerErrorCode;
4
4
  (function (BidLedgerErrorCode) {
5
5
  BidLedgerErrorCode["INVALID_BID_VALUE"] = "BID_LEDGER_ERROR_INVALID_BID_VALUE";
6
6
  BidLedgerErrorCode["DUPLICATE_BID"] = "BID_LEDGER_ERROR_DUPLICATE_BID";
7
+ BidLedgerErrorCode["BID_TOO_OLD"] = "BID_LEDGER_ERROR_BID_TOO_OLD";
7
8
  BidLedgerErrorCode["REVEAL_CONFLICT"] = "BID_LEDGER_ERROR_REVEAL_CONFLICT";
8
9
  BidLedgerErrorCode["UNSETTLED_VALUE_OVERFLOW"] = "BID_LEDGER_ERROR_UNSETTLED_VALUE_OVERFLOW";
9
10
  })(BidLedgerErrorCode || (BidLedgerErrorCode = {}));
@@ -15,27 +16,29 @@ const KEEP_SLOTS = RECORD_RETENTION_EPOCHS * SLOTS_PER_EPOCH;
15
16
  export class BidLedger {
16
17
  bidsBySlot = new Map();
17
18
  revealedPayloadByBlockRoot = new Map();
19
+ pruneCutoffSlot = 0;
18
20
  hasSubmitted(slot, parentBlockHash, parentBlockRoot) {
19
21
  return this.bidsBySlot.get(slot)?.has(tupleKey(parentBlockHash, parentBlockRoot)) ?? false;
20
22
  }
23
+ assertCanRecordBid({ slot, parentBlockHash, parentBlockRoot, }) {
24
+ if (slot < this.pruneCutoffSlot) {
25
+ throw new BidLedgerError({ code: BidLedgerErrorCode.BID_TOO_OLD, slot, pruneCutoffSlot: this.pruneCutoffSlot });
26
+ }
27
+ if (this.hasSubmitted(slot, parentBlockHash, parentBlockRoot)) {
28
+ throw new BidLedgerError({ code: BidLedgerErrorCode.DUPLICATE_BID, slot, parentBlockHash, parentBlockRoot }, `Bid already recorded slot=${slot} parentBlockHash=${parentBlockHash} parentBlockRoot=${parentBlockRoot}`);
29
+ }
30
+ }
21
31
  recordBid(bid) {
22
32
  if (!Number.isSafeInteger(bid.valueGwei) || bid.valueGwei < 0) {
23
33
  throw new BidLedgerError({ code: BidLedgerErrorCode.INVALID_BID_VALUE, valueGwei: bid.valueGwei }, `Invalid bid value valueGwei=${bid.valueGwei}`);
24
34
  }
35
+ this.assertCanRecordBid(bid);
25
36
  let bidsForSlot = this.bidsBySlot.get(bid.slot);
26
37
  if (bidsForSlot === undefined) {
27
38
  bidsForSlot = new Map();
28
39
  this.bidsBySlot.set(bid.slot, bidsForSlot);
29
40
  }
30
41
  const key = tupleKey(bid.parentBlockHash, bid.parentBlockRoot);
31
- if (bidsForSlot.has(key)) {
32
- throw new BidLedgerError({
33
- code: BidLedgerErrorCode.DUPLICATE_BID,
34
- slot: bid.slot,
35
- parentBlockHash: bid.parentBlockHash,
36
- parentBlockRoot: bid.parentBlockRoot,
37
- }, `Bid already recorded slot=${bid.slot} parentBlockHash=${bid.parentBlockHash} parentBlockRoot=${bid.parentBlockRoot}`);
38
- }
39
42
  const record = { ...bid, wonBlockRoots: new Set(), paymentSettled: false };
40
43
  bidsForSlot.set(key, record);
41
44
  return toRecord(record);
@@ -111,9 +114,11 @@ export class BidLedger {
111
114
  return Array.from(this.bidsBySlot.get(slot)?.values() ?? [], toRecord);
112
115
  }
113
116
  prune(currentSlot) {
117
+ // Pruning must not make an expired slot eligible for another submission.
118
+ this.pruneCutoffSlot = Math.max(this.pruneCutoffSlot, currentSlot - KEEP_SLOTS);
114
119
  let removed = 0;
115
120
  for (const [slot, bidsForSlot] of this.bidsBySlot) {
116
- if (slot >= currentSlot - KEEP_SLOTS) {
121
+ if (slot >= this.pruneCutoffSlot) {
117
122
  continue;
118
123
  }
119
124
  for (const [key, record] of bidsForSlot) {
@@ -127,7 +132,7 @@ export class BidLedger {
127
132
  }
128
133
  }
129
134
  for (const [blockRoot, revealedPayload] of this.revealedPayloadByBlockRoot) {
130
- if (revealedPayload.slot < currentSlot - KEEP_SLOTS) {
135
+ if (revealedPayload.slot < this.pruneCutoffSlot) {
131
136
  this.revealedPayloadByBlockRoot.delete(blockRoot);
132
137
  }
133
138
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bidLedger.js","sourceRoot":"","sources":["../../src/services/bidLedger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bidLedger.js","sourceRoot":"","sources":["../../src/services/bidLedger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { ApiClient } from "@lodestar/api";
2
+ import type { ChainForkConfig } from "@lodestar/config";
3
+ import type { BuilderIndex, RootHex, Slot, gloas, heze } from "@lodestar/types";
4
+ import { LodestarError } from "@lodestar/utils";
5
+ import type { BidIdentity, BidLedger } from "./bidLedger.js";
6
+ import type { BuilderSigner } from "./builderSigner.js";
7
+ export type BidPublisherModules = {
8
+ api: ApiClient;
9
+ config: ChainForkConfig;
10
+ signer: BuilderSigner;
11
+ ledger: BidLedger;
12
+ builderIndex: BuilderIndex;
13
+ hasPayload: (identity: BidIdentity) => boolean;
14
+ };
15
+ export declare enum BidPublisherErrorCode {
16
+ BUILDER_INDEX_MISMATCH = "BID_PUBLISHER_ERROR_BUILDER_INDEX_MISMATCH",
17
+ PAYLOAD_NOT_RETAINED = "BID_PUBLISHER_ERROR_PAYLOAD_NOT_RETAINED",
18
+ PRE_GLOAS_BID = "BID_PUBLISHER_ERROR_PRE_GLOAS_BID"
19
+ }
20
+ export type BidPublisherErrorType = {
21
+ code: BidPublisherErrorCode.PRE_GLOAS_BID;
22
+ slot: Slot;
23
+ } | {
24
+ code: BidPublisherErrorCode.BUILDER_INDEX_MISMATCH;
25
+ builderIndex: BuilderIndex;
26
+ bidBuilderIndex: BuilderIndex;
27
+ } | {
28
+ code: BidPublisherErrorCode.PAYLOAD_NOT_RETAINED;
29
+ slot: Slot;
30
+ parentBlockHash: RootHex;
31
+ parentBlockRoot: RootHex;
32
+ blockHash: RootHex;
33
+ };
34
+ export declare class BidPublisherError extends LodestarError<BidPublisherErrorType> {
35
+ }
36
+ /** Signs and submits a bid only if its payload is retained locally. */
37
+ export declare class BidPublisher {
38
+ private readonly modules;
39
+ constructor(modules: BidPublisherModules);
40
+ publish(bid: heze.ExecutionPayloadBid, signal: AbortSignal): Promise<heze.SignedExecutionPayloadBid>;
41
+ publish(bid: gloas.ExecutionPayloadBid, signal: AbortSignal): Promise<gloas.SignedExecutionPayloadBid>;
42
+ }
43
+ //# sourceMappingURL=bidPublisher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bidPublisher.d.ts","sourceRoot":"","sources":["../../src/services/bidPublisher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEtD,OAAO,KAAK,EAAC,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAC,MAAM,iBAAiB,CAAC;AAE9E,OAAO,EAAC,aAAa,EAAY,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAC,WAAW,EAAE,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEtD,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,OAAO,CAAC;CAChD,CAAC;AAEF,oBAAY,qBAAqB;IAC/B,sBAAsB,+CAA+C;IACrE,oBAAoB,6CAA6C;IACjE,aAAa,sCAAsC;CACpD;AAED,MAAM,MAAM,qBAAqB,GAC7B;IACE,IAAI,EAAE,qBAAqB,CAAC,aAAa,CAAC;IAC1C,IAAI,EAAE,IAAI,CAAC;CACZ,GACD;IACE,IAAI,EAAE,qBAAqB,CAAC,sBAAsB,CAAC;IACnD,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,YAAY,CAAC;CAC/B,GACD;IACE,IAAI,EAAE,qBAAqB,CAAC,oBAAoB,CAAC;IACjD,IAAI,EAAE,IAAI,CAAC;IACX,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEN,qBAAa,iBAAkB,SAAQ,aAAa,CAAC,qBAAqB,CAAC;CAAG;AAE9E,uEAAuE;AACvE,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;IAApC,YAA6B,OAAO,EAAE,mBAAmB,EAAI;IAE7D,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACrG,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,mBAAmB,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;CA6CxG"}
@@ -0,0 +1,50 @@
1
+ import { isForkPostGloas } from "@lodestar/params";
2
+ import { sszTypesFor } from "@lodestar/types";
3
+ import { LodestarError, toRootHex } from "@lodestar/utils";
4
+ export var BidPublisherErrorCode;
5
+ (function (BidPublisherErrorCode) {
6
+ BidPublisherErrorCode["BUILDER_INDEX_MISMATCH"] = "BID_PUBLISHER_ERROR_BUILDER_INDEX_MISMATCH";
7
+ BidPublisherErrorCode["PAYLOAD_NOT_RETAINED"] = "BID_PUBLISHER_ERROR_PAYLOAD_NOT_RETAINED";
8
+ BidPublisherErrorCode["PRE_GLOAS_BID"] = "BID_PUBLISHER_ERROR_PRE_GLOAS_BID";
9
+ })(BidPublisherErrorCode || (BidPublisherErrorCode = {}));
10
+ export class BidPublisherError extends LodestarError {
11
+ }
12
+ /** Signs and submits a bid only if its payload is retained locally. */
13
+ export class BidPublisher {
14
+ modules;
15
+ constructor(modules) {
16
+ this.modules = modules;
17
+ }
18
+ async publish(bid, signal) {
19
+ signal.throwIfAborted();
20
+ const { api, config, builderIndex, hasPayload, ledger, signer } = this.modules;
21
+ const fork = config.getForkName(bid.slot);
22
+ if (!isForkPostGloas(fork)) {
23
+ throw new BidPublisherError({ code: BidPublisherErrorCode.PRE_GLOAS_BID, slot: bid.slot });
24
+ }
25
+ if (bid.builderIndex !== builderIndex) {
26
+ throw new BidPublisherError({
27
+ code: BidPublisherErrorCode.BUILDER_INDEX_MISMATCH,
28
+ builderIndex,
29
+ bidBuilderIndex: bid.builderIndex,
30
+ }, `Bid builder index does not match local builder index builderIndex=${builderIndex} bidBuilderIndex=${bid.builderIndex}`);
31
+ }
32
+ const identity = {
33
+ slot: bid.slot,
34
+ parentBlockHash: toRootHex(bid.parentBlockHash),
35
+ parentBlockRoot: toRootHex(bid.parentBlockRoot),
36
+ blockHash: toRootHex(bid.blockHash),
37
+ };
38
+ if (!hasPayload(identity)) {
39
+ throw new BidPublisherError({ code: BidPublisherErrorCode.PAYLOAD_NOT_RETAINED, ...identity }, `Bid payload is not retained slot=${identity.slot} parentBlockHash=${identity.parentBlockHash} parentBlockRoot=${identity.parentBlockRoot} blockHash=${identity.blockHash}`);
40
+ }
41
+ ledger.assertCanRecordBid(identity);
42
+ const signedExecutionPayloadBid = signer.signExecutionPayloadBid(bid);
43
+ const signedBidRoot = toRootHex(sszTypesFor(fork, "SignedExecutionPayloadBid").hashTreeRoot(signedExecutionPayloadBid));
44
+ ledger.recordBid({ ...identity, valueGwei: bid.value, signedBidRoot });
45
+ const response = await api.beacon.publishExecutionPayloadBid({ signedExecutionPayloadBid }, { signal });
46
+ response.assertOk();
47
+ return signedExecutionPayloadBid;
48
+ }
49
+ }
50
+ //# sourceMappingURL=bidPublisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bidPublisher.js","sourceRoot":"","sources":["../../src/services/bidPublisher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAC,WAAW,EAAC,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAazD,MAAM,CAAN,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,8FAAqE,CAAA;IACrE,0FAAiE,CAAA;IACjE,4EAAmD,CAAA;AACrD,CAAC,EAJW,qBAAqB,KAArB,qBAAqB,QAIhC;AAoBD,MAAM,OAAO,iBAAkB,SAAQ,aAAoC;CAAG;AAE9E,uEAAuE;AACvE,MAAM,OAAO,YAAY;IACM,OAAO;IAApC,YAA6B,OAA4B;uBAA5B,OAAO;IAAwB,CAAC;IAI7D,KAAK,CAAC,OAAO,CAAC,GAA8B,EAAE,MAAmB;QAC/D,MAAM,CAAC,cAAc,EAAE,CAAC;QAExB,MAAM,EAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAC,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,iBAAiB,CAAC,EAAC,IAAI,EAAE,qBAAqB,CAAC,aAAa,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAC,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,GAAG,CAAC,YAAY,KAAK,YAAY,EAAE,CAAC;YACtC,MAAM,IAAI,iBAAiB,CACzB;gBACE,IAAI,EAAE,qBAAqB,CAAC,sBAAsB;gBAClD,YAAY;gBACZ,eAAe,EAAE,GAAG,CAAC,YAAY;aAClC,EACD,qEAAqE,YAAY,oBAAoB,GAAG,CAAC,YAAY,EAAE,CACxH,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAgB;YAC5B,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,eAAe,EAAE,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;YAC/C,eAAe,EAAE,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;YAC/C,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC;SACpC,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,iBAAiB,CACzB,EAAC,IAAI,EAAE,qBAAqB,CAAC,oBAAoB,EAAE,GAAG,QAAQ,EAAC,EAC/D,oCAAoC,QAAQ,CAAC,IAAI,oBAAoB,QAAQ,CAAC,eAAe,oBAAoB,QAAQ,CAAC,eAAe,cAAc,QAAQ,CAAC,SAAS,EAAE,CAC5K,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAEpC,MAAM,yBAAyB,GAAG,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG,SAAS,CAC7B,WAAW,CAAC,IAAI,EAAE,2BAA2B,CAAC,CAAC,YAAY,CAAC,yBAAyB,CAAC,CACvF,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,EAAC,GAAG,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,EAAE,aAAa,EAAC,CAAC,CAAC;QAErE,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,0BAA0B,CAAC,EAAC,yBAAyB,EAAC,EAAE,EAAC,MAAM,EAAC,CAAC,CAAC;QACpG,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO,yBAAyB,CAAC;IACnC,CAAC;CACF"}
@@ -1,6 +1,6 @@
1
1
  import { PublicKey, SecretKey } from "@chainsafe/lodestar-z/blst";
2
2
  import { BeaconConfig } from "@lodestar/config";
3
- import { gloas } from "@lodestar/types";
3
+ import { gloas, heze } from "@lodestar/types";
4
4
  export type Keypair = {
5
5
  publicKey: PublicKey;
6
6
  secretKey: SecretKey;
@@ -10,6 +10,7 @@ export declare class BuilderSigner {
10
10
  private readonly keypair;
11
11
  constructor(config: BeaconConfig, keypair: Keypair);
12
12
  signExecutionPayloadEnvelope(envelope: gloas.ExecutionPayloadEnvelope): gloas.SignedExecutionPayloadEnvelope;
13
+ signExecutionPayloadBid(bid: heze.ExecutionPayloadBid): heze.SignedExecutionPayloadBid;
13
14
  signExecutionPayloadBid(bid: gloas.ExecutionPayloadBid): gloas.SignedExecutionPayloadBid;
14
15
  getPubkeyHex(): string;
15
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"builderSigner.d.ts","sourceRoot":"","sources":["../../src/services/builderSigner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAC,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAC;AAEtC,MAAM,MAAM,OAAO,GAAG;IAAC,SAAS,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAC,CAAC;AAEnE,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,YAAY,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAGjD;IAED,4BAA4B,CAAC,QAAQ,EAAE,KAAK,CAAC,wBAAwB,GAAG,KAAK,CAAC,8BAA8B,CAO3G;IAED,uBAAuB,CAAC,GAAG,EAAE,KAAK,CAAC,mBAAmB,GAAG,KAAK,CAAC,yBAAyB,CAOvF;IAED,YAAY,IAAI,MAAM,CAErB;CACF"}
1
+ {"version":3,"file":"builderSigner.d.ts","sourceRoot":"","sources":["../../src/services/builderSigner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAC,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,MAAM,iBAAiB,CAAC;AAE5C,MAAM,MAAM,OAAO,GAAG;IAAC,SAAS,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAC,CAAC;AAEnE,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,YAAY,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAGjD;IAED,4BAA4B,CAAC,QAAQ,EAAE,KAAK,CAAC,wBAAwB,GAAG,KAAK,CAAC,8BAA8B,CAO3G;IAED,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,yBAAyB,CAAC;IACvF,uBAAuB,CAAC,GAAG,EAAE,KAAK,CAAC,mBAAmB,GAAG,KAAK,CAAC,yBAAyB,CAAC;IAUzF,YAAY,IAAI,MAAM,CAErB;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"builderSigner.js","sourceRoot":"","sources":["../../src/services/builderSigner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,iCAAiC,EAAE,sCAAsC,EAAC,MAAM,4BAA4B,CAAC;AAKrH,MAAM,OAAO,aAAa;IACP,MAAM,CAAe;IACrB,OAAO,CAAU;IAElC,YAAY,MAAoB,EAAE,OAAgB;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,4BAA4B,CAAC,QAAwC;QACnE,MAAM,WAAW,GAAG,sCAAsC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAElF,OAAO;YACL,OAAO,EAAE,QAAQ;YACjB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE;SAC9D,CAAC;IACJ,CAAC;IAED,uBAAuB,CAAC,GAA8B;QACpD,MAAM,WAAW,GAAG,iCAAiC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAExE,OAAO;YACL,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE;SAC9D,CAAC;IACJ,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACxC,CAAC;CACF"}
1
+ {"version":3,"file":"builderSigner.js","sourceRoot":"","sources":["../../src/services/builderSigner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,iCAAiC,EAAE,sCAAsC,EAAC,MAAM,4BAA4B,CAAC;AAKrH,MAAM,OAAO,aAAa;IACP,MAAM,CAAe;IACrB,OAAO,CAAU;IAElC,YAAY,MAAoB,EAAE,OAAgB;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,4BAA4B,CAAC,QAAwC;QACnE,MAAM,WAAW,GAAG,sCAAsC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAElF,OAAO;YACL,OAAO,EAAE,QAAQ;YACjB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE;SAC9D,CAAC;IACJ,CAAC;IAID,uBAAuB,CAAC,GAA8B;QACpD,MAAM,WAAW,GAAG,iCAAiC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAExE,OAAO;YACL,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE;SAC9D,CAAC;IACJ,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,57 @@
1
+ import { ForkName, type ForkPostGloas } from "@lodestar/params";
2
+ import type { BuilderIndex, Bytes32, ExecutionAddress, ExecutionPayloadBid, Root, RootHex, Slot, gloas, heze } from "@lodestar/types";
3
+ import { LodestarError } from "@lodestar/utils";
4
+ import type { BuiltPayload } from "./payloadSource.js";
5
+ type CommonBidInput<F extends ForkPostGloas> = {
6
+ slot: Slot;
7
+ parentBlockRoot: Root;
8
+ /** Expected value from the BN payload attributes used for this build. */
9
+ prevRandao: Bytes32;
10
+ builderIndex: BuilderIndex;
11
+ feeRecipient: ExecutionAddress;
12
+ /** Bid value in gwei */
13
+ value: number;
14
+ payload: BuiltPayload & {
15
+ fork: F;
16
+ };
17
+ };
18
+ export type GloasBidInput = CommonBidInput<ForkName.gloas>;
19
+ export type HezeBidInput = CommonBidInput<ForkName.heze> & {
20
+ inclusionListBits: heze.ExecutionPayloadBid["inclusionListBits"];
21
+ };
22
+ export type ExecutionPayloadBidInput = GloasBidInput | HezeBidInput;
23
+ export declare enum ExecutionPayloadBidErrorCode {
24
+ INVALID_VALUE = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_VALUE",
25
+ INVALID_GAS_LIMIT = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_GAS_LIMIT",
26
+ SLOT_MISMATCH = "EXECUTION_PAYLOAD_BID_ERROR_SLOT_MISMATCH",
27
+ BLOCK_HASH_EQUALS_PARENT = "EXECUTION_PAYLOAD_BID_ERROR_BLOCK_HASH_EQUALS_PARENT",
28
+ INVALID_INCLUSION_LIST_BITS = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_INCLUSION_LIST_BITS",
29
+ PREV_RANDAO_MISMATCH = "EXECUTION_PAYLOAD_BID_ERROR_PREV_RANDAO_MISMATCH"
30
+ }
31
+ export type ExecutionPayloadBidErrorType = {
32
+ code: ExecutionPayloadBidErrorCode.INVALID_GAS_LIMIT;
33
+ gasLimit: number;
34
+ } | {
35
+ code: ExecutionPayloadBidErrorCode.SLOT_MISMATCH;
36
+ slot: Slot;
37
+ payloadSlot: Slot;
38
+ } | {
39
+ code: ExecutionPayloadBidErrorCode.BLOCK_HASH_EQUALS_PARENT;
40
+ } | {
41
+ code: ExecutionPayloadBidErrorCode.INVALID_INCLUSION_LIST_BITS;
42
+ bitLen: number | undefined;
43
+ } | {
44
+ code: ExecutionPayloadBidErrorCode.PREV_RANDAO_MISMATCH;
45
+ expectedPrevRandao: RootHex;
46
+ payloadPrevRandao: RootHex;
47
+ } | {
48
+ code: ExecutionPayloadBidErrorCode.INVALID_VALUE;
49
+ value: number;
50
+ };
51
+ export declare class ExecutionPayloadBidError extends LodestarError<ExecutionPayloadBidErrorType> {
52
+ }
53
+ export declare function createExecutionPayloadBid(input: GloasBidInput): gloas.ExecutionPayloadBid;
54
+ export declare function createExecutionPayloadBid(input: HezeBidInput): heze.ExecutionPayloadBid;
55
+ export declare function createExecutionPayloadBid(input: ExecutionPayloadBidInput): ExecutionPayloadBid;
56
+ export {};
57
+ //# sourceMappingURL=executionPayloadBid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executionPayloadBid.d.ts","sourceRoot":"","sources":["../../src/services/executionPayloadBid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,KAAK,aAAa,EAAgD,MAAM,kBAAkB,CAAC;AAC7G,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,KAAK,EACL,IAAI,EACL,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,aAAa,EAA6B,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAErD,KAAK,cAAc,CAAC,CAAC,SAAS,aAAa,IAAI;IAC7C,IAAI,EAAE,IAAI,CAAC;IACX,eAAe,EAAE,IAAI,CAAC;IACtB,yEAAyE;IACzE,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,GAAG;QAAC,IAAI,EAAE,CAAC,CAAA;KAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE3D,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG;IACzD,iBAAiB,EAAE,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;CAClE,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,aAAa,GAAG,YAAY,CAAC;AAEpE,oBAAY,4BAA4B;IACtC,aAAa,8CAA8C;IAC3D,iBAAiB,kDAAkD;IACnE,aAAa,8CAA8C;IAC3D,wBAAwB,yDAAyD;IACjF,2BAA2B,4DAA4D;IACvF,oBAAoB,qDAAqD;CAC1E;AAED,MAAM,MAAM,4BAA4B,GACpC;IAAC,IAAI,EAAE,4BAA4B,CAAC,iBAAiB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,GACxE;IAAC,IAAI,EAAE,4BAA4B,CAAC,aAAa,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,IAAI,CAAA;CAAC,GACjF;IAAC,IAAI,EAAE,4BAA4B,CAAC,wBAAwB,CAAA;CAAC,GAC7D;IAAC,IAAI,EAAE,4BAA4B,CAAC,2BAA2B,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAAC,GAC5F;IACE,IAAI,EAAE,4BAA4B,CAAC,oBAAoB,CAAC;IACxD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;CAC5B,GACD;IACE,IAAI,EAAE,4BAA4B,CAAC,aAAa,CAAC;IACjD,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,qBAAa,wBAAyB,SAAQ,aAAa,CAAC,4BAA4B,CAAC;CAAG;AAE5F,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,aAAa,GAAG,KAAK,CAAC,mBAAmB,CAAC;AAC3F,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC;AACzF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,wBAAwB,GAAG,mBAAmB,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { INCLUSION_LIST_COMMITTEE_SIZE, isForkPostHeze } from "@lodestar/params";
2
+ import { sszTypesFor } from "@lodestar/types";
3
+ import { LodestarError, byteArrayEquals, toRootHex } from "@lodestar/utils";
4
+ export var ExecutionPayloadBidErrorCode;
5
+ (function (ExecutionPayloadBidErrorCode) {
6
+ ExecutionPayloadBidErrorCode["INVALID_VALUE"] = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_VALUE";
7
+ ExecutionPayloadBidErrorCode["INVALID_GAS_LIMIT"] = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_GAS_LIMIT";
8
+ ExecutionPayloadBidErrorCode["SLOT_MISMATCH"] = "EXECUTION_PAYLOAD_BID_ERROR_SLOT_MISMATCH";
9
+ ExecutionPayloadBidErrorCode["BLOCK_HASH_EQUALS_PARENT"] = "EXECUTION_PAYLOAD_BID_ERROR_BLOCK_HASH_EQUALS_PARENT";
10
+ ExecutionPayloadBidErrorCode["INVALID_INCLUSION_LIST_BITS"] = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_INCLUSION_LIST_BITS";
11
+ ExecutionPayloadBidErrorCode["PREV_RANDAO_MISMATCH"] = "EXECUTION_PAYLOAD_BID_ERROR_PREV_RANDAO_MISMATCH";
12
+ })(ExecutionPayloadBidErrorCode || (ExecutionPayloadBidErrorCode = {}));
13
+ export class ExecutionPayloadBidError extends LodestarError {
14
+ }
15
+ export function createExecutionPayloadBid(input) {
16
+ if (!Number.isSafeInteger(input.value) || input.value < 0) {
17
+ throw new ExecutionPayloadBidError({ code: ExecutionPayloadBidErrorCode.INVALID_VALUE, value: input.value }, `Invalid bid value value=${input.value}`);
18
+ }
19
+ const { fork, executionPayload, executionRequests, blobsBundle } = input.payload;
20
+ if (executionPayload.gasLimit > Number.MAX_SAFE_INTEGER) {
21
+ throw new ExecutionPayloadBidError({
22
+ code: ExecutionPayloadBidErrorCode.INVALID_GAS_LIMIT,
23
+ gasLimit: executionPayload.gasLimit,
24
+ });
25
+ }
26
+ if (executionPayload.slotNumber !== input.slot) {
27
+ throw new ExecutionPayloadBidError({
28
+ code: ExecutionPayloadBidErrorCode.SLOT_MISMATCH,
29
+ slot: input.slot,
30
+ payloadSlot: executionPayload.slotNumber,
31
+ });
32
+ }
33
+ if (byteArrayEquals(executionPayload.blockHash, executionPayload.parentHash)) {
34
+ throw new ExecutionPayloadBidError({ code: ExecutionPayloadBidErrorCode.BLOCK_HASH_EQUALS_PARENT });
35
+ }
36
+ if (!byteArrayEquals(executionPayload.prevRandao, input.prevRandao)) {
37
+ throw new ExecutionPayloadBidError({
38
+ code: ExecutionPayloadBidErrorCode.PREV_RANDAO_MISMATCH,
39
+ expectedPrevRandao: toRootHex(input.prevRandao),
40
+ payloadPrevRandao: toRootHex(executionPayload.prevRandao),
41
+ });
42
+ }
43
+ const bid = {
44
+ parentBlockHash: executionPayload.parentHash,
45
+ parentBlockRoot: input.parentBlockRoot,
46
+ blockHash: executionPayload.blockHash,
47
+ prevRandao: input.prevRandao,
48
+ feeRecipient: input.feeRecipient,
49
+ gasLimit: BigInt(executionPayload.gasLimit),
50
+ builderIndex: input.builderIndex,
51
+ slot: input.slot,
52
+ value: input.value,
53
+ executionPayment: 0n,
54
+ blobKzgCommitments: blobsBundle.commitments,
55
+ executionRequestsRoot: sszTypesFor(fork).ExecutionRequests.hashTreeRoot(executionRequests),
56
+ };
57
+ if (isForkPostHeze(fork)) {
58
+ const inclusionListBits = "inclusionListBits" in input ? input.inclusionListBits : undefined;
59
+ if (inclusionListBits?.bitLen !== INCLUSION_LIST_COMMITTEE_SIZE) {
60
+ throw new ExecutionPayloadBidError({
61
+ code: ExecutionPayloadBidErrorCode.INVALID_INCLUSION_LIST_BITS,
62
+ bitLen: inclusionListBits?.bitLen,
63
+ });
64
+ }
65
+ return { ...bid, inclusionListBits };
66
+ }
67
+ return bid;
68
+ }
69
+ //# sourceMappingURL=executionPayloadBid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executionPayloadBid.js","sourceRoot":"","sources":["../../src/services/executionPayloadBid.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodestar/builder",
3
- "version": "1.50.0-dev.033e6b7138",
3
+ "version": "1.50.0-dev.1f38fe79fb",
4
4
  "description": "A Typescript implementation of the builder client",
5
5
  "author": "ChainSafe Systems",
6
6
  "license": "Apache-2.0",
@@ -48,16 +48,16 @@
48
48
  "dependencies": {
49
49
  "@chainsafe/lodestar-z": "catalog:",
50
50
  "@chainsafe/ssz": "^1.8.0",
51
- "@lodestar/api": "^1.50.0-dev.033e6b7138",
52
- "@lodestar/config": "^1.50.0-dev.033e6b7138",
53
- "@lodestar/params": "^1.50.0-dev.033e6b7138",
54
- "@lodestar/state-transition": "^1.50.0-dev.033e6b7138",
55
- "@lodestar/types": "^1.50.0-dev.033e6b7138",
56
- "@lodestar/utils": "^1.50.0-dev.033e6b7138"
51
+ "@lodestar/api": "^1.50.0-dev.1f38fe79fb",
52
+ "@lodestar/config": "^1.50.0-dev.1f38fe79fb",
53
+ "@lodestar/params": "^1.50.0-dev.1f38fe79fb",
54
+ "@lodestar/state-transition": "^1.50.0-dev.1f38fe79fb",
55
+ "@lodestar/types": "^1.50.0-dev.1f38fe79fb",
56
+ "@lodestar/utils": "^1.50.0-dev.1f38fe79fb"
57
57
  },
58
58
  "devDependencies": {
59
- "@lodestar/logger": "^1.50.0-dev.033e6b7138",
60
- "@lodestar/test-utils": "^1.50.0-dev.033e6b7138"
59
+ "@lodestar/logger": "^1.50.0-dev.1f38fe79fb",
60
+ "@lodestar/test-utils": "^1.50.0-dev.1f38fe79fb"
61
61
  },
62
- "gitHead": "8b6be93646da6e7d9a47bb92ef8994fe9c957613"
62
+ "gitHead": "9a33d9d331de55a20740f4d737b6751081d9d93c"
63
63
  }
@@ -32,6 +32,7 @@ type MutableBidLedgerRecord = SubmittedBid & {
32
32
  export enum BidLedgerErrorCode {
33
33
  INVALID_BID_VALUE = "BID_LEDGER_ERROR_INVALID_BID_VALUE",
34
34
  DUPLICATE_BID = "BID_LEDGER_ERROR_DUPLICATE_BID",
35
+ BID_TOO_OLD = "BID_LEDGER_ERROR_BID_TOO_OLD",
35
36
  REVEAL_CONFLICT = "BID_LEDGER_ERROR_REVEAL_CONFLICT",
36
37
  UNSETTLED_VALUE_OVERFLOW = "BID_LEDGER_ERROR_UNSETTLED_VALUE_OVERFLOW",
37
38
  }
@@ -47,6 +48,11 @@ export type BidLedgerErrorType =
47
48
  parentBlockHash: RootHex;
48
49
  parentBlockRoot: RootHex;
49
50
  }
51
+ | {
52
+ code: BidLedgerErrorCode.BID_TOO_OLD;
53
+ slot: Slot;
54
+ pruneCutoffSlot: Slot;
55
+ }
50
56
  | {
51
57
  code: BidLedgerErrorCode.REVEAL_CONFLICT;
52
58
  blockRoot: RootHex;
@@ -69,11 +75,28 @@ const KEEP_SLOTS = RECORD_RETENTION_EPOCHS * SLOTS_PER_EPOCH;
69
75
  export class BidLedger {
70
76
  private readonly bidsBySlot = new Map<Slot, Map<string, MutableBidLedgerRecord>>();
71
77
  private readonly revealedPayloadByBlockRoot = new Map<RootHex, RevealedPayload>();
78
+ private pruneCutoffSlot = 0;
72
79
 
73
80
  hasSubmitted(slot: Slot, parentBlockHash: RootHex, parentBlockRoot: RootHex): boolean {
74
81
  return this.bidsBySlot.get(slot)?.has(tupleKey(parentBlockHash, parentBlockRoot)) ?? false;
75
82
  }
76
83
 
84
+ assertCanRecordBid({
85
+ slot,
86
+ parentBlockHash,
87
+ parentBlockRoot,
88
+ }: Pick<SubmittedBid, "slot" | "parentBlockHash" | "parentBlockRoot">): void {
89
+ if (slot < this.pruneCutoffSlot) {
90
+ throw new BidLedgerError({code: BidLedgerErrorCode.BID_TOO_OLD, slot, pruneCutoffSlot: this.pruneCutoffSlot});
91
+ }
92
+ if (this.hasSubmitted(slot, parentBlockHash, parentBlockRoot)) {
93
+ throw new BidLedgerError(
94
+ {code: BidLedgerErrorCode.DUPLICATE_BID, slot, parentBlockHash, parentBlockRoot},
95
+ `Bid already recorded slot=${slot} parentBlockHash=${parentBlockHash} parentBlockRoot=${parentBlockRoot}`
96
+ );
97
+ }
98
+ }
99
+
77
100
  recordBid(bid: SubmittedBid): BidLedgerRecord {
78
101
  if (!Number.isSafeInteger(bid.valueGwei) || bid.valueGwei < 0) {
79
102
  throw new BidLedgerError(
@@ -82,6 +105,7 @@ export class BidLedger {
82
105
  );
83
106
  }
84
107
 
108
+ this.assertCanRecordBid(bid);
85
109
  let bidsForSlot = this.bidsBySlot.get(bid.slot);
86
110
  if (bidsForSlot === undefined) {
87
111
  bidsForSlot = new Map();
@@ -89,18 +113,6 @@ export class BidLedger {
89
113
  }
90
114
 
91
115
  const key = tupleKey(bid.parentBlockHash, bid.parentBlockRoot);
92
- if (bidsForSlot.has(key)) {
93
- throw new BidLedgerError(
94
- {
95
- code: BidLedgerErrorCode.DUPLICATE_BID,
96
- slot: bid.slot,
97
- parentBlockHash: bid.parentBlockHash,
98
- parentBlockRoot: bid.parentBlockRoot,
99
- },
100
- `Bid already recorded slot=${bid.slot} parentBlockHash=${bid.parentBlockHash} parentBlockRoot=${bid.parentBlockRoot}`
101
- );
102
- }
103
-
104
116
  const record = {...bid, wonBlockRoots: new Set<RootHex>(), paymentSettled: false};
105
117
  bidsForSlot.set(key, record);
106
118
  return toRecord(record);
@@ -198,9 +210,11 @@ export class BidLedger {
198
210
  }
199
211
 
200
212
  prune(currentSlot: Slot): number {
213
+ // Pruning must not make an expired slot eligible for another submission.
214
+ this.pruneCutoffSlot = Math.max(this.pruneCutoffSlot, currentSlot - KEEP_SLOTS);
201
215
  let removed = 0;
202
216
  for (const [slot, bidsForSlot] of this.bidsBySlot) {
203
- if (slot >= currentSlot - KEEP_SLOTS) {
217
+ if (slot >= this.pruneCutoffSlot) {
204
218
  continue;
205
219
  }
206
220
 
@@ -216,7 +230,7 @@ export class BidLedger {
216
230
  }
217
231
 
218
232
  for (const [blockRoot, revealedPayload] of this.revealedPayloadByBlockRoot) {
219
- if (revealedPayload.slot < currentSlot - KEEP_SLOTS) {
233
+ if (revealedPayload.slot < this.pruneCutoffSlot) {
220
234
  this.revealedPayloadByBlockRoot.delete(blockRoot);
221
235
  }
222
236
  }
@@ -0,0 +1,95 @@
1
+ import type {ApiClient} from "@lodestar/api";
2
+ import type {ChainForkConfig} from "@lodestar/config";
3
+ import {isForkPostGloas} from "@lodestar/params";
4
+ import type {BuilderIndex, RootHex, Slot, gloas, heze} from "@lodestar/types";
5
+ import {sszTypesFor} from "@lodestar/types";
6
+ import {LodestarError, toRootHex} from "@lodestar/utils";
7
+ import type {BidIdentity, BidLedger} from "./bidLedger.js";
8
+ import type {BuilderSigner} from "./builderSigner.js";
9
+
10
+ export type BidPublisherModules = {
11
+ api: ApiClient;
12
+ config: ChainForkConfig;
13
+ signer: BuilderSigner;
14
+ ledger: BidLedger;
15
+ builderIndex: BuilderIndex;
16
+ hasPayload: (identity: BidIdentity) => boolean;
17
+ };
18
+
19
+ export enum BidPublisherErrorCode {
20
+ BUILDER_INDEX_MISMATCH = "BID_PUBLISHER_ERROR_BUILDER_INDEX_MISMATCH",
21
+ PAYLOAD_NOT_RETAINED = "BID_PUBLISHER_ERROR_PAYLOAD_NOT_RETAINED",
22
+ PRE_GLOAS_BID = "BID_PUBLISHER_ERROR_PRE_GLOAS_BID",
23
+ }
24
+
25
+ export type BidPublisherErrorType =
26
+ | {
27
+ code: BidPublisherErrorCode.PRE_GLOAS_BID;
28
+ slot: Slot;
29
+ }
30
+ | {
31
+ code: BidPublisherErrorCode.BUILDER_INDEX_MISMATCH;
32
+ builderIndex: BuilderIndex;
33
+ bidBuilderIndex: BuilderIndex;
34
+ }
35
+ | {
36
+ code: BidPublisherErrorCode.PAYLOAD_NOT_RETAINED;
37
+ slot: Slot;
38
+ parentBlockHash: RootHex;
39
+ parentBlockRoot: RootHex;
40
+ blockHash: RootHex;
41
+ };
42
+
43
+ export class BidPublisherError extends LodestarError<BidPublisherErrorType> {}
44
+
45
+ /** Signs and submits a bid only if its payload is retained locally. */
46
+ export class BidPublisher {
47
+ constructor(private readonly modules: BidPublisherModules) {}
48
+
49
+ publish(bid: heze.ExecutionPayloadBid, signal: AbortSignal): Promise<heze.SignedExecutionPayloadBid>;
50
+ publish(bid: gloas.ExecutionPayloadBid, signal: AbortSignal): Promise<gloas.SignedExecutionPayloadBid>;
51
+ async publish(bid: gloas.ExecutionPayloadBid, signal: AbortSignal): Promise<gloas.SignedExecutionPayloadBid> {
52
+ signal.throwIfAborted();
53
+
54
+ const {api, config, builderIndex, hasPayload, ledger, signer} = this.modules;
55
+ const fork = config.getForkName(bid.slot);
56
+ if (!isForkPostGloas(fork)) {
57
+ throw new BidPublisherError({code: BidPublisherErrorCode.PRE_GLOAS_BID, slot: bid.slot});
58
+ }
59
+ if (bid.builderIndex !== builderIndex) {
60
+ throw new BidPublisherError(
61
+ {
62
+ code: BidPublisherErrorCode.BUILDER_INDEX_MISMATCH,
63
+ builderIndex,
64
+ bidBuilderIndex: bid.builderIndex,
65
+ },
66
+ `Bid builder index does not match local builder index builderIndex=${builderIndex} bidBuilderIndex=${bid.builderIndex}`
67
+ );
68
+ }
69
+
70
+ const identity: BidIdentity = {
71
+ slot: bid.slot,
72
+ parentBlockHash: toRootHex(bid.parentBlockHash),
73
+ parentBlockRoot: toRootHex(bid.parentBlockRoot),
74
+ blockHash: toRootHex(bid.blockHash),
75
+ };
76
+ if (!hasPayload(identity)) {
77
+ throw new BidPublisherError(
78
+ {code: BidPublisherErrorCode.PAYLOAD_NOT_RETAINED, ...identity},
79
+ `Bid payload is not retained slot=${identity.slot} parentBlockHash=${identity.parentBlockHash} parentBlockRoot=${identity.parentBlockRoot} blockHash=${identity.blockHash}`
80
+ );
81
+ }
82
+
83
+ ledger.assertCanRecordBid(identity);
84
+
85
+ const signedExecutionPayloadBid = signer.signExecutionPayloadBid(bid);
86
+ const signedBidRoot = toRootHex(
87
+ sszTypesFor(fork, "SignedExecutionPayloadBid").hashTreeRoot(signedExecutionPayloadBid)
88
+ );
89
+ ledger.recordBid({...identity, valueGwei: bid.value, signedBidRoot});
90
+
91
+ const response = await api.beacon.publishExecutionPayloadBid({signedExecutionPayloadBid}, {signal});
92
+ response.assertOk();
93
+ return signedExecutionPayloadBid;
94
+ }
95
+ }
@@ -1,7 +1,7 @@
1
1
  import {PublicKey, SecretKey} from "@chainsafe/lodestar-z/blst";
2
2
  import {BeaconConfig} from "@lodestar/config";
3
3
  import {getExecutionPayloadBidSigningRoot, getExecutionPayloadEnvelopeSigningRoot} from "@lodestar/state-transition";
4
- import {gloas} from "@lodestar/types";
4
+ import {gloas, heze} from "@lodestar/types";
5
5
 
6
6
  export type Keypair = {publicKey: PublicKey; secretKey: SecretKey};
7
7
 
@@ -23,6 +23,8 @@ export class BuilderSigner {
23
23
  };
24
24
  }
25
25
 
26
+ signExecutionPayloadBid(bid: heze.ExecutionPayloadBid): heze.SignedExecutionPayloadBid;
27
+ signExecutionPayloadBid(bid: gloas.ExecutionPayloadBid): gloas.SignedExecutionPayloadBid;
26
28
  signExecutionPayloadBid(bid: gloas.ExecutionPayloadBid): gloas.SignedExecutionPayloadBid {
27
29
  const signingRoot = getExecutionPayloadBidSigningRoot(this.config, bid);
28
30
 
@@ -0,0 +1,125 @@
1
+ import {ForkName, type ForkPostGloas, INCLUSION_LIST_COMMITTEE_SIZE, isForkPostHeze} from "@lodestar/params";
2
+ import type {
3
+ BuilderIndex,
4
+ Bytes32,
5
+ ExecutionAddress,
6
+ ExecutionPayloadBid,
7
+ Root,
8
+ RootHex,
9
+ Slot,
10
+ gloas,
11
+ heze,
12
+ } from "@lodestar/types";
13
+ import {sszTypesFor} from "@lodestar/types";
14
+ import {LodestarError, byteArrayEquals, toRootHex} from "@lodestar/utils";
15
+ import type {BuiltPayload} from "./payloadSource.js";
16
+
17
+ type CommonBidInput<F extends ForkPostGloas> = {
18
+ slot: Slot;
19
+ parentBlockRoot: Root;
20
+ /** Expected value from the BN payload attributes used for this build. */
21
+ prevRandao: Bytes32;
22
+ builderIndex: BuilderIndex;
23
+ feeRecipient: ExecutionAddress;
24
+ /** Bid value in gwei */
25
+ value: number;
26
+ payload: BuiltPayload & {fork: F};
27
+ };
28
+
29
+ export type GloasBidInput = CommonBidInput<ForkName.gloas>;
30
+
31
+ export type HezeBidInput = CommonBidInput<ForkName.heze> & {
32
+ inclusionListBits: heze.ExecutionPayloadBid["inclusionListBits"];
33
+ };
34
+
35
+ export type ExecutionPayloadBidInput = GloasBidInput | HezeBidInput;
36
+
37
+ export enum ExecutionPayloadBidErrorCode {
38
+ INVALID_VALUE = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_VALUE",
39
+ INVALID_GAS_LIMIT = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_GAS_LIMIT",
40
+ SLOT_MISMATCH = "EXECUTION_PAYLOAD_BID_ERROR_SLOT_MISMATCH",
41
+ BLOCK_HASH_EQUALS_PARENT = "EXECUTION_PAYLOAD_BID_ERROR_BLOCK_HASH_EQUALS_PARENT",
42
+ INVALID_INCLUSION_LIST_BITS = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_INCLUSION_LIST_BITS",
43
+ PREV_RANDAO_MISMATCH = "EXECUTION_PAYLOAD_BID_ERROR_PREV_RANDAO_MISMATCH",
44
+ }
45
+
46
+ export type ExecutionPayloadBidErrorType =
47
+ | {code: ExecutionPayloadBidErrorCode.INVALID_GAS_LIMIT; gasLimit: number}
48
+ | {code: ExecutionPayloadBidErrorCode.SLOT_MISMATCH; slot: Slot; payloadSlot: Slot}
49
+ | {code: ExecutionPayloadBidErrorCode.BLOCK_HASH_EQUALS_PARENT}
50
+ | {code: ExecutionPayloadBidErrorCode.INVALID_INCLUSION_LIST_BITS; bitLen: number | undefined}
51
+ | {
52
+ code: ExecutionPayloadBidErrorCode.PREV_RANDAO_MISMATCH;
53
+ expectedPrevRandao: RootHex;
54
+ payloadPrevRandao: RootHex;
55
+ }
56
+ | {
57
+ code: ExecutionPayloadBidErrorCode.INVALID_VALUE;
58
+ value: number;
59
+ };
60
+
61
+ export class ExecutionPayloadBidError extends LodestarError<ExecutionPayloadBidErrorType> {}
62
+
63
+ export function createExecutionPayloadBid(input: GloasBidInput): gloas.ExecutionPayloadBid;
64
+ export function createExecutionPayloadBid(input: HezeBidInput): heze.ExecutionPayloadBid;
65
+ export function createExecutionPayloadBid(input: ExecutionPayloadBidInput): ExecutionPayloadBid;
66
+ export function createExecutionPayloadBid(input: ExecutionPayloadBidInput): ExecutionPayloadBid {
67
+ if (!Number.isSafeInteger(input.value) || input.value < 0) {
68
+ throw new ExecutionPayloadBidError(
69
+ {code: ExecutionPayloadBidErrorCode.INVALID_VALUE, value: input.value},
70
+ `Invalid bid value value=${input.value}`
71
+ );
72
+ }
73
+
74
+ const {fork, executionPayload, executionRequests, blobsBundle} = input.payload;
75
+ if (executionPayload.gasLimit > Number.MAX_SAFE_INTEGER) {
76
+ throw new ExecutionPayloadBidError({
77
+ code: ExecutionPayloadBidErrorCode.INVALID_GAS_LIMIT,
78
+ gasLimit: executionPayload.gasLimit,
79
+ });
80
+ }
81
+ if (executionPayload.slotNumber !== input.slot) {
82
+ throw new ExecutionPayloadBidError({
83
+ code: ExecutionPayloadBidErrorCode.SLOT_MISMATCH,
84
+ slot: input.slot,
85
+ payloadSlot: executionPayload.slotNumber,
86
+ });
87
+ }
88
+ if (byteArrayEquals(executionPayload.blockHash, executionPayload.parentHash)) {
89
+ throw new ExecutionPayloadBidError({code: ExecutionPayloadBidErrorCode.BLOCK_HASH_EQUALS_PARENT});
90
+ }
91
+ if (!byteArrayEquals(executionPayload.prevRandao, input.prevRandao)) {
92
+ throw new ExecutionPayloadBidError({
93
+ code: ExecutionPayloadBidErrorCode.PREV_RANDAO_MISMATCH,
94
+ expectedPrevRandao: toRootHex(input.prevRandao),
95
+ payloadPrevRandao: toRootHex(executionPayload.prevRandao),
96
+ });
97
+ }
98
+ const bid: gloas.ExecutionPayloadBid = {
99
+ parentBlockHash: executionPayload.parentHash,
100
+ parentBlockRoot: input.parentBlockRoot,
101
+ blockHash: executionPayload.blockHash,
102
+ prevRandao: input.prevRandao,
103
+ feeRecipient: input.feeRecipient,
104
+ gasLimit: BigInt(executionPayload.gasLimit),
105
+ builderIndex: input.builderIndex,
106
+ slot: input.slot,
107
+ value: input.value,
108
+ executionPayment: 0n,
109
+ blobKzgCommitments: blobsBundle.commitments,
110
+ executionRequestsRoot: sszTypesFor(fork).ExecutionRequests.hashTreeRoot(executionRequests),
111
+ };
112
+
113
+ if (isForkPostHeze(fork)) {
114
+ const inclusionListBits = "inclusionListBits" in input ? input.inclusionListBits : undefined;
115
+ if (inclusionListBits?.bitLen !== INCLUSION_LIST_COMMITTEE_SIZE) {
116
+ throw new ExecutionPayloadBidError({
117
+ code: ExecutionPayloadBidErrorCode.INVALID_INCLUSION_LIST_BITS,
118
+ bitLen: inclusionListBits?.bitLen,
119
+ });
120
+ }
121
+ return {...bid, inclusionListBits};
122
+ }
123
+
124
+ return bid;
125
+ }