@lodestar/beacon-node 1.49.0-dev.09a1892a85 → 1.49.0-dev.0a27fd270f

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 (289) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +15 -6
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/pool/index.js +4 -2
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/index.js +28 -0
  9. package/lib/api/impl/beacon/state/index.js.map +1 -1
  10. package/lib/api/impl/validator/index.d.ts.map +1 -1
  11. package/lib/api/impl/validator/index.js +9 -7
  12. package/lib/api/impl/validator/index.js.map +1 -1
  13. package/lib/chain/archiveStore/archiveStore.d.ts +1 -2
  14. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  15. package/lib/chain/archiveStore/archiveStore.js +23 -7
  16. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  17. package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
  18. package/lib/chain/archiveStore/historicalState/metrics.js +5 -6
  19. package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
  20. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +11 -2
  21. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  22. package/lib/chain/archiveStore/utils/archiveBlocks.js +46 -28
  23. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  24. package/lib/chain/archiveStore/utils/pruneHistory.d.ts +2 -2
  25. package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
  26. package/lib/chain/archiveStore/utils/pruneHistory.js +11 -2
  27. package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
  28. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  29. package/lib/chain/blocks/importExecutionPayload.js +13 -0
  30. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  31. package/lib/chain/blocks/index.js +2 -2
  32. package/lib/chain/blocks/index.js.map +1 -1
  33. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -1
  34. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  35. package/lib/chain/chain.d.ts +10 -0
  36. package/lib/chain/chain.d.ts.map +1 -1
  37. package/lib/chain/chain.js +85 -16
  38. package/lib/chain/chain.js.map +1 -1
  39. package/lib/chain/emitter.d.ts +10 -0
  40. package/lib/chain/emitter.d.ts.map +1 -1
  41. package/lib/chain/emitter.js +4 -0
  42. package/lib/chain/emitter.js.map +1 -1
  43. package/lib/chain/errors/attesterSlashingError.d.ts +4 -1
  44. package/lib/chain/errors/attesterSlashingError.d.ts.map +1 -1
  45. package/lib/chain/errors/attesterSlashingError.js +1 -0
  46. package/lib/chain/errors/attesterSlashingError.js.map +1 -1
  47. package/lib/chain/errors/envelopeReconstructionError.d.ts +23 -0
  48. package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -0
  49. package/lib/chain/errors/envelopeReconstructionError.js +13 -0
  50. package/lib/chain/errors/envelopeReconstructionError.js.map +1 -0
  51. package/lib/chain/errors/index.d.ts +1 -0
  52. package/lib/chain/errors/index.d.ts.map +1 -1
  53. package/lib/chain/errors/index.js +1 -0
  54. package/lib/chain/errors/index.js.map +1 -1
  55. package/lib/chain/errors/payloadAttestation.d.ts +4 -0
  56. package/lib/chain/errors/payloadAttestation.d.ts.map +1 -1
  57. package/lib/chain/errors/payloadAttestation.js +1 -0
  58. package/lib/chain/errors/payloadAttestation.js.map +1 -1
  59. package/lib/chain/errors/proposerSlashingError.d.ts +4 -1
  60. package/lib/chain/errors/proposerSlashingError.d.ts.map +1 -1
  61. package/lib/chain/errors/proposerSlashingError.js +1 -0
  62. package/lib/chain/errors/proposerSlashingError.js.map +1 -1
  63. package/lib/chain/interface.d.ts +6 -1
  64. package/lib/chain/interface.d.ts.map +1 -1
  65. package/lib/chain/interface.js.map +1 -1
  66. package/lib/chain/options.d.ts +2 -4
  67. package/lib/chain/options.d.ts.map +1 -1
  68. package/lib/chain/options.js +1 -1
  69. package/lib/chain/options.js.map +1 -1
  70. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  71. package/lib/chain/produceBlock/computeNewStateRoot.js +4 -2
  72. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  73. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  74. package/lib/chain/produceBlock/produceBlockBody.js +6 -6
  75. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  76. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +2 -1
  77. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  78. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +3 -2
  79. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  80. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  81. package/lib/chain/validation/attesterSlashing.js +1 -2
  82. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  83. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  84. package/lib/chain/validation/payloadAttestationMessage.js +8 -1
  85. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  86. package/lib/chain/validation/proposerSlashing.js +1 -2
  87. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  88. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  89. package/lib/chain/validatorMonitor.js +2 -2
  90. package/lib/chain/validatorMonitor.js.map +1 -1
  91. package/lib/db/beacon.d.ts +1 -2
  92. package/lib/db/beacon.d.ts.map +1 -1
  93. package/lib/db/beacon.js +1 -3
  94. package/lib/db/beacon.js.map +1 -1
  95. package/lib/db/buckets.d.ts +0 -1
  96. package/lib/db/buckets.d.ts.map +1 -1
  97. package/lib/db/buckets.js +1 -1
  98. package/lib/db/buckets.js.map +1 -1
  99. package/lib/db/interface.d.ts +1 -2
  100. package/lib/db/interface.d.ts.map +1 -1
  101. package/lib/db/repositories/blockArchive.d.ts +5 -0
  102. package/lib/db/repositories/blockArchive.d.ts.map +1 -1
  103. package/lib/db/repositories/blockArchive.js +36 -1
  104. package/lib/db/repositories/blockArchive.js.map +1 -1
  105. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  106. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  107. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts +21 -9
  108. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts.map +1 -1
  109. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +32 -12
  110. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  111. package/lib/db/repositories/index.d.ts +1 -2
  112. package/lib/db/repositories/index.d.ts.map +1 -1
  113. package/lib/db/repositories/index.js +1 -2
  114. package/lib/db/repositories/index.js.map +1 -1
  115. package/lib/execution/engine/disabled.d.ts +1 -0
  116. package/lib/execution/engine/disabled.d.ts.map +1 -1
  117. package/lib/execution/engine/disabled.js +3 -0
  118. package/lib/execution/engine/disabled.js.map +1 -1
  119. package/lib/execution/engine/http.d.ts +2 -1
  120. package/lib/execution/engine/http.d.ts.map +1 -1
  121. package/lib/execution/engine/http.js +7 -1
  122. package/lib/execution/engine/http.js.map +1 -1
  123. package/lib/execution/engine/interface.d.ts +3 -1
  124. package/lib/execution/engine/interface.d.ts.map +1 -1
  125. package/lib/execution/engine/mock.d.ts +1 -0
  126. package/lib/execution/engine/mock.d.ts.map +1 -1
  127. package/lib/execution/engine/mock.js +14 -2
  128. package/lib/execution/engine/mock.js.map +1 -1
  129. package/lib/execution/engine/types.d.ts +11 -0
  130. package/lib/execution/engine/types.d.ts.map +1 -1
  131. package/lib/execution/engine/types.js +10 -0
  132. package/lib/execution/engine/types.js.map +1 -1
  133. package/lib/metrics/metrics/beacon.d.ts +9 -0
  134. package/lib/metrics/metrics/beacon.d.ts.map +1 -1
  135. package/lib/metrics/metrics/beacon.js +16 -0
  136. package/lib/metrics/metrics/beacon.js.map +1 -1
  137. package/lib/metrics/metrics/lodestar.d.ts +21 -11
  138. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  139. package/lib/metrics/metrics/lodestar.js +48 -23
  140. package/lib/metrics/metrics/lodestar.js.map +1 -1
  141. package/lib/metrics/metrics.d.ts +3 -1
  142. package/lib/metrics/metrics.d.ts.map +1 -1
  143. package/lib/metrics/metrics.js +2 -2
  144. package/lib/metrics/metrics.js.map +1 -1
  145. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  146. package/lib/network/gossip/gossipsub.js +15 -0
  147. package/lib/network/gossip/gossipsub.js.map +1 -1
  148. package/lib/network/gossip/topic.d.ts +1 -1
  149. package/lib/network/gossip/topic.d.ts.map +1 -1
  150. package/lib/network/gossip/topic.js +1 -1
  151. package/lib/network/gossip/topic.js.map +1 -1
  152. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  153. package/lib/network/processor/gossipHandlers.js +16 -5
  154. package/lib/network/processor/gossipHandlers.js.map +1 -1
  155. package/lib/network/processor/gossipValidatorFn.d.ts +2 -0
  156. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  157. package/lib/network/processor/gossipValidatorFn.js +88 -7
  158. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  159. package/lib/network/processor/index.d.ts +6 -2
  160. package/lib/network/processor/index.d.ts.map +1 -1
  161. package/lib/network/processor/index.js +62 -24
  162. package/lib/network/processor/index.js.map +1 -1
  163. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  164. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +47 -34
  165. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  166. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
  167. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +23 -4
  168. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  169. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  170. package/lib/network/reqresp/handlers/index.js +20 -4
  171. package/lib/network/reqresp/handlers/index.js.map +1 -1
  172. package/lib/node/nodejs.d.ts +2 -7
  173. package/lib/node/nodejs.d.ts.map +1 -1
  174. package/lib/node/nodejs.js +2 -22
  175. package/lib/node/nodejs.js.map +1 -1
  176. package/lib/sync/interface.d.ts +1 -2
  177. package/lib/sync/interface.d.ts.map +1 -1
  178. package/lib/sync/options.d.ts +0 -6
  179. package/lib/sync/options.d.ts.map +1 -1
  180. package/lib/sync/options.js +0 -2
  181. package/lib/sync/options.js.map +1 -1
  182. package/lib/sync/types.d.ts +21 -2
  183. package/lib/sync/types.d.ts.map +1 -1
  184. package/lib/sync/types.js +22 -2
  185. package/lib/sync/types.js.map +1 -1
  186. package/lib/sync/unknownBlock.d.ts +20 -0
  187. package/lib/sync/unknownBlock.d.ts.map +1 -1
  188. package/lib/sync/unknownBlock.js +199 -15
  189. package/lib/sync/unknownBlock.js.map +1 -1
  190. package/lib/util/execution.d.ts +42 -0
  191. package/lib/util/execution.d.ts.map +1 -1
  192. package/lib/util/execution.js +123 -2
  193. package/lib/util/execution.js.map +1 -1
  194. package/lib/util/headerEnvelope.d.ts +17 -0
  195. package/lib/util/headerEnvelope.d.ts.map +1 -0
  196. package/lib/util/headerEnvelope.js +43 -0
  197. package/lib/util/headerEnvelope.js.map +1 -0
  198. package/lib/util/shuffle.d.ts +0 -4
  199. package/lib/util/shuffle.d.ts.map +1 -1
  200. package/lib/util/shuffle.js +0 -8
  201. package/lib/util/shuffle.js.map +1 -1
  202. package/package.json +16 -16
  203. package/src/api/impl/beacon/blocks/index.ts +18 -5
  204. package/src/api/impl/beacon/pool/index.ts +6 -2
  205. package/src/api/impl/beacon/state/index.ts +36 -0
  206. package/src/api/impl/validator/index.ts +9 -7
  207. package/src/chain/archiveStore/archiveStore.ts +24 -8
  208. package/src/chain/archiveStore/historicalState/metrics.ts +5 -7
  209. package/src/chain/archiveStore/utils/archiveBlocks.ts +54 -32
  210. package/src/chain/archiveStore/utils/pruneHistory.ts +14 -5
  211. package/src/chain/blocks/importExecutionPayload.ts +14 -0
  212. package/src/chain/blocks/index.ts +2 -2
  213. package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -1
  214. package/src/chain/chain.ts +96 -20
  215. package/src/chain/emitter.ts +7 -2
  216. package/src/chain/errors/attesterSlashingError.ts +3 -1
  217. package/src/chain/errors/envelopeReconstructionError.ts +22 -0
  218. package/src/chain/errors/index.ts +1 -0
  219. package/src/chain/errors/payloadAttestation.ts +2 -0
  220. package/src/chain/errors/proposerSlashingError.ts +3 -1
  221. package/src/chain/interface.ts +6 -1
  222. package/src/chain/options.ts +3 -5
  223. package/src/chain/produceBlock/computeNewStateRoot.ts +9 -2
  224. package/src/chain/produceBlock/produceBlockBody.ts +17 -6
  225. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +3 -2
  226. package/src/chain/validation/attesterSlashing.ts +1 -2
  227. package/src/chain/validation/payloadAttestationMessage.ts +9 -0
  228. package/src/chain/validation/proposerSlashing.ts +1 -2
  229. package/src/chain/validatorMonitor.ts +12 -2
  230. package/src/db/beacon.ts +0 -5
  231. package/src/db/buckets.ts +2 -2
  232. package/src/db/interface.ts +0 -3
  233. package/src/db/repositories/blockArchive.ts +38 -1
  234. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +43 -13
  235. package/src/db/repositories/index.ts +6 -2
  236. package/src/execution/engine/disabled.ts +4 -0
  237. package/src/execution/engine/http.ts +12 -0
  238. package/src/execution/engine/interface.ts +4 -1
  239. package/src/execution/engine/mock.ts +22 -2
  240. package/src/execution/engine/types.ts +25 -0
  241. package/src/metrics/metrics/beacon.ts +16 -0
  242. package/src/metrics/metrics/lodestar.ts +58 -26
  243. package/src/metrics/metrics.ts +7 -2
  244. package/src/network/gossip/gossipsub.ts +18 -1
  245. package/src/network/gossip/topic.ts +2 -2
  246. package/src/network/processor/gossipHandlers.ts +18 -5
  247. package/src/network/processor/gossipValidatorFn.ts +111 -7
  248. package/src/network/processor/index.ts +81 -24
  249. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +57 -39
  250. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +27 -5
  251. package/src/network/reqresp/handlers/index.ts +49 -5
  252. package/src/node/nodejs.ts +0 -27
  253. package/src/sync/interface.ts +1 -2
  254. package/src/sync/options.ts +0 -8
  255. package/src/sync/types.ts +24 -5
  256. package/src/sync/unknownBlock.ts +207 -14
  257. package/src/util/execution.ts +175 -2
  258. package/src/util/headerEnvelope.ts +76 -0
  259. package/src/util/shuffle.ts +0 -9
  260. package/lib/chain/archiveStore/utils/updateBackfillRange.d.ts +0 -20
  261. package/lib/chain/archiveStore/utils/updateBackfillRange.d.ts.map +0 -1
  262. package/lib/chain/archiveStore/utils/updateBackfillRange.js +0 -40
  263. package/lib/chain/archiveStore/utils/updateBackfillRange.js.map +0 -1
  264. package/lib/db/repositories/backfilledRanges.d.ts +0 -18
  265. package/lib/db/repositories/backfilledRanges.d.ts.map +0 -1
  266. package/lib/db/repositories/backfilledRanges.js +0 -26
  267. package/lib/db/repositories/backfilledRanges.js.map +0 -1
  268. package/lib/sync/backfill/backfill.d.ts +0 -169
  269. package/lib/sync/backfill/backfill.d.ts.map +0 -1
  270. package/lib/sync/backfill/backfill.js +0 -686
  271. package/lib/sync/backfill/backfill.js.map +0 -1
  272. package/lib/sync/backfill/errors.d.ts +0 -30
  273. package/lib/sync/backfill/errors.d.ts.map +0 -1
  274. package/lib/sync/backfill/errors.js +0 -15
  275. package/lib/sync/backfill/errors.js.map +0 -1
  276. package/lib/sync/backfill/index.d.ts +0 -2
  277. package/lib/sync/backfill/index.d.ts.map +0 -1
  278. package/lib/sync/backfill/index.js +0 -2
  279. package/lib/sync/backfill/index.js.map +0 -1
  280. package/lib/sync/backfill/verify.d.ts +0 -18
  281. package/lib/sync/backfill/verify.d.ts.map +0 -1
  282. package/lib/sync/backfill/verify.js +0 -36
  283. package/lib/sync/backfill/verify.js.map +0 -1
  284. package/src/chain/archiveStore/utils/updateBackfillRange.ts +0 -50
  285. package/src/db/repositories/backfilledRanges.ts +0 -29
  286. package/src/sync/backfill/backfill.ts +0 -916
  287. package/src/sync/backfill/errors.ts +0 -23
  288. package/src/sync/backfill/index.ts +0 -1
  289. package/src/sync/backfill/verify.ts +0 -58
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headerEnvelope.js","sourceRoot":"","sources":["../../src/util/headerEnvelope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAUpC,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,gDAAgD,CAAC;AAWxD,MAAM,EAAC,YAAY,EAAE,WAAW,EAAE,eAAe,EAAC,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC;AAEvF,gGAAgG;AAChG,MAAM,UAAU,gBAAgB,CAAC,QAAkC;IACjE,MAAM,EAAC,OAAO,EAAE,GAAG,cAAc,EAAC,GAAG,QAAQ,CAAC;IAC9C,MAAM,EAAC,YAAY,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,GAAG,OAAO,EAAC,GAAG,OAAO,CAAC;IACxF,OAAO;QACL,GAAG,cAAc;QACjB,aAAa,EAAE;YACb,GAAG,OAAO;YACV,gBAAgB,EAAE,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC;YAChD,eAAe,EAAE,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC;YAC9C,mBAAmB,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC;SACvD;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,QAAwC;IAC7E,OAAO,EAAC,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAC,CAAC;AACtF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACxC,cAAoD,EACpD,MAA8B;IAE9B,MAAM,EAAC,aAAa,EAAE,GAAG,cAAc,EAAC,GAAG,cAAc,CAAC,OAAO,CAAC;IAClE,MAAM,EAAC,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,GAAG,OAAO,EAAC,GAAG,aAAa,CAAC;IAC3F,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;IAEhC,cAAc,CAAC,cAAc,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IACvG,cAAc,CAAC,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;IACnG,cAAc,CAAC,iBAAiB,EAAE,IAAI,EAAE,mBAAmB,EAAE,eAAe,CAAC,YAAY,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;IAEnH,OAAO;QACL,OAAO,EAAE,EAAC,GAAG,cAAc,EAAE,OAAO,EAAE,EAAC,GAAG,OAAO,EAAE,GAAG,MAAM,EAAC,EAAC;QAC9D,SAAS,EAAE,cAAc,CAAC,SAAS;KACpC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAgC,EAAE,IAAY,EAAE,MAAkB,EAAE,OAAmB;IAC7G,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,2BAA2B,CACnC,EAAC,IAAI,EAAE,+BAA+B,CAAC,kBAAkB,EAAE,IAAI,EAAE,KAAK,EAAC,EACvE,iBAAiB,KAAK,uBAAuB,IAAI,WAAW,SAAS,CAAC,MAAM,CAAC,YAAY,SAAS,CAAC,OAAO,CAAC,EAAE,CAC9G,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -3,8 +3,4 @@
3
3
  * Note: Uses Math.random() as entropy source, use for non-critical stuff
