@lodestar/beacon-node 1.39.0-dev.882891d89c → 1.39.0-dev.b37f2bd1bd

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 (338) hide show
  1. package/lib/api/impl/beacon/blocks/utils.js +1 -1
  2. package/lib/api/impl/beacon/blocks/utils.js.map +1 -1
  3. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  4. package/lib/chain/blocks/verifyBlock.js +1 -1
  5. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  6. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +1 -2
  7. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  8. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  9. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  10. package/lib/chain/chain.d.ts +4 -1
  11. package/lib/chain/chain.d.ts.map +1 -1
  12. package/lib/chain/chain.js +16 -8
  13. package/lib/chain/chain.js.map +1 -1
  14. package/lib/chain/genesis/genesis.d.ts +51 -0
  15. package/lib/chain/genesis/genesis.d.ts.map +1 -0
  16. package/lib/chain/genesis/genesis.js +123 -0
  17. package/lib/chain/genesis/genesis.js.map +1 -0
  18. package/lib/chain/genesis/interface.d.ts +13 -0
  19. package/lib/chain/genesis/interface.d.ts.map +1 -0
  20. package/lib/chain/genesis/interface.js +2 -0
  21. package/lib/chain/genesis/interface.js.map +1 -0
  22. package/lib/chain/initState.d.ts +14 -1
  23. package/lib/chain/initState.d.ts.map +1 -1
  24. package/lib/chain/initState.js +62 -1
  25. package/lib/chain/initState.js.map +1 -1
  26. package/lib/chain/interface.d.ts +2 -0
  27. package/lib/chain/interface.d.ts.map +1 -1
  28. package/lib/chain/interface.js.map +1 -1
  29. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -4
  30. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  31. package/lib/chain/opPools/aggregatedAttestationPool.js +4 -4
  32. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  33. package/lib/chain/opPools/opPool.d.ts +0 -3
  34. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  35. package/lib/chain/opPools/opPool.js +8 -9
  36. package/lib/chain/opPools/opPool.js.map +1 -1
  37. package/lib/chain/prepareNextSlot.d.ts +4 -0
  38. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  39. package/lib/chain/prepareNextSlot.js +21 -1
  40. package/lib/chain/prepareNextSlot.js.map +1 -1
  41. package/lib/chain/produceBlock/produceBlockBody.d.ts +1 -0
  42. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  43. package/lib/chain/produceBlock/produceBlockBody.js +11 -8
  44. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  45. package/lib/chain/rewards/attestationsRewards.d.ts +1 -2
  46. package/lib/chain/rewards/attestationsRewards.d.ts.map +1 -1
  47. package/lib/chain/rewards/attestationsRewards.js +8 -8
  48. package/lib/chain/rewards/attestationsRewards.js.map +1 -1
  49. package/lib/chain/rewards/blockRewards.d.ts +1 -2
  50. package/lib/chain/rewards/blockRewards.d.ts.map +1 -1
  51. package/lib/chain/rewards/blockRewards.js +5 -5
  52. package/lib/chain/rewards/blockRewards.js.map +1 -1
  53. package/lib/chain/rewards/syncCommitteeRewards.d.ts +1 -2
  54. package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +1 -1
  55. package/lib/chain/rewards/syncCommitteeRewards.js +2 -2
  56. package/lib/chain/rewards/syncCommitteeRewards.js.map +1 -1
  57. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -4
  58. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  59. package/lib/chain/stateCache/persistentCheckpointsCache.js +2 -4
  60. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  61. package/lib/chain/validation/attesterSlashing.js +1 -1
  62. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  63. package/lib/chain/validation/block.js +1 -1
  64. package/lib/chain/validation/block.js.map +1 -1
  65. package/lib/chain/validation/blsToExecutionChange.js +1 -1
  66. package/lib/chain/validation/proposerSlashing.js +1 -1
  67. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  68. package/lib/chain/validation/signatureSets/aggregateAndProof.js +1 -1
  69. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  70. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +1 -2
  71. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  72. package/lib/chain/validation/signatureSets/contributionAndProof.js +2 -2
  73. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  74. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +1 -2
  75. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  76. package/lib/chain/validation/signatureSets/syncCommittee.js +2 -2
  77. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  78. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
  79. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  80. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  81. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  82. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +1 -2
  83. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  84. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +2 -1
  85. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  86. package/lib/chain/validation/syncCommittee.js +1 -1
  87. package/lib/chain/validation/syncCommittee.js.map +1 -1
  88. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  89. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -3
  90. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  91. package/lib/chain/validation/voluntaryExit.js +1 -1
  92. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  93. package/lib/db/beacon.d.ts +7 -3
  94. package/lib/db/beacon.d.ts.map +1 -1
  95. package/lib/db/beacon.js +12 -33
  96. package/lib/db/beacon.js.map +1 -1
  97. package/lib/db/buckets.d.ts +6 -12
  98. package/lib/db/buckets.d.ts.map +1 -1
  99. package/lib/db/buckets.js +1 -6
  100. package/lib/db/buckets.js.map +1 -1
  101. package/lib/db/interface.d.ts +7 -2
  102. package/lib/db/interface.d.ts.map +1 -1
  103. package/lib/db/repositories/depositDataRoot.d.ts +22 -0
  104. package/lib/db/repositories/depositDataRoot.d.ts.map +1 -0
  105. package/lib/db/repositories/depositDataRoot.js +62 -0
  106. package/lib/db/repositories/depositDataRoot.js.map +1 -0
  107. package/lib/db/repositories/depositEvent.d.ts +13 -0
  108. package/lib/db/repositories/depositEvent.d.ts.map +1 -0
  109. package/lib/db/repositories/depositEvent.js +27 -0
  110. package/lib/db/repositories/depositEvent.js.map +1 -0
  111. package/lib/db/repositories/eth1Data.d.ts +13 -0
  112. package/lib/db/repositories/eth1Data.d.ts.map +1 -0
  113. package/lib/db/repositories/eth1Data.js +26 -0
  114. package/lib/db/repositories/eth1Data.js.map +1 -0
  115. package/lib/db/repositories/index.d.ts +3 -0
  116. package/lib/db/repositories/index.d.ts.map +1 -1
  117. package/lib/db/repositories/index.js +3 -0
  118. package/lib/db/repositories/index.js.map +1 -1
  119. package/lib/db/single/index.d.ts +3 -0
  120. package/lib/db/single/index.d.ts.map +1 -0
  121. package/lib/db/single/index.js +3 -0
  122. package/lib/db/single/index.js.map +1 -0
  123. package/lib/db/single/preGenesisState.d.ts +16 -0
  124. package/lib/db/single/preGenesisState.d.ts.map +1 -0
  125. package/lib/db/single/preGenesisState.js +29 -0
  126. package/lib/db/single/preGenesisState.js.map +1 -0
  127. package/lib/db/single/preGenesisStateLastProcessedBlock.d.ts +14 -0
  128. package/lib/db/single/preGenesisStateLastProcessedBlock.d.ts.map +1 -0
  129. package/lib/db/single/preGenesisStateLastProcessedBlock.js +27 -0
  130. package/lib/db/single/preGenesisStateLastProcessedBlock.js.map +1 -0
  131. package/lib/eth1/errors.d.ts +66 -0
  132. package/lib/eth1/errors.d.ts.map +1 -0
  133. package/lib/eth1/errors.js +27 -0
  134. package/lib/eth1/errors.js.map +1 -0
  135. package/lib/eth1/eth1DataCache.d.ts +19 -0
  136. package/lib/eth1/eth1DataCache.d.ts.map +1 -0
  137. package/lib/eth1/eth1DataCache.js +19 -0
  138. package/lib/eth1/eth1DataCache.js.map +1 -0
  139. package/lib/eth1/eth1DepositDataTracker.d.ts +80 -0
  140. package/lib/eth1/eth1DepositDataTracker.d.ts.map +1 -0
  141. package/lib/eth1/eth1DepositDataTracker.js +317 -0
  142. package/lib/eth1/eth1DepositDataTracker.js.map +1 -0
  143. package/lib/eth1/eth1DepositsCache.d.ts +42 -0
  144. package/lib/eth1/eth1DepositsCache.d.ts.map +1 -0
  145. package/lib/eth1/eth1DepositsCache.js +119 -0
  146. package/lib/eth1/eth1DepositsCache.js.map +1 -0
  147. package/lib/eth1/index.d.ts +31 -0
  148. package/lib/eth1/index.d.ts.map +1 -0
  149. package/lib/eth1/index.js +71 -0
  150. package/lib/eth1/index.js.map +1 -0
  151. package/lib/eth1/interface.d.ts +74 -0
  152. package/lib/eth1/interface.d.ts.map +1 -0
  153. package/lib/eth1/interface.js +8 -0
  154. package/lib/eth1/interface.js.map +1 -0
  155. package/lib/eth1/options.d.ts +22 -0
  156. package/lib/eth1/options.d.ts.map +1 -0
  157. package/lib/eth1/options.js +8 -0
  158. package/lib/eth1/options.js.map +1 -0
  159. package/lib/eth1/provider/eth1Provider.d.ts +39 -0
  160. package/lib/eth1/provider/eth1Provider.d.ts.map +1 -0
  161. package/lib/eth1/provider/eth1Provider.js +147 -0
  162. package/lib/eth1/provider/eth1Provider.js.map +1 -0
  163. package/lib/{execution/engine → eth1/provider}/jsonRpcHttpClient.d.ts +1 -1
  164. package/lib/eth1/provider/jsonRpcHttpClient.d.ts.map +1 -0
  165. package/lib/eth1/provider/jsonRpcHttpClient.js.map +1 -0
  166. package/lib/eth1/provider/jwt.d.ts.map +1 -0
  167. package/lib/eth1/provider/jwt.js.map +1 -0
  168. package/lib/eth1/provider/utils.d.ts +65 -0
  169. package/lib/eth1/provider/utils.d.ts.map +1 -0
  170. package/lib/eth1/provider/utils.js +120 -0
  171. package/lib/eth1/provider/utils.js.map +1 -0
  172. package/lib/eth1/stream.d.ts +15 -0
  173. package/lib/eth1/stream.d.ts.map +1 -0
  174. package/lib/eth1/stream.js +54 -0
  175. package/lib/eth1/stream.js.map +1 -0
  176. package/lib/eth1/utils/depositContract.d.ts +14 -0
  177. package/lib/eth1/utils/depositContract.d.ts.map +1 -0
  178. package/lib/eth1/utils/depositContract.js +33 -0
  179. package/lib/eth1/utils/depositContract.js.map +1 -0
  180. package/lib/eth1/utils/deposits.d.ts +8 -0
  181. package/lib/eth1/utils/deposits.d.ts.map +1 -0
  182. package/lib/eth1/utils/deposits.js +47 -0
  183. package/lib/eth1/utils/deposits.js.map +1 -0
  184. package/lib/eth1/utils/eth1Data.d.ts +22 -0
  185. package/lib/eth1/utils/eth1Data.d.ts.map +1 -0
  186. package/lib/eth1/utils/eth1Data.js +77 -0
  187. package/lib/eth1/utils/eth1Data.js.map +1 -0
  188. package/lib/eth1/utils/eth1DepositEvent.d.ts +7 -0
  189. package/lib/eth1/utils/eth1DepositEvent.d.ts.map +1 -0
  190. package/lib/eth1/utils/eth1DepositEvent.js +13 -0
  191. package/lib/eth1/utils/eth1DepositEvent.js.map +1 -0
  192. package/lib/eth1/utils/eth1Vote.d.ts +17 -0
  193. package/lib/eth1/utils/eth1Vote.d.ts.map +1 -0
  194. package/lib/eth1/utils/eth1Vote.js +111 -0
  195. package/lib/eth1/utils/eth1Vote.js.map +1 -0
  196. package/lib/eth1/utils/groupDepositEventsByBlock.d.ts +9 -0
  197. package/lib/eth1/utils/groupDepositEventsByBlock.d.ts.map +1 -0
  198. package/lib/eth1/utils/groupDepositEventsByBlock.js +17 -0
  199. package/lib/eth1/utils/groupDepositEventsByBlock.js.map +1 -0
  200. package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.d.ts +10 -0
  201. package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.d.ts.map +1 -0
  202. package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.js +14 -0
  203. package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.js.map +1 -0
  204. package/lib/execution/engine/http.d.ts +1 -1
  205. package/lib/execution/engine/http.d.ts.map +1 -1
  206. package/lib/execution/engine/http.js +3 -2
  207. package/lib/execution/engine/http.js.map +1 -1
  208. package/lib/execution/engine/index.d.ts.map +1 -1
  209. package/lib/execution/engine/index.js +1 -1
  210. package/lib/execution/engine/index.js.map +1 -1
  211. package/lib/execution/engine/interface.d.ts +1 -1
  212. package/lib/execution/engine/interface.d.ts.map +1 -1
  213. package/lib/execution/engine/interface.js.map +1 -1
  214. package/lib/execution/engine/mock.d.ts.map +1 -1
  215. package/lib/execution/engine/mock.js +1 -1
  216. package/lib/execution/engine/mock.js.map +1 -1
  217. package/lib/execution/engine/payloadIdCache.d.ts +1 -1
  218. package/lib/execution/engine/payloadIdCache.d.ts.map +1 -1
  219. package/lib/execution/engine/types.d.ts +1 -1
  220. package/lib/execution/engine/types.d.ts.map +1 -1
  221. package/lib/execution/engine/types.js +1 -1
  222. package/lib/execution/engine/types.js.map +1 -1
  223. package/lib/execution/engine/utils.d.ts +2 -64
  224. package/lib/execution/engine/utils.d.ts.map +1 -1
  225. package/lib/execution/engine/utils.js +2 -91
  226. package/lib/execution/engine/utils.js.map +1 -1
  227. package/lib/index.d.ts +2 -1
  228. package/lib/index.d.ts.map +1 -1
  229. package/lib/index.js +2 -1
  230. package/lib/index.js.map +1 -1
  231. package/lib/metrics/metrics/lodestar.d.ts +35 -0
  232. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  233. package/lib/metrics/metrics/lodestar.js +90 -0
  234. package/lib/metrics/metrics/lodestar.js.map +1 -1
  235. package/lib/node/nodejs.d.ts.map +1 -1
  236. package/lib/node/nodejs.js +9 -10
  237. package/lib/node/nodejs.js.map +1 -1
  238. package/lib/node/options.d.ts +2 -0
  239. package/lib/node/options.d.ts.map +1 -1
  240. package/lib/node/options.js +2 -0
  241. package/lib/node/options.js.map +1 -1
  242. package/lib/node/utils/interop/deposits.d.ts +1 -2
  243. package/lib/node/utils/interop/deposits.d.ts.map +1 -1
  244. package/lib/node/utils/interop/deposits.js.map +1 -1
  245. package/lib/node/utils/interop/state.d.ts +1 -1
  246. package/lib/node/utils/interop/state.d.ts.map +1 -1
  247. package/lib/node/utils/state.d.ts +7 -1
  248. package/lib/node/utils/state.d.ts.map +1 -1
  249. package/lib/node/utils/state.js +14 -1
  250. package/lib/node/utils/state.js.map +1 -1
  251. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  252. package/lib/sync/backfill/backfill.js +4 -2
  253. package/lib/sync/backfill/backfill.js.map +1 -1
  254. package/lib/sync/backfill/verify.d.ts +1 -1
  255. package/lib/sync/backfill/verify.d.ts.map +1 -1
  256. package/lib/sync/backfill/verify.js +2 -2
  257. package/lib/sync/backfill/verify.js.map +1 -1
  258. package/package.json +20 -14
  259. package/src/api/impl/beacon/blocks/utils.ts +1 -1
  260. package/src/chain/blocks/verifyBlock.ts +0 -1
  261. package/src/chain/blocks/verifyBlocksSignatures.ts +1 -3
  262. package/src/chain/chain.ts +19 -7
  263. package/src/chain/genesis/genesis.ts +190 -0
  264. package/src/chain/genesis/interface.ts +14 -0
  265. package/src/chain/initState.ts +97 -1
  266. package/src/chain/interface.ts +2 -0
  267. package/src/chain/opPools/aggregatedAttestationPool.ts +7 -7
  268. package/src/chain/opPools/opPool.ts +8 -8
  269. package/src/chain/prepareNextSlot.ts +28 -1
  270. package/src/chain/produceBlock/produceBlockBody.ts +12 -8
  271. package/src/chain/rewards/attestationsRewards.ts +4 -13
  272. package/src/chain/rewards/blockRewards.ts +3 -6
  273. package/src/chain/rewards/syncCommitteeRewards.ts +1 -3
  274. package/src/chain/stateCache/persistentCheckpointsCache.ts +2 -15
  275. package/src/chain/validation/attesterSlashing.ts +1 -1
  276. package/src/chain/validation/block.ts +1 -1
  277. package/src/chain/validation/blsToExecutionChange.ts +1 -1
  278. package/src/chain/validation/proposerSlashing.ts +1 -1
  279. package/src/chain/validation/signatureSets/aggregateAndProof.ts +1 -1
  280. package/src/chain/validation/signatureSets/contributionAndProof.ts +1 -3
  281. package/src/chain/validation/signatureSets/syncCommittee.ts +1 -3
  282. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +1 -3
  283. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +1 -2
  284. package/src/chain/validation/syncCommittee.ts +1 -1
  285. package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -8
  286. package/src/chain/validation/voluntaryExit.ts +1 -1
  287. package/src/db/beacon.ts +16 -38
  288. package/src/db/buckets.ts +7 -12
  289. package/src/db/interface.ts +13 -2
  290. package/src/db/repositories/depositDataRoot.ts +80 -0
  291. package/src/db/repositories/depositEvent.ts +32 -0
  292. package/src/db/repositories/eth1Data.ts +33 -0
  293. package/src/db/repositories/index.ts +3 -0
  294. package/src/db/single/index.ts +2 -0
  295. package/src/db/single/preGenesisState.ts +37 -0
  296. package/src/db/single/preGenesisStateLastProcessedBlock.ts +34 -0
  297. package/src/eth1/errors.ts +40 -0
  298. package/src/eth1/eth1DataCache.ts +26 -0
  299. package/src/eth1/eth1DepositDataTracker.ts +410 -0
  300. package/src/eth1/eth1DepositsCache.ts +141 -0
  301. package/src/eth1/index.ts +94 -0
  302. package/src/eth1/interface.ts +87 -0
  303. package/src/eth1/options.ts +28 -0
  304. package/src/eth1/provider/eth1Provider.ts +229 -0
  305. package/src/{execution/engine → eth1/provider}/jsonRpcHttpClient.ts +1 -1
  306. package/src/eth1/provider/utils.ts +136 -0
  307. package/src/eth1/stream.ts +75 -0
  308. package/src/eth1/utils/depositContract.ts +37 -0
  309. package/src/eth1/utils/deposits.ts +70 -0
  310. package/src/eth1/utils/eth1Data.ts +100 -0
  311. package/src/eth1/utils/eth1DepositEvent.ts +12 -0
  312. package/src/eth1/utils/eth1Vote.ts +142 -0
  313. package/src/eth1/utils/groupDepositEventsByBlock.ts +19 -0
  314. package/src/eth1/utils/optimizeNextBlockDiffForGenesis.ts +18 -0
  315. package/src/execution/engine/http.ts +9 -8
  316. package/src/execution/engine/index.ts +1 -1
  317. package/src/execution/engine/interface.ts +1 -1
  318. package/src/execution/engine/mock.ts +2 -1
  319. package/src/execution/engine/payloadIdCache.ts +1 -1
  320. package/src/execution/engine/types.ts +9 -9
  321. package/src/execution/engine/utils.ts +5 -111
  322. package/src/index.ts +2 -1
  323. package/src/metrics/metrics/lodestar.ts +92 -0
  324. package/src/node/nodejs.ts +9 -11
  325. package/src/node/options.ts +3 -0
  326. package/src/node/utils/interop/deposits.ts +1 -3
  327. package/src/node/utils/interop/state.ts +1 -1
  328. package/src/node/utils/state.ts +18 -3
  329. package/src/sync/backfill/backfill.ts +3 -8
  330. package/src/sync/backfill/verify.ts +1 -3
  331. package/lib/execution/engine/jsonRpcHttpClient.d.ts.map +0 -1
  332. package/lib/execution/engine/jsonRpcHttpClient.js.map +0 -1
  333. package/lib/execution/engine/jwt.d.ts.map +0 -1
  334. package/lib/execution/engine/jwt.js.map +0 -1
  335. /package/lib/{execution/engine → eth1/provider}/jsonRpcHttpClient.js +0 -0
  336. /package/lib/{execution/engine → eth1/provider}/jwt.d.ts +0 -0
  337. /package/lib/{execution/engine → eth1/provider}/jwt.js +0 -0
  338. /package/src/{execution/engine → eth1/provider}/jwt.ts +0 -0
