@chainsafe/lodestar 1.47.0-dev.ec596194e2 → 1.47.0-dev.f0f26cd2b6

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 (75) hide show
  1. package/.git-data.json +1 -1
  2. package/lib/cmds/beacon/handler.d.ts.map +1 -1
  3. package/lib/cmds/beacon/handler.js +10 -4
  4. package/lib/cmds/beacon/handler.js.map +1 -1
  5. package/lib/cmds/builder/handler.d.ts.map +1 -1
  6. package/lib/cmds/builder/handler.js +19 -3
  7. package/lib/cmds/builder/handler.js.map +1 -1
  8. package/lib/cmds/builder/loadKeypair.d.ts +2 -1
  9. package/lib/cmds/builder/loadKeypair.d.ts.map +1 -1
  10. package/lib/cmds/builder/loadKeypair.js +3 -2
  11. package/lib/cmds/builder/loadKeypair.js.map +1 -1
  12. package/lib/cmds/builder/options.d.ts +8 -0
  13. package/lib/cmds/builder/options.d.ts.map +1 -1
  14. package/lib/cmds/builder/options.js +24 -0
  15. package/lib/cmds/builder/options.js.map +1 -1
  16. package/lib/cmds/dev/options.d.ts +4 -0
  17. package/lib/cmds/dev/options.d.ts.map +1 -1
  18. package/lib/cmds/validator/blsToExecutionChange.js +1 -1
  19. package/lib/cmds/validator/blsToExecutionChange.js.map +1 -1
  20. package/lib/cmds/validator/handler.d.ts.map +1 -1
  21. package/lib/cmds/validator/handler.js +15 -2
  22. package/lib/cmds/validator/handler.js.map +1 -1
  23. package/lib/cmds/validator/keymanager/decryptKeystoreDefinitions.js +1 -1
  24. package/lib/cmds/validator/keymanager/decryptKeystoreDefinitions.js.map +1 -1
  25. package/lib/cmds/validator/keymanager/impl.d.ts +13 -2
  26. package/lib/cmds/validator/keymanager/impl.d.ts.map +1 -1
  27. package/lib/cmds/validator/keymanager/impl.js +41 -4
  28. package/lib/cmds/validator/keymanager/impl.js.map +1 -1
  29. package/lib/cmds/validator/keymanager/keystoreCache.js +1 -1
  30. package/lib/cmds/validator/keymanager/keystoreCache.js.map +1 -1
  31. package/lib/cmds/validator/keymanager/persistedKeys.d.ts.map +1 -1
  32. package/lib/cmds/validator/keymanager/persistedKeys.js +3 -1
  33. package/lib/cmds/validator/keymanager/persistedKeys.js.map +1 -1
  34. package/lib/cmds/validator/options.d.ts +4 -0
  35. package/lib/cmds/validator/options.d.ts.map +1 -1
  36. package/lib/cmds/validator/options.js +24 -0
  37. package/lib/cmds/validator/options.js.map +1 -1
  38. package/lib/cmds/validator/signers/index.js +1 -1
  39. package/lib/cmds/validator/signers/index.js.map +1 -1
  40. package/lib/cmds/validator/voluntaryExit.js +1 -1
  41. package/lib/cmds/validator/voluntaryExit.js.map +1 -1
  42. package/lib/networks/chiado.d.ts.map +1 -1
  43. package/lib/networks/chiado.js +4 -10
  44. package/lib/networks/chiado.js.map +1 -1
  45. package/lib/options/beaconNodeOptions/builder.d.ts.map +1 -1
  46. package/lib/options/beaconNodeOptions/builder.js +2 -2
  47. package/lib/options/beaconNodeOptions/builder.js.map +1 -1
  48. package/lib/options/beaconNodeOptions/chain.d.ts.map +1 -1
  49. package/lib/options/beaconNodeOptions/chain.js +1 -1
  50. package/lib/options/beaconNodeOptions/chain.js.map +1 -1
  51. package/lib/util/format.js +1 -1
  52. package/lib/util/format.js.map +1 -1
  53. package/lib/util/proposerConfig.d.ts +16 -11
  54. package/lib/util/proposerConfig.d.ts.map +1 -1
  55. package/lib/util/proposerConfig.js +128 -11
  56. package/lib/util/proposerConfig.js.map +1 -1
  57. package/package.json +21 -21
  58. package/src/cmds/beacon/handler.ts +10 -4
  59. package/src/cmds/builder/handler.ts +24 -4
  60. package/src/cmds/builder/loadKeypair.ts +5 -1
  61. package/src/cmds/builder/options.ts +33 -0
  62. package/src/cmds/validator/blsToExecutionChange.ts +1 -1
  63. package/src/cmds/validator/handler.ts +29 -2
  64. package/src/cmds/validator/keymanager/decryptKeystoreDefinitions.ts +1 -1
  65. package/src/cmds/validator/keymanager/impl.ts +56 -4
  66. package/src/cmds/validator/keymanager/keystoreCache.ts +1 -1
  67. package/src/cmds/validator/keymanager/persistedKeys.ts +5 -1
  68. package/src/cmds/validator/options.ts +36 -0
  69. package/src/cmds/validator/signers/index.ts +1 -1
  70. package/src/cmds/validator/voluntaryExit.ts +1 -1
  71. package/src/networks/chiado.ts +4 -10
  72. package/src/options/beaconNodeOptions/builder.ts +4 -2
  73. package/src/options/beaconNodeOptions/chain.ts +2 -1
  74. package/src/util/format.ts +1 -1
  75. package/src/util/proposerConfig.ts +152 -13
@@ -1,7 +1,12 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { builderConfigDataFromJson } from "@lodestar/api/keymanager";
4
+ import { MAX_BUILDER_AUTH_DATA_SIZE, MAX_BUILDER_ENTRIES, MAX_BUILDER_URL_SIZE } from "@lodestar/params";
5
+ import { fromHex, isValidAsciiHttpUrl, toHex } from "@lodestar/utils";
3
6
  import { parseFeeRecipient } from "./feeRecipient.js";