4
4
  */
5
5
  export declare function shuffle<T>(arr: T[]): T[];
6
- /**
7
- * Return one random item from array
8
- */
9
- export declare function shuffleOne<T>(arr: T[]): T | undefined;
10
6
  //# sourceMappingURL=shuffle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shuffle.d.ts","sourceRoot":"","sources":["../../src/util/shuffle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAOxC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,SAAS,CAIrD"}
1
+ {"version":3,"file":"shuffle.d.ts","sourceRoot":"","sources":["../../src/util/shuffle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAOxC"}
@@ -10,12 +10,4 @@ export function shuffle(arr) {
10
10
  }
11
11
  return _arr;
12
12
  }
13
- /**
14
- * Return one random item from array
15
- */
16
- export function shuffleOne(arr) {
17
- if (arr.length === 0)
18
- return undefined;
19
- return arr[Math.floor(Math.random() * arr.length)];
20
- }
21
13
  //# sourceMappingURL=shuffle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shuffle.js","sourceRoot":"","sources":["../../src/util/shuffle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAI,GAAQ;IACjC,MAAM,IAAI,GAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAI,GAAQ;IACpC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEvC,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"shuffle.js","sourceRoot":"","sources":["../../src/util/shuffle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAI,GAAQ;IACjC,MAAM,IAAI,GAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.49.0-dev.09a1892a85",
