@lodestar/beacon-node 1.48.0-dev.f22c5ce63e → 1.48.0-rc.0

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 (296) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +4 -11
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/state/utils.js +14 -0
  6. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  7. package/lib/api/impl/config/index.d.ts.map +1 -1
  8. package/lib/api/impl/config/index.js +4 -1
  9. package/lib/api/impl/config/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 +39 -39
  12. package/lib/api/impl/validator/index.js.map +1 -1
  13. package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
  14. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  15. package/lib/chain/archiveStore/archiveStore.js +5 -1
  16. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  17. package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
  18. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -0
  19. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  20. package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
  21. package/lib/chain/archiveStore/historicalState/metrics.js +12 -1
  22. package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -0
  24. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
  26. package/lib/chain/archiveStore/historicalState/worker.js +4 -1
  27. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  28. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +9 -1
  29. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  30. package/lib/chain/archiveStore/utils/archiveBlocks.js +68 -38
  31. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  32. package/lib/chain/blocks/importBlock.d.ts +5 -1
  33. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  34. package/lib/chain/blocks/importBlock.js +12 -18
  35. package/lib/chain/blocks/importBlock.js.map +1 -1
  36. package/lib/chain/blocks/index.d.ts +8 -4
  37. package/lib/chain/blocks/index.d.ts.map +1 -1
  38. package/lib/chain/blocks/index.js +83 -17
  39. package/lib/chain/blocks/index.js.map +1 -1
  40. package/lib/chain/blocks/types.d.ts +8 -0
  41. package/lib/chain/blocks/types.d.ts.map +1 -1
  42. package/lib/chain/blocks/types.js.map +1 -1
  43. package/lib/chain/blocks/utils/chainSegment.d.ts +1 -1
  44. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  45. package/lib/chain/blocks/utils/chainSegment.js +26 -11
  46. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  47. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  48. package/lib/chain/blocks/writeBlockInputToDb.js +9 -16
  49. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  50. package/lib/chain/chain.d.ts +11 -5
  51. package/lib/chain/chain.d.ts.map +1 -1
  52. package/lib/chain/chain.js +129 -75
  53. package/lib/chain/chain.js.map +1 -1
  54. package/lib/chain/emitter.d.ts +1 -1
  55. package/lib/chain/emitter.js +1 -1
  56. package/lib/chain/errors/blockError.d.ts +19 -7
  57. package/lib/chain/errors/blockError.d.ts.map +1 -1
  58. package/lib/chain/errors/blockError.js +2 -2
  59. package/lib/chain/errors/blockError.js.map +1 -1
  60. package/lib/chain/errors/dataColumnSidecarError.d.ts +15 -2
  61. package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
  62. package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
  63. package/lib/chain/errors/executionPayloadBid.d.ts +4 -0
  64. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  65. package/lib/chain/errors/executionPayloadBid.js +1 -0
  66. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  67. package/lib/chain/errors/executionPayloadEnvelope.d.ts +10 -11
  68. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  69. package/lib/chain/errors/executionPayloadEnvelope.js +0 -2
  70. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  71. package/lib/chain/errors/gossipValidation.d.ts +2 -1
  72. package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
  73. package/lib/chain/errors/gossipValidation.js +1 -0
  74. package/lib/chain/errors/gossipValidation.js.map +1 -1
  75. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  76. package/lib/chain/forkChoice/index.js +2 -0
  77. package/lib/chain/forkChoice/index.js.map +1 -1
  78. package/lib/chain/interface.d.ts +4 -4
  79. package/lib/chain/interface.d.ts.map +1 -1
  80. package/lib/chain/lightClient/index.d.ts +3 -3
  81. package/lib/chain/lightClient/index.d.ts.map +1 -1
  82. package/lib/chain/lightClient/index.js +21 -23
  83. package/lib/chain/lightClient/index.js.map +1 -1
  84. package/lib/chain/lightClient/proofs.d.ts +2 -1
  85. package/lib/chain/lightClient/proofs.d.ts.map +1 -1
  86. package/lib/chain/lightClient/proofs.js +5 -1
  87. package/lib/chain/lightClient/proofs.js.map +1 -1
  88. package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
  89. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  90. package/lib/chain/prepareNextSlot.js +13 -13
  91. package/lib/chain/prepareNextSlot.js.map +1 -1
  92. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  93. package/lib/chain/produceBlock/produceBlockBody.js +46 -64
  94. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  95. package/lib/chain/validation/block.d.ts.map +1 -1
  96. package/lib/chain/validation/block.js +35 -54
  97. package/lib/chain/validation/block.js.map +1 -1
  98. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  99. package/lib/chain/validation/dataColumnSidecar.js +38 -13
  100. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  101. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  102. package/lib/chain/validation/executionPayloadBid.js +56 -40
  103. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  104. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  105. package/lib/chain/validation/executionPayloadEnvelope.js +10 -29
  106. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  107. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  108. package/lib/chain/validation/payloadAttestationMessage.js +5 -6
  109. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  110. package/lib/chain/validatorMonitor.d.ts +7 -1
  111. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  112. package/lib/chain/validatorMonitor.js +22 -5
  113. package/lib/chain/validatorMonitor.js.map +1 -1
  114. package/lib/db/beacon.d.ts +14 -5
  115. package/lib/db/beacon.d.ts.map +1 -1
  116. package/lib/db/beacon.js +17 -3
  117. package/lib/db/beacon.js.map +1 -1
  118. package/lib/db/dataColumnStore.d.ts +39 -0
  119. package/lib/db/dataColumnStore.d.ts.map +1 -0
  120. package/lib/db/dataColumnStore.js +81 -0
  121. package/lib/db/dataColumnStore.js.map +1 -0
  122. package/lib/db/flatFileStore/atomicWrite.d.ts +8 -0
  123. package/lib/db/flatFileStore/atomicWrite.d.ts.map +1 -0
  124. package/lib/db/flatFileStore/atomicWrite.js +61 -0
  125. package/lib/db/flatFileStore/atomicWrite.js.map +1 -0
  126. package/lib/db/flatFileStore/dcolFormat.d.ts +90 -0
  127. package/lib/db/flatFileStore/dcolFormat.d.ts.map +1 -0
  128. package/lib/db/flatFileStore/dcolFormat.js +286 -0
  129. package/lib/db/flatFileStore/dcolFormat.js.map +1 -0
  130. package/lib/db/flatFileStore/errors.d.ts +82 -0
  131. package/lib/db/flatFileStore/errors.d.ts.map +1 -0
  132. package/lib/db/flatFileStore/errors.js +32 -0
  133. package/lib/db/flatFileStore/errors.js.map +1 -0
  134. package/lib/db/flatFileStore/flatFileStore.d.ts +41 -0
  135. package/lib/db/flatFileStore/flatFileStore.d.ts.map +1 -0
  136. package/lib/db/flatFileStore/flatFileStore.js +251 -0
  137. package/lib/db/flatFileStore/flatFileStore.js.map +1 -0
  138. package/lib/db/flatFileStore/index.d.ts +4 -0
  139. package/lib/db/flatFileStore/index.d.ts.map +1 -0
  140. package/lib/db/flatFileStore/index.js +2 -0
  141. package/lib/db/flatFileStore/index.js.map +1 -0
  142. package/lib/db/flatFileStore/interface.d.ts +25 -0
  143. package/lib/db/flatFileStore/interface.d.ts.map +1 -0
  144. package/lib/db/flatFileStore/interface.js +2 -0
  145. package/lib/db/flatFileStore/interface.js.map +1 -0
  146. package/lib/db/flatFileStore/metrics.d.ts +24 -0
  147. package/lib/db/flatFileStore/metrics.d.ts.map +1 -0
  148. package/lib/db/flatFileStore/metrics.js +25 -0
  149. package/lib/db/flatFileStore/metrics.js.map +1 -0
  150. package/lib/db/flatFileStore/path.d.ts +9 -0
  151. package/lib/db/flatFileStore/path.d.ts.map +1 -0
  152. package/lib/db/flatFileStore/path.js +21 -0
  153. package/lib/db/flatFileStore/path.js.map +1 -0
  154. package/lib/db/flatFileStore/slotIndex.d.ts +14 -0
  155. package/lib/db/flatFileStore/slotIndex.d.ts.map +1 -0
  156. package/lib/db/flatFileStore/slotIndex.js +46 -0
  157. package/lib/db/flatFileStore/slotIndex.js.map +1 -0
  158. package/lib/db/flatFileStore/snappy.d.ts +3 -0
  159. package/lib/db/flatFileStore/snappy.d.ts.map +1 -0
  160. package/lib/db/flatFileStore/snappy.js +12 -0
  161. package/lib/db/flatFileStore/snappy.js.map +1 -0
  162. package/lib/db/index.d.ts +1 -0
  163. package/lib/db/index.d.ts.map +1 -1
  164. package/lib/db/interface.d.ts +8 -1
  165. package/lib/db/interface.d.ts.map +1 -1
  166. package/lib/db/repositories/blockArchive.d.ts +8 -1
  167. package/lib/db/repositories/blockArchive.d.ts.map +1 -1
  168. package/lib/db/repositories/blockArchive.js +65 -28
  169. package/lib/db/repositories/blockArchive.js.map +1 -1
  170. package/lib/db/repositories/blockArchiveIndex.d.ts +1 -2
  171. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  172. package/lib/db/repositories/blockArchiveIndex.js +3 -7
  173. package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
  174. package/lib/execution/builder/validateBid.d.ts.map +1 -1
  175. package/lib/execution/builder/validateBid.js +8 -5
  176. package/lib/execution/builder/validateBid.js.map +1 -1
  177. package/lib/execution/engine/mock.d.ts.map +1 -1
  178. package/lib/execution/engine/mock.js +4 -1
  179. package/lib/execution/engine/mock.js.map +1 -1
  180. package/lib/metrics/metrics/lodestar.d.ts +22 -3
  181. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  182. package/lib/metrics/metrics/lodestar.js +60 -6
  183. package/lib/metrics/metrics/lodestar.js.map +1 -1
  184. package/lib/monitoring/clientStats.js +1 -1
  185. package/lib/monitoring/clientStats.js.map +1 -1
  186. package/lib/network/gossip/encoding.d.ts.map +1 -1
  187. package/lib/network/gossip/encoding.js +0 -7
  188. package/lib/network/gossip/encoding.js.map +1 -1
  189. package/lib/network/gossip/topic.d.ts +2 -1
  190. package/lib/network/gossip/topic.d.ts.map +1 -1
  191. package/lib/network/gossip/topic.js +4 -20
  192. package/lib/network/gossip/topic.js.map +1 -1
  193. package/lib/network/network.js +2 -2
  194. package/lib/network/network.js.map +1 -1
  195. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  196. package/lib/network/processor/gossipHandlers.js +388 -285
  197. package/lib/network/processor/gossipHandlers.js.map +1 -1
  198. package/lib/network/processor/index.d.ts +49 -3
  199. package/lib/network/processor/index.d.ts.map +1 -1
  200. package/lib/network/processor/index.js +254 -114
  201. package/lib/network/processor/index.js.map +1 -1
  202. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  203. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +112 -91
  204. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  205. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts.map +1 -1
  206. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +2 -0
  207. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  208. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  209. package/lib/network/reqresp/protocols.js +6 -22
  210. package/lib/network/reqresp/protocols.js.map +1 -1
  211. package/lib/network/reqresp/rateLimit.js +2 -1
  212. package/lib/network/reqresp/rateLimit.js.map +1 -1
  213. package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts +2 -1
  214. package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
  215. package/lib/network/reqresp/utils/dataColumnResponseValidation.js +14 -9
  216. package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
  217. package/lib/node/nodejs.d.ts +2 -1
  218. package/lib/node/nodejs.d.ts.map +1 -1
  219. package/lib/node/nodejs.js +4 -2
  220. package/lib/node/nodejs.js.map +1 -1
  221. package/lib/sync/range/range.d.ts.map +1 -1
  222. package/lib/sync/range/range.js +24 -1
  223. package/lib/sync/range/range.js.map +1 -1
  224. package/lib/util/sszBytes.d.ts +6 -0
  225. package/lib/util/sszBytes.d.ts.map +1 -1
  226. package/lib/util/sszBytes.js +1 -1
  227. package/lib/util/sszBytes.js.map +1 -1
  228. package/package.json +18 -19
  229. package/src/api/impl/beacon/blocks/index.ts +8 -14
  230. package/src/api/impl/beacon/state/utils.ts +15 -0
  231. package/src/api/impl/config/index.ts +4 -1
  232. package/src/api/impl/validator/index.ts +44 -43
  233. package/src/chain/archiveStore/archiveStore.ts +12 -1
  234. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -0
  235. package/src/chain/archiveStore/historicalState/metrics.ts +14 -1
  236. package/src/chain/archiveStore/historicalState/types.ts +2 -0
  237. package/src/chain/archiveStore/historicalState/worker.ts +4 -1
  238. package/src/chain/archiveStore/utils/archiveBlocks.ts +73 -42
  239. package/src/chain/blocks/importBlock.ts +25 -20
  240. package/src/chain/blocks/index.ts +120 -23
  241. package/src/chain/blocks/types.ts +9 -0
  242. package/src/chain/blocks/utils/chainSegment.ts +26 -12
  243. package/src/chain/blocks/writeBlockInputToDb.ts +10 -17
  244. package/src/chain/chain.ts +153 -84
  245. package/src/chain/emitter.ts +1 -1
  246. package/src/chain/errors/blockError.ts +22 -10
  247. package/src/chain/errors/dataColumnSidecarError.ts +24 -8
  248. package/src/chain/errors/executionPayloadBid.ts +2 -0
  249. package/src/chain/errors/executionPayloadEnvelope.ts +14 -11
  250. package/src/chain/errors/gossipValidation.ts +1 -0
  251. package/src/chain/forkChoice/index.ts +2 -0
  252. package/src/chain/interface.ts +4 -4
  253. package/src/chain/lightClient/index.ts +32 -36
  254. package/src/chain/lightClient/proofs.ts +10 -0
  255. package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
  256. package/src/chain/prepareNextSlot.ts +16 -16
  257. package/src/chain/produceBlock/produceBlockBody.ts +50 -71
  258. package/src/chain/validation/block.ts +35 -70
  259. package/src/chain/validation/dataColumnSidecar.ts +47 -14
  260. package/src/chain/validation/executionPayloadBid.ts +62 -44
  261. package/src/chain/validation/executionPayloadEnvelope.ts +10 -37
  262. package/src/chain/validation/payloadAttestationMessage.ts +8 -9
  263. package/src/chain/validatorMonitor.ts +24 -7
  264. package/src/db/beacon.ts +33 -6
  265. package/src/db/dataColumnStore.ts +113 -0
  266. package/src/db/flatFileStore/atomicWrite.ts +65 -0
  267. package/src/db/flatFileStore/dcolFormat.ts +389 -0
  268. package/src/db/flatFileStore/errors.ts +53 -0
  269. package/src/db/flatFileStore/flatFileStore.ts +310 -0
  270. package/src/db/flatFileStore/index.ts +3 -0
  271. package/src/db/flatFileStore/interface.ts +21 -0
  272. package/src/db/flatFileStore/metrics.ts +48 -0
  273. package/src/db/flatFileStore/path.ts +32 -0
  274. package/src/db/flatFileStore/slotIndex.ts +56 -0
  275. package/src/db/flatFileStore/snappy.ts +14 -0
  276. package/src/db/index.ts +1 -0
  277. package/src/db/interface.ts +9 -1
  278. package/src/db/repositories/blockArchive.ts +89 -30
  279. package/src/db/repositories/blockArchiveIndex.ts +4 -9
  280. package/src/execution/builder/validateBid.ts +10 -6
  281. package/src/execution/engine/mock.ts +4 -1
  282. package/src/metrics/metrics/lodestar.ts +63 -6
  283. package/src/monitoring/clientStats.ts +1 -1
  284. package/src/network/gossip/encoding.ts +0 -7
  285. package/src/network/gossip/topic.ts +3 -25
  286. package/src/network/network.ts +2 -2
  287. package/src/network/processor/gossipHandlers.ts +500 -355
  288. package/src/network/processor/index.ts +287 -165
  289. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +139 -105
  290. package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +2 -0
  291. package/src/network/reqresp/protocols.ts +7 -24
  292. package/src/network/reqresp/rateLimit.ts +2 -1
  293. package/src/network/reqresp/utils/dataColumnResponseValidation.ts +15 -7
  294. package/src/node/nodejs.ts +6 -1
  295. package/src/sync/range/range.ts +23 -1
  296. package/src/util/sszBytes.ts +1 -1