4
7
  import { readFile } from "./file.js";
8
+ const UINT64_MAX = 2n ** 64n - 1n;
9
+ const BUILDER_AUTH_DATA_PATTERN = new RegExp(`^0x(?:[a-fA-F0-9]{2}){1,${MAX_BUILDER_AUTH_DATA_SIZE}}$`);
5
10
  export function parseProposerConfig(configFilePath, defaultArgsConfig) {
6
11
  const configFile = readFile(configFilePath, ["yml", "yaml"]);
7
12
  const defaultConfigParsed = parseProposerConfigSection(configFile.default_config || {}, defaultArgsConfig);
@@ -21,7 +26,7 @@ function stringtoBool(input) {
21
26
  }
22
27
  function parseProposerConfigSection(proposerFileSection, overrideConfig) {
23
28
  const { graffiti, strict_fee_recipient_check, fee_recipient, builder } = proposerFileSection;
24
- const { gas_limit, selection: builderSelection, boost_factor } = builder || {};
29
+ const { gas_limit, selection: builderSelection, boost_factor, min_bid, max_execution_payment, builders, } = builder || {};
25
30
  if (graffiti !== undefined && typeof graffiti !== "string") {
26
31
  throw Error("graffiti is not 'string");
27
32
  }
@@ -43,24 +48,50 @@ function parseProposerConfigSection(proposerFileSection, overrideConfig) {
43
48
  if (boost_factor !== undefined && typeof boost_factor !== "string") {
44
49
  throw Error("boost_factor is not 'string");
45
50
  }
51
+ if (min_bid !== undefined && typeof min_bid !== "string") {
52
+ throw Error("min_bid is not 'string");
53
+ }
54
+ if (max_execution_payment !== undefined && typeof max_execution_payment !== "string") {
55
+ throw Error("max_execution_payment is not 'string");
56
+ }
57
+ const parsedBuilder = overrideConfig?.builder || builder
58
+ ? {
59
+ gasLimit: overrideConfig?.builder?.gasLimit ?? (gas_limit !== undefined ? Number(gas_limit) : undefined),
60
+ selection: overrideConfig?.builder?.selection ?? parseBuilderSelection(builderSelection),
61
+ boostFactor: overrideConfig?.builder?.boostFactor ?? parseBuilderBoostFactor(boost_factor),
62
+ minBid: overrideConfig?.builder?.minBid ?? parseBuilderMinBid(min_bid),
63
+ maxExecutionPayment: overrideConfig?.builder?.maxExecutionPayment ?? parseBuilderGweiAmount(max_execution_payment),
64
+ builders: overrideConfig?.builder?.builders ?? parseBuilderEntries(builders),
65
+ }
66
+ : undefined;
67
+ if (overrideConfig?.builder?.builders !== undefined && builders !== undefined) {
68
+ throw Error("Cannot configure both --builder.urls and builders in the proposer settings file");
69
+ }
46
70
  return {
47
71
  graffiti: overrideConfig?.graffiti ?? graffiti,
48
72
  strictFeeRecipientCheck: overrideConfig?.strictFeeRecipientCheck ??
49
73
  (strict_fee_recipient_check ? stringtoBool(strict_fee_recipient_check) : undefined),
50
74
  feeRecipient: overrideConfig?.feeRecipient ?? (fee_recipient ? parseFeeRecipient(fee_recipient) : undefined),
51
- builder: overrideConfig?.builder || builder
52
- ? {
53
- gasLimit: overrideConfig?.builder?.gasLimit ?? (gas_limit !== undefined ? Number(gas_limit) : undefined),
54
- selection: overrideConfig?.builder?.selection ?? parseBuilderSelection(builderSelection),
55
- boostFactor: overrideConfig?.builder?.boostFactor ?? parseBuilderBoostFactor(boost_factor),
56
- }
57
- : undefined,
75
+ builder: parsedBuilder,
58
76
  };
59
77
  }
60
78
  export function readProposerConfigDir(filepath, filename) {
61
79
  const proposerConfigStr = fs.readFileSync(path.join(filepath, filename), "utf8");
62
- const proposerConfigJSON = JSON.parse(proposerConfigStr);
63
- return proposerConfigJSON;
80
+ // Persisted via `writeProposerConfig` with BigInt values serialized as strings
81
+ const persisted = JSON.parse(proposerConfigStr);
82
+ if (persisted.builder) {
83
+ const { boostFactor, minBid, maxExecutionPayment, builders } = persisted.builder;
84
+ persisted.builder.boostFactor = boostFactor !== undefined ? BigInt(boostFactor) : undefined;
85
+ persisted.builder.minBid = minBid !== undefined ? BigInt(minBid) : undefined;
86
+ persisted.builder.maxExecutionPayment = maxExecutionPayment !== undefined ? BigInt(maxExecutionPayment) : undefined;
87
+ persisted.builder.builders = builders?.map((entry) => ({
88
+ ...entry,
89
+ maxExecutionPayment: entry.maxExecutionPayment !== undefined ? BigInt(entry.maxExecutionPayment) : undefined,
90
+ minBid: entry.minBid !== undefined ? BigInt(entry.minBid) : undefined,
91
+ builderBoostFactor: entry.builderBoostFactor !== undefined ? BigInt(entry.builderBoostFactor) : undefined,
92
+ }));
93
+ }
94
+ return persisted;
64
95
  }
65
96
  export function parseBuilderSelection(builderSelection) {
66
97
  if (builderSelection) {
@@ -89,6 +120,92 @@ export function parseBuilderBoostFactor(boostFactor) {
89
120
  if (!/^\d+$/.test(boostFactor)) {
90
121
  throw Error("Invalid input for builder boost factor, must be a valid number without decimals");
91
122
  }
92
- return BigInt(boostFactor);
123
+ const parsed = BigInt(boostFactor);
124
+ if (parsed > UINT64_MAX) {
125
+ throw Error("Invalid input for builder boost factor, must not exceed 2**64 - 1");
126
+ }
127
+ return parsed;
128
+ }
129
+ export function parseBuilderMinBid(minBid) {
130
+ if (minBid === undefined)
131
+ return;
132
+ if (!/^\d+$/.test(minBid.toString())) {
133
+ throw Error("Invalid input for builder min bid, must be a valid number without decimals");
134
+ }
135
+ const parsed = BigInt(minBid);
136
+ if (parsed > UINT64_MAX) {
137
+ throw Error("Invalid input for builder min bid, must not exceed 2**64 - 1");
138
+ }
139
+ return parsed;
140
+ }
141
+ export function parseBuilderGweiAmount(amount) {
142
+ if (amount === undefined)
143
+ return;
144
+ if (!/^\d+$/.test(amount.toString())) {
145
+ throw Error("Invalid input for builder Gwei amount, must be a valid number without decimals");
146
+ }
147
+ const parsed = BigInt(amount);
148
+ if (parsed > UINT64_MAX) {
149
+ throw Error("Invalid input for builder Gwei amount, must not exceed 2**64 - 1");
150
+ }
151
+ return parsed;
152
+ }
153
+ /**
154
+ * Parse per-builder entries from the proposer settings file, same shape and validation as the
155
+ * keymanager builders api. No two entries may share both their url and their auth data, an
156
+ * omitted auth data is compared as the value derived from the entry url.
157
+ */
158
+ export function parseBuilderEntries(builders) {
159
+ if (builders === undefined)
160
+ return undefined;
161
+ const { builders: entries } = builderConfigDataFromJson({ builders });
162
+ const seenEntries = new Set();
163
+ for (const entry of entries ?? []) {
164
+ if (!isValidAsciiHttpUrl(entry.url)) {
165
+ throw Error(`Invalid builder url: ${entry.url}`);
166
+ }
167
+ const authData = entry.authData !== undefined ? toHex(fromHex(entry.authData)) : toHex(Buffer.from(entry.url));
168
+ const entryKey = `${entry.url}|${authData}`;
169
+ if (seenEntries.has(entryKey)) {
170
+ throw Error(`Duplicate builder entry url=${entry.url}`);
171
+ }
172
+ seenEntries.add(entryKey);
173
+ }
174
+ return entries;
175
+ }
176
+ /**
177
+ * Parse builder urls into builder entries. Auth data agreed with a builder out of band may be
178
+ * appended as a hex fragment (`https://builder.example.com#0x0123`), it is stripped from the url
179
+ * and never sent on the wire. Without a fragment the auth data derives from the url.
180
+ */
181
+ export function parseBuilderUrls(urls) {
182
+ if (urls === undefined)
183
+ return undefined;
184
+ const entries = [];
185
+ const seenEntries = new Set();
186
+ for (const value of urls) {
187
+ const fragmentIndex = value.indexOf("#");
188
+ const url = fragmentIndex === -1 ? value : value.slice(0, fragmentIndex);
189
+ const authData = fragmentIndex === -1 ? undefined : value.slice(fragmentIndex + 1);
190
+ if (!isValidAsciiHttpUrl(url)) {
191
+ throw Error(`Invalid builder url: ${url}`);
192
+ }
193
+ if (Buffer.byteLength(url, "utf8") > MAX_BUILDER_URL_SIZE) {
194
+ throw Error(`Invalid builder url, must not exceed ${MAX_BUILDER_URL_SIZE} bytes: ${url}`);
195
+ }
196
+ if (authData !== undefined && !BUILDER_AUTH_DATA_PATTERN.test(authData)) {
197
+ throw Error(`Invalid builder url auth data, must be a 0x-prefixed hex string of 1 to ${MAX_BUILDER_AUTH_DATA_SIZE} bytes: ${url}`);
198
+ }
199
+ const entryKey = `${url}|${authData !== undefined ? toHex(fromHex(authData)) : toHex(Buffer.from(url))}`;
200
+ if (seenEntries.has(entryKey)) {
201
+ throw Error(`Duplicate builder url: ${url}`);
202
+ }
203
+ seenEntries.add(entryKey);
204
+ entries.push({ url, authData });
205
+ }
206
+ if (entries.length > MAX_BUILDER_ENTRIES) {
207
+ throw Error(`Number of builder urls must not exceed ${MAX_BUILDER_ENTRIES}, got ${entries.length}`);
208
+ }
209
+ return entries;
93
210
  }
94
211
  //# sourceMappingURL=proposerConfig.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"proposerConfig.js","sourceRoot":"","sources":["../../src/util/proposerConfig.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proposerConfig.js","sourceRoot":"","sources":["../../src/util/proposerConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAqB,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AACvF,OAAO,EAAC,0BAA0B,EAAE,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,kBAAkB,CAAC;AACvG,OAAO,EAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAC,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAC;AAEnC,MAAM,UAAU,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,CAAC;AAClC,MAAM,yBAAyB,GAAG,IAAI,MAAM,CAAC,2BAA2B,0BAA0B,IAAI,CAAC,CAAC;AAyBxG,MAAM,UAAU,mBAAmB,CACjC,cAAsB,EACtB,iBAAkC;IAElC,MAAM,UAAU,GAAG,QAAQ,CAAqB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IACjF,MAAM,mBAAmB,GAAG,0BAA0B,CAAC,UAAU,CAAC,cAAc,IAAI,EAAE,EAAE,iBAAiB,CAAC,CAAC;IAE3G,MAAM,kBAAkB,GAAG,UAAU,CAAC,eAAe,IAAI,EAAE,CAAC;IAC5D,MAAM,oBAAoB,GAA8C,EAAE,CAAC;IAC3E,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACxD,oBAAoB,CAAC,SAAS,CAAC,GAAG,0BAA0B,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9F,CAAC;IAED,OAAO;QACL,cAAc,EAAE,oBAAoB;QACpC,aAAa,EAAE,mBAAmB;KACnC,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,SAAS,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IACvE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,0BAA0B,CACjC,mBAA8C,EAC9C,cAA+B;IAE/B,MAAM,EAAC,QAAQ,EAAE,0BAA0B,EAAE,aAAa,EAAE,OAAO,EAAC,GAAG,mBAAmB,CAAC;IAC3F,MAAM,EACJ,SAAS,EACT,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,OAAO,EACP,qBAAqB,EACrB,QAAQ,GACT,GAAG,OAAO,IAAI,EAAE,CAAC;IAElB,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC3D,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACzC,CAAC;IACD,IACE,0BAA0B,KAAK,SAAS;QACxC,CAAC,CAAC,0BAA0B,KAAK,MAAM,IAAI,0BAA0B,KAAK,OAAO,CAAC,EAClF,CAAC;QACD,MAAM,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,aAAa,KAAK,SAAS,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACrE,MAAM,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YACpC,MAAM,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,IAAI,YAAY,KAAK,SAAS,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACnE,MAAM,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzD,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,qBAAqB,KAAK,SAAS,IAAI,OAAO,qBAAqB,KAAK,QAAQ,EAAE,CAAC;QACrF,MAAM,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,aAAa,GACjB,cAAc,EAAE,OAAO,IAAI,OAAO;QAChC,CAAC,CAAC;YACE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACxG,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,IAAI,qBAAqB,CAAC,gBAAgB,CAAC;YACxF,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,IAAI,uBAAuB,CAAC,YAAY,CAAC;YAC1F,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,IAAI,kBAAkB,CAAC,OAAO,CAAC;YACtE,mBAAmB,EACjB,cAAc,EAAE,OAAO,EAAE,mBAAmB,IAAI,sBAAsB,CAAC,qBAAqB,CAAC;YAC/F,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,IAAI,mBAAmB,CAAC,QAAQ,CAAC;SAC7E;QACH,CAAC,CAAC,SAAS,CAAC;IAEhB,IAAI,cAAc,EAAE,OAAO,EAAE,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC9E,MAAM,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACjG,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,cAAc,EAAE,QAAQ,IAAI,QAAQ;QAC9C,uBAAuB,EACrB,cAAc,EAAE,uBAAuB;YACvC,CAAC,0BAA0B,CAAC,CAAC,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrF,YAAY,EAAE,cAAc,EAAE,YAAY,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5G,OAAO,EAAE,aAAa;KACvB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,QAAgB;IACtE,MAAM,iBAAiB,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;IACjF,+EAA+E;IAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAmB,CAAC;IAClE,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,EAAC,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAC,GAAG,SAAS,CAAC,OAAO,CAAC;QAC/E,SAAS,CAAC,OAAO,CAAC,WAAW,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5F,SAAS,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,SAAS,CAAC,OAAO,CAAC,mBAAmB,GAAG,mBAAmB,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpH,SAAS,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACrD,GAAG,KAAK;YACR,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS;YAC5G,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;YACrE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,SAAS;SAC1G,CAAC,CAAC,CAAC;IACN,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,gBAAyB;IAC7D,IAAI,gBAAgB,EAAE,CAAC;QACrB,QAAQ,gBAAgB,EAAE,CAAC;YACzB,KAAK,SAAS;gBACZ,MAAM;YACR,KAAK,WAAW;gBACd,MAAM;YACR,KAAK,eAAe;gBAClB,MAAM;YACR,KAAK,aAAa;gBAChB,MAAM,KAAK,CAAC,iFAAiF,CAAC,CAAC;YACjG,KAAK,iBAAiB;gBACpB,MAAM;YACR,KAAK,eAAe;gBAClB,MAAM;YACR;gBACE,MAAM,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IACD,OAAO,gBAAqD,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,WAAoB;IAC1D,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO;IAEtC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,MAAM,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACjG,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACnC,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAwB;IACzD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO;IAEjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,KAAK,CAAC,4EAA4E,CAAC,CAAC;IAC5F,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAwB;IAC7D,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO;IAEjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,KAAK,CAAC,gFAAgF,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,KAAK,CAAC,kEAAkE,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAkB;IACpD,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAE7C,MAAM,EAAC,QAAQ,EAAE,OAAO,EAAC,GAAG,yBAAyB,CAAC,EAAC,QAAQ,EAAC,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,KAAK,CAAC,wBAAwB,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/G,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC5C,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC,+BAA+B,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAe;IAC9C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAEzC,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QACnF,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,oBAAoB,EAAE,CAAC;YAC1D,MAAM,KAAK,CAAC,wCAAwC,oBAAoB,WAAW,GAAG,EAAE,CAAC,CAAC;QAC5F,CAAC;QACD,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxE,MAAM,KAAK,CACT,2EAA2E,0BAA0B,WAAW,GAAG,EAAE,CACtH,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,GAAG,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACzG,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,EAAE,QAAQ,EAAC,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;QACzC,MAAM,KAAK,CAAC,0CAA0C,mBAAmB,SAAS,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chainsafe/lodestar",
3
- "version": "1.47.0-dev.ec596194e2",
3
+ "version": "1.47.0-dev.f0f26cd2b6",
4
4
  "description": "Command line interface for lodestar",
5
5
  "author": "ChainSafe Systems",
6
6
  "license": "Apache-2.0",
@@ -59,26 +59,26 @@
59
59
  "dependencies": {
60
60
  "@chainsafe/bls-keygen": "^0.4.0",
61
61
  "@chainsafe/bls-keystore": "^3.1.0",
62
- "@chainsafe/blst": "^2.2.0",
63
62
  "@chainsafe/discv5": "^12.0.2",
64
63
  "@chainsafe/enr": "^6.0.2",
65
- "@chainsafe/persistent-merkle-tree": "^1.3.0",
66
- "@chainsafe/ssz": "^1.6.2",
64
+ "@chainsafe/lodestar-z": "catalog:",
65
+ "@chainsafe/persistent-merkle-tree": "^1.3.1",
66
+ "@chainsafe/ssz": "^1.6.3",
67
67
  "@chainsafe/threads": "^1.11.3",
68
- "@libp2p/crypto": "^5.1.13",
69
- "@libp2p/interface": "^3.1.0",
70
- "@libp2p/peer-id": "^6.0.4",
71
- "@lodestar/api": "^1.47.0-dev.ec596194e2",
72
- "@lodestar/beacon-node": "^1.47.0-dev.ec596194e2",
73
- "@lodestar/builder": "^1.47.0-dev.ec596194e2",
74
- "@lodestar/config": "^1.47.0-dev.ec596194e2",
75
- "@lodestar/db": "^1.47.0-dev.ec596194e2",
76
- "@lodestar/logger": "^1.47.0-dev.ec596194e2",
77
- "@lodestar/params": "^1.47.0-dev.ec596194e2",
78
- "@lodestar/state-transition": "^1.47.0-dev.ec596194e2",
79
- "@lodestar/types": "^1.47.0-dev.ec596194e2",
80
- "@lodestar/utils": "^1.47.0-dev.ec596194e2",
81
- "@lodestar/validator": "^1.47.0-dev.ec596194e2",
68
+ "@libp2p/crypto": "^5.1.23",
69
+ "@libp2p/interface": "^3.3.0",
70
+ "@libp2p/peer-id": "^6.0.15",
71
+ "@lodestar/api": "^1.47.0-dev.f0f26cd2b6",
72
+ "@lodestar/beacon-node": "^1.47.0-dev.f0f26cd2b6",
73
+ "@lodestar/builder": "^1.47.0-dev.f0f26cd2b6",
74
+ "@lodestar/config": "^1.47.0-dev.f0f26cd2b6",
75
+ "@lodestar/db": "^1.47.0-dev.f0f26cd2b6",
76
+ "@lodestar/logger": "^1.47.0-dev.f0f26cd2b6",
77
+ "@lodestar/params": "^1.47.0-dev.f0f26cd2b6",
78
+ "@lodestar/state-transition": "^1.47.0-dev.f0f26cd2b6",
79
+ "@lodestar/types": "^1.47.0-dev.f0f26cd2b6",
80
+ "@lodestar/utils": "^1.47.0-dev.f0f26cd2b6",
81
+ "@lodestar/validator": "^1.47.0-dev.f0f26cd2b6",
82
82
  "@multiformats/multiaddr": "^13.0.1",
83
83
  "deepmerge": "^4.3.1",
84
84
  "ethers": "^6.7.0",
@@ -92,9 +92,9 @@
92
92
  "yargs": "^17.7.1"
93
93
  },
94
94
  "devDependencies": {
95
- "@chainsafe/as-sha256": "^1.2.4",
95
+ "@chainsafe/as-sha256": "^1.2.5",
96
96
  "@ethereumjs/rlp": "^4.0.1",
97
- "@lodestar/test-utils": "^1.47.0-dev.ec596194e2",
97
+ "@lodestar/test-utils": "^1.47.0-dev.f0f26cd2b6",
98
98
  "@types/debug": "^4.1.7",
99
99
  "@types/inquirer": "^9.0.3",
100
100
  "@types/js-yaml": "^4.0.5",
@@ -108,5 +108,5 @@
108
108
  "web3": "^4.0.3",
109
109
  "web3-eth-accounts": "^4.0.3"
110
110
  },
111
- "gitHead": "dba08d7a33a32e7e0a39fc6d3f61707e64f5e565"
111
+ "gitHead": "f2cb518d19fecb98b13ff35caa3c0c421e02ad39"
112
112
  }
@@ -1,13 +1,14 @@
1
1
  import path from "node:path";
2
2
  import {getHeapStatistics} from "node:v8";
3
3
  import {SignableENR} from "@chainsafe/enr";
4
+ import {pubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
4
5
  import {hasher} from "@chainsafe/persistent-merkle-tree";
5
6
  import {BeaconDb, BeaconNode} from "@lodestar/beacon-node";
6
7
  import {ChainForkConfig, createBeaconConfig} from "@lodestar/config";
7
8
  import {LevelDbController} from "@lodestar/db/controller/level";
8
9
  import {LoggerNode, getNodeLogger} from "@lodestar/logger/node";
9
- import {ACTIVE_PRESET, PresetName} from "@lodestar/params";
10
- import {createBeaconStateView, createPubkeyCache, syncPubkeys} from "@lodestar/state-transition";
10
+ import {ACTIVE_PRESET, MAX_PENDING_DEPOSITS_PER_EPOCH, PresetName, SLOTS_PER_EPOCH} from "@lodestar/params";
11
+ import {createBeaconStateView} from "@lodestar/state-transition";
11
12
  import {ErrorAborted, bytesToInt, formatBytes} from "@lodestar/utils";
12
13
  import {ProcessShutdownCallback} from "@lodestar/validator";
13
14
  import {BeaconNodeOptions, getBeaconConfigFromArgs} from "../../config/index.js";
@@ -78,8 +79,13 @@ export async function beaconHandler(args: BeaconArgs & GlobalArgs): Promise<void
78
79
  wsCheckpoint,
79
80
  } = await initBeaconState(args, beaconPaths.dataDir, config, db, logger);
80
81
  const beaconConfig = createBeaconConfig(config, anchorState.genesisValidatorsRoot);
81
- const pubkeyCache = createPubkeyCache();
82
- syncPubkeys(pubkeyCache, anchorState.validators.getAllReadonlyValues());
82
+ // Reserve 3 months of worst-case registry growth (MAX_PENDING_DEPOSITS_PER_EPOCH per epoch),
83
+ // over a year at organic rates, to avoid routine cache reallocations. Cache growth is protected
84
+ // by its native lock; if this headroom is exceeded, it grows by the same fixed step.
85
+ const headroomEpochs = (90 * 24 * 60 * 60) / (config.SECONDS_PER_SLOT * SLOTS_PER_EPOCH);
86
+ const pubkeyCacheHeadroom = MAX_PENDING_DEPOSITS_PER_EPOCH * Math.ceil(headroomEpochs);
87
+ pubkeyCache.ensureCapacity(anchorState.validators.length + pubkeyCacheHeadroom);
88
+ pubkeyCache.syncPubkeys(anchorState.validators.getAllReadonlyValues());
83
89
  const anchorStateView = args["chain.nativeStateView"]
84
90
  ? createBeaconStateView({useNative: true, stateBytes: anchorStateBytes})
85
91
  : createBeaconStateView({useNative: false, anchorState, config: beaconConfig, pubkeyCache});
@@ -1,14 +1,16 @@
1
1
  import path from "node:path";
2
2
  import {getClient} from "@lodestar/api";
3
- import {Builder} from "@lodestar/builder";
3
+ import {RegistryMetricCreator, collectNodeJSMetrics, getHttpMetricsServer} from "@lodestar/beacon-node";
4
+ import {Builder, getMetrics} from "@lodestar/builder";
4
5
  import {getNodeLogger} from "@lodestar/logger/node";
5
6
  import {fromHex, toPrintableUrl} from "@lodestar/utils";
6
7
  import {getBeaconConfigFromArgs} from "../../config/beaconParams.js";
7
8
  import {GlobalArgs} from "../../options/index.js";
8
9
  import {getGlobalPaths} from "../../paths/global.js";
9
10
  import {cleanOldLogFiles, onGracefulShutdown, parseFeeRecipient, parseLoggerArgs} from "../../util/index.js";
11
+ import {getVersionData} from "../../util/version.js";
10
12
  import {loadBuilderKeypair} from "./loadKeypair.js";
11
- import {IBuilderCliArgs} from "./options.js";
13
+ import {IBuilderCliArgs, builderMetricsDefaultOptions} from "./options.js";
12
14
 
13
15
  const ZERO_ADDRESS = "0x" + "0".repeat(40);
14
16
 
@@ -29,13 +31,16 @@ export async function builderHandler(args: IBuilderCliArgs & GlobalArgs): Promis
29
31
  logger.debug("Not able to delete log files", {}, e as Error);
30
32
  }
31
33
 
34
+ const {version, commit} = getVersionData();
35
+ logger.info("Lodestar", {network, version, commit});
36
+
32
37
  const executionFeeRecipient = parseFeeRecipient(args.executionFeeRecipient);
33
38
 
34
39
  if (executionFeeRecipient === ZERO_ADDRESS) {
35
40
  throw Error("Cannot put zero address as an executionFeeRecipient");
36
41
  }
37
42
 
38
- const keypair = await loadBuilderKeypair(args.keystore, args.keystorePassword, args.builderPubkey);
43
+ const keypair = await loadBuilderKeypair(logger, args.keystore, args.keystorePassword, args.builderPubkey);
39
44
 
40
45
  const onGracefulShutdownCbs: (() => Promise<void> | void)[] = [];
41
46
  onGracefulShutdown(async () => {
@@ -45,9 +50,23 @@ export async function builderHandler(args: IBuilderCliArgs & GlobalArgs): Promis
45
50
  const abortController = new AbortController();
46
51
  onGracefulShutdownCbs.push(async () => abortController.abort());
47
52
 
53
+ const register = args.metrics ? new RegistryMetricCreator() : null;
54
+ const metrics = register && getMetrics(register, {version, commit, network});
55
+
56
+ if (metrics) {
57
+ const closeMetrics = collectNodeJSMetrics(register);
58
+ onGracefulShutdownCbs.push(() => closeMetrics());
59
+
60
+ const port = args["metrics.port"] ?? builderMetricsDefaultOptions.port;
61
+ const address = args["metrics.address"] ?? builderMetricsDefaultOptions.address;
62
+ const metricsServer = await getHttpMetricsServer({port, address}, {register, logger});
63
+
64
+ onGracefulShutdownCbs.push(() => metricsServer.close());
65
+ }
66
+
48
67
  const api = getClient(
49
68
  {urls: [args.beaconNodeUrl], globalInit: {signal: abortController.signal, timeoutMs: args.requestTimeout}},
50
- {config, logger}
69
+ {config, logger, metrics: metrics?.restApiClient}
51
70
  );
52
71
 
53
72
  logger.info("Beacon node", {beaconNode: toPrintableUrl(args.beaconNodeUrl), timeoutMs: args.requestTimeout});
@@ -59,6 +78,7 @@ export async function builderHandler(args: IBuilderCliArgs & GlobalArgs): Promis
59
78
  abortController,
60
79
  api,
61
80
  executionFeeRecipient: fromHex(executionFeeRecipient),
81
+ metrics,
62
82
  });
63
83
 
64
84
  onGracefulShutdownCbs.push(() => builder.close());
@@ -1,11 +1,13 @@
1
1
  import fs from "node:fs";
2
2
  import {Keystore} from "@chainsafe/bls-keystore";
3
- import {SecretKey} from "@chainsafe/blst";
3
+ import {SecretKey} from "@chainsafe/lodestar-z/blst";
4
4
  import {Keypair} from "@lodestar/builder";
5
+ import {Logger} from "@lodestar/utils";
5
6
  import {ensure0xPrefix} from "../../util/format.js";
6
7
  import {readPassphraseFile} from "../../util/passphrase.js";
7
8
 
8
9
  export async function loadBuilderKeypair(
10
+ logger: Logger,
9
11
  keystorePath: string,
10
12
  passwordPath: string,
11
13
  expectedPubkey?: string
@@ -28,5 +30,7 @@ export async function loadBuilderKeypair(
28
30
  throw Error(`Pubkey mismatch: keystore ${publicKeyHex}, expected ${expectedPubkey}`);
29
31
  }
30
32
 
33
+ logger.info("Loaded builder keystore", {pubkey: publicKeyHex});
34
+
31
35
  return {secretKey, publicKey};
32
36
  }
@@ -2,6 +2,12 @@ import {defaultOptions} from "@lodestar/builder";
2
2
  import {CliCommandOptions} from "@lodestar/utils";
3
3
  import {LogArgs, logOptions} from "../../options/logOptions.js";
4
4
 
5
+ export const builderMetricsDefaultOptions = {
6
+ enabled: false,
7
+ port: 5065,
8
+ address: "127.0.0.1",
9
+ };
10
+
5
11
  export type IBuilderCliArgs = LogArgs & {
6
12
  beaconNodeUrl: string;
7
13
  keystore: string;
@@ -9,6 +15,10 @@ export type IBuilderCliArgs = LogArgs & {
9
15
  builderPubkey?: string;
10
16
  executionFeeRecipient: string;
11
17
  requestTimeout: number;
18
+
19
+ metrics?: boolean;
20
+ "metrics.port"?: number;
21
+ "metrics.address"?: string;
12
22
  };
13
23
 
14
24
  export const builderOptions: CliCommandOptions<IBuilderCliArgs> = {
@@ -48,4 +58,27 @@ export const builderOptions: CliCommandOptions<IBuilderCliArgs> = {
48
58
  type: "number",
49
59
  default: defaultOptions.requestTimeout,
50
60
  },
61
+
62
+ // Metrics
63
+
64
+ metrics: {
65
+ description: "Enable the Prometheus metrics HTTP server",
66
+ type: "boolean",
67
+ defaultDescription: String(builderMetricsDefaultOptions.enabled),
68
+ group: "metrics",
69
+ },
70
+
71
+ "metrics.port": {
72
+ description: "Listen TCP port for the Prometheus metrics HTTP server",
73
+ type: "number",
74
+ defaultDescription: String(builderMetricsDefaultOptions.port),
75
+ group: "metrics",
76
+ },
77
+
78
+ "metrics.address": {
79
+ description: "Listen address for the Prometheus metrics HTTP server",
80
+ type: "string",
81
+ defaultDescription: String(builderMetricsDefaultOptions.address),
82
+ group: "metrics",
83
+ },
51
84
  };
@@ -1,4 +1,4 @@
1
- import {SecretKey} from "@chainsafe/blst";
1
+ import {SecretKey} from "@chainsafe/lodestar-z/blst";
2
2
  import {getClient} from "@lodestar/api";
3
3
  import {createBeaconConfig} from "@lodestar/config";
4
4
  import {DOMAIN_BLS_TO_EXECUTION_CHANGE, ForkName} from "@lodestar/params";
@@ -28,7 +28,13 @@ import {
28
28
  parseLoggerArgs,
29
29
  parseProposerConfig,
30
30
  } from "../../util/index.js";
31
- import {parseBuilderBoostFactor, parseBuilderSelection} from "../../util/proposerConfig.js";
31
+ import {
32
+ parseBuilderBoostFactor,
33
+ parseBuilderGweiAmount,
34
+ parseBuilderMinBid,
35
+ parseBuilderSelection,
36
+ parseBuilderUrls,
37
+ } from "../../util/proposerConfig.js";
32
38
  import {getVersionData} from "../../util/version.js";
33
39
  import {KeymanagerApi} from "./keymanager/impl.js";
34
40
  import {IPersistedKeysBackend} from "./keymanager/interface.js";
@@ -212,7 +218,8 @@ export async function validatorHandler(args: IValidatorCliArgs & GlobalArgs): Pr
212
218
  validator,
213
219
  persistedKeysBackend,
214
220
  abortController.signal,
215
- proposerConfigWriteDisabled
221
+ proposerConfigWriteDisabled,
222
+ args.allowDangerousTrustedPayments
216
223
  );
217
224
  const keymanagerServer = new KeymanagerRestApiServer(
218
225
  {
@@ -250,6 +257,9 @@ function getProposerConfigFromArgs(
250
257
  args["builder.selection"] ?? (args.builder ? defaultOptions.builderAliasSelection : undefined)
251
258
  ),
252
259
  boostFactor: parseBuilderBoostFactor(args["builder.boostFactor"]),
260
+ minBid: parseBuilderMinBid(args["builder.minBid"]),
261
+ maxExecutionPayment: parseBuilderGweiAmount(args["builder.maxExecutionPayment"]),
262
+ builders: parseBuilderUrls(args["builder.urls"]),
253
263
  },
254
264
  };
255
265
 
@@ -273,6 +283,23 @@ function getProposerConfigFromArgs(
273
283
  valProposerConfig = {defaultConfig} as ValidatorProposerConfig;
274
284
  }
275
285
  }
286
+
287
+ // Trusted execution payments are only backed by the builder's promise to pay, require an
288
+ // explicit opt-in before any configuration source can set a max execution payment above 0
289
+ if (args.allowDangerousTrustedPayments !== true) {
290
+ const configs = [valProposerConfig.defaultConfig, ...Object.values(valProposerConfig.proposerConfig ?? {})];
291
+ const hasTrustedPayment = configs.some(
292
+ (config) =>
293
+ (config.builder?.maxExecutionPayment ?? 0n) > 0n ||
294
+ (config.builder?.builders ?? []).some((entry) => (entry.maxExecutionPayment ?? 0n) > 0n)
295
+ );
296
+ if (hasTrustedPayment) {
297
+ throw new YargsError(
298
+ "Configuring a builder max execution payment above 0 requires --allowDangerousTrustedPayments"
299
+ );
300
+ }
301
+ }
302
+
276
303
  return valProposerConfig;
277
304
  }