14
+ "version": "1.49.0-dev.0a27fd270f",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -118,7 +118,7 @@
118
118
  "@fastify/swagger-ui": "^5.0.1",
119
119
  "@libp2p/bootstrap": "^12.0.30",
120
120
  "@libp2p/crypto": "^5.1.23",
121
- "@libp2p/gossipsub": "^17.1.0",
121
+ "@libp2p/gossipsub": "^17.1.2",
122
122
  "@libp2p/identify": "^4.1.13",
123
123
  "@libp2p/interface": "^3.3.0",
124
124
  "@libp2p/mdns": "^12.0.30",
@@ -127,17 +127,17 @@
127
127
  "@libp2p/prometheus-metrics": "^5.0.28",
128
128
  "@libp2p/tcp": "^11.0.27",
129
129
  "@libp2p/utils": "^7.4.0",
130
- "@lodestar/api": "^1.49.0-dev.09a1892a85",
131
- "@lodestar/config": "^1.49.0-dev.09a1892a85",
132
- "@lodestar/db": "^1.49.0-dev.09a1892a85",
133
- "@lodestar/fork-choice": "^1.49.0-dev.09a1892a85",
134
- "@lodestar/logger": "^1.49.0-dev.09a1892a85",
135
- "@lodestar/params": "^1.49.0-dev.09a1892a85",
136
- "@lodestar/reqresp": "^1.49.0-dev.09a1892a85",
137
- "@lodestar/state-transition": "^1.49.0-dev.09a1892a85",
138
- "@lodestar/types": "^1.49.0-dev.09a1892a85",
139
- "@lodestar/utils": "^1.49.0-dev.09a1892a85",
140
- "@lodestar/validator": "^1.49.0-dev.09a1892a85",
130
+ "@lodestar/api": "^1.49.0-dev.0a27fd270f",
131
+ "@lodestar/config": "^1.49.0-dev.0a27fd270f",
132
+ "@lodestar/db": "^1.49.0-dev.0a27fd270f",
133
+ "@lodestar/fork-choice": "^1.49.0-dev.0a27fd270f",
134
+ "@lodestar/logger": "^1.49.0-dev.0a27fd270f",
135
+ "@lodestar/params": "^1.49.0-dev.0a27fd270f",
136
+ "@lodestar/reqresp": "^1.49.0-dev.0a27fd270f",
137
+ "@lodestar/state-transition": "^1.49.0-dev.0a27fd270f",
138
+ "@lodestar/types": "^1.49.0-dev.0a27fd270f",
139
+ "@lodestar/utils": "^1.49.0-dev.0a27fd270f",
140
+ "@lodestar/validator": "^1.49.0-dev.0a27fd270f",
141
141
  "@multiformats/multiaddr": "^13.0.1",