@@ -0,0 +1,141 @@
1
+ import {byteArrayEquals} from "@chainsafe/ssz";
2
+ import {ChainForkConfig} from "@lodestar/config";
3
+ import {FilterOptions} from "@lodestar/db";
4
+ import {phase0, ssz} from "@lodestar/types";
5
+ import {IBeaconDb} from "../db/index.js";
6
+ import {Eth1Error, Eth1ErrorCode} from "./errors.js";
7
+ import {Eth1Block} from "./interface.js";
8
+ import {getDepositsWithProofs} from "./utils/deposits.js";
9
+ import {getEth1DataForBlocks} from "./utils/eth1Data.js";
10
+ import {assertConsecutiveDeposits} from "./utils/eth1DepositEvent.js";
11
+
12
+ export class Eth1DepositsCache {
13
+ unsafeAllowDepositDataOverwrite: boolean;
14
+ db: IBeaconDb;
15
+ config: ChainForkConfig;
16
+
17
+ constructor(opts: {unsafeAllowDepositDataOverwrite?: boolean}, config: ChainForkConfig, db: IBeaconDb) {
18
+ this.config = config;
19
+ this.db = db;
20
+ this.unsafeAllowDepositDataOverwrite = opts.unsafeAllowDepositDataOverwrite ?? false;
21
+ }
22
+
23
+ /**
24
+ * Returns a list of `Deposit` objects, within the given deposit index `range`.
25
+ *
26
+ * The `depositCount` is used to generate the proofs for the `Deposits`. For example, if we
27
+ * have 100 proofs, but the Ethereum Consensus chain only acknowledges 50 of them, we must produce our
28
+ * proofs with respect to a tree size of 50.
29
+ */
30
+ async get(indexRange: FilterOptions<number>, eth1Data: phase0.Eth1Data): Promise<phase0.Deposit[]> {
31
+ const depositEvents = await this.db.depositEvent.values(indexRange);
32
+ const depositRootTree = await this.db.depositDataRoot.getDepositRootTree();
33
+ return getDepositsWithProofs(depositEvents, depositRootTree, eth1Data);
34
+ }
35
+
36
+ /**
37
+ * Add log to cache
38
+ * This function enforces that `logs` are imported one-by-one with consecutive indexes
39
+ */
40
+ async add(depositEvents: phase0.DepositEvent[]): Promise<void> {
41
+ assertConsecutiveDeposits(depositEvents);
42
+
43
+ const lastLog = await this.db.depositEvent.lastValue();
44
+ const firstEvent = depositEvents[0];
45
+
46
+ // Check, validate and skip if we got any deposit events already present in DB
47
+ // This can happen if the remote eth1/EL resets its head in these four scenarios:
48
+ // 1. Remote eth1/EL resynced/restarted from head behind its previous head pre-merge
49
+ // 2. In a post merge scenario, Lodestar restarted from finalized state from DB which
50
+ // generally is a few epochs behind the last synced head. This causes eth1 tracker to reset
51
+ // and refetch the deposits as the lodestar syncs further along (Post merge there is 1-1
52
+ // correspondence between EL and CL blocks)
53
+ // 3. The EL reorged beyond the eth1 follow distance.
54
+ //
55
+ // While 1. & 2. are benign and we handle them below by checking if the duplicate log fetched
56
+ // is same as one written in DB. Refer to this issue for some data dump of how this happens
57
+ // https://github.com/ChainSafe/lodestar/issues/3674
58
+ //
59
+ // If the duplicate log fetched is not same as written in DB then its probablu scenario 3.
60
+ // which would be a catastrophic event for the network (or we messed up real bad!!!).
61
+ //
62
+ // So we provide for a way to overwrite this log without deleting full db via
63
+ // --unsafeAllowDepositDataOverwrite cli flag which will just overwrite the previous tracker data
64
+ // if any. This option as indicated by its name is unsafe and to be only used if you know what
65
+ // you are doing.
66
+ if (lastLog !== null && firstEvent !== undefined) {
67
+ const newIndex = firstEvent.index;
68
+ const lastLogIndex = lastLog.index;
69
+
70
+ if (!this.unsafeAllowDepositDataOverwrite && firstEvent.index <= lastLog.index) {
71
+ // lastLogIndex - newIndex + 1 events are duplicate since this is a consecutive log
72
+ // as asserted by assertConsecutiveDeposits. Splice those events out from depositEvents.
73
+ const skipEvents = depositEvents.splice(0, lastLogIndex - newIndex + 1);
74
+ // After splicing skipEvents will contain duplicate events to be checked and validated
75
+ // and rest of the remaining events in depositEvents could be safely written to DB and
76
+ // move the tracker along.
77
+ for (const depositEvent of skipEvents) {
78
+ const prevDBSerializedEvent = await this.db.depositEvent.getBinary(depositEvent.index);
79
+ if (!prevDBSerializedEvent) {
80
+ throw new Eth1Error({code: Eth1ErrorCode.MISSING_DEPOSIT_LOG, newIndex, lastLogIndex});
81
+ }
82
+ const serializedEvent = ssz.phase0.DepositEvent.serialize(depositEvent);
83
+ if (!byteArrayEquals(prevDBSerializedEvent, serializedEvent)) {
84
+ throw new Eth1Error({code: Eth1ErrorCode.DUPLICATE_DISTINCT_LOG, newIndex, lastLogIndex});
85
+ }
86
+ }
87
+ } else if (newIndex > lastLogIndex + 1) {
88
+ // deposit events need to be consective, the way we fetch our tracker. If the deposit event
89
+ // is not consecutive it means either our tracker, or the corresponding eth1/EL
90
+ // node or the database has messed up. All these failures are critical and the tracker
91
+ // shouldn't proceed without the resolution of this error.
92
+ throw new Eth1Error({code: Eth1ErrorCode.NON_CONSECUTIVE_LOGS, newIndex, lastLogIndex});
93
+ }
94
+ }
95
+
96
+ const depositRoots = depositEvents.map((depositEvent) => ({
97
+ index: depositEvent.index,
98
+ root: ssz.phase0.DepositData.hashTreeRoot(depositEvent.depositData),
99
+ }));
100
+
101
+ // Store events after verifying that data is consecutive
102
+ // depositDataRoot will throw if adding non consecutive roots
103
+ await this.db.depositDataRoot.batchPutValues(depositRoots);
104
+ await this.db.depositEvent.batchPutValues(depositEvents);
105
+ }
106
+
107
+ /**
108
+ * Appends partial eth1 data (depositRoot, depositCount) in a block range (inclusive)
109
+ * Returned array is sequential and ascending in blockNumber
110
+ * @param fromBlock
111
+ * @param toBlock
112
+ */
113
+ async getEth1DataForBlocks(
114
+ blocks: Eth1Block[],
115
+ lastProcessedDepositBlockNumber: number | null
116
+ ): Promise<(phase0.Eth1Data & Eth1Block)[]> {
117
+ const highestBlock = blocks.at(-1)?.blockNumber;
118
+ return getEth1DataForBlocks(
119
+ blocks,
120
+ this.db.depositEvent.valuesStream({lte: highestBlock, reverse: true}),
121
+ await this.db.depositDataRoot.getDepositRootTree(),
122
+ lastProcessedDepositBlockNumber
123
+ );
124
+ }
125
+
126
+ /**
127
+ * Returns the highest blockNumber stored in DB if any
128
+ */
129
+ async getHighestDepositEventBlockNumber(): Promise<number | null> {
130
+ const latestEvent = await this.db.depositEvent.lastValue();
131
+ return latestEvent?.blockNumber || null;
132
+ }
133
+
134
+ /**
135
+ * Returns the lowest blockNumber stored in DB if any
136
+ */
137
+ async getLowestDepositEventBlockNumber(): Promise<number | null> {
138
+ const firstEvent = await this.db.depositEvent.firstValue();
139
+ return firstEvent?.blockNumber || null;
140
+ }
141
+ }
@@ -0,0 +1,94 @@
1
+ import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
2
+ import {Eth1DepositDataTracker, Eth1DepositDataTrackerModules} from "./eth1DepositDataTracker.js";
3
+ import {Eth1DataAndDeposits, IEth1ForBlockProduction, IEth1Provider} from "./interface.js";
4
+ import {Eth1Options} from "./options.js";
5
+ import {Eth1Provider} from "./provider/eth1Provider.js";
6
+ export {Eth1Provider};
7
+ export type {IEth1ForBlockProduction, IEth1Provider};
8
+
9
+ // This module encapsulates all consumer functionality to the execution node (formerly eth1). The execution client
10
+ // has to:
11
+ //
12
+ // - For genesis, the beacon node must follow the eth1 chain: get all deposit events + blocks within that range.
13
+ // Once the genesis conditions are met, start the POS chain with the resulting state. The logic is similar to the
14
+ // two points below, but the implementation is specialized for each scenario.
15
+ //
16
+ // - Follow the eth1 block chain to validate eth1Data votes. It needs all consecutive blocks within a specific range
17
+ // and at a distance from the head.
18
+ // ETH1_FOLLOW_DISTANCE uint64(2**11) (= 2,048) Eth1 blocks ~8 hours
19
+ // EPOCHS_PER_ETH1_VOTING_PERIOD uint64(2**6) (= 64) epochs ~6.8 hours
20
+ //
21
+ // - Fetch ALL deposit events from the deposit contract to build the deposit tree and validate future merkle proofs.
22
+ // Then it must follow deposit events at a distance roughly similar to the `ETH1_FOLLOW_DISTANCE` parameter above.
23
+
24
+ export function initializeEth1ForBlockProduction(
25
+ opts: Eth1Options,
26
+ modules: Pick<Eth1DepositDataTrackerModules, "db" | "config" | "metrics" | "logger" | "signal">
27
+ ): IEth1ForBlockProduction {
28
+ if (opts.enabled) {
29
+ return new Eth1ForBlockProduction(opts, {
30
+ config: modules.config,
31
+ db: modules.db,
32
+ metrics: modules.metrics,
33
+ logger: modules.logger,
34
+ signal: modules.signal,
35
+ });
36
+ }
37
+ return new Eth1ForBlockProductionDisabled();
38
+ }
39
+
40
+ export class Eth1ForBlockProduction implements IEth1ForBlockProduction {
41
+ private readonly eth1DepositDataTracker: Eth1DepositDataTracker | null;
42
+
43
+ constructor(opts: Eth1Options, modules: Eth1DepositDataTrackerModules & {eth1Provider?: IEth1Provider}) {
44
+ const eth1Provider =
45
+ modules.eth1Provider ||
46
+ new Eth1Provider(
47
+ modules.config,
48
+ {...opts, logger: modules.logger},
49
+ modules.signal,
50
+ modules.metrics?.eth1HttpClient
51
+ );
52
+
53
+ this.eth1DepositDataTracker = opts.disableEth1DepositDataTracker
54
+ ? null
55
+ : new Eth1DepositDataTracker(opts, modules, eth1Provider);
56
+ }
57
+
58
+ async getEth1DataAndDeposits(state: CachedBeaconStateAllForks): Promise<Eth1DataAndDeposits> {
59
+ if (this.eth1DepositDataTracker === null) {
60
+ return {eth1Data: state.eth1Data, deposits: []};
61
+ }
62
+ return this.eth1DepositDataTracker.getEth1DataAndDeposits(state);
63
+ }
64
+
65
+ isPollingEth1Data(): boolean {
66
+ return this.eth1DepositDataTracker?.isPollingEth1Data() ?? false;
67
+ }
68
+
69
+ stopPollingEth1Data(): void {
70
+ this.eth1DepositDataTracker?.stopPollingEth1Data();
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Disabled version of Eth1ForBlockProduction
76
+ * May produce invalid blocks by not adding new deposits and voting for the same eth1Data
77
+ */
78
+ export class Eth1ForBlockProductionDisabled implements IEth1ForBlockProduction {
79
+ /**
80
+ * Returns same eth1Data as in state and no deposits
81
+ * May produce invalid blocks if deposits have to be added
82
+ */
83
+ async getEth1DataAndDeposits(state: CachedBeaconStateAllForks): Promise<Eth1DataAndDeposits> {
84
+ return {eth1Data: state.eth1Data, deposits: []};
85
+ }
86
+
87
+ isPollingEth1Data(): boolean {
88
+ return false;
89
+ }
90
+
91
+ stopPollingEth1Data(): void {
92
+ // Ignore
93
+ }
94
+ }
@@ -0,0 +1,87 @@
1
+ import {BeaconConfig} from "@lodestar/config";
2
+ import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
3
+ import {phase0} from "@lodestar/types";
4
+
5
+ export type EthJsonRpcBlockRaw = {
6
+ /** the block number. null when its pending block. `"0x1b4"` */
7
+ number: string;
8
+ /** 32 Bytes - hash of the block. null when its pending block. `"0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae"` */
9
+ hash: string;
10
+ /** 32 Bytes - hash of the parent block. `"0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54"` */
11
+ parentHash: string;
12
+ /**
13
+ * integer of the total difficulty of the chain until this block. `"0x78ed983323d"`.
14
+ * Current mainnet value is 0x684de10dc5c03f006b6, 75 bits so requires a bigint.
15
+ */
16
+ totalDifficulty: string;
17
+ /** the unix timestamp for when the block was collated. `"0x55ba467c"` */
18
+ timestamp: string;
19
+ };
20
+
21
+ export interface IEth1Provider {
22
+ deployBlock: number;
23
+ getBlockNumber(): Promise<number>;
24
+ /** Returns HTTP code 200 + value=null if block is not found */
25
+ getBlockByNumber(blockNumber: number | "latest"): Promise<EthJsonRpcBlockRaw | null>;
26
+ /** Returns HTTP code 200 + value=null if block is not found */
27
+ getBlockByHash(blockHashHex: string): Promise<EthJsonRpcBlockRaw | null>;
28
+ /** null returns are ignored, may return a different number of blocks than expected */
29
+ getBlocksByNumber(fromBlock: number, toBlock: number): Promise<EthJsonRpcBlockRaw[]>;
30
+ getDepositEvents(fromBlock: number, toBlock: number): Promise<phase0.DepositEvent[]>;
31
+ validateContract(): Promise<void>;
32
+ getState(): Eth1ProviderState;
33
+ }
34
+
35
+ export enum Eth1ProviderState {
36
+ ONLINE = "ONLINE",
37
+ OFFLINE = "OFFLINE",
38
+ ERROR = "ERROR",
39
+ AUTH_FAILED = "AUTH_FAILED",
40
+ }
41
+
42
+ export type Eth1DataAndDeposits = {
43
+ eth1Data: phase0.Eth1Data;
44
+ deposits: phase0.Deposit[];
45
+ };
46
+
47
+ export interface IEth1ForBlockProduction {
48
+ getEth1DataAndDeposits(state: CachedBeaconStateAllForks): Promise<Eth1DataAndDeposits>;
49
+
50
+ isPollingEth1Data(): boolean;
51
+
52
+ /**
53
+ * Should stop polling eth1Data after a Electra block is finalized AND deposit_requests_start_index is reached
54
+ */
55
+ stopPollingEth1Data(): void;
56
+ }
57
+
58
+ /** Different Eth1Block from phase0.Eth1Block with blockHash */
59
+ export type Eth1Block = {
60
+ blockHash: Uint8Array;
61
+ blockNumber: number;
62
+ timestamp: number;
63
+ };
64
+
65
+ export type BatchDepositEvents = {
66
+ depositEvents: phase0.DepositEvent[];
67
+ blockNumber: number;
68
+ };
69
+
70
+ export type Eth1Streamer = {
71
+ getDepositsStream(fromBlock: number): AsyncGenerator<BatchDepositEvents>;
72
+ getDepositsAndBlockStreamForGenesis(fromBlock: number): AsyncGenerator<[phase0.DepositEvent[], phase0.Eth1Block]>;
73
+ };
74
+
75
+ export type IEth1StreamParams = Pick<
76
+ BeaconConfig,
77
+ "ETH1_FOLLOW_DISTANCE" | "MIN_GENESIS_TIME" | "GENESIS_DELAY" | "SECONDS_PER_ETH1_BLOCK"
78
+ > & {
79
+ maxBlocksPerPoll: number;
80
+ };
81
+
82
+ export type IJson = string | number | boolean | undefined | IJson[] | {[key: string]: IJson};
83
+
84
+ export interface RpcPayload<P = IJson[]> {
85
+ method: string;
86
+ params: P;
87
+ }
@@ -0,0 +1,28 @@
1
+ export type Eth1Options = {
2
+ enabled?: boolean;
3
+ disableEth1DepositDataTracker?: boolean;
4
+ providerUrls?: string[];
5
+ /**
6
+ * jwtSecretHex is the jwt secret if the eth1 modules should ping the jwt auth
7
+ * protected engine endpoints.
8
+ */
9
+ jwtSecretHex?: string;
10
+ jwtId?: string;
11
+ jwtVersion?: string;
12
+ depositContractDeployBlock?: number;
13
+ unsafeAllowDepositDataOverwrite?: boolean;
14
+ /**
15
+ * Vote for a specific eth1_data regardless of validity and existing votes.
16
+ * hex encoded ssz serialized Eth1Data type.
17
+ */
18
+ forcedEth1DataVote?: string;
19
+ };
20
+
21
+ export const DEFAULT_PROVIDER_URLS = ["http://localhost:8545"];
22
+
23
+ export const defaultEth1Options: Eth1Options = {
24
+ enabled: true,
25
+ providerUrls: DEFAULT_PROVIDER_URLS,
26
+ depositContractDeployBlock: 0,
27
+ unsafeAllowDepositDataOverwrite: false,
28
+ };
@@ -0,0 +1,229 @@
1
+ import {ChainConfig} from "@lodestar/config";
2
+ import {Logger} from "@lodestar/logger";
3
+ import {phase0} from "@lodestar/types";
4
+ import {
5
+ FetchError,
6
+ createElapsedTimeTracker,
7
+ fromHex,
8
+ isErrorAborted,
9
+ isFetchError,
10
+ toHex,
11
+ toPrintableUrl,
12
+ } from "@lodestar/utils";
13
+ import {HTTP_CONNECTION_ERROR_CODES, HTTP_FATAL_ERROR_CODES} from "../../execution/engine/utils.js";
14
+ import {isValidAddress} from "../../util/address.js";
15
+ import {linspace} from "../../util/numpy.js";
16
+ import {Eth1Block, Eth1ProviderState, EthJsonRpcBlockRaw, IEth1Provider} from "../interface.js";
17
+ import {DEFAULT_PROVIDER_URLS, Eth1Options} from "../options.js";
18
+ import {depositEventTopics, parseDepositLog} from "../utils/depositContract.js";
19
+ import {
20
+ ErrorJsonRpcResponse,
21
+ HttpRpcError,
22
+ JsonRpcHttpClient,
23
+ JsonRpcHttpClientEvent,
24
+ JsonRpcHttpClientMetrics,
25
+ ReqOpts,
26
+ } from "./jsonRpcHttpClient.js";
27
+ import {dataToBytes, isJsonRpcTruncatedError, numToQuantity, quantityToNum} from "./utils.js";
28
+
29
+ /**
30
+ * Binds return types to Ethereum JSON RPC methods
31
+ */
32
+ type EthJsonRpcReturnTypes = {
33
+ eth_getBlockByNumber: EthJsonRpcBlockRaw | null;
34
+ eth_getBlockByHash: EthJsonRpcBlockRaw | null;
35
+ eth_blockNumber: string;
36
+ eth_getCode: string;
37
+ eth_getLogs: {
38
+ removed: boolean;
39
+ logIndex: string;
40
+ transactionIndex: string;
41
+ transactionHash: string;
42
+ blockHash: string;
43
+ blockNumber: string;
44
+ address: string;
45
+ data: string;
46
+ topics: string[];
47
+ }[];
48
+ };
49
+
50
+ // Define static options once to prevent extra allocations
51
+ const getBlocksByNumberOpts: ReqOpts = {routeId: "getBlockByNumber_batched"};
52
+ const getBlockByNumberOpts: ReqOpts = {routeId: "getBlockByNumber"};
53
+ const getBlockByHashOpts: ReqOpts = {routeId: "getBlockByHash"};
54
+ const getBlockNumberOpts: ReqOpts = {routeId: "getBlockNumber"};
55
+ const getLogsOpts: ReqOpts = {routeId: "getLogs"};
56
+
57
+ const isOneMinutePassed = createElapsedTimeTracker({minElapsedTime: 60_000});
58
+
59
+ export class Eth1Provider implements IEth1Provider {
60
+ readonly deployBlock: number;
61
+ private readonly depositContractAddress: string;
62
+ private readonly rpc: JsonRpcHttpClient;
63
+ // The default state is ONLINE, it will be updated to offline if we receive a http error
64
+ private state: Eth1ProviderState = Eth1ProviderState.ONLINE;
65
+ private logger?: Logger;
66
+
67
+ constructor(
68
+ config: Pick<ChainConfig, "DEPOSIT_CONTRACT_ADDRESS">,
69
+ opts: Pick<Eth1Options, "depositContractDeployBlock" | "providerUrls" | "jwtSecretHex" | "jwtId" | "jwtVersion"> & {
70
+ logger?: Logger;
71
+ },
72
+ signal?: AbortSignal,
73
+ metrics?: JsonRpcHttpClientMetrics | null
74
+ ) {
75
+ this.logger = opts.logger;
76
+ this.deployBlock = opts.depositContractDeployBlock ?? 0;
77
+ this.depositContractAddress = toHex(config.DEPOSIT_CONTRACT_ADDRESS);
78
+
79
+ const providerUrls = opts.providerUrls ?? DEFAULT_PROVIDER_URLS;
80
+ this.rpc = new JsonRpcHttpClient(providerUrls, {
81
+ signal,
82
+ // Don't fallback with is truncated error. Throw early and let the retry on this class handle it
83
+ shouldNotFallback: isJsonRpcTruncatedError,
84
+ jwtSecret: opts.jwtSecretHex ? fromHex(opts.jwtSecretHex) : undefined,
85
+ jwtId: opts.jwtId,
86
+ jwtVersion: opts.jwtVersion,
87
+ metrics: metrics,
88
+ });
89
+ this.logger?.info("Eth1 provider", {urls: providerUrls.map(toPrintableUrl).toString()});
90
+
91
+ this.rpc.emitter.on(JsonRpcHttpClientEvent.RESPONSE, () => {
92
+ const oldState = this.state;
93
+ this.state = Eth1ProviderState.ONLINE;
94
+
95
+ if (oldState !== Eth1ProviderState.ONLINE) {
96
+ this.logger?.info("Eth1 provider is back online", {oldState, newState: this.state});
97
+ }
98
+ });
99
+
100
+ this.rpc.emitter.on(JsonRpcHttpClientEvent.ERROR, ({error}) => {
101
+ if (isErrorAborted(error)) {
102
+ this.state = Eth1ProviderState.ONLINE;
103
+ } else if ((error as unknown) instanceof HttpRpcError || (error as unknown) instanceof ErrorJsonRpcResponse) {
104
+ this.state = Eth1ProviderState.ERROR;
105
+ } else if (error && isFetchError(error) && HTTP_FATAL_ERROR_CODES.includes((error as FetchError).code)) {
106
+ this.state = Eth1ProviderState.OFFLINE;
107
+ } else if (error && isFetchError(error) && HTTP_CONNECTION_ERROR_CODES.includes((error as FetchError).code)) {
108
+ this.state = Eth1ProviderState.AUTH_FAILED;
109
+ }
110
+
111
+ if (this.state !== Eth1ProviderState.ONLINE && isOneMinutePassed()) {
112
+ this.logger?.error(
113
+ "Eth1 provider error",
114
+ {
115
+ state: this.state,
116
+ lastErrorAt: new Date(Date.now() - isOneMinutePassed.msSinceLastCall).toLocaleTimeString(),
117
+ },
118
+ error
119
+ );
120
+ }
121
+ });
122
+ }
123
+
124
+ getState(): Eth1ProviderState {
125
+ return this.state;
126
+ }
127
+
128
+ async validateContract(): Promise<void> {
129
+ if (!isValidAddress(this.depositContractAddress)) {
130
+ throw Error(`Invalid contract address: ${this.depositContractAddress}`);
131
+ }
132
+
133
+ const code = await this.getCode(this.depositContractAddress);
134
+ if (!code || code === "0x") {
135
+ throw new Error(`There is no deposit contract at given address: ${this.depositContractAddress}`);
136
+ }
137
+ }
138
+
139
+ async getDepositEvents(fromBlock: number, toBlock: number): Promise<phase0.DepositEvent[]> {
140
+ const logsRawArr = await this.getLogs({
141
+ fromBlock,
142
+ toBlock,
143
+ address: this.depositContractAddress,
144
+ topics: depositEventTopics,
145
+ });
146
+ return logsRawArr.flat(1).map((log) => parseDepositLog(log));
147
+ }
148
+
149
+ /**
150
+ * Fetches an arbitrary array of block numbers in batch
151
+ */
152
+ async getBlocksByNumber(fromBlock: number, toBlock: number): Promise<EthJsonRpcBlockRaw[]> {
153
+ const method = "eth_getBlockByNumber";
154
+ const blocksArr = await this.rpc.fetchBatch<EthJsonRpcReturnTypes[typeof method]>(
155
+ linspace(fromBlock, toBlock).map((blockNumber) => ({method, params: [numToQuantity(blockNumber), false]})),
156
+ getBlocksByNumberOpts
157
+ );
158
+ const blocks: EthJsonRpcBlockRaw[] = [];
159
+ for (const block of blocksArr.flat(1)) {
160
+ if (block) blocks.push(block);
161
+ }
162
+ return blocks;
163
+ }
164
+
165
+ async getBlockByNumber(blockNumber: number | "latest"): Promise<EthJsonRpcBlockRaw | null> {
166
+ const method = "eth_getBlockByNumber";
167
+ const blockNumberHex = typeof blockNumber === "string" ? blockNumber : numToQuantity(blockNumber);
168
+ return this.rpc.fetch<EthJsonRpcReturnTypes[typeof method]>(
169
+ // false = include only transaction roots, not full objects
170
+ {method, params: [blockNumberHex, false]},
171
+ getBlockByNumberOpts
172
+ );
173
+ }
174
+
175
+ async getBlockByHash(blockHashHex: string): Promise<EthJsonRpcBlockRaw | null> {
176
+ const method = "eth_getBlockByHash";
177
+ return this.rpc.fetch<EthJsonRpcReturnTypes[typeof method]>(
178
+ // false = include only transaction roots, not full objects
179
+ {method, params: [blockHashHex, false]},
180
+ getBlockByHashOpts
181
+ );
182
+ }
183
+
184
+ async getBlockNumber(): Promise<number> {
185
+ const method = "eth_blockNumber";
186
+ const blockNumberRaw = await this.rpc.fetch<EthJsonRpcReturnTypes[typeof method]>(
187
+ {method, params: []},
188
+ getBlockNumberOpts
189
+ );
190
+ return parseInt(blockNumberRaw, 16);
191
+ }
192
+
193
+ async getCode(address: string): Promise<string> {
194
+ const method = "eth_getCode";
195
+ return this.rpc.fetch<EthJsonRpcReturnTypes[typeof method]>({method, params: [address, "latest"]});
196
+ }
197
+
198
+ async getLogs(options: {
199
+ fromBlock: number;
200
+ toBlock: number;
201
+ address: string;
202
+ topics: string[];
203
+ }): Promise<{blockNumber: number; data: string; topics: string[]}[]> {
204
+ const method = "eth_getLogs";
205
+ const hexOptions = {
206
+ ...options,
207
+ fromBlock: numToQuantity(options.fromBlock),
208
+ toBlock: numToQuantity(options.toBlock),
209
+ };
210
+ const logsRaw = await this.rpc.fetch<EthJsonRpcReturnTypes[typeof method]>(
211
+ {method, params: [hexOptions]},
212
+ getLogsOpts
213
+ );
214
+ return logsRaw.map((logRaw) => ({
215
+ blockNumber: parseInt(logRaw.blockNumber, 16),
216
+ data: logRaw.data,
217
+ topics: logRaw.topics,
218
+ }));
219
+ }
220
+ }
221
+
222
+ export function parseEth1Block(blockRaw: EthJsonRpcBlockRaw): Eth1Block {
223
+ if (typeof blockRaw !== "object") throw Error("block is not an object");
224
+ return {
225
+ blockHash: dataToBytes(blockRaw.hash, 32),
226
+ blockNumber: quantityToNum(blockRaw.number, "block.number"),
227
+ timestamp: quantityToNum(blockRaw.timestamp, "block.timestamp"),
228
+ };
229
+ }
@@ -1,8 +1,8 @@
1
1
  import {EventEmitter} from "node:events";
2
2
  import {StrictEventEmitter} from "strict-event-emitter-types";
3
3
  import {ErrorAborted, Gauge, Histogram, TimeoutError, fetch, isValidHttpUrl, retry} from "@lodestar/utils";
4
+ import {IJson, RpcPayload} from "../interface.js";
4
5
  import {JwtClaim, encodeJwtToken} from "./jwt.js";
5
- import {IJson, RpcPayload} from "./utils.js";
6
6
 
7
7
  export enum JsonRpcHttpClientEvent {
8
8
  /**