278
305
 
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import {Keystore} from "@chainsafe/bls-keystore";
4
- import {SecretKey} from "@chainsafe/blst";
4
+ import {SecretKey} from "@chainsafe/lodestar-z/blst";
5
5
  import {LogLevel, Logger} from "@lodestar/utils";
6
6
  import {SignerLocal, SignerType} from "@lodestar/validator";
7
7
  import {lockFilepath, unlockFilepath} from "../../../util/lockfile.js";
@@ -1,7 +1,8 @@
1
1
  import {Keystore} from "@chainsafe/bls-keystore";
2
- import {SecretKey} from "@chainsafe/blst";
2
+ import {SecretKey} from "@chainsafe/lodestar-z/blst";
3
3
  import {
4
4
  BuilderBoostFactorData,
5
+ BuilderConfigData,
5
6
  DeleteRemoteKeyStatus,
6
7
  DeletionStatus,
7
8
  FeeRecipientData,
@@ -32,12 +33,13 @@ export class KeymanagerApi implements Api {
32
33
  private readonly validator: Validator,
33
34
  private readonly persistedKeysBackend: IPersistedKeysBackend,
34
35
  private readonly signal: AbortSignal,
35
- private readonly proposerConfigWriteDisabled?: boolean
36
+ private readonly proposerConfigWriteDisabled?: boolean,
37
+ private readonly allowDangerousTrustedPayments?: boolean
36
38
  ) {}
37
39
 
38
40
  private checkIfProposerWriteEnabled(): void {
39
41
  if (this.proposerConfigWriteDisabled === true) {
40
- throw Error("proposerSettingsFile option activated");
42
+ throw new ApiError(403, "proposerSettingsFile option activated");
41
43
  }
42
44
  }
43
45
 
@@ -379,6 +381,48 @@ export class KeymanagerApi implements Api {
379
381
  return {status: 204};
380
382
  }
381
383
 
384
+ async getBuilderConfig({pubkey}: {pubkey: PubkeyHex}): ReturnType<Api["getBuilderConfig"]> {
385
+ this.assertValidKnownPubkey(pubkey);
386
+ return {data: this.validator.validatorStore.getBuilderConfig(pubkey)};
387
+ }
388
+
389
+ async setBuilderConfig({
390
+ pubkey,
391
+ builderConfig,
392
+ }: {
393
+ pubkey: PubkeyHex;
394
+ builderConfig: BuilderConfigData;
395
+ }): ReturnType<Api["setBuilderConfig"]> {
396
+ this.checkIfProposerWriteEnabled();
397
+ this.assertValidKnownPubkey(pubkey);
398
+
399
+ if (
400
+ this.allowDangerousTrustedPayments !== true &&
401
+ builderConfig.builders?.some((entry) => (entry.maxExecutionPayment ?? 0n) > 0n)
402
+ ) {
403
+ throw new ApiError(
404
+ 400,
405
+ "Configuring a builder max execution payment above 0 requires --allowDangerousTrustedPayments"
406
+ );
407
+ }
408
+
409
+ try {
410
+ this.validator.validatorStore.setBuilderConfig(pubkey, builderConfig);
411
+ } catch (e) {
412
+ throw new ApiError(400, (e as Error).message);
413
+ }
414
+ this.persistedKeysBackend.writeProposerConfig(pubkey, this.validator.validatorStore.getProposerConfig(pubkey));
415
+ return {status: 202};
416
+ }
417
+
418
+ async deleteBuilderConfig({pubkey}: {pubkey: PubkeyHex}): ReturnType<Api["deleteBuilderConfig"]> {
419
+ this.checkIfProposerWriteEnabled();
420
+ this.assertValidKnownPubkey(pubkey);
421
+ this.validator.validatorStore.deleteBuilderConfig(pubkey);
422
+ this.persistedKeysBackend.writeProposerConfig(pubkey, this.validator.validatorStore.getProposerConfig(pubkey));
423
+ return {status: 204};
424
+ }
425
+
382
426
  async getProposerConfig({pubkey}: {pubkey: PubkeyHex}): ReturnType<Api["getProposerConfig"]> {
383
427
  this.assertValidKnownPubkey(pubkey);
384
428
 
@@ -390,7 +434,15 @@ export class KeymanagerApi implements Api {
390
434
  ? {
391
435
  ...config.builder,
392
436
  // Default JSON serialization can't handle BigInt
393
- boostFactor: config.builder.boostFactor ? config.builder.boostFactor.toString() : undefined,
437
+ boostFactor: config.builder.boostFactor?.toString(),
438
+ minBid: config.builder.minBid?.toString(),
439
+ maxExecutionPayment: config.builder.maxExecutionPayment?.toString(),
440
+ builders: config.builder.builders?.map((entry) => ({
441
+ ...entry,
442
+ maxExecutionPayment: entry.maxExecutionPayment?.toString(),
443
+ minBid: entry.minBid?.toString(),
444
+ builderBoostFactor: entry.builderBoostFactor?.toString(),
445
+ })),
394
446
  }
395
447
  : undefined,
396
448
  };
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import {Keystore} from "@chainsafe/bls-keystore";
4
- import {SecretKey} from "@chainsafe/blst";
4
+ import {SecretKey} from "@chainsafe/lodestar-z/blst";
5
5
  import {fromHex, toHex, toPubkeyHex} from "@lodestar/utils";
6
6
  import {SignerLocal, SignerType} from "@lodestar/validator";
7
7
  import {writeFile600Perm} from "../../../util/file.js";
@@ -53,7 +53,11 @@ export class PersistedKeysBackend implements IPersistedKeysBackend {
53
53
  if (proposerConfig !== null) {
54
54
  // if proposerConfig is not empty write or update the json to file
55
55
  const {proposerDirPath} = this.getValidatorPaths(pubkeyHex);
56
- writeFile600Perm(proposerDirPath, JSON.stringify(proposerConfig));
56
+ writeFile600Perm(
57
+ proposerDirPath,
58
+ // Default JSON serialization can't handle BigInt
59
+ JSON.stringify(proposerConfig, (_key, value) => (typeof value === "bigint" ? value.toString() : value))
60
+ );
57
61
  } else {
58
62
  this.deleteProposerConfig(pubkeyHex);
59
63
  }