142
142
  "datastore-core": "^12.0.1",
143
143
  "datastore-level": "^13.0.1",
@@ -156,10 +156,10 @@
156
156
  "xxhash-wasm": "1.0.2"
157
157
  },
158
158
  "devDependencies": {
159
- "@chainsafe/swap-or-not-shuffle": "^1.2.1",
160
159
  "@libp2p/interface-internal": "^3.1.12",
161
160
  "@libp2p/logger": "^6.2.13",
162
- "@lodestar/spec-test-util": "^1.49.0-dev.09a1892a85",
161
+ "@lodestar/spec-test-util": "^1.49.0-dev.0a27fd270f",
162
+ "@lodestar/test-utils": "^1.49.0-dev.0a27fd270f",
163
163
  "@types/js-yaml": "^4.0.5",
164
164
  "@types/qs": "^6.9.7",
165
165
  "@types/tmp": "^0.2.3",
@@ -174,5 +174,5 @@
174
174
  "beacon",
175
175
  "blockchain"
176
176
  ],
177
- "gitHead": "74ba20cac9dd2a2636fd6c85fdc16bf2edce059e"
177
+ "gitHead": "46f83d1d030496378b5e8f6d5e90e6b48de46513"
178
178
  }
@@ -35,7 +35,7 @@ import {
35
35
  isSignedExecutionPayloadEnvelopeContents,
36
36
  sszTypesFor,
37
37
  } from "@lodestar/types";
38
- import {fromHex, sleep, toHex, toRootHex} from "@lodestar/utils";
38
+ import {fromHex, prettyGweiToEth, sleep, toHex, toRootHex} from "@lodestar/utils";
39
39
  import {BlockInputSource, isBlockInputBlobs, isBlockInputColumns} from "../../../../chain/blocks/blockInput/index.js";
40
40
  import {PayloadEnvelopeInputSource} from "../../../../chain/blocks/payloadEnvelopeInput/index.js";
41
41
  import {ImportBlockOpts} from "../../../../chain/blocks/types.js";
@@ -47,6 +47,8 @@ import {
47
47
  BlockError,
48
48
  BlockErrorCode,
49
49
  BlockGossipError,
50
+ EnvelopeReconstructionError,
51
+ EnvelopeReconstructionErrorCode,
50
52
  ExecutionPayloadEnvelopeError,
51
53
  ExecutionPayloadEnvelopeErrorCode,
52
54
  } from "../../../../chain/errors/index.js";
@@ -1089,7 +1091,7 @@ export function getBeaconBlockApi({
1089
1091
  builderIndex: bid.builderIndex,
1090
1092
  blockHash: toRootHex(bid.blockHash),
1091
1093
  parentBlockHash: toRootHex(bid.parentBlockHash),
1092
- value: bid.value,
1094
+ value: prettyGweiToEth(bid.value),
1093
1095
  sentPeers,
1094
1096
  });
1095
1097
  },