@@ -82,7 +82,7 @@ import {IBlockInput, isBlockInputBlobs, isBlockInputColumns} from "./blocks/bloc
82
82
  import {BlockProcessor, ImportBlockOpts} from "./blocks/index.js";
83
83
  import {PayloadEnvelopeInputSource} from "./blocks/payloadEnvelopeInput/index.js";
84
84
  import {PayloadEnvelopeProcessor} from "./blocks/payloadEnvelopeProcessor.js";
85
- import {ImportPayloadOpts} from "./blocks/types.js";
85
+ import {ImportPayloadOpts, ProcessBlocksResult} from "./blocks/types.js";
86
86
  import {persistBlockInput} from "./blocks/writeBlockInputToDb.js";
87
87
  import {persistPayloadEnvelopeInput} from "./blocks/writePayloadEnvelopeInputToDb.js";
88
88
  import {BlsMultiThreadWorkerPool, BlsSingleThreadVerifier, IBlsVerifier} from "./bls/index.js";
@@ -268,6 +268,7 @@ export class BeaconChain implements IBeaconChain {
268
268
  db,
269
269
  dbName,
270
270
  dataDir,
271
+ dataColumnDir,
271
272
  logger,
272
273
  processShutdownCallback,
273
274
  clock,
@@ -285,6 +286,7 @@ export class BeaconChain implements IBeaconChain {
285
286
  db: IBeaconDb;
286
287
  dbName: string;
287
288
  dataDir: string;
289
+ dataColumnDir?: string;
288
290
  logger: Logger;
289
291
  processShutdownCallback: ProcessShutdownCallback;
290
292
  /** Used for testing to supply fake clock */
@@ -505,7 +507,12 @@ export class BeaconChain implements IBeaconChain {
505
507
 
506
508
  this.archiveStore = new ArchiveStore(
507
509
  {db, chain: this, logger: logger as LoggerNode, metrics},
508
- {...opts, dbName, anchorState: {finalizedCheckpoint: anchorState.finalizedCheckpoint}},
510
+ {
511
+ ...opts,
512
+ dbName,
513
+ dataColumnDir: dataColumnDir ?? path.join(dataDir, "data_columns"),
514
+ anchorState: {finalizedCheckpoint: anchorState.finalizedCheckpoint},
515
+ },
509
516
  signal
510
517
  );
511
518
 
@@ -969,12 +976,15 @@ export class BeaconChain implements IBeaconChain {
969
976
 
970
977
  async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecar[]> {
971
978
  const fork = this.config.getForkName(blockSlot);
979
+ const sidecarsByIndex = new Map<number, DataColumnSidecar>();
972
980
 
973
981
  if (isForkPostGloas(fork)) {
974
982
  // After gloas, columns are tracked in PayloadEnvelopeInput
975
983
  const payloadInput = this.seenPayloadEnvelopeInputCache.get(blockRootHex);
976
984
  if (payloadInput) {
977
- return payloadInput.getAllColumns();
985
+ for (const sidecar of payloadInput.getAllColumns()) {
986
+ sidecarsByIndex.set(sidecar.index, sidecar);
987
+ }
978
988
  }
979
989
  } else {
980
990
  // Before gloas, columns are tracked in BlockInput
@@ -983,16 +993,17 @@ export class BeaconChain implements IBeaconChain {
983
993
  if (!isBlockInputColumns(blockInput)) {
984
994
  throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
985
995
  }
986
- return blockInput.getAllColumns();
996
+ for (const sidecar of blockInput.getAllColumns()) {
997
+ sidecarsByIndex.set(sidecar.index, sidecar);
998
+ }
987
999
  }
988
1000
  }
989
1001
 
990
- const sidecarsUnfinalized = await this.db.dataColumnSidecar.values(fromHex(blockRootHex));
991
- if (sidecarsUnfinalized.length > 0) {
992
- return sidecarsUnfinalized;
1002
+ for (const sidecar of await this.db.dataColumns.getAll({slot: blockSlot, blockRoot: blockRootHex})) {
1003
+ if (!sidecarsByIndex.has(sidecar.index)) sidecarsByIndex.set(sidecar.index, sidecar);
993
1004
  }
994
- const sidecarsFinalized = await this.db.dataColumnSidecarArchive.values(blockSlot);
995
- return sidecarsFinalized;
1005
+
1006
+ return [...sidecarsByIndex.values()].sort((a, b) => a.index - b.index);
996
1007
  }
997
1008
 
998
1009
  async getSerializedDataColumnSidecars(
@@ -1001,22 +1012,25 @@ export class BeaconChain implements IBeaconChain {
1001
1012
  indices: number[]
1002
1013
  ): Promise<(Uint8Array | undefined)[]> {
1003
1014
  const fork = this.config.getForkName(blockSlot);
1015
+ const dataColumnSidecars: (Uint8Array | undefined)[] = indices.map(() => undefined);
1004
1016
 
1005
1017
  if (isForkPostGloas(fork)) {
1006
1018
  // After gloas, columns are tracked in PayloadEnvelopeInput
1007
1019
  const payloadInput = this.seenPayloadEnvelopeInputCache.get(blockRootHex);
1008
1020
  if (payloadInput) {
1009
- return indices.map((index) => {
1021
+ for (let i = 0; i < indices.length; i++) {
1022
+ const index = indices[i];
1010
1023
  const sidecar = payloadInput.getColumn(index);
1011
1024
  if (!sidecar) {
1012
- return undefined;
1025
+ continue;
1013
1026
  }
1014
1027
  const serialized = this.serializedCache.get(sidecar);
1015
1028
  if (serialized) {
1016
- return serialized;
1029
+ dataColumnSidecars[i] = serialized;
1030
+ } else {
1031
+ dataColumnSidecars[i] = sszTypesFor(fork as ForkPostGloas).DataColumnSidecar.serialize(sidecar);
1017
1032
  }
1018
- return sszTypesFor(fork as ForkPostGloas).DataColumnSidecar.serialize(sidecar);
1019
- });
1033
+ }
1020
1034
  }
1021
1035
  } else {
1022
1036
  // Before gloas, columns are tracked in BlockInput
@@ -1025,26 +1039,42 @@ export class BeaconChain implements IBeaconChain {
1025
1039
  if (!isBlockInputColumns(blockInput)) {
1026
1040
  throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
1027
1041
  }
1028
- return indices.map((index) => {
1042
+ for (let i = 0; i < indices.length; i++) {
1043
+ const index = indices[i];
1029
1044
  const sidecar = blockInput.getColumn(index);
1030
1045
  if (!sidecar) {
1031
- return undefined;
1046
+ continue;
1032
1047
  }
1033
1048
  const serialized = this.serializedCache.get(sidecar);
1034
1049
  if (serialized) {
1035
- return serialized;
1050
+ dataColumnSidecars[i] = serialized;
1051
+ } else {
1052
+ dataColumnSidecars[i] = sszTypesFor(blockInput.forkName as ForkPostFulu).DataColumnSidecar.serialize(
1053
+ sidecar
1054
+ );
1036
1055
  }
1037
- return sszTypesFor(blockInput.forkName as ForkPostFulu).DataColumnSidecar.serialize(sidecar);
1038
- });
1056
+ }
1039
1057
  }
1040
1058
  }
1041
1059
 
1042
- const sidecarsUnfinalized = await this.db.dataColumnSidecar.getManyBinary(fromHex(blockRootHex), indices);
1043
- if (sidecarsUnfinalized.some((sidecar) => sidecar != null)) {
1044
- return sidecarsUnfinalized;
1060
+ const missingPositions = dataColumnSidecars
1061
+ .map((sidecar, position) => (sidecar === undefined ? position : -1))
1062
+ .filter((position) => position !== -1);
1063
+
1064
+ if (missingPositions.length > 0) {
1065
+ const persistedSidecars = await this.db.dataColumns.getManyBinary(
1066
+ {slot: blockSlot, blockRoot: blockRootHex},
1067
+ missingPositions.map((position) => indices[position])
1068
+ );
1069
+ for (let i = 0; i < missingPositions.length; i++) {
1070
+ const sidecar = persistedSidecars[i];
1071
+ if (sidecar !== undefined) {
1072
+ dataColumnSidecars[missingPositions[i]] = sidecar;
1073
+ }
1074
+ }
1045
1075
  }
1046
- const sidecarsFinalized = await this.db.dataColumnSidecarArchive.getManyBinary(blockSlot, indices);
1047
- return sidecarsFinalized;
1076
+
1077
+ return dataColumnSidecars;
1048
1078
  }
1049
1079
 
1050
1080
  async produceCommonBlockBody(blockAttributes: BlockAttributes): Promise<CommonBlockBody> {
@@ -1167,15 +1197,15 @@ export class BeaconChain implements IBeaconChain {
1167
1197
  }
1168
1198
 
1169
1199
  async processBlock(block: IBlockInput, opts?: ImportBlockOpts): Promise<void> {
1170
- return this.blockProcessor.processBlocksJob([block], null, opts);
1200
+ await this.blockProcessor.processBlocksJob([block], null, opts);
1171
1201
  }
1172
1202
 
1173
1203
  async processChainSegment(
1174
1204
  blocks: IBlockInput[],
1175
1205
  payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
1176
1206
  opts?: ImportBlockOpts
1177
- ): Promise<void> {
1178
- await this.blockProcessor.processBlocksJob(blocks, payloadEnvelopes, opts);
1207
+ ): Promise<ProcessBlocksResult> {
1208
+ return this.blockProcessor.processBlocksJob(blocks, payloadEnvelopes, opts);
1179
1209
  }
1180
1210
 
1181
1211
  async processExecutionPayload(payloadInput: PayloadEnvelopeInput, opts?: ImportPayloadOpts): Promise<void> {
@@ -1271,59 +1301,65 @@ export class BeaconChain implements IBeaconChain {
1271
1301
  try {
1272
1302
  const prevHead = this.forkChoice.getHead();
1273
1303
  const head = this.forkChoice.updateAndGetHead({mode: UpdateHeadOpt.GetCanonicalHead}).head;
1304
+ this.emitHeadEvents(prevHead, head);
1305
+ return head;
1306
+ } catch (e) {
1307
+ this.metrics?.forkChoice.errors.inc({entrypoint: UpdateHeadOpt.GetCanonicalHead});
1308
+ throw e;
1309
+ } finally {
1310
+ timer?.();
1311
+ }
1312
+ }
1274
1313
 
1275
- const headRootChanged = head.blockRoot !== prevHead.blockRoot;
1276
-
1277
- if (!headRootChanged && prevHead.payloadStatus === head.payloadStatus) {
1278
- return head;
1279
- }
1314
+ /**
1315
+ * Emit `head` and `head_v2` when the fork choice head differs between two observations. Every caller that
1316
+ * can move the head, `updateAndGetHead()` and `updateTime()`, must capture the head before and pass both.
1317
+ */
1318
+ private emitHeadEvents(prevHead: ProtoBlock, head: ProtoBlock): void {
1319
+ const headRootChanged = head.blockRoot !== prevHead.blockRoot;
1280
1320
 
1281
- try {
1282
- const previousDutyDependentRoot = this.forkChoice.getDependentRoot(head, EpochDifference.previous);
1283
- const currentDutyDependentRoot = this.forkChoice.getDependentRoot(head, EpochDifference.current);
1284
- const epochTransition = computeStartSlotAtEpoch(computeEpochAtSlot(head.slot)) === head.slot;
1285
- const executionOptimistic = isOptimisticBlock(head);
1286
-
1287
- if (headRootChanged) {
1288
- this.emitter.emit(routes.events.EventType.head, {
1289
- block: head.blockRoot,
1290
- epochTransition,
1291
- slot: head.slot,
1292
- state: head.stateRoot,
1293
- previousDutyDependentRoot,
1294
- currentDutyDependentRoot,
1295
- executionOptimistic,
1296
- });
1297
- }
1321
+ if (!headRootChanged && prevHead.payloadStatus === head.payloadStatus) {
1322
+ return;
1323
+ }
1298
1324
 
1299
- this.emitter.emit(routes.events.EventType.headV2, {
1300
- version: this.config.getForkName(head.slot),
1301
- data: {
1302
- slot: head.slot,
1303
- block: head.blockRoot,
1304
- state: head.stateRoot,
1305
- payloadStatus: head.payloadStatus === PayloadStatus.FULL ? "full" : "empty",
1306
- epochTransition,
1307
- currentEpochDependentRoot: previousDutyDependentRoot,
1308
- nextEpochDependentRoot: currentDutyDependentRoot,
1309
- executionOptimistic,
1310
- },
1325
+ try {
1326
+ const previousDutyDependentRoot = this.forkChoice.getDependentRoot(head, EpochDifference.previous);
1327
+ const currentDutyDependentRoot = this.forkChoice.getDependentRoot(head, EpochDifference.current);
1328
+ const epochTransition = computeStartSlotAtEpoch(computeEpochAtSlot(head.slot)) === head.slot;
1329
+ const executionOptimistic = isOptimisticBlock(head);
1330
+
1331
+ if (headRootChanged) {
1332
+ this.emitter.emit(routes.events.EventType.head, {
1333
+ block: head.blockRoot,
1334
+ epochTransition,
1335
+ slot: head.slot,
1336
+ state: head.stateRoot,
1337
+ previousDutyDependentRoot,
1338
+ currentDutyDependentRoot,
1339
+ executionOptimistic,
1311
1340
  });
1312
- } catch (e) {
1313
- // getDependentRoot() may fail with error: "No block for root" as we can see in holesky non-finality issue
1314
- this.logger.debug(
1315
- "Error emitting head/head_v2 event",
1316
- {slot: head.slot, root: head.blockRoot, headRootChanged},
1317
- e as Error
1318
- );
1319
1341
  }
1320
1342
 
1321
- return head;
1343
+ this.emitter.emit(routes.events.EventType.headV2, {
1344
+ version: this.config.getForkName(head.slot),
1345
+ data: {
1346
+ slot: head.slot,
1347
+ block: head.blockRoot,
1348
+ state: head.stateRoot,
1349
+ payloadStatus: head.payloadStatus === PayloadStatus.FULL ? "full" : "empty",
1350
+ epochTransition,
1351
+ currentEpochDependentRoot: previousDutyDependentRoot,
1352
+ nextEpochDependentRoot: currentDutyDependentRoot,
1353
+ executionOptimistic,
1354
+ },
1355
+ });
1322
1356
  } catch (e) {
1323
- this.metrics?.forkChoice.errors.inc({entrypoint: UpdateHeadOpt.GetCanonicalHead});
1324
- throw e;
1325
- } finally {
1326
- timer?.();
1357
+ // getDependentRoot() may fail with error: "No block for root" as we can see in holesky non-finality issue
1358
+ this.logger.debug(
1359
+ "Error emitting head/head_v2 event",
1360
+ {slot: head.slot, root: head.blockRoot, headRootChanged},
1361
+ e as Error
1362
+ );
1327
1363
  }
1328
1364
  }
1329
1365
 
@@ -1381,10 +1417,15 @@ export class BeaconChain implements IBeaconChain {
1381
1417
  const slot = data.slot;
1382
1418
  if (isBlindedBeaconBlock(data)) {
1383
1419
  const sszType = this.config.getPostBellatrixForkTypes(slot).BlindedBeaconBlock;
1384
- void this.persistSszObject("BlindedBeaconBlock", sszType.serialize(data), sszType.hashTreeRoot(data), suffix);
1420
+ void this.persistSszObject(
1421
+ "BlindedBeaconBlock",
1422
+ sszType.serialize(data),
1423
+ toRootHex(sszType.hashTreeRoot(data)),
1424
+ suffix
1425
+ );
1385
1426
  } else {
1386
1427
  const sszType = this.config.getForkTypes(slot).BeaconBlock;
1387
- void this.persistSszObject("BeaconBlock", sszType.serialize(data), sszType.hashTreeRoot(data), suffix);
1428
+ void this.persistSszObject("BeaconBlock", sszType.serialize(data), toRootHex(sszType.hashTreeRoot(data)), suffix);
1388
1429
  }
1389
1430
  }
1390
1431
 
@@ -1405,33 +1446,39 @@ export class BeaconChain implements IBeaconChain {
1405
1446
  this.persistSszObject(
1406
1447
  `SignedBeaconBlock_slot_${blockSlot}`,
1407
1448
  blockType.serialize(block),
1408
- blockType.hashTreeRoot(block),
1449
+ toRootHex(this.config.getForkTypes(blockSlot).BeaconBlock.hashTreeRoot(block.message)),
1409
1450
  `${logStr}_block`
1410
1451
  ),
1411
1452
  this.persistSszObject(
1412
1453
  `preState_slot_${preState.slot}_BeaconState`,
1413
1454
  preState.serialize(),
1414
- preState.hashTreeRoot(),
1455
+ toRootHex(preState.hashTreeRoot()),
1415
1456
  `${logStr}_pre_state`
1416
1457
  ),
1417
1458
  this.persistSszObject(
1418
1459
  `postState_slot_${postState.slot}_BeaconState`,
1419
1460
  postState.serialize(),
1420
- postState.hashTreeRoot(),
1461
+ toRootHex(postStateRoot),
1421
1462
  `${logStr}_post_state`
1422
1463
  ),
1423
1464
  ]);
1424
1465
  }
1425
1466
 
1426
- persistInvalidSszValue<T>(type: Type<T>, sszObject: T, suffix?: string): void {
1467
+ persistInvalidSszValue<T>(type: Type<T>, sszObject: T, suffix?: string, rootHex?: RootHex): void {
1427
1468
  if (this.opts.persistInvalidSszObjects) {
1428
- void this.persistSszObject(type.typeName, type.serialize(sszObject), type.hashTreeRoot(sszObject), suffix);
1469
+ void this.persistSszObject(
1470
+ type.typeName,
1471
+ type.serialize(sszObject),
1472
+ // in SignedBeaconBlock case, we want to use BeaconBlock root instead
1473
+ rootHex ?? toRootHex(type.hashTreeRoot(sszObject)),
1474
+ suffix
1475
+ );
1429
1476
  }
1430
1477
  }
1431
1478
 
1432
- persistInvalidSszBytes(typeName: string, sszBytes: Uint8Array, suffix?: string): void {
1479
+ persistInvalidSszBytes(typeName: string, sszBytes: Uint8Array, rootHex: RootHex, suffix?: string): void {
1433
1480
  if (this.opts.persistInvalidSszObjects) {
1434
- void this.persistSszObject(typeName, sszBytes, sszBytes, suffix);
1481
+ void this.persistSszObject(typeName, sszBytes, rootHex, suffix);
1435
1482
  }
1436
1483
  }
1437
1484
 
@@ -1562,14 +1609,14 @@ export class BeaconChain implements IBeaconChain {
1562
1609
  return {state: blockState, stateId: "block_state_any_epoch", shouldWarn: true};
1563
1610
  }
1564
1611
 
1565
- private async persistSszObject(prefix: string, bytes: Uint8Array, root: Uint8Array, logStr?: string): Promise<void> {
1612
+ private async persistSszObject(prefix: string, bytes: Uint8Array, rootHex: RootHex, logStr?: string): Promise<void> {
1566
1613
  const now = new Date();
1567
1614
  // yyyy-MM-dd
1568
1615
  const dateStr = now.toISOString().split("T")[0];
1569
1616
 
1570
1617
  // by default store to lodestar_archive of current dir
1571
1618
  const dirpath = path.join(this.opts.persistInvalidSszObjectsDir ?? "invalid_ssz_objects", dateStr);
1572
- const filepath = path.join(dirpath, `${prefix}_${toRootHex(root)}.ssz`);
1619
+ const filepath = path.join(dirpath, `${prefix}_${rootHex}.ssz`);
1573
1620
 
1574
1621
  await ensureDir(dirpath);
1575
1622
 
@@ -1612,7 +1659,10 @@ export class BeaconChain implements IBeaconChain {
1612
1659
  this.processShutdownCallback(this.forkChoice.irrecoverableError);
1613
1660
  }
1614
1661
 
1662
+ // updateTime() recomputes the head on epoch-boundary checkpoint pull-up and under fast confirmation
1663
+ const prevHead = this.forkChoice.getHead();
1615
1664
  this.forkChoice.updateTime(slot);
1665
+ this.emitHeadEvents(prevHead, this.forkChoice.getHead());
1616
1666
  this.metrics?.clockSlot.set(slot);
1617
1667
 
1618
1668
  this.attestationPool.prune(slot);
@@ -1670,6 +1720,25 @@ export class BeaconChain implements IBeaconChain {
1670
1720
 
1671
1721
  private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithHex): Promise<void> {
1672
1722
  this.logger.verbose("Fork choice finalized", {epoch: cp.epoch, root: cp.rootHex});
1723
+ this.metrics?.finalizedEpoch.set(cp.epoch);
1724
+ const finalizedBlock = this.forkChoice.getBlockHexDefaultStatus(cp.rootHex);
1725
+ if (finalizedBlock) {
1726
+ // The callback runs synchronously inside fork choice checkpoint updates, defer writing to subscribers
1727
+ callInNextEventLoop(() => {
1728
+ this.emitter.emit(routes.events.EventType.finalizedCheckpoint, {
1729
+ block: cp.rootHex,
1730
+ epoch: cp.epoch,
1731
+ state: finalizedBlock.stateRoot,
1732
+ executionOptimistic: isOptimisticBlock(finalizedBlock),
1733
+ });
1734
+ });
1735
+ } else {
1736
+ this.logger.debug("Finalized block not found in fork choice, skip finalized_checkpoint event", {
1737
+ epoch: cp.epoch,
1738
+ root: cp.rootHex,
1739
+ });
1740
+ }
1741
+
1673
1742
  const finalizedSlot = computeStartSlotAtEpoch(cp.epoch);
1674
1743
  this.seenBlockProposers.prune(finalizedSlot);
1675
1744
 
@@ -33,7 +33,7 @@ export enum ChainEvent {
33
33
  /**
34
34
  * This event signals that the fork choice store has been updated.
35
35
  *
36
- * This event is guaranteed to be triggered whenever the fork choice justified checkpoint is updated. This is in response to a newly processed block.
36
+ * This event is guaranteed to be triggered whenever the fork choice finalized checkpoint is updated. This is either in response to a newly processed block or a new clock tick.
37
37
  */
38
38
  forkChoiceFinalized = "forkChoice:finalized",
39
39
  /**
@@ -78,8 +78,8 @@ export enum BlockErrorCode {
78
78
  TOO_MANY_KZG_COMMITMENTS = "BLOCK_ERROR_TOO_MANY_KZG_COMMITMENTS",
79
79
  /** Bid parent block root does not match block parent root */
80
80
  BID_PARENT_ROOT_MISMATCH = "BLOCK_ERROR_BID_PARENT_ROOT_MISMATCH",
81
- /** A block body operation or parent execution request list exceeds its per-block limit */
82
- TOO_MANY_BLOCK_OPERATIONS = "BLOCK_ERROR_TOO_MANY_BLOCK_OPERATIONS",
81
+ /** A block contains deposits where none are allowed */
82
+ NON_ZERO_DEPOSITS = "BLOCK_ERROR_NON_ZERO_DEPOSITS",
83
83
  /** The parent block's execution payload has been verified as invalid */
84
84
  PARENT_EXECUTION_INVALID = "BLOCK_ERROR_PARENT_EXECUTION_INVALID",
85
85
  /**
@@ -120,9 +120,9 @@ export type BlockErrorType =
120
120
  | {code: BlockErrorCode.ALREADY_KNOWN; root: RootHex}
121
121
  | {code: BlockErrorCode.REPEAT_PROPOSAL; proposerIndex: ValidatorIndex; root: RootHex}
122
122
  | {code: BlockErrorCode.BLOCK_SLOT_LIMIT_REACHED}
123
- | {code: BlockErrorCode.INCORRECT_PROPOSER; proposerIndex: ValidatorIndex}
124
- | {code: BlockErrorCode.PROPOSAL_SIGNATURE_INVALID; blockSlot: Slot}
125
- | {code: BlockErrorCode.UNKNOWN_PROPOSER; proposerIndex: ValidatorIndex}
123
+ | {code: BlockErrorCode.INCORRECT_PROPOSER; slot: Slot; root: RootHex; proposerIndex: ValidatorIndex}
124
+ | {code: BlockErrorCode.PROPOSAL_SIGNATURE_INVALID; slot: Slot; root: RootHex}
125
+ | {code: BlockErrorCode.UNKNOWN_PROPOSER; slot: Slot; root: RootHex; proposerIndex: ValidatorIndex}
126
126
  | {code: BlockErrorCode.INVALID_SIGNATURE; state: IBeaconStateView}
127
127
  | {
128
128
  code: BlockErrorCode.INVALID_STATE_ROOT;
@@ -132,7 +132,7 @@ export type BlockErrorType =
132
132
  postState: IBeaconStateView;
133
133
  }
134
134
  | {code: BlockErrorCode.NOT_FINALIZED_DESCENDANT; parentRoot: RootHex}
135
- | {code: BlockErrorCode.NOT_LATER_THAN_PARENT; parentSlot: Slot; slot: Slot}
135
+ | {code: BlockErrorCode.NOT_LATER_THAN_PARENT; slot: Slot; root: RootHex; parentSlot: Slot}
136
136
  | {code: BlockErrorCode.NON_LINEAR_PARENT_ROOTS}
137
137
  | {code: BlockErrorCode.NON_LINEAR_SLOTS}
138
138
  | {code: BlockErrorCode.ENVELOPE_BLOCK_ROOT_MISMATCH; envelopeBlockRoot: RootHex; blockRoot: RootHex}
@@ -140,7 +140,7 @@ export type BlockErrorType =
140
140
  | {code: BlockErrorCode.BEACON_CHAIN_ERROR; error: Error}
141
141
  | {code: BlockErrorCode.KNOWN_BAD_BLOCK}
142
142
  | {code: BlockErrorCode.BLACKLISTED_BLOCK}
143
- | {code: BlockErrorCode.INCORRECT_TIMESTAMP; timestamp: number; expectedTimestamp: number}
143
+ | {code: BlockErrorCode.INCORRECT_TIMESTAMP; slot: Slot; root: RootHex; timestamp: number; expectedTimestamp: number}
144
144
  | {code: BlockErrorCode.TOO_MUCH_GAS_USED; gasUsed: number; gasLimit: number}
145
145
  | {code: BlockErrorCode.SAME_PARENT_HASH; blockHash: RootHex}
146
146
  | {code: BlockErrorCode.TRANSACTIONS_TOO_BIG; size: number; max: number}
@@ -151,9 +151,21 @@ export type BlockErrorType =
151
151
  errorMessage: string;
152
152
  }
153
153
  | {code: BlockErrorCode.DATA_UNAVAILABLE}
154
- | {code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS; blobKzgCommitmentsLen: number; commitmentLimit: number}
155
- | {code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH; bidParentRoot: RootHex; blockParentRoot: RootHex}
156
- | {code: BlockErrorCode.TOO_MANY_BLOCK_OPERATIONS; name: string; count: number; limit: number}
154
+ | {
155
+ code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS;
156
+ slot: Slot;
157
+ root: RootHex;
158
+ blobKzgCommitmentsLen: number;
159
+ commitmentLimit: number;
160
+ }
161
+ | {
162
+ code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH;
163
+ slot: Slot;
164
+ root: RootHex;
165
+ bidParentRoot: RootHex;
166
+ blockParentRoot: RootHex;
167
+ }
168
+ | {code: BlockErrorCode.NON_ZERO_DEPOSITS; slot: Slot; root: RootHex; count: number}
157
169
  | {code: BlockErrorCode.PARENT_EXECUTION_INVALID; parentRoot: RootHex}
158
170
  | {code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN; parentRoot: RootHex; parentBlockHash: RootHex}
159
171
  | {code: BlockErrorCode.NON_LINEAR_PAYLOAD_ROOTS; parentBlockHash: RootHex; expectedBlockHash: RootHex};
@@ -47,10 +47,12 @@ export enum DataColumnSidecarErrorCode {
47
47
  }
48
48
 
49
49
  export type DataColumnSidecarErrorType =
50
- | {code: DataColumnSidecarErrorCode.INVALID_INDEX; slot: Slot; columnIndex: number}
51
- | {code: DataColumnSidecarErrorCode.NO_COMMITMENTS; slot: Slot; columnIndex: number}
50
+ | {code: DataColumnSidecarErrorCode.INVALID_INDEX; slot: Slot; root: RootHex; columnIndex: number}
51
+ | {code: DataColumnSidecarErrorCode.NO_COMMITMENTS; slot: Slot; root: RootHex; columnIndex: number}
52
52
  | {
53
53
  code: DataColumnSidecarErrorCode.MISMATCHED_LENGTHS;
54
+ slot: Slot;
55
+ root: RootHex;
54
56
  columnLength: number;
55
57
  commitmentsLength: number;
56
58
  proofsLength: number;
@@ -61,10 +63,17 @@ export type DataColumnSidecarErrorType =
61
63
  columnIndex: number;
62
64
  fork: ForkName;
63
65
  }
64
- | {code: DataColumnSidecarErrorCode.INVALID_SUBNET; columnIndex: number; gossipSubnet: SubnetID}
66
+ | {
67
+ code: DataColumnSidecarErrorCode.INVALID_SUBNET;
68
+ slot: Slot;
69
+ root: RootHex;
70
+ columnIndex: number;
71
+ gossipSubnet: SubnetID;
72
+ }
65
73
  | {
66
74
  code: DataColumnSidecarErrorCode.TOO_MANY_KZG_COMMITMENTS;
67
75
  slot: number;
76
+ root: RootHex;
68
77
  columnIndex: number;
69
78
  count: number;
70
79
  limit: number;
@@ -85,12 +94,12 @@ export type DataColumnSidecarErrorType =
85
94
  | {
86
95
  code: DataColumnSidecarErrorCode.PROPOSAL_SIGNATURE_INVALID;
87
96
  slot: Slot;
88
- blockRoot: RootHex;
97
+ root: RootHex;
89
98
  index: number;
90
99
  }
91
- | {code: DataColumnSidecarErrorCode.NOT_LATER_THAN_PARENT; parentSlot: Slot; slot: Slot}
92
- | {code: DataColumnSidecarErrorCode.INCLUSION_PROOF_INVALID; slot: Slot; columnIndex: number}
93
- | {code: DataColumnSidecarErrorCode.INVALID_KZG_PROOF; slot: Slot; columnIndex: number}
100
+ | {code: DataColumnSidecarErrorCode.NOT_LATER_THAN_PARENT; slot: Slot; root: RootHex; parentSlot: Slot}
101
+ | {code: DataColumnSidecarErrorCode.INCLUSION_PROOF_INVALID; slot: Slot; root: RootHex; columnIndex: number}
102
+ | {code: DataColumnSidecarErrorCode.INVALID_KZG_PROOF; slot: Slot; root: RootHex; columnIndex: number}
94
103
  | {code: DataColumnSidecarErrorCode.INCORRECT_SIDECAR_COUNT; slot: number; expected: number; actual: number}
95
104
  | {
96
105
  code: DataColumnSidecarErrorCode.INCORRECT_BLOCK;
@@ -106,6 +115,7 @@ export type DataColumnSidecarErrorType =
106
115
  }
107
116
  | {
108
117
  code: DataColumnSidecarErrorCode.INCORRECT_SIDECAR_SLOT;
118
+ root: RootHex;
109
119
  columnIndex: number;
110
120
  expected: Slot;
111
121
  actual: Slot;
@@ -127,7 +137,13 @@ export type DataColumnSidecarErrorType =
127
137
  actual: number;
128
138
  }
129
139
  | {code: DataColumnSidecarErrorCode.INVALID_KZG_PROOF_BATCH; slot: number; reason: string}
130
- | {code: DataColumnSidecarErrorCode.INCORRECT_PROPOSER; actualProposerIndex: number; expectedProposerIndex: number}
140
+ | {
141
+ code: DataColumnSidecarErrorCode.INCORRECT_PROPOSER;
142
+ slot: Slot;
143
+ root: RootHex;
144
+ actualProposerIndex: number;
145
+ expectedProposerIndex: number;
146
+ }
131
147
  | {code: DataColumnSidecarErrorCode.PAYLOAD_ENVELOPE_INPUT_MISSING; slot: Slot; blockRoot: RootHex};
132
148
 
133
149
  export class DataColumnSidecarGossipError extends GossipActionError<DataColumnSidecarErrorType> {}
@@ -5,6 +5,7 @@ export enum ExecutionPayloadBidErrorCode {
5
5
  BUILDER_NOT_ELIGIBLE = "EXECUTION_PAYLOAD_BID_ERROR_BUILDER_NOT_ELIGIBLE",
6
6
  INVALID_BUILDER_VERSION = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_BUILDER_VERSION",
7
7
  NON_ZERO_EXECUTION_PAYMENT = "EXECUTION_PAYLOAD_BID_ERROR_NON_ZERO_EXECUTION_PAYMENT",
8
+ BLOCK_HASH_EQUALS_PARENT_BLOCK_HASH = "EXECUTION_PAYLOAD_BID_ERROR_BLOCK_HASH_EQUALS_PARENT_BLOCK_HASH",
8
9
  INCOMPATIBLE_WITH_HEAD = "EXECUTION_PAYLOAD_BID_ERROR_INCOMPATIBLE_WITH_HEAD",
9
10
  BID_ALREADY_KNOWN = "EXECUTION_PAYLOAD_BID_ERROR_BID_ALREADY_KNOWN",
10
11
  BID_TOO_LOW = "EXECUTION_PAYLOAD_BID_ERROR_BID_TOO_LOW",
@@ -63,6 +64,7 @@ export type ExecutionPayloadBidErrorType =
63
64
  }
64
65
  | {code: ExecutionPayloadBidErrorCode.UNKNOWN_BLOCK_ROOT; parentBlockRoot: RootHex}
65
66
  | {code: ExecutionPayloadBidErrorCode.UNKNOWN_PARENT_BLOCK_HASH; parentBlockHash: RootHex}
67
+ | {code: ExecutionPayloadBidErrorCode.BLOCK_HASH_EQUALS_PARENT_BLOCK_HASH; blockHash: RootHex}
66
68
  | {code: ExecutionPayloadBidErrorCode.INVALID_SLOT; builderIndex: BuilderIndex; slot: Slot}
67
69
  | {code: ExecutionPayloadBidErrorCode.NOT_LATER_THAN_PARENT; parentSlot: Slot; slot: Slot}
68
70
  | {
@@ -12,8 +12,6 @@ export enum ExecutionPayloadEnvelopeErrorCode {
12
12
  BUILDER_INDEX_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_BUILDER_INDEX_MISMATCH",
13
13
  BLOCK_HASH_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_BLOCK_HASH_MISMATCH",
14
14
  EXECUTION_REQUESTS_ROOT_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_EXECUTION_REQUESTS_ROOT_MISMATCH",
15
- EXECUTION_REQUESTS_COUNT_EXCEEDED = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_EXECUTION_REQUESTS_COUNT_EXCEEDED",
16
- WITHDRAWALS_COUNT_EXCEEDED = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_WITHDRAWALS_COUNT_EXCEEDED",
17
15
  INVALID_SIGNATURE = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_INVALID_SIGNATURE",
18
16
  PAYLOAD_ENVELOPE_INPUT_MISSING = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_PAYLOAD_ENVELOPE_INPUT_MISSING",
19
17
  }
@@ -28,30 +26,35 @@ export type ExecutionPayloadEnvelopeErrorType =
28
26
  slot: Slot;
29
27
  }
30
28
  | {code: ExecutionPayloadEnvelopeErrorCode.INVALID_BLOCK; blockRoot: RootHex}
31
- | {code: ExecutionPayloadEnvelopeErrorCode.SLOT_MISMATCH; envelopeSlot: Slot; blockSlot: Slot}
29
+ | {
30
+ code: ExecutionPayloadEnvelopeErrorCode.SLOT_MISMATCH;
31
+ slot: Slot;
32
+ root: RootHex;
33
+ envelopeSlot: Slot;
34
+ blockSlot: Slot;
35
+ }
32
36
  | {
33
37
  code: ExecutionPayloadEnvelopeErrorCode.BUILDER_INDEX_MISMATCH;
38
+ slot: Slot;
39
+ root: RootHex;
34
40
  envelopeBuilderIndex: BuilderIndex;
35
41
  bidBuilderIndex: BuilderIndex | null;
36
42
  }
37
43
  | {
38
44
  code: ExecutionPayloadEnvelopeErrorCode.BLOCK_HASH_MISMATCH;
45
+ slot: Slot;
46
+ root: RootHex;
39
47
  envelopeBlockHash: RootHex;
40
48
  bidBlockHash: RootHex | null;
41
49
  }
42
50
  | {
43
51
  code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_ROOT_MISMATCH;
52
+ slot: Slot;
53
+ root: RootHex;
44
54
  envelopeRequestsRoot: RootHex;
45
55
  bidRequestsRoot: RootHex;
46
56
  }
47
- | {
48
- code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_COUNT_EXCEEDED;
49
- name: string;
50
- count: number;
51
- limit: number;
52
- }
53
- | {code: ExecutionPayloadEnvelopeErrorCode.WITHDRAWALS_COUNT_EXCEEDED; count: number; limit: number}
54
- | {code: ExecutionPayloadEnvelopeErrorCode.INVALID_SIGNATURE}
57
+ | {code: ExecutionPayloadEnvelopeErrorCode.INVALID_SIGNATURE; slot: Slot; root: RootHex}
55
58
  | {code: ExecutionPayloadEnvelopeErrorCode.PAYLOAD_ENVELOPE_INPUT_MISSING; blockRoot: RootHex};
56
59
 
57
60
  export class ExecutionPayloadEnvelopeError extends GossipActionError<ExecutionPayloadEnvelopeErrorType> {}
@@ -8,6 +8,7 @@ export enum GossipAction {
8
8
  export enum GossipErrorCode {
9
9
  INVALID_SERIALIZED_BYTES_ERROR_CODE = "GOSSIP_ERROR_INVALID_SERIALIZED_BYTES",
10
10
  PAST_SLOT = "GOSSIP_ERROR_PAST_SLOT",
11
+ FUTURE_SLOT = "GOSSIP_ERROR_FUTURE_SLOT",
11
12
  }
12
13
 
13
14
  export class GossipActionError<T extends {code: string}> extends LodestarError<T> {
@@ -135,6 +135,7 @@ export function initializeForkChoiceFromFinalizedState(
135
135
  blockRoot: toRootHex(checkpoint.root),
136
136
  timeliness: true, // Optimistically assume is timely
137
137
  ptcTimeliness: true, // Spec: block_timeliness for anchor = [True, True]
138
+ importedTimely: true, // Optimistically assume is timely
138
139
  proposerIndex: blockHeader.proposerIndex,
139
140
 
140
141
  justifiedEpoch: justifiedCheckpoint.epoch,
@@ -233,6 +234,7 @@ export function initializeForkChoiceFromUnfinalizedState(
233
234
  targetRoot: headRoot,
234
235
  timeliness: true, // Optimistically assume is timely
235
236
  ptcTimeliness: true, // Spec: block_timeliness for anchor = [True, True]
237
+ importedTimely: true, // Optimistically assume is timely
236
238
  proposerIndex: blockHeader.proposerIndex,
237
239
 
238
240
  justifiedEpoch: justifiedCheckpoint.epoch,