@@ -1109,9 +1111,20 @@ export function getBeaconBlockApi({
1109
1111
  const blockRoot = config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block.message);
1110
1112
  const blockRootHex = toRootHex(blockRoot);
1111
1113
 
1112
- const data = context?.returnBytes
1113
- ? await chain.getSerializedExecutionPayloadEnvelope(slot, blockRootHex)
1114
- : await chain.getExecutionPayloadEnvelope(slot, blockRootHex);
1114
+ let data: Uint8Array | gloas.SignedExecutionPayloadEnvelope | null;
1115
+ try {
1116
+ data = context?.returnBytes
1117
+ ? await chain.getSerializedExecutionPayloadEnvelope(slot, blockRootHex)
1118
+ : await chain.getExecutionPayloadEnvelope(slot, blockRootHex);
1119
+ } catch (e) {
1120
+ if (e instanceof EnvelopeReconstructionError) {
1121
+ throw new ApiError(
1122
+ e.type.code === EnvelopeReconstructionErrorCode.ENGINE_UNAVAILABLE ? 503 : 500,
1123
+ `Failed to reconstruct execution payload envelope: ${e.message}`
1124
+ );
1125
+ }
1126
+ throw e;
1127
+ }
1115
1128
 
1116
1129
  if (!data) {
1117
1130
  throw new ApiError(404, `Execution payload envelope not found for slot=${slot}, blockRoot=${blockRootHex}`);
@@ -39,7 +39,7 @@ export function getBeaconPoolApi({
39
39
  return {
40
40
  async getPoolAttestationsV2({slot, committeeIndex}) {
41
41
  // Already filtered by slot
42
- let attestations = chain.aggregatedAttestationPool.getAll(slot);
42
+ let attestations = [...chain.aggregatedAttestationPool.getAll(slot), ...chain.attestationPool.getAll(slot)];
43
43
  const fork = chain.config.getForkName(slot ?? attestations[0]?.data.slot ?? chain.clock.currentSlot);
44
44
  const isPostElectra = isForkPostElectra(fork);
45
45
 
@@ -48,7 +48,11 @@ export function getBeaconPoolApi({
48
48
  );
49
49
 
50
50
  if (committeeIndex !== undefined) {
51
- attestations = attestations.filter((attestation) => committeeIndex === attestation.data.index);
51
+ attestations = attestations.filter((attestation) =>
52
+ isElectraAttestation(attestation)
53
+ ? attestation.committeeBits.get(committeeIndex)
54
+ : committeeIndex === attestation.data.index
55
+ );
52
56
  }
53
57
 
54
58
  return {data: attestations, meta: {version: fork}};
@@ -441,5 +441,41 @@ export function getBeaconStateApi({
441
441
  meta: {executionOptimistic, finalized, version: fork},
442
442
  };
443
443
  },
444
+
445
+ async getBuilderPendingPayments({stateId}, context) {
446
+ const {state, executionOptimistic, finalized} = await getState(stateId);
447
+ const fork = state.forkName;
448
+
449
+ if (!isStatePostGloas(state)) {
450
+ throw new ApiError(400, `Cannot retrieve pending builder payments for pre-gloas state fork=${fork}`);
451
+ }
452
+
453
+ const builderPendingPayments = state.builderPendingPayments;
454
+
455
+ return {
456
+ data: context?.returnBytes
457
+ ? ssz.gloas.BuilderPendingPayments.serialize(builderPendingPayments)
458
+ : builderPendingPayments,
459
+ meta: {executionOptimistic, finalized, version: fork},
460
+ };
461
+ },
462
+
463
+ async getBuilderPendingWithdrawals({stateId}, context) {
464
+ const {state, executionOptimistic, finalized} = await getState(stateId);
465
+ const fork = state.forkName;
466
+
467
+ if (!isStatePostGloas(state)) {
468
+ throw new ApiError(400, `Cannot retrieve pending builder withdrawals for pre-gloas state fork=${fork}`);
469
+ }
470
+
471
+ const builderPendingWithdrawals = state.builderPendingWithdrawals;
472
+
473
+ return {
474
+ data: context?.returnBytes
475
+ ? ssz.gloas.BuilderPendingWithdrawals.serialize(builderPendingWithdrawals)
476
+ : builderPendingWithdrawals,
477
+ meta: {executionOptimistic, finalized, version: fork},
478
+ };
479
+ },
444
480
  };
445
481
  }
@@ -481,8 +481,8 @@ export function getValidatorApi(
481
481
  metrics?.blockProductionExecutionPayloadValue.observe({source}, Number(formatWeiToEth(executionPayloadValue)));
482
482
  logger.verbose("Produced blinded block", {
483
483
  slot,
484
- executionPayloadValue,
485
- consensusBlockValue,
484
+ executionPayloadValue: prettyWeiToEth(executionPayloadValue),
485
+ consensusBlockValue: prettyWeiToEth(consensusBlockValue),
486
486
  root: toRootHex(config.getPostBellatrixForkTypes(slot).BlindedBeaconBlock.hashTreeRoot(block)),
487
487
  });
488
488
 
@@ -540,8 +540,8 @@ export function getValidatorApi(
540
540
  const blockRoot = toRootHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block));
541
541
  logger.verbose("Produced execution block", {
542
542
  slot,
543
- executionPayloadValue,
544
- consensusBlockValue,
543
+ executionPayloadValue: prettyWeiToEth(executionPayloadValue),
544
+ consensusBlockValue: prettyWeiToEth(consensusBlockValue),
545
545
  root: blockRoot,
546
546
  });
547
547
  if (chain.opts.persistProducedBlocks) {
@@ -1057,6 +1057,8 @@ export function getValidatorApi(
1057
1057
  rank: index + 1,
1058
1058
  source: candidate.url !== undefined ? toPrintableUrl(candidate.url) : "p2p",
1059
1059
  builder: candidate.signedBid.message.builderIndex,
1060
+ value: prettyGweiToEth(candidate.signedBid.message.value),
1061
+ executionPayment: prettyGweiToEth(candidate.signedBid.message.executionPayment),
1060
1062
  total: prettyGweiToEth(candidate.totalGwei),
1061
1063
  boost: candidate.boostFactor,
1062
1064
  boosted: prettyGweiToEth(getBoostedTotalScaled(candidate) / 100n),
@@ -1247,8 +1249,8 @@ export function getValidatorApi(
1247
1249
  const blockRoot = toRootHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block));
1248
1250
  logger.verbose("Produced block", {
1249
1251
  ...logCtx,
1250
- executionPayloadValue,
1251
- consensusBlockValue,
1252
+ executionPayloadValue: prettyWeiToEth(executionPayloadValue),
1253
+ consensusBlockValue: prettyWeiToEth(consensusBlockValue),
1252
1254
  root: blockRoot,
1253
1255
  });
1254
1256
  if (chain.opts.persistProducedBlocks) {
@@ -2104,7 +2106,7 @@ export function getValidatorApi(
2104
2106
  auth: entry.auth,
2105
2107
  });
2106
2108
  } catch (e) {
2107
- failures.push({index: i, message: (e as Error).message});
2109
+ failures.push({index: i, message: `${builder}: ${(e as Error).message}`});
2108
2110
  logger.verbose(
2109
2111
  `Error on submitBuilderPreferences [${i}]`,
2110
2112
  {slot: entry.auth.message.slot, builder},
@@ -16,7 +16,6 @@ import {ArchiveMode, ArchiveStoreOpts, StateArchiveStrategy} from "./interface.j
16
16
  import {FrequencyStateArchiveStrategy} from "./strategies/frequencyStateArchiveStrategy.js";
17
17
  import {archiveBlocks} from "./utils/archiveBlocks.js";
18
18
  import {pruneHistory} from "./utils/pruneHistory.js";
19
- import {updateBackfillRange} from "./utils/updateBackfillRange.js";
20
19
 
21
20
  type ArchiveStoreModules = {
22
21
  chain: IBeaconChain;
@@ -37,7 +36,6 @@ export enum ArchiveStoreTask {
37
36
  OnFinalizedCheckpoint = "on_finalized_checkpoint",
38
37
  MaybeArchiveState = "maybe_archive_state",
39
38
  ForkchoicePrune = "forkchoice_prune",
40
- UpdateBackfillRange = "update_backfill_range",
41
39
  }
42
40
 
43
41
  /**
@@ -120,6 +118,26 @@ export class ArchiveStore {
120
118
  );
121
119
  }
122
120
 
121
+ // Initialize earliestAvailableSlot from the earliest block actually retained (after any pruning
122
+ // above), rather than the anchor state slot set in the constructor. On an in-place restart the DB
123
+ // still holds finalized history below the anchor; leaving the value at the anchor makes the node
124
+ // reject by_range requests (beacon_blocks, execution_payload_envelopes and data_column_sidecars
125
+ // all gate on this slot) for data it still retains. An empty archive (e.g. a fresh checkpoint
126
+ // sync with nothing below the anchor) leaves the constructor's anchor slot in place.
127
+ const earliestArchivedBlockSlot = await this.db.blockArchive.firstKey();
128
+ if (earliestArchivedBlockSlot != null) {
129
+ const oldEarliestAvailableSlot = this.chain.earliestAvailableSlot;
130
+ this.chain.earliestAvailableSlot = earliestArchivedBlockSlot;
131
+ this.logger.verbose("Initialized earliestAvailableSlot from retained block archive", {
132
+ oldEarliestAvailableSlot,
133
+ newEarliestAvailableSlot: earliestArchivedBlockSlot,
134
+ });
135
+ } else {
136
+ this.logger.verbose("Empty block archive on init, keeping anchor earliestAvailableSlot", {
137
+ earliestAvailableSlot: this.chain.earliestAvailableSlot,
138
+ });
139
+ }
140
+
123
141
  if (this.opts.serveHistoricalState) {
124
142
  this.historicalStateRegen = await HistoricalStateRegen.init({
125
143
  opts: {
@@ -230,13 +248,14 @@ export class ArchiveStore {
230
248
  isNodeSynced,
231
249
  this.archiveDataEpochs,
232
250
  this.chain.opts.persistOrphanedBlocks,
233
- this.chain.opts.persistOrphanedBlocksDir
251
+ this.chain.opts.persistOrphanedBlocksDir,
252
+ this.chain.opts.dedupePayloads
234
253
  );
235
254
  timer?.({source: ArchiveStoreTask.ArchiveBlocks});
236
255
 
237
256
  if (this.opts.pruneHistory) {
238
257
  timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
239
- await pruneHistory(
258
+ const blockCutoffSlot = await pruneHistory(
240
259
  this.chain.config,
241
260
  this.db,
242
261
  this.logger,
@@ -244,6 +263,7 @@ export class ArchiveStore {
244
263
  finalizedEpoch,
245
264
  this.chain.clock.currentEpoch
246
265
  );
266
+ this.chain.earliestAvailableSlot = Math.max(this.chain.earliestAvailableSlot, blockCutoffSlot);
247
267
  timer?.({source: ArchiveStoreTask.PruneHistory});
248
268
  }
249
269
 
@@ -261,10 +281,6 @@ export class ArchiveStore {
261
281
  const prunedBlocks = this.chain.forkChoice.prune(finalized.rootHex);
262
282
  timer?.({source: ArchiveStoreTask.ForkchoicePrune});
263
283
 
264
- timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
265
- await updateBackfillRange({chain: this.chain, db: this.db, logger: this.logger}, finalized);
266
- timer?.({source: ArchiveStoreTask.UpdateBackfillRange});
267
-
268
284
  this.logger.verbose("Finish processing finalized checkpoint", {
269
285
  epoch: finalizedEpoch,
270
286
  rootHex: finalized.rootHex,
@@ -6,7 +6,6 @@ import {
6
6
  ProcessOperationsStep,
7
7
  ProposerRewardType,
8
8
  StateCloneSource,
9
- StateHashTreeRootSource,
10
9
  } from "@lodestar/state-transition";
11
10
  import {Gauge, Histogram} from "@lodestar/utils";
12
11
  import {RegistryMetricCreator} from "../../../metrics/index.js";
@@ -92,12 +91,6 @@ export function createHistoricalStateTransitionMetrics(
92
91
  help: "Time to call commit after process a single block in seconds",
93
92
  buckets: [0.005, 0.01, 0.02, 0.05, 0.1, 1],
94
93
  }),
95
- stateHashTreeRootTime: metricsRegister.histogram<{source: StateHashTreeRootSource}>({
96
- name: "lodestar_historical_state_stfn_hash_tree_root_seconds",
97
- help: "Time to compute the hash tree root of a post state in seconds",
98
- buckets: [0.05, 0.1, 0.2, 0.5, 1, 1.5],
99
- labelNames: ["source"],
100
- }),
101
94
  numEffectiveBalanceUpdates: metricsRegister.gauge({
102
95
  name: "lodestar_historical_state_stfn_num_effective_balance_updates_count",
103
96
  help: "Count of effective balance updates in epoch transition",
@@ -163,6 +156,11 @@ export function createHistoricalStateTransitionMetrics(
163
156
  name: "lodestar_historical_state_stfn_attestations_per_block_total",
164
157
  help: "Count of attestations per block",
165
158
  }),
159
+ progressiveBalancesMismatches: metricsRegister.counter<{target: "current" | "previous"}>({
160
+ name: "lodestar_historical_state_stfn_progressive_balances_mismatches_total",
161
+ help: "Total count of progressive balance cache mismatches by target balance",
162
+ labelNames: ["target"],
163
+ }),
166
164
  proposerRewards: metricsRegister.gauge<{type: ProposerRewardType}>({
167
165
  name: "lodestar_historical_state_stfn_proposer_rewards_total",
168
166
  help: "Proposer reward by type per block",
@@ -1,15 +1,16 @@
1
1
  import path from "node:path";
2
2
  import {ChainForkConfig} from "@lodestar/config";
3
3
  import {KeyValue} from "@lodestar/db";
4
- import {CheckpointWithHex, IForkChoice, PayloadStatus, ProtoBlock} from "@lodestar/fork-choice";
4
+ import {CheckpointWithHex, ExecutionStatus, IForkChoice, PayloadStatus, ProtoBlock} from "@lodestar/fork-choice";
5
5
  import {ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
6
6
  import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
7
7
  import {Epoch, Slot} from "@lodestar/types";
8
8
  import {Logger, fromAsync, fromHex, prettyPrintIndices, toRootHex} from "@lodestar/utils";
9
9
  import {IBeaconDb} from "../../../db/index.js";
10
- import {BlockArchiveBatchPutBinaryItem} from "../../../db/repositories/index.js";
10
+ import {BlockArchiveBatchPutBinaryItem, encodeArchivedHeaderEnvelope} from "../../../db/repositories/index.js";
11
11
  import {Metrics} from "../../../metrics/metrics.js";
12
12
  import {ensureDir, writeIfNotExist} from "../../../util/file.js";
13
+ import {toSignedHeaderEnvelope} from "../../../util/headerEnvelope.js";
13
14
  import {BlockRootHex} from "../../../util/sszBytes.js";
14
15
  import {LightClientServer} from "../../lightClient/index.js";
15
16
 
@@ -69,7 +70,8 @@ export async function archiveBlocks(
69
70
  isNodeSynced: boolean,
70
71
  archiveDataEpochs?: number,
71
72
  persistOrphanedBlocks?: boolean,
72
- persistOrphanedBlocksDir?: string
73
+ persistOrphanedBlocksDir?: string,
74
+ dedupePayloads = true
73
75
  ): Promise<void> {
74
76
  // Use fork choice to determine the blocks to archive and delete.
75
77
  // `ancestors` is the canonical walk back from the finalized root, including the previous finalized
@@ -156,7 +158,8 @@ export async function archiveBlocks(
156
158
  config,
157
159
  db,
158
160
  logger,
159
- finalizedCanonicalBlocks
161
+ finalizedCanonicalBlocks,
162
+ dedupePayloads
160
163
  );
161
164
  logger.verbose("Migrated executionPayloadEnvelopes from hot DB to cold DB", {
162
165
  ...logCtx,
@@ -475,49 +478,68 @@ async function migrateDataColumnSidecarsFromHotToColdDb(
475
478
  /**
476
479
  * Post-gloas given a finalized checkpoint at a block root, payload of that block root
477
480
  * is not considered finalized, hence they are archived in the next run.
481
+ *
482
+ * With `dedupePayloads` (default), execution-valid envelopes are archived as header envelopes. Envelopes of
483
+ * still-optimistic blocks are archived in full, since the EL may not serve their bodies, and are not
484
+ * converted later. Archive put + hot delete are one atomic db batch.
478
485
  */
479
- async function migrateExecutionPayloadEnvelopesFromHotToColdDb(
486
+ export async function migrateExecutionPayloadEnvelopesFromHotToColdDb(
480
487
  config: ChainForkConfig,
481
488
  db: IBeaconDb,
482
489
  logger: Logger,
483
- canonicalBlocks: ProtoBlock[]
490
+ canonicalBlocks: ProtoBlock[],
491
+ dedupePayloads: boolean
484
492
  ): Promise<Slot[]> {
485
493
  const payloadBlocks = canonicalBlocks.filter(
486
- (block) => config.getForkSeq(block.slot) < ForkSeq.gloas || block.payloadStatus === PayloadStatus.FULL
494
+ (block) => config.getForkSeq(block.slot) >= ForkSeq.gloas && block.payloadStatus === PayloadStatus.FULL
487
495
  );
488
496
  if (payloadBlocks.length === 0) return [];
489
- const blocks = payloadBlocks.map((block) => ({slot: block.slot, root: fromHex(block.blockRoot)}));
490
497
 
491
- const envelopeEntries: KeyValue<Slot, Uint8Array>[] = [];
492
- const migratedRoots: Uint8Array[] = [];
498
+ const migratedSlots: Slot[] = [];
493
499
 
494
- const envelopeBytesArray = await Promise.all(
495
- blocks.map((block) => db.executionPayloadEnvelope.getBinary(block.root))
496
- );
500
+ // Process in chunks to bound memory: after a long non-finality period the ancestor walk can span
501
+ // thousands of blocks, and each full envelope is a few hundred KB when deserialized.
502
+ for (let i = 0; i < payloadBlocks.length; i += BLOCK_BATCH_SIZE) {
503
+ const batch = payloadBlocks.slice(i, i + BLOCK_BATCH_SIZE);
504
+ // Only header envelopes need deserializing; full ones are copied as bytes
505
+ const archivedBytesArray = await Promise.all(
506
+ batch.map(async (block) => {
507
+ const root = fromHex(block.blockRoot);
508
+ if (dedupePayloads && block.executionStatus === ExecutionStatus.Valid) {
509
+ const envelope = await db.executionPayloadEnvelope.get(root);
510
+ return envelope === null ? null : encodeArchivedHeaderEnvelope(toSignedHeaderEnvelope(envelope));
511
+ }
512
+ return db.executionPayloadEnvelope.getBinary(root);
513
+ })
514
+ );
515
+
516
+ const entries: {slot: Slot; archivedBytes: Uint8Array; hotKey: Uint8Array}[] = [];
517
+ for (let j = 0; j < batch.length; j++) {
518
+ const block = batch[j];
519
+ const archivedBytes = archivedBytesArray[j];
520
+ if (archivedBytes === null) {
521
+ logger.debug("ExecutionPayloadEnvelope in forkchoice but missing in hot db, could be already archived", {
522
+ slot: block.slot,
523
+ root: block.blockRoot,
524
+ });
525
+ continue;
526
+ }
497
527
 
498
- for (let i = 0; i < blocks.length; i++) {
499
- const bytes = envelopeBytesArray[i];
500
- if (bytes !== null) {
501
- envelopeEntries.push({key: blocks[i].slot, value: bytes});
502
- migratedRoots.push(blocks[i].root);
503
- } else {
504
- logger.debug("ExecutionPayloadEnvelope in forkchoice but missing in hot db, could be already archived", {
505
- slot: blocks[i].slot,
506
- root: toRootHex(blocks[i].root),
528
+ entries.push({
529
+ slot: block.slot,
530
+ archivedBytes,
531
+ hotKey: db.executionPayloadEnvelope.encodeKey(fromHex(block.blockRoot)),
507
532
  });
533
+ migratedSlots.push(block.slot);
508
534
  }
509
- }
510
535
 
511
- if (envelopeEntries.length === 0) return [];
512
-
513
- await Promise.all([
514
- db.executionPayloadEnvelopeArchive.batchPutBinary(envelopeEntries),
515
- db.executionPayloadEnvelope.batchDelete(migratedRoots),
516
- ]);
536
+ if (entries.length > 0) {
537
+ await db.executionPayloadEnvelopeArchive.batchArchiveAndDeleteHot(entries);
538
+ }
539
+ }
517
540
 
518
- // Slots are ascending in hot-db key order — sort to guarantee `prettyPrintIndices` output is clean
519
- // regardless of ancestor-walk order (newest to oldest).
520
- return envelopeEntries.map((entry) => entry.key).sort((a, b) => a - b);
541
+ // Ancestor walk is newest to oldest; sort ascending so `prettyPrintIndices` renders cleanly.
542
+ return migratedSlots.sort((a, b) => a - b);
521
543
  }
522
544
 
523
545
  /**
@@ -1,7 +1,7 @@
1
1
  import {ChainConfig} from "@lodestar/config";
2
2
  import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
3
- import {Epoch} from "@lodestar/types";
4
- import {Logger} from "@lodestar/utils";
3
+ import {Epoch, Slot} from "@lodestar/types";
4
+ import {Logger, prettyPrintIndices} from "@lodestar/utils";
5
5
  import {IBeaconDb} from "../../../db/interface.js";
6
6
  import {Metrics} from "../../../metrics/index.js";
7
7
 
@@ -12,7 +12,7 @@ export async function pruneHistory(
12
12
  metrics: Metrics | null | undefined,
13
13
  finalizedEpoch: Epoch,
14
14
  currentEpoch: Epoch
15
- ): Promise<void> {
15
+ ): Promise<Slot> {
16
16
  const blockCutoffEpoch = Math.min(
17
17
  // set by config, with underflow protection
18
18
  Math.max(currentEpoch - config.MIN_EPOCHS_FOR_BLOCK_REQUESTS, 0),
@@ -20,18 +20,22 @@ export async function pruneHistory(
20
20
  finalizedEpoch
21
21
  );
22
22
  const blockCutoffSlot = computeStartSlotAtEpoch(blockCutoffEpoch);
23
+ // The latest archived state is the anchor on restart and can trail finalization by a few epochs
24
+ const lastArchivedStateSlot = (await db.stateArchive.lastKey()) ?? 0;
25
+ const stateCutoffSlot = Math.min(computeStartSlotAtEpoch(finalizedEpoch), lastArchivedStateSlot);
23
26
 
24
27
  logger.debug("Preparing to prune history", {
25
28
  currentEpoch,
26
29
  finalizedEpoch,
27
30
  blockCutoffEpoch,
31
+ stateCutoffSlot,
28
32
  });
29
33
 
30
34
  const step0 = metrics?.pruneHistory.fetchKeys.startTimer();
31
35
  const [blocks, envelopes, states] = await Promise.all([
32
36
  db.blockArchive.keys({gte: 0, lt: blockCutoffSlot}),
33
37
  db.executionPayloadEnvelopeArchive.keys({gte: 0, lt: blockCutoffSlot}),
34
- db.stateArchive.keys({gte: 0, lt: finalizedEpoch}),
38
+ db.stateArchive.keys({gte: 0, lt: stateCutoffSlot}),
35
39
  ]);
36
40
  step0?.();
37
41
 
@@ -40,12 +44,15 @@ export async function pruneHistory(
40
44
  blocksToPrune: blocks.length,
41
45
  envelopesToPrune: envelopes.length,
42
46
  statesToPrune: states.length,
47
+ blockSlots: prettyPrintIndices(blocks),
48
+ envelopeSlots: prettyPrintIndices(envelopes),
49
+ stateSlots: prettyPrintIndices(states),
43
50
  });
44
51
 
45
52
  const step1 = metrics?.pruneHistory.pruneKeys.startTimer();
46
53
  await Promise.all([
47
54
  // ->
48
- db.blockArchive.batchDelete(blocks),
55
+ db.blockArchive.batchDeleteRange(blocks),
49
56
  db.executionPayloadEnvelopeArchive.batchDelete(envelopes),
50
57
  db.stateArchive.batchDelete(states),
51
58
  ]);
@@ -56,4 +63,6 @@ export async function pruneHistory(
56
63
  });
57
64
 
58
65
  metrics?.pruneHistory.pruneCount.inc();
66
+
67
+ return blockCutoffSlot;
59
68
  }
@@ -12,6 +12,7 @@ import {isQueueErrorAborted} from "../../util/queue/index.js";
12
12
  import {BeaconChain} from "../chain.js";
13
13
  import {RegenCaller} from "../regen/interface.js";
14
14
  import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
15
+ import {PayloadEnvelopeInputSource} from "./payloadEnvelopeInput/index.js";
15
16
  import {ImportPayloadOpts} from "./types.js";
16
17
  import {
17
18
  verifyExecutionPayloadEnvelope,
@@ -172,6 +173,9 @@ export async function importExecutionPayload(
172
173
  }
173
174
 
174
175
  // 4a. Run EL and signature verification in parallel
176
+ const logCtx = {slot, root: blockRootHex, executionBlock: envelope.payload.blockNumber};
177
+ this.logger.debug("Call engine api newPayload", logCtx);
178
+ const verifyStartSec = Date.now() / 1000;
175
179
  const [execResult, signatureValid] = await Promise.all([
176
180
  this.executionEngine.notifyNewPayload(
177
181
  fork,
@@ -191,6 +195,8 @@ export async function importExecutionPayload(
191
195
  this.bls
192
196
  ),
193
197
  ]);
198
+ this.logger.debug("Receive engine api newPayload result", {...logCtx, status: execResult.status});
199
+ this.metrics?.engineNotifyNewPayloadResult.inc({result: execResult.status});
194
200
 
195
201
  // 4b. Check signature verification result
196
202
  if (!signatureValid) {
@@ -223,6 +229,14 @@ export async function importExecutionPayload(
223
229
  });
224
230
  }
225
231
 
232
+ const {source, seenTimestampSec} = payloadInput.getPayloadEnvelopeSource();
233
+ if (execResult.status === ExecutionPayloadStatus.VALID && source === PayloadEnvelopeInputSource.gossip) {
234
+ const nowSec = Date.now() / 1000;
235
+ this.metrics?.gossipExecutionPayloadEnvelope.executionPayload.recvToValidation.observe(nowSec - seenTimestampSec);
236
+ // same metric as pre-gloas, it tracks EL verification time regardless of fork
237
+ this.metrics?.gossipBlock.executionPayload.validationTime.observe(nowSec - verifyStartSec);
238
+ }
239
+
226
240
  // 5. Persist payload envelope to hot DB. Wait for write-queue space here to apply backpressure
227
241
  // on the import pipeline during sync, then perform the write asynchronously to avoid blocking.
228
242
  await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
@@ -104,7 +104,7 @@ export async function processBlocks(
104
104
  payloadEnvelopesToImport.delete(orphaned.slot);
105
105
  // never validated, drop it from the shared cache so it is not served to peers, by-root sync reloads the
106
106
  // entry from db if the payload is ever needed
107
- this.seenPayloadEnvelopeInputCache.prune(orphaned.payloadEnvelopeInput.blockRootHex);
107
+ this.seenPayloadEnvelopeInputCache.remove(orphaned.payloadEnvelopeInput.blockRootHex);
108
108
  }
109
109
  }
110
110
 
@@ -278,7 +278,7 @@ async function importPayloadEnvelopesOfKnownBlocks(
278
278
  this.forkChoice.isDescendant(blockRootHex, PayloadStatus.EMPTY, head.blockRoot, head.payloadStatus)
279
279
  ) {
280
280
  // never validated, see processBlocks()
281
- this.seenPayloadEnvelopeInputCache.prune(blockRootHex);
281
+ this.seenPayloadEnvelopeInputCache.remove(blockRootHex);
282
282
  orphaned.push({slot, payloadEnvelopeInput: payloadInput});
283
283
  continue;
284
284
  }