@bsv/wallet-toolbox 1.7.18 → 2.0.0-beta.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 (606) hide show
  1. package/out/src/sdk/validationHelpers.d.ts +303 -0
  2. package/out/src/sdk/validationHelpers.d.ts.map +1 -0
  3. package/out/src/sdk/validationHelpers.js +632 -0
  4. package/out/src/sdk/validationHelpers.js.map +1 -0
  5. package/package.json +9 -2
  6. package/.env.template +0 -22
  7. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  8. package/.github/ISSUE_TEMPLATE/discussion.md +0 -24
  9. package/.github/pull_request_template.md +0 -22
  10. package/.github/workflows/push.yaml +0 -145
  11. package/.prettierrc +0 -10
  12. package/CONTRIBUTING.md +0 -89
  13. package/jest.config.ts +0 -25
  14. package/out/test/Wallet/StorageClient/storageClient.man.test.d.ts +0 -2
  15. package/out/test/Wallet/StorageClient/storageClient.man.test.d.ts.map +0 -1
  16. package/out/test/Wallet/StorageClient/storageClient.man.test.js +0 -64
  17. package/out/test/Wallet/StorageClient/storageClient.man.test.js.map +0 -1
  18. package/out/test/Wallet/action/internalizeAction.a.test.d.ts +0 -2
  19. package/out/test/Wallet/action/internalizeAction.a.test.d.ts.map +0 -1
  20. package/out/test/Wallet/action/internalizeAction.a.test.js +0 -243
  21. package/out/test/Wallet/action/internalizeAction.a.test.js.map +0 -1
  22. package/out/test/Wallet/certificate/acquireCertificate.test.d.ts +0 -2
  23. package/out/test/Wallet/certificate/acquireCertificate.test.d.ts.map +0 -1
  24. package/out/test/Wallet/certificate/acquireCertificate.test.js +0 -210
  25. package/out/test/Wallet/certificate/acquireCertificate.test.js.map +0 -1
  26. package/out/test/Wallet/certificate/listCertificates.test.d.ts +0 -2
  27. package/out/test/Wallet/certificate/listCertificates.test.d.ts.map +0 -1
  28. package/out/test/Wallet/certificate/listCertificates.test.js +0 -305
  29. package/out/test/Wallet/certificate/listCertificates.test.js.map +0 -1
  30. package/out/test/Wallet/get/getHeaderForHeight.test.d.ts +0 -2
  31. package/out/test/Wallet/get/getHeaderForHeight.test.d.ts.map +0 -1
  32. package/out/test/Wallet/get/getHeaderForHeight.test.js +0 -74
  33. package/out/test/Wallet/get/getHeaderForHeight.test.js.map +0 -1
  34. package/out/test/Wallet/get/getHeight.test.d.ts +0 -2
  35. package/out/test/Wallet/get/getHeight.test.d.ts.map +0 -1
  36. package/out/test/Wallet/get/getHeight.test.js +0 -48
  37. package/out/test/Wallet/get/getHeight.test.js.map +0 -1
  38. package/out/test/Wallet/get/getKnownTxids.test.d.ts +0 -2
  39. package/out/test/Wallet/get/getKnownTxids.test.d.ts.map +0 -1
  40. package/out/test/Wallet/get/getKnownTxids.test.js +0 -73
  41. package/out/test/Wallet/get/getKnownTxids.test.js.map +0 -1
  42. package/out/test/Wallet/get/getNetwork.test.d.ts +0 -2
  43. package/out/test/Wallet/get/getNetwork.test.d.ts.map +0 -1
  44. package/out/test/Wallet/get/getNetwork.test.js +0 -26
  45. package/out/test/Wallet/get/getNetwork.test.js.map +0 -1
  46. package/out/test/Wallet/get/getVersion.test.d.ts +0 -2
  47. package/out/test/Wallet/get/getVersion.test.d.ts.map +0 -1
  48. package/out/test/Wallet/get/getVersion.test.js +0 -25
  49. package/out/test/Wallet/get/getVersion.test.js.map +0 -1
  50. package/out/test/Wallet/live/walletLive.man.test.d.ts +0 -26
  51. package/out/test/Wallet/live/walletLive.man.test.d.ts.map +0 -1
  52. package/out/test/Wallet/live/walletLive.man.test.js +0 -417
  53. package/out/test/Wallet/live/walletLive.man.test.js.map +0 -1
  54. package/out/test/Wallet/local/localWallet.man.test.d.ts +0 -2
  55. package/out/test/Wallet/local/localWallet.man.test.d.ts.map +0 -1
  56. package/out/test/Wallet/local/localWallet.man.test.js +0 -83
  57. package/out/test/Wallet/local/localWallet.man.test.js.map +0 -1
  58. package/out/test/Wallet/local/localWallet2.man.test.d.ts +0 -2
  59. package/out/test/Wallet/local/localWallet2.man.test.d.ts.map +0 -1
  60. package/out/test/Wallet/local/localWallet2.man.test.js +0 -284
  61. package/out/test/Wallet/local/localWallet2.man.test.js.map +0 -1
  62. package/out/test/Wallet/signAction/mountaintop.man.test.d.ts +0 -2
  63. package/out/test/Wallet/signAction/mountaintop.man.test.d.ts.map +0 -1
  64. package/out/test/Wallet/signAction/mountaintop.man.test.js +0 -109
  65. package/out/test/Wallet/signAction/mountaintop.man.test.js.map +0 -1
  66. package/out/test/Wallet/specOps/specOps.man.test.d.ts +0 -2
  67. package/out/test/Wallet/specOps/specOps.man.test.d.ts.map +0 -1
  68. package/out/test/Wallet/specOps/specOps.man.test.js +0 -163
  69. package/out/test/Wallet/specOps/specOps.man.test.js.map +0 -1
  70. package/out/test/Wallet/support/janitor.man.test.d.ts +0 -2
  71. package/out/test/Wallet/support/janitor.man.test.d.ts.map +0 -1
  72. package/out/test/Wallet/support/janitor.man.test.js +0 -38
  73. package/out/test/Wallet/support/janitor.man.test.js.map +0 -1
  74. package/out/test/Wallet/support/operations.man.test.d.ts +0 -2
  75. package/out/test/Wallet/support/operations.man.test.d.ts.map +0 -1
  76. package/out/test/Wallet/support/operations.man.test.js +0 -370
  77. package/out/test/Wallet/support/operations.man.test.js.map +0 -1
  78. package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.d.ts +0 -2
  79. package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.d.ts.map +0 -1
  80. package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.js +0 -385
  81. package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.js.map +0 -1
  82. package/out/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.d.ts +0 -2
  83. package/out/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.d.ts.map +0 -1
  84. package/out/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.js +0 -206
  85. package/out/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.js.map +0 -1
  86. package/out/test/Wallet/sync/setActive.test.d.ts +0 -2
  87. package/out/test/Wallet/sync/setActive.test.d.ts.map +0 -1
  88. package/out/test/Wallet/sync/setActive.test.js +0 -161
  89. package/out/test/Wallet/sync/setActive.test.js.map +0 -1
  90. package/out/test/WalletClient/LocalKVStore.man.test.d.ts +0 -2
  91. package/out/test/WalletClient/LocalKVStore.man.test.d.ts.map +0 -1
  92. package/out/test/WalletClient/LocalKVStore.man.test.js +0 -99
  93. package/out/test/WalletClient/LocalKVStore.man.test.js.map +0 -1
  94. package/out/test/WalletClient/WERR.man.test.d.ts +0 -2
  95. package/out/test/WalletClient/WERR.man.test.d.ts.map +0 -1
  96. package/out/test/WalletClient/WERR.man.test.js +0 -34
  97. package/out/test/WalletClient/WERR.man.test.js.map +0 -1
  98. package/out/test/bsv-ts-sdk/LocalKVStore.test.d.ts +0 -2
  99. package/out/test/bsv-ts-sdk/LocalKVStore.test.d.ts.map +0 -1
  100. package/out/test/bsv-ts-sdk/LocalKVStore.test.js +0 -98
  101. package/out/test/bsv-ts-sdk/LocalKVStore.test.js.map +0 -1
  102. package/out/test/checkDB.d.ts +0 -4
  103. package/out/test/checkDB.d.ts.map +0 -1
  104. package/out/test/checkDB.js +0 -55
  105. package/out/test/checkDB.js.map +0 -1
  106. package/out/test/examples/backup.man.test.d.ts +0 -14
  107. package/out/test/examples/backup.man.test.d.ts.map +0 -1
  108. package/out/test/examples/backup.man.test.js +0 -59
  109. package/out/test/examples/backup.man.test.js.map +0 -1
  110. package/out/test/examples/pushdrop.test.d.ts +0 -56
  111. package/out/test/examples/pushdrop.test.d.ts.map +0 -1
  112. package/out/test/examples/pushdrop.test.js +0 -232
  113. package/out/test/examples/pushdrop.test.js.map +0 -1
  114. package/out/test/monitor/Monitor.test.d.ts +0 -2
  115. package/out/test/monitor/Monitor.test.d.ts.map +0 -1
  116. package/out/test/monitor/Monitor.test.js +0 -560
  117. package/out/test/monitor/Monitor.test.js.map +0 -1
  118. package/out/test/services/Services.test.d.ts +0 -2
  119. package/out/test/services/Services.test.d.ts.map +0 -1
  120. package/out/test/services/Services.test.js +0 -246
  121. package/out/test/services/Services.test.js.map +0 -1
  122. package/out/test/storage/KnexMigrations.test.d.ts +0 -2
  123. package/out/test/storage/KnexMigrations.test.d.ts.map +0 -1
  124. package/out/test/storage/KnexMigrations.test.js +0 -81
  125. package/out/test/storage/KnexMigrations.test.js.map +0 -1
  126. package/out/test/storage/StorageMySQLDojoReader.man.test.d.ts +0 -2
  127. package/out/test/storage/StorageMySQLDojoReader.man.test.d.ts.map +0 -1
  128. package/out/test/storage/StorageMySQLDojoReader.man.test.js +0 -86
  129. package/out/test/storage/StorageMySQLDojoReader.man.test.js.map +0 -1
  130. package/out/test/storage/count.test.d.ts +0 -2
  131. package/out/test/storage/count.test.d.ts.map +0 -1
  132. package/out/test/storage/count.test.js +0 -142
  133. package/out/test/storage/count.test.js.map +0 -1
  134. package/out/test/storage/find.test.d.ts +0 -2
  135. package/out/test/storage/find.test.d.ts.map +0 -1
  136. package/out/test/storage/find.test.js +0 -144
  137. package/out/test/storage/find.test.js.map +0 -1
  138. package/out/test/storage/findLegacy.test.d.ts +0 -2
  139. package/out/test/storage/findLegacy.test.d.ts.map +0 -1
  140. package/out/test/storage/findLegacy.test.js +0 -52
  141. package/out/test/storage/findLegacy.test.js.map +0 -1
  142. package/out/test/storage/idb/allocateChange.test.d.ts +0 -2
  143. package/out/test/storage/idb/allocateChange.test.d.ts.map +0 -1
  144. package/out/test/storage/idb/allocateChange.test.js +0 -110
  145. package/out/test/storage/idb/allocateChange.test.js.map +0 -1
  146. package/out/test/storage/idb/count.test.d.ts +0 -2
  147. package/out/test/storage/idb/count.test.d.ts.map +0 -1
  148. package/out/test/storage/idb/count.test.js +0 -129
  149. package/out/test/storage/idb/count.test.js.map +0 -1
  150. package/out/test/storage/idb/find.test.d.ts +0 -2
  151. package/out/test/storage/idb/find.test.d.ts.map +0 -1
  152. package/out/test/storage/idb/find.test.js +0 -131
  153. package/out/test/storage/idb/find.test.js.map +0 -1
  154. package/out/test/storage/idb/idbSpeed.test.d.ts +0 -2
  155. package/out/test/storage/idb/idbSpeed.test.d.ts.map +0 -1
  156. package/out/test/storage/idb/idbSpeed.test.js +0 -30
  157. package/out/test/storage/idb/idbSpeed.test.js.map +0 -1
  158. package/out/test/storage/idb/insert.test.d.ts +0 -2
  159. package/out/test/storage/idb/insert.test.d.ts.map +0 -1
  160. package/out/test/storage/idb/insert.test.js +0 -242
  161. package/out/test/storage/idb/insert.test.js.map +0 -1
  162. package/out/test/storage/idb/transactionAbort.test.d.ts +0 -2
  163. package/out/test/storage/idb/transactionAbort.test.d.ts.map +0 -1
  164. package/out/test/storage/idb/transactionAbort.test.js +0 -97
  165. package/out/test/storage/idb/transactionAbort.test.js.map +0 -1
  166. package/out/test/storage/idb/update.test.d.ts +0 -2
  167. package/out/test/storage/idb/update.test.d.ts.map +0 -1
  168. package/out/test/storage/idb/update.test.js +0 -902
  169. package/out/test/storage/idb/update.test.js.map +0 -1
  170. package/out/test/storage/insert.test.d.ts +0 -2
  171. package/out/test/storage/insert.test.d.ts.map +0 -1
  172. package/out/test/storage/insert.test.js +0 -256
  173. package/out/test/storage/insert.test.js.map +0 -1
  174. package/out/test/storage/update.test.d.ts +0 -2
  175. package/out/test/storage/update.test.d.ts.map +0 -1
  176. package/out/test/storage/update.test.js +0 -919
  177. package/out/test/storage/update.test.js.map +0 -1
  178. package/out/test/storage/update2.test.d.ts +0 -2
  179. package/out/test/storage/update2.test.d.ts.map +0 -1
  180. package/out/test/storage/update2.test.js +0 -767
  181. package/out/test/storage/update2.test.js.map +0 -1
  182. package/out/test/utils/TestUtilsWalletStorage.d.ts +0 -523
  183. package/out/test/utils/TestUtilsWalletStorage.d.ts.map +0 -1
  184. package/out/test/utils/TestUtilsWalletStorage.js +0 -1958
  185. package/out/test/utils/TestUtilsWalletStorage.js.map +0 -1
  186. package/out/test/utils/localWalletMethods.d.ts +0 -33
  187. package/out/test/utils/localWalletMethods.d.ts.map +0 -1
  188. package/out/test/utils/localWalletMethods.js +0 -304
  189. package/out/test/utils/localWalletMethods.js.map +0 -1
  190. package/out/test/wallet/action/abortAction.test.d.ts +0 -2
  191. package/out/test/wallet/action/abortAction.test.d.ts.map +0 -1
  192. package/out/test/wallet/action/abortAction.test.js +0 -44
  193. package/out/test/wallet/action/abortAction.test.js.map +0 -1
  194. package/out/test/wallet/action/createAction.test.d.ts +0 -2
  195. package/out/test/wallet/action/createAction.test.d.ts.map +0 -1
  196. package/out/test/wallet/action/createAction.test.js +0 -272
  197. package/out/test/wallet/action/createAction.test.js.map +0 -1
  198. package/out/test/wallet/action/createAction2.test.d.ts +0 -37
  199. package/out/test/wallet/action/createAction2.test.d.ts.map +0 -1
  200. package/out/test/wallet/action/createAction2.test.js +0 -1143
  201. package/out/test/wallet/action/createAction2.test.js.map +0 -1
  202. package/out/test/wallet/action/createActionToGenerateBeefs.man.test.d.ts +0 -2
  203. package/out/test/wallet/action/createActionToGenerateBeefs.man.test.d.ts.map +0 -1
  204. package/out/test/wallet/action/createActionToGenerateBeefs.man.test.js +0 -273
  205. package/out/test/wallet/action/createActionToGenerateBeefs.man.test.js.map +0 -1
  206. package/out/test/wallet/action/internalizeAction.test.d.ts +0 -2
  207. package/out/test/wallet/action/internalizeAction.test.d.ts.map +0 -1
  208. package/out/test/wallet/action/internalizeAction.test.js +0 -608
  209. package/out/test/wallet/action/internalizeAction.test.js.map +0 -1
  210. package/out/test/wallet/action/relinquishOutput.test.d.ts +0 -2
  211. package/out/test/wallet/action/relinquishOutput.test.d.ts.map +0 -1
  212. package/out/test/wallet/action/relinquishOutput.test.js +0 -31
  213. package/out/test/wallet/action/relinquishOutput.test.js.map +0 -1
  214. package/out/test/wallet/construct/Wallet.constructor.test.d.ts +0 -2
  215. package/out/test/wallet/construct/Wallet.constructor.test.d.ts.map +0 -1
  216. package/out/test/wallet/construct/Wallet.constructor.test.js +0 -49
  217. package/out/test/wallet/construct/Wallet.constructor.test.js.map +0 -1
  218. package/out/test/wallet/list/listActions.test.d.ts +0 -2
  219. package/out/test/wallet/list/listActions.test.d.ts.map +0 -1
  220. package/out/test/wallet/list/listActions.test.js +0 -271
  221. package/out/test/wallet/list/listActions.test.js.map +0 -1
  222. package/out/test/wallet/list/listActions2.test.d.ts +0 -2
  223. package/out/test/wallet/list/listActions2.test.d.ts.map +0 -1
  224. package/out/test/wallet/list/listActions2.test.js +0 -1141
  225. package/out/test/wallet/list/listActions2.test.js.map +0 -1
  226. package/out/test/wallet/list/listCertificates.test.d.ts +0 -2
  227. package/out/test/wallet/list/listCertificates.test.d.ts.map +0 -1
  228. package/out/test/wallet/list/listCertificates.test.js +0 -111
  229. package/out/test/wallet/list/listCertificates.test.js.map +0 -1
  230. package/out/test/wallet/list/listOutputs.test.d.ts +0 -2
  231. package/out/test/wallet/list/listOutputs.test.d.ts.map +0 -1
  232. package/out/test/wallet/list/listOutputs.test.js +0 -424
  233. package/out/test/wallet/list/listOutputs.test.js.map +0 -1
  234. package/out/test/wallet/sync/Wallet.sync.test.d.ts +0 -2
  235. package/out/test/wallet/sync/Wallet.sync.test.d.ts.map +0 -1
  236. package/out/test/wallet/sync/Wallet.sync.test.js +0 -155
  237. package/out/test/wallet/sync/Wallet.sync.test.js.map +0 -1
  238. package/out/tsconfig.all.tsbuildinfo +0 -1
  239. package/src/CWIStyleWalletManager.ts +0 -1999
  240. package/src/Setup.ts +0 -579
  241. package/src/SetupClient.ts +0 -322
  242. package/src/SetupWallet.ts +0 -108
  243. package/src/SimpleWalletManager.ts +0 -526
  244. package/src/Wallet.ts +0 -1169
  245. package/src/WalletAuthenticationManager.ts +0 -153
  246. package/src/WalletLogger.ts +0 -213
  247. package/src/WalletPermissionsManager.ts +0 -3660
  248. package/src/WalletSettingsManager.ts +0 -114
  249. package/src/__tests/CWIStyleWalletManager.test.d.ts.map +0 -1
  250. package/src/__tests/CWIStyleWalletManager.test.js.map +0 -1
  251. package/src/__tests/CWIStyleWalletManager.test.ts +0 -675
  252. package/src/__tests/WalletPermissionsManager.callbacks.test.ts +0 -323
  253. package/src/__tests/WalletPermissionsManager.checks.test.ts +0 -844
  254. package/src/__tests/WalletPermissionsManager.encryption.test.ts +0 -412
  255. package/src/__tests/WalletPermissionsManager.fixtures.ts +0 -307
  256. package/src/__tests/WalletPermissionsManager.flows.test.ts +0 -462
  257. package/src/__tests/WalletPermissionsManager.initialization.test.ts +0 -300
  258. package/src/__tests/WalletPermissionsManager.pmodules.test.ts +0 -798
  259. package/src/__tests/WalletPermissionsManager.proxying.test.ts +0 -724
  260. package/src/__tests/WalletPermissionsManager.tokens.test.ts +0 -503
  261. package/src/index.all.ts +0 -27
  262. package/src/index.client.ts +0 -25
  263. package/src/index.mobile.ts +0 -21
  264. package/src/index.ts +0 -1
  265. package/src/monitor/Monitor.ts +0 -412
  266. package/src/monitor/MonitorDaemon.ts +0 -188
  267. package/src/monitor/README.md +0 -3
  268. package/src/monitor/__test/MonitorDaemon.man.test.ts +0 -45
  269. package/src/monitor/tasks/TaskCheckForProofs.ts +0 -243
  270. package/src/monitor/tasks/TaskCheckNoSends.ts +0 -73
  271. package/src/monitor/tasks/TaskClock.ts +0 -33
  272. package/src/monitor/tasks/TaskFailAbandoned.ts +0 -54
  273. package/src/monitor/tasks/TaskMonitorCallHistory.ts +0 -26
  274. package/src/monitor/tasks/TaskNewHeader.ts +0 -93
  275. package/src/monitor/tasks/TaskPurge.ts +0 -68
  276. package/src/monitor/tasks/TaskReorg.ts +0 -89
  277. package/src/monitor/tasks/TaskReviewStatus.ts +0 -48
  278. package/src/monitor/tasks/TaskSendWaiting.ts +0 -122
  279. package/src/monitor/tasks/TaskSyncWhenIdle.ts +0 -26
  280. package/src/monitor/tasks/TaskUnFail.ts +0 -151
  281. package/src/monitor/tasks/WalletMonitorTask.ts +0 -47
  282. package/src/sdk/CertOpsWallet.ts +0 -18
  283. package/src/sdk/PrivilegedKeyManager.ts +0 -372
  284. package/src/sdk/README.md +0 -13
  285. package/src/sdk/WERR_errors.ts +0 -234
  286. package/src/sdk/WalletError.ts +0 -170
  287. package/src/sdk/WalletErrorFromJson.ts +0 -80
  288. package/src/sdk/WalletServices.interfaces.ts +0 -700
  289. package/src/sdk/WalletSigner.interfaces.ts +0 -11
  290. package/src/sdk/WalletStorage.interfaces.ts +0 -606
  291. package/src/sdk/__test/CertificateLifeCycle.test.ts +0 -131
  292. package/src/sdk/__test/PrivilegedKeyManager.test.ts +0 -738
  293. package/src/sdk/__test/WalletError.test.ts +0 -318
  294. package/src/sdk/__test/validationHelpers.test.ts +0 -21
  295. package/src/sdk/index.ts +0 -10
  296. package/src/sdk/types.ts +0 -226
  297. package/src/services/README.md +0 -11
  298. package/src/services/ServiceCollection.ts +0 -248
  299. package/src/services/Services.ts +0 -603
  300. package/src/services/__tests/ARC.man.test.ts +0 -123
  301. package/src/services/__tests/ARC.timeout.man.test.ts +0 -79
  302. package/src/services/__tests/ArcGorillaPool.man.test.ts +0 -108
  303. package/src/services/__tests/arcServices.test.ts +0 -8
  304. package/src/services/__tests/bitrails.test.ts +0 -56
  305. package/src/services/__tests/getMerklePath.test.ts +0 -15
  306. package/src/services/__tests/getRawTx.test.ts +0 -13
  307. package/src/services/__tests/postBeef.test.ts +0 -104
  308. package/src/services/__tests/verifyBeef.test.ts +0 -50
  309. package/src/services/chaintracker/BHServiceClient.ts +0 -212
  310. package/src/services/chaintracker/ChaintracksChainTracker.ts +0 -71
  311. package/src/services/chaintracker/__tests/ChaintracksChainTracker.test.ts +0 -33
  312. package/src/services/chaintracker/__tests/ChaintracksServiceClient.test.ts +0 -29
  313. package/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.ts +0 -72
  314. package/src/services/chaintracker/chaintracks/Api/BulkIngestorApi.ts +0 -83
  315. package/src/services/chaintracker/chaintracks/Api/BulkStorageApi.ts +0 -92
  316. package/src/services/chaintracker/chaintracks/Api/ChaintracksApi.ts +0 -64
  317. package/src/services/chaintracker/chaintracks/Api/ChaintracksClientApi.ts +0 -189
  318. package/src/services/chaintracker/chaintracks/Api/ChaintracksFetchApi.ts +0 -18
  319. package/src/services/chaintracker/chaintracks/Api/ChaintracksFsApi.ts +0 -58
  320. package/src/services/chaintracker/chaintracks/Api/ChaintracksStorageApi.ts +0 -386
  321. package/src/services/chaintracker/chaintracks/Api/LiveIngestorApi.ts +0 -25
  322. package/src/services/chaintracker/chaintracks/Chaintracks.ts +0 -609
  323. package/src/services/chaintracker/chaintracks/ChaintracksService.ts +0 -199
  324. package/src/services/chaintracker/chaintracks/ChaintracksServiceClient.ts +0 -154
  325. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.ts +0 -176
  326. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.ts +0 -174
  327. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDNBabbage.ts +0 -18
  328. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.ts +0 -113
  329. package/src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainWs.ts +0 -81
  330. package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.ts +0 -86
  331. package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorTeranodeP2P.ts +0 -59
  332. package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.ts +0 -104
  333. package/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainWs.ts +0 -66
  334. package/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.ts +0 -566
  335. package/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.ts +0 -219
  336. package/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorCDNBabbage.test.ts +0 -54
  337. package/src/services/chaintracker/chaintracks/Ingest/__tests/LiveIngestorWhatsOnChainPoll.test.ts +0 -33
  338. package/src/services/chaintracker/chaintracks/Ingest/__tests/WhatsOnChainServices.test.ts +0 -124
  339. package/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.ts +0 -92
  340. package/src/services/chaintracker/chaintracks/Storage/ChaintracksKnexMigrations.ts +0 -104
  341. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.ts +0 -382
  342. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.ts +0 -574
  343. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.ts +0 -438
  344. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageMemory.ts +0 -29
  345. package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.ts +0 -304
  346. package/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageIdb.test.ts +0 -102
  347. package/src/services/chaintracker/chaintracks/Storage/__tests/ChaintracksStorageKnex.test.ts +0 -45
  348. package/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.ts +0 -77
  349. package/src/services/chaintracker/chaintracks/__tests/ChaintracksClientApi.test.ts +0 -192
  350. package/src/services/chaintracker/chaintracks/__tests/LocalCdnServer.ts +0 -75
  351. package/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.ts +0 -62
  352. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNetBlockHeaders.json +0 -1
  353. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_0.headers +0 -0
  354. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_1.headers +0 -0
  355. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_2.headers +0 -0
  356. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest349/mainNet_3.headers +0 -0
  357. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNetBlockHeaders.json +0 -1
  358. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_0.headers +0 -0
  359. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_1.headers +0 -0
  360. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_2.headers +0 -0
  361. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest379/mainNet_3.headers +0 -0
  362. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNetBlockHeaders.json +0 -1
  363. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_0.headers +0 -0
  364. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_1.headers +0 -0
  365. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_2.headers +0 -0
  366. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest399/mainNet_3.headers +0 -0
  367. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNetBlockHeaders.json +0 -1
  368. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_0.headers +0 -0
  369. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_1.headers +0 -0
  370. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_2.headers +0 -0
  371. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_3.headers +0 -0
  372. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest402/mainNet_4.headers +0 -0
  373. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNetBlockHeaders.json +0 -1
  374. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_0.headers +0 -0
  375. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_1.headers +0 -0
  376. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_2.headers +0 -0
  377. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_3.headers +0 -0
  378. package/src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_4.headers +0 -0
  379. package/src/services/chaintracker/chaintracks/createDefaultIdbChaintracksOptions.ts +0 -92
  380. package/src/services/chaintracker/chaintracks/createDefaultKnexChaintracksOptions.ts +0 -111
  381. package/src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.ts +0 -91
  382. package/src/services/chaintracker/chaintracks/createIdbChaintracks.ts +0 -60
  383. package/src/services/chaintracker/chaintracks/createKnexChaintracks.ts +0 -65
  384. package/src/services/chaintracker/chaintracks/createNoDbChaintracks.ts +0 -60
  385. package/src/services/chaintracker/chaintracks/index.all.ts +0 -12
  386. package/src/services/chaintracker/chaintracks/index.client.ts +0 -4
  387. package/src/services/chaintracker/chaintracks/index.mobile.ts +0 -37
  388. package/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts +0 -975
  389. package/src/services/chaintracker/chaintracks/util/BulkFileDataReader.ts +0 -60
  390. package/src/services/chaintracker/chaintracks/util/BulkFilesReader.ts +0 -336
  391. package/src/services/chaintracker/chaintracks/util/BulkHeaderFile.ts +0 -247
  392. package/src/services/chaintracker/chaintracks/util/ChaintracksFetch.ts +0 -69
  393. package/src/services/chaintracker/chaintracks/util/ChaintracksFs.ts +0 -141
  394. package/src/services/chaintracker/chaintracks/util/HeightRange.ts +0 -153
  395. package/src/services/chaintracker/chaintracks/util/SingleWriterMultiReaderLock.ts +0 -76
  396. package/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.ts +0 -304
  397. package/src/services/chaintracker/chaintracks/util/__tests/ChaintracksFetch.test.ts +0 -60
  398. package/src/services/chaintracker/chaintracks/util/__tests/HeightRange.test.ts +0 -67
  399. package/src/services/chaintracker/chaintracks/util/__tests/SingleWriterMultiReaderLock.test.ts +0 -49
  400. package/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.ts +0 -573
  401. package/src/services/chaintracker/chaintracks/util/dirtyHashes.ts +0 -29
  402. package/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.ts +0 -432
  403. package/src/services/chaintracker/index.all.ts +0 -4
  404. package/src/services/chaintracker/index.client.ts +0 -4
  405. package/src/services/chaintracker/index.mobile.ts +0 -4
  406. package/src/services/createDefaultWalletServicesOptions.ts +0 -77
  407. package/src/services/index.ts +0 -1
  408. package/src/services/processingErrors/arcSuccessError.json +0 -76
  409. package/src/services/providers/ARC.ts +0 -350
  410. package/src/services/providers/Bitails.ts +0 -256
  411. package/src/services/providers/SdkWhatsOnChain.ts +0 -83
  412. package/src/services/providers/WhatsOnChain.ts +0 -883
  413. package/src/services/providers/__tests/WhatsOnChain.test.ts +0 -242
  414. package/src/services/providers/__tests/exchangeRates.test.ts +0 -18
  415. package/src/services/providers/exchangeRates.ts +0 -265
  416. package/src/services/providers/getBeefForTxid.ts +0 -369
  417. package/src/signer/README.md +0 -5
  418. package/src/signer/WalletSigner.ts +0 -17
  419. package/src/signer/methods/acquireDirectCertificate.ts +0 -52
  420. package/src/signer/methods/buildSignableTransaction.ts +0 -183
  421. package/src/signer/methods/completeSignedTransaction.ts +0 -117
  422. package/src/signer/methods/createAction.ts +0 -172
  423. package/src/signer/methods/internalizeAction.ts +0 -106
  424. package/src/signer/methods/proveCertificate.ts +0 -43
  425. package/src/signer/methods/signAction.ts +0 -54
  426. package/src/storage/README.md +0 -14
  427. package/src/storage/StorageIdb.ts +0 -2304
  428. package/src/storage/StorageKnex.ts +0 -1425
  429. package/src/storage/StorageProvider.ts +0 -810
  430. package/src/storage/StorageReader.ts +0 -194
  431. package/src/storage/StorageReaderWriter.ts +0 -432
  432. package/src/storage/StorageSyncReader.ts +0 -34
  433. package/src/storage/WalletStorageManager.ts +0 -943
  434. package/src/storage/__test/StorageIdb.test.ts +0 -43
  435. package/src/storage/__test/WalletStorageManager.test.ts +0 -275
  436. package/src/storage/__test/adminStats.man.test.ts +0 -89
  437. package/src/storage/__test/getBeefForTransaction.test.ts +0 -385
  438. package/src/storage/index.all.ts +0 -11
  439. package/src/storage/index.client.ts +0 -7
  440. package/src/storage/index.mobile.ts +0 -6
  441. package/src/storage/methods/ListActionsSpecOp.ts +0 -70
  442. package/src/storage/methods/ListOutputsSpecOp.ts +0 -129
  443. package/src/storage/methods/__test/GenerateChange/generateChangeSdk.test.ts +0 -1057
  444. package/src/storage/methods/__test/GenerateChange/randomValsUsed1.ts +0 -20
  445. package/src/storage/methods/__test/offsetKey.test.ts +0 -274
  446. package/src/storage/methods/attemptToPostReqsToNetwork.ts +0 -389
  447. package/src/storage/methods/createAction.ts +0 -947
  448. package/src/storage/methods/generateChange.ts +0 -556
  449. package/src/storage/methods/getBeefForTransaction.ts +0 -139
  450. package/src/storage/methods/getSyncChunk.ts +0 -293
  451. package/src/storage/methods/internalizeAction.ts +0 -562
  452. package/src/storage/methods/listActionsIdb.ts +0 -183
  453. package/src/storage/methods/listActionsKnex.ts +0 -226
  454. package/src/storage/methods/listCertificates.ts +0 -73
  455. package/src/storage/methods/listOutputsIdb.ts +0 -203
  456. package/src/storage/methods/listOutputsKnex.ts +0 -263
  457. package/src/storage/methods/offsetKey.ts +0 -89
  458. package/src/storage/methods/processAction.ts +0 -420
  459. package/src/storage/methods/purgeData.ts +0 -251
  460. package/src/storage/methods/purgeDataIdb.ts +0 -10
  461. package/src/storage/methods/reviewStatus.ts +0 -101
  462. package/src/storage/methods/reviewStatusIdb.ts +0 -43
  463. package/src/storage/methods/utils.Buffer.ts +0 -33
  464. package/src/storage/methods/utils.ts +0 -56
  465. package/src/storage/remoting/StorageClient.ts +0 -567
  466. package/src/storage/remoting/StorageMobile.ts +0 -544
  467. package/src/storage/remoting/StorageServer.ts +0 -291
  468. package/src/storage/remoting/__test/StorageClient.test.ts +0 -113
  469. package/src/storage/schema/KnexMigrations.ts +0 -489
  470. package/src/storage/schema/StorageIdbSchema.ts +0 -150
  471. package/src/storage/schema/entities/EntityBase.ts +0 -210
  472. package/src/storage/schema/entities/EntityCertificate.ts +0 -188
  473. package/src/storage/schema/entities/EntityCertificateField.ts +0 -136
  474. package/src/storage/schema/entities/EntityCommission.ts +0 -148
  475. package/src/storage/schema/entities/EntityOutput.ts +0 -290
  476. package/src/storage/schema/entities/EntityOutputBasket.ts +0 -153
  477. package/src/storage/schema/entities/EntityOutputTag.ts +0 -121
  478. package/src/storage/schema/entities/EntityOutputTagMap.ts +0 -123
  479. package/src/storage/schema/entities/EntityProvenTx.ts +0 -319
  480. package/src/storage/schema/entities/EntityProvenTxReq.ts +0 -580
  481. package/src/storage/schema/entities/EntitySyncState.ts +0 -389
  482. package/src/storage/schema/entities/EntityTransaction.ts +0 -306
  483. package/src/storage/schema/entities/EntityTxLabel.ts +0 -121
  484. package/src/storage/schema/entities/EntityTxLabelMap.ts +0 -123
  485. package/src/storage/schema/entities/EntityUser.ts +0 -112
  486. package/src/storage/schema/entities/MergeEntity.ts +0 -73
  487. package/src/storage/schema/entities/__tests/CertificateFieldTests.test.ts +0 -353
  488. package/src/storage/schema/entities/__tests/CertificateTests.test.ts +0 -354
  489. package/src/storage/schema/entities/__tests/CommissionTests.test.ts +0 -371
  490. package/src/storage/schema/entities/__tests/OutputBasketTests.test.ts +0 -278
  491. package/src/storage/schema/entities/__tests/OutputTagMapTests.test.ts +0 -242
  492. package/src/storage/schema/entities/__tests/OutputTagTests.test.ts +0 -288
  493. package/src/storage/schema/entities/__tests/OutputTests.test.ts +0 -464
  494. package/src/storage/schema/entities/__tests/ProvenTxReqTests.test.ts +0 -340
  495. package/src/storage/schema/entities/__tests/ProvenTxTests.test.ts +0 -504
  496. package/src/storage/schema/entities/__tests/SyncStateTests.test.ts +0 -288
  497. package/src/storage/schema/entities/__tests/TransactionTests.test.ts +0 -604
  498. package/src/storage/schema/entities/__tests/TxLabelMapTests.test.ts +0 -361
  499. package/src/storage/schema/entities/__tests/TxLabelTests.test.ts +0 -198
  500. package/src/storage/schema/entities/__tests/stampLogTests.test.ts +0 -90
  501. package/src/storage/schema/entities/__tests/usersTests.test.ts +0 -340
  502. package/src/storage/schema/entities/index.ts +0 -16
  503. package/src/storage/schema/tables/TableCertificate.ts +0 -21
  504. package/src/storage/schema/tables/TableCertificateField.ts +0 -12
  505. package/src/storage/schema/tables/TableCommission.ts +0 -13
  506. package/src/storage/schema/tables/TableMonitorEvent.ts +0 -9
  507. package/src/storage/schema/tables/TableOutput.ts +0 -64
  508. package/src/storage/schema/tables/TableOutputBasket.ts +0 -12
  509. package/src/storage/schema/tables/TableOutputTag.ts +0 -10
  510. package/src/storage/schema/tables/TableOutputTagMap.ts +0 -9
  511. package/src/storage/schema/tables/TableProvenTx.ts +0 -14
  512. package/src/storage/schema/tables/TableProvenTxReq.ts +0 -65
  513. package/src/storage/schema/tables/TableSettings.ts +0 -17
  514. package/src/storage/schema/tables/TableSyncState.ts +0 -18
  515. package/src/storage/schema/tables/TableTransaction.ts +0 -54
  516. package/src/storage/schema/tables/TableTxLabel.ts +0 -10
  517. package/src/storage/schema/tables/TableTxLabelMap.ts +0 -9
  518. package/src/storage/schema/tables/TableUser.ts +0 -16
  519. package/src/storage/schema/tables/index.ts +0 -16
  520. package/src/storage/sync/StorageMySQLDojoReader.ts +0 -696
  521. package/src/storage/sync/index.ts +0 -1
  522. package/src/utility/Format.ts +0 -133
  523. package/src/utility/README.md +0 -3
  524. package/src/utility/ReaderUint8Array.ts +0 -187
  525. package/src/utility/ScriptTemplateBRC29.ts +0 -73
  526. package/src/utility/__tests/utilityHelpers.noBuffer.test.ts +0 -109
  527. package/src/utility/aggregateResults.ts +0 -68
  528. package/src/utility/identityUtils.ts +0 -159
  529. package/src/utility/index.all.ts +0 -7
  530. package/src/utility/index.client.ts +0 -7
  531. package/src/utility/parseTxScriptOffsets.ts +0 -29
  532. package/src/utility/stampLog.ts +0 -69
  533. package/src/utility/tscProofToMerklePath.ts +0 -48
  534. package/src/utility/utilityHelpers.buffer.ts +0 -34
  535. package/src/utility/utilityHelpers.noBuffer.ts +0 -60
  536. package/src/utility/utilityHelpers.ts +0 -275
  537. package/src/wab-client/WABClient.ts +0 -94
  538. package/src/wab-client/__tests/WABClient.man.test.ts +0 -59
  539. package/src/wab-client/auth-method-interactors/AuthMethodInteractor.ts +0 -47
  540. package/src/wab-client/auth-method-interactors/DevConsoleInteractor.ts +0 -73
  541. package/src/wab-client/auth-method-interactors/PersonaIDInteractor.ts +0 -35
  542. package/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.ts +0 -72
  543. package/syncVersions.js +0 -71
  544. package/test/Wallet/StorageClient/storageClient.man.test.ts +0 -75
  545. package/test/Wallet/action/internalizeAction.a.test.ts +0 -286
  546. package/test/Wallet/certificate/acquireCertificate.test.ts +0 -298
  547. package/test/Wallet/certificate/listCertificates.test.ts +0 -346
  548. package/test/Wallet/get/getHeaderForHeight.test.ts +0 -82
  549. package/test/Wallet/get/getHeight.test.ts +0 -52
  550. package/test/Wallet/get/getKnownTxids.test.ts +0 -86
  551. package/test/Wallet/get/getNetwork.test.ts +0 -27
  552. package/test/Wallet/get/getVersion.test.ts +0 -27
  553. package/test/Wallet/live/walletLive.man.test.ts +0 -521
  554. package/test/Wallet/local/localWallet.man.test.ts +0 -93
  555. package/test/Wallet/local/localWallet2.man.test.ts +0 -277
  556. package/test/Wallet/signAction/mountaintop.man.test.ts +0 -130
  557. package/test/Wallet/specOps/specOps.man.test.ts +0 -220
  558. package/test/Wallet/support/janitor.man.test.ts +0 -40
  559. package/test/Wallet/support/operations.man.test.ts +0 -407
  560. package/test/Wallet/support/reqErrorReview.2025.05.06.man.test.ts +0 -347
  561. package/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.ts +0 -203
  562. package/test/Wallet/sync/setActive.test.ts +0 -170
  563. package/test/WalletClient/LocalKVStore.man.test.ts +0 -114
  564. package/test/WalletClient/WERR.man.test.ts +0 -35
  565. package/test/bsv-ts-sdk/LocalKVStore.test.ts +0 -102
  566. package/test/checkDB.ts +0 -57
  567. package/test/checkdb +0 -0
  568. package/test/examples/backup.man.test.ts +0 -59
  569. package/test/examples/pushdrop.test.ts +0 -282
  570. package/test/monitor/Monitor.test.ts +0 -620
  571. package/test/services/Services.test.ts +0 -263
  572. package/test/storage/KnexMigrations.test.ts +0 -86
  573. package/test/storage/StorageMySQLDojoReader.man.test.ts +0 -60
  574. package/test/storage/count.test.ts +0 -177
  575. package/test/storage/find.test.ts +0 -195
  576. package/test/storage/findLegacy.test.ts +0 -67
  577. package/test/storage/idb/allocateChange.test.ts +0 -251
  578. package/test/storage/idb/count.test.ts +0 -158
  579. package/test/storage/idb/find.test.ts +0 -177
  580. package/test/storage/idb/idbSpeed.test.ts +0 -36
  581. package/test/storage/idb/insert.test.ts +0 -268
  582. package/test/storage/idb/transactionAbort.test.ts +0 -108
  583. package/test/storage/idb/update.test.ts +0 -999
  584. package/test/storage/insert.test.ts +0 -278
  585. package/test/storage/update.test.ts +0 -1021
  586. package/test/storage/update2.test.ts +0 -897
  587. package/test/utils/TestUtilsWalletStorage.ts +0 -2526
  588. package/test/utils/localWalletMethods.ts +0 -363
  589. package/test/utils/removeFailedFromDatabase.sql +0 -17
  590. package/test/wallet/action/abortAction.test.ts +0 -47
  591. package/test/wallet/action/createAction.test.ts +0 -299
  592. package/test/wallet/action/createAction2.test.ts +0 -1273
  593. package/test/wallet/action/createActionToGenerateBeefs.man.test.ts +0 -293
  594. package/test/wallet/action/internalizeAction.test.ts +0 -682
  595. package/test/wallet/action/relinquishOutput.test.ts +0 -37
  596. package/test/wallet/construct/Wallet.constructor.test.ts +0 -57
  597. package/test/wallet/list/listActions.test.ts +0 -279
  598. package/test/wallet/list/listActions2.test.ts +0 -1381
  599. package/test/wallet/list/listCertificates.test.ts +0 -118
  600. package/test/wallet/list/listOutputs.test.ts +0 -447
  601. package/test/wallet/sync/Wallet.sync.test.ts +0 -215
  602. package/ts2md.json +0 -44
  603. package/tsconfig.all.json +0 -31
  604. package/tsconfig.client.json +0 -29
  605. package/tsconfig.json +0 -17
  606. package/tsconfig.mobile.json +0 -28
@@ -1,975 +0,0 @@
1
- import { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'
2
- import { BlockHeader, Chain, WERR_INTERNAL, WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk'
3
- import { Hash } from '@bsv/sdk'
4
- import { asArray, asString, asUint8Array } from '../../../../utility/utilityHelpers.noBuffer'
5
- import { BulkHeaderFileInfo, BulkHeaderFilesInfo } from './BulkHeaderFile'
6
- import { isKnownValidBulkHeaderFile, validBulkHeaderFiles } from './validBulkHeaderFilesByFileHash'
7
- import { HeightRange } from './HeightRange'
8
- import {
9
- addWork,
10
- convertBitsToWork,
11
- deserializeBlockHeader,
12
- serializeBaseBlockHeaders,
13
- subWork,
14
- validateBufferOfHeaders,
15
- validateGenesisHeader
16
- } from './blockHeaderUtilities'
17
- import { ChaintracksStorageBulkFileApi } from '../Api/ChaintracksStorageApi'
18
- import { ChaintracksFetch } from './ChaintracksFetch'
19
- import { ChaintracksFsApi } from '../Api/ChaintracksFsApi'
20
- import { SingleWriterMultiReaderLock } from './SingleWriterMultiReaderLock'
21
-
22
- export interface BulkFileDataManagerOptions {
23
- chain: Chain
24
- maxPerFile: number
25
- maxRetained?: number
26
- fetch?: ChaintracksFetchApi
27
- fromKnownSourceUrl?: string
28
- }
29
-
30
- /**
31
- * Manages bulk file data (typically 8MB chunks of 100,000 headers each).
32
- *
33
- * If not cached in memory,
34
- * optionally fetches data by `sourceUrl` from CDN on demand,
35
- * optionally finds data by `fileId` in a database on demand,
36
- * and retains a limited number of files in memory,
37
- * subject to the optional `maxRetained` limit.
38
- */
39
- export class BulkFileDataManager {
40
- static createDefaultOptions(chain: Chain): BulkFileDataManagerOptions {
41
- return {
42
- chain,
43
- maxPerFile: 100000,
44
- maxRetained: 2,
45
- fetch: new ChaintracksFetch(),
46
- fromKnownSourceUrl: 'https://cdn.projectbabbage.com/blockheaders'
47
- }
48
- }
49
-
50
- private log: (...args: any[]) => void = () => {}
51
-
52
- private bfds: BulkFileData[] = []
53
- private fileHashToIndex: Record<string, number> = {}
54
- private lock: SingleWriterMultiReaderLock = new SingleWriterMultiReaderLock()
55
- private storage?: ChaintracksStorageBulkFileApi
56
-
57
- readonly chain: Chain
58
- readonly maxPerFile: number
59
- readonly fetch?: ChaintracksFetchApi
60
- readonly maxRetained?: number
61
- readonly fromKnownSourceUrl?: string
62
-
63
- constructor(options: BulkFileDataManagerOptions | Chain) {
64
- if (typeof options === 'object') options = options as BulkFileDataManagerOptions
65
- else options = BulkFileDataManager.createDefaultOptions(options as Chain)
66
- this.chain = options.chain
67
- this.maxPerFile = options.maxPerFile
68
- this.maxRetained = options.maxRetained
69
- this.fromKnownSourceUrl = options.fromKnownSourceUrl
70
- this.fetch = options.fetch
71
-
72
- this.deleteBulkFilesNoLock()
73
- }
74
-
75
- async deleteBulkFiles(): Promise<void> {
76
- return this.lock.withWriteLock(async () => this.deleteBulkFilesNoLock())
77
- }
78
-
79
- private deleteBulkFilesNoLock(): void {
80
- this.bfds = []
81
- this.fileHashToIndex = {}
82
-
83
- if (this.fromKnownSourceUrl) {
84
- const vbhfs = validBulkHeaderFiles
85
- const filtered = vbhfs.filter(f => f.sourceUrl === this.fromKnownSourceUrl)
86
- const files = selectBulkHeaderFiles(filtered, this.chain, this.maxPerFile)
87
- for (const file of files) {
88
- this.add({ ...file, fileHash: file.fileHash!, mru: Date.now() })
89
- }
90
- }
91
- }
92
-
93
- /**
94
- * If `bfds` are going to be backed by persistent storage,
95
- * must be called before making storage available.
96
- *
97
- * Synchronizes bfds and storage files, after which this manager maintains sync.
98
- * There should be no changes to bulk files by direct access to storage bulk file methods.
99
- */
100
- async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void> {
101
- return this.lock.withWriteLock(async () => this.setStorageNoLock(storage, log))
102
- }
103
-
104
- private async setStorageNoLock(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void> {
105
- this.storage = storage
106
- this.log = log
107
-
108
- // Get files currently in persistent storage.
109
- let sfs = await this.storage.getBulkFiles()
110
-
111
- // Sync bfds with storage. Two scenarios supported:
112
-
113
- const bfdsRanges = this.heightRangesFromBulkFiles(this.bfds)
114
- const sfsRanges = this.heightRangesFromBulkFiles(sfs)
115
-
116
- if (sfsRanges.cdn.length >= bfdsRanges.cdn.length) {
117
- // Storage win if it has greater or equal CDN coverage
118
- // Replace all bfds with sfs
119
- this.bfds = []
120
- for (const file of sfs) {
121
- const vbf: BulkFileData = await this.validateFileInfo(file)
122
- this.bfds.push(vbf)
123
- }
124
- } else {
125
- // Bfds win if they have greater CDN coverage
126
- // Replace all sfs with bfds
127
- for (const s of sfs.reverse()) await this.storage.deleteBulkFile(s.fileId!)
128
- for (const bfd of this.bfds) {
129
- await this.ensureData(bfd)
130
- bfd.fileId = await this.storage.insertBulkFile(bfdToInfo(bfd, true))
131
- }
132
- }
133
- }
134
-
135
- heightRangesFromBulkFiles(files: BulkHeaderFileInfo[]): {
136
- all: HeightRange
137
- cdn: HeightRange
138
- incremental: HeightRange
139
- } {
140
- const ranges = { all: new HeightRange(0, -1), cdn: new HeightRange(0, -1), incremental: new HeightRange(0, -1) }
141
- for (const file of files) {
142
- const range = new HeightRange(file.firstHeight, file.firstHeight + file.count - 1)
143
- ranges.all = ranges.all.union(range)
144
- if (isBdfCdn(file)) ranges.cdn = ranges.cdn.union(range)
145
- if (isBdfIncremental(file)) ranges.incremental = ranges.incremental.union(range)
146
- }
147
- return ranges
148
- }
149
-
150
- async createReader(range?: HeightRange, maxBufferSize?: number): Promise<BulkFileDataReader> {
151
- range = range || (await this.getHeightRange())
152
- maxBufferSize = maxBufferSize || 1000000 * 80 // 100,000 headers, 8MB
153
- return new BulkFileDataReader(this, range, maxBufferSize)
154
- }
155
-
156
- async updateFromUrl(cdnUrl: string): Promise<void> {
157
- if (!this.fetch) throw new WERR_INVALID_OPERATION('fetch is not defined in the BulkFileDataManager.')
158
-
159
- const toUrl = (file: string) => this.fetch!.pathJoin(cdnUrl, file)
160
- const url = toUrl(`${this.chain}NetBlockHeaders.json`)
161
-
162
- const availableBulkFiles = (await this.fetch.fetchJson(url)) as BulkHeaderFilesInfo
163
- if (!availableBulkFiles)
164
- throw new WERR_INVALID_PARAMETER(`cdnUrl`, `a valid BulkHeaderFilesInfo JSON resource available from ${url}`)
165
-
166
- const selectedFiles = selectBulkHeaderFiles(
167
- availableBulkFiles.files,
168
- this.chain,
169
- this.maxPerFile || availableBulkFiles.headersPerFile
170
- )
171
- for (const bf of selectedFiles) {
172
- if (!bf.fileHash) {
173
- throw new WERR_INVALID_PARAMETER(`fileHash`, `valid for all files in json downloaded from ${url}`)
174
- }
175
- if (!bf.chain || bf.chain !== this.chain) {
176
- throw new WERR_INVALID_PARAMETER(`chain`, `"${this.chain}" for all files in json downloaded from ${url}`)
177
- }
178
- if (!bf.sourceUrl || bf.sourceUrl !== cdnUrl) bf.sourceUrl = cdnUrl
179
- }
180
-
181
- const rangeBefore = await this.getHeightRange()
182
- const r = await this.merge(selectedFiles)
183
- const rangeAfter = await this.getHeightRange()
184
-
185
- let log = 'BulkDataFileManager.updateFromUrl\n'
186
- log += ` url: ${url}\n`
187
- log += ` bulk range before: ${rangeBefore}\n`
188
- log += ` bulk range after: ${rangeAfter}\n`
189
- this.log(log)
190
- }
191
-
192
- async merge(files: BulkHeaderFileInfo[]): Promise<BulkFileDataManagerMergeResult> {
193
- return this.lock.withWriteLock(async () => this.mergeNoLock(files))
194
- }
195
-
196
- private async mergeNoLock(files: BulkHeaderFileInfo[]): Promise<BulkFileDataManagerMergeResult> {
197
- const r: BulkFileDataManagerMergeResult = { inserted: [], updated: [], unchanged: [], dropped: [] }
198
- for (const file of files) {
199
- const hbf = this.getBfdForHeight(file.firstHeight)
200
- if (hbf && file.fileId) hbf.fileId = file.fileId // Always update fileId if provided
201
- const lbf = this.getLastBfd()
202
- if (
203
- hbf &&
204
- hbf.fileHash === file.fileHash &&
205
- hbf.count === file.count &&
206
- hbf.lastHash === file.lastHash &&
207
- hbf.lastChainWork === file.lastChainWork
208
- ) {
209
- // We already have an identical matching file...
210
- r.unchanged.push(bfdToInfo(hbf))
211
- continue
212
- }
213
- const vbf: BulkFileData = await this.validateFileInfo(file)
214
- if (hbf) {
215
- // We have a matching file by firstHeight but count and fileHash differ
216
- await this.update(vbf, hbf, r)
217
- } else if (isBdfIncremental(vbf) && lbf && isBdfIncremental(lbf)) {
218
- await this.mergeIncremental(lbf, vbf, r)
219
- } else {
220
- const added = await this.add(vbf)
221
- r.inserted.push(added)
222
- }
223
- }
224
- this.log(`BulkFileDataManager.merge:\n${this.toLogString(r)}\n`)
225
- return r
226
- }
227
-
228
- private async mergeIncremental(lbf: BulkFileData, vbf: BulkFileData, r: BulkFileDataManagerMergeResult) {
229
- lbf.count += vbf.count
230
- lbf.lastHash = vbf.lastHash
231
- lbf.lastChainWork = vbf.lastChainWork
232
- await this.ensureData(lbf)
233
- const newData = new Uint8Array(lbf.data!.length + vbf.data!.length)
234
- newData.set(lbf.data!)
235
- newData.set(vbf.data!, lbf.data!.length)
236
- lbf.data = newData
237
- delete this.fileHashToIndex[lbf.fileHash!]
238
- lbf.fileHash = asString(Hash.sha256(asArray(newData)), 'base64')
239
- this.fileHashToIndex[lbf.fileHash] = this.bfds.length - 1
240
- lbf.mru = Date.now()
241
- const lbfInfo = bfdToInfo(lbf, true)
242
- r.updated.push(lbfInfo)
243
- if (this.storage && lbf.fileId) {
244
- await this.storage.updateBulkFile(lbf.fileId, lbfInfo)
245
- }
246
- }
247
-
248
- toLogString(what?: BulkFileDataManagerMergeResult | BulkFileData[] | BulkHeaderFileInfo[]): string {
249
- let log = ''
250
- if (!what) {
251
- log += this.toLogString(this.bfds)
252
- } else if (what['updated']) {
253
- what = what as BulkFileDataManagerMergeResult
254
- for (const { category, bfds } of [
255
- { category: 'unchanged', bfds: what.unchanged },
256
- { category: 'dropped', bfds: what.dropped },
257
- { category: 'updated', bfds: what.updated },
258
- { category: 'inserted', bfds: what.inserted }
259
- ]) {
260
- if (bfds.length > 0) {
261
- log += ` ${category}:\n`
262
- log += this.toLogString(bfds)
263
- }
264
- }
265
- } else if (Array.isArray(what)) {
266
- what = what as BulkHeaderFileInfo[]
267
- let i = -1
268
- for (const bfd of what) {
269
- i++
270
- log += ` ${i}: ${bfd.fileName} fileId=${bfd.fileId} ${bfd.firstHeight}-${bfd.firstHeight + bfd.count - 1}\n`
271
- }
272
- }
273
-
274
- return log
275
- }
276
-
277
- async mergeIncrementalBlockHeaders(newBulkHeaders: BlockHeader[], incrementalChainWork?: string): Promise<void> {
278
- if (newBulkHeaders.length === 0) return
279
- return this.lock.withWriteLock(async () => {
280
- const lbf = this.getLastFileNoLock()
281
- const nextHeight = lbf ? lbf.firstHeight + lbf.count : 0
282
- if (nextHeight > 0 && newBulkHeaders.length > 0 && newBulkHeaders[0].height < nextHeight) {
283
- // Don't modify the incoming array...
284
- newBulkHeaders = [...newBulkHeaders]
285
- // If we have more headers than we need, drop the incoming headers.
286
- while (newBulkHeaders.length > 0 && newBulkHeaders[0].height < nextHeight) {
287
- const h = newBulkHeaders.shift()
288
- if (h && incrementalChainWork) {
289
- incrementalChainWork = subWork(incrementalChainWork, convertBitsToWork(h.bits))
290
- }
291
- }
292
- }
293
- if (newBulkHeaders.length === 0) return
294
- if (!lbf || nextHeight !== newBulkHeaders[0].height)
295
- throw new WERR_INVALID_PARAMETER('newBulkHeaders', 'an extension of existing bulk headers')
296
- if (!lbf.lastHash) throw new WERR_INTERNAL(`lastHash is not defined for the last bulk file ${lbf.fileName}`)
297
-
298
- const fbh = newBulkHeaders[0]
299
- const lbh = newBulkHeaders.slice(-1)[0]
300
- let lastChainWork = lbf.lastChainWork
301
- if (incrementalChainWork) {
302
- lastChainWork = addWork(incrementalChainWork, lastChainWork)
303
- } else {
304
- // If lastChainWork is not provided, calculate it from the last file with basic validation.
305
- let lastHeight = lbf.firstHeight + lbf.count - 1
306
- let lastHash = lbf.lastHash
307
- for (const h of newBulkHeaders) {
308
- if (h.height !== lastHeight + 1 || h.previousHash !== lastHash) {
309
- throw new WERR_INVALID_PARAMETER(
310
- 'headers',
311
- `an extension of existing bulk headers, header with height ${h.height} is non-sequential`
312
- )
313
- }
314
- lastChainWork = addWork(lastChainWork, convertBitsToWork(h.bits))
315
- lastHeight = h.height
316
- lastHash = h.hash
317
- }
318
- }
319
- const data = serializeBaseBlockHeaders(newBulkHeaders)
320
-
321
- const fileHash = asString(Hash.sha256(asArray(data)), 'base64')
322
- const bf: BulkHeaderFileInfo = {
323
- fileId: undefined,
324
- chain: this.chain,
325
- sourceUrl: undefined,
326
- fileName: 'incremental',
327
- firstHeight: fbh.height,
328
- count: newBulkHeaders.length,
329
- prevChainWork: lbf.lastChainWork,
330
- lastChainWork,
331
- prevHash: lbf.lastHash,
332
- lastHash: lbh.hash,
333
- fileHash,
334
- data
335
- }
336
- await this.mergeNoLock([bf])
337
- })
338
- }
339
-
340
- async getBulkFiles(keepData?: boolean): Promise<BulkHeaderFileInfo[]> {
341
- return this.lock.withReadLock(async () => {
342
- return this.bfds.map(bfd => bfdToInfo(bfd, keepData))
343
- })
344
- }
345
-
346
- async getHeightRange(): Promise<HeightRange> {
347
- return this.lock.withReadLock(async () => {
348
- if (this.bfds.length === 0) return HeightRange.empty
349
- const first = this.bfds[0]
350
- const last = this.bfds[this.bfds.length - 1]
351
- return new HeightRange(first.firstHeight, last.firstHeight + last.count - 1)
352
- })
353
- }
354
-
355
- async getDataFromFile(file: BulkHeaderFileInfo, offset?: number, length?: number): Promise<Uint8Array | undefined> {
356
- const bfd = await this.getBfdForHeight(file.firstHeight)
357
- if (!bfd || bfd.count < file.count)
358
- throw new WERR_INVALID_PARAMETER(
359
- 'file',
360
- `a match for ${file.firstHeight}, ${file.count} in the BulkFileDataManager.`
361
- )
362
- return this.lock.withReadLock(async () => this.getDataFromFileNoLock(bfd, offset, length))
363
- }
364
-
365
- private async getDataFromFileNoLock(
366
- bfd: BulkFileData,
367
- offset?: number,
368
- length?: number
369
- ): Promise<Uint8Array | undefined> {
370
- const fileLength = bfd.count * 80
371
- offset = offset || 0
372
- if (offset > fileLength - 1) return undefined
373
- length = length || bfd.count * 80 - offset
374
- length = Math.min(length, fileLength - offset)
375
- let data: Uint8Array | undefined
376
- if (bfd.data) {
377
- data = bfd.data.slice(offset, offset + length)
378
- } else if (bfd.fileId && this.storage) {
379
- data = await this.storage.getBulkFileData(bfd.fileId, offset, length)
380
- }
381
- if (!data) {
382
- await this.ensureData(bfd)
383
- if (bfd.data) data = bfd.data.slice(offset, offset + length)
384
- }
385
- if (!data) return undefined
386
- return data
387
- }
388
-
389
- async findHeaderForHeightOrUndefined(height: number): Promise<BlockHeader | undefined> {
390
- return this.lock.withReadLock(async () => {
391
- if (!Number.isInteger(height) || height < 0)
392
- throw new WERR_INVALID_PARAMETER('height', `a non-negative integer (${height}).`)
393
- const file = this.bfds.find(f => f.firstHeight <= height && f.firstHeight + f.count > height)
394
- if (!file) return undefined
395
- const offset = (height - file.firstHeight) * 80
396
- const data = await this.getDataFromFileNoLock(file, offset, 80)
397
- if (!data) return undefined
398
- const header = deserializeBlockHeader(data, 0, height)
399
- return header
400
- })
401
- }
402
-
403
- async getFileForHeight(height: number): Promise<BulkHeaderFileInfo | undefined> {
404
- return this.lock.withReadLock(async () => {
405
- const bfd = this.getBfdForHeight(height)
406
- if (!bfd) return undefined
407
- return bfdToInfo(bfd)
408
- })
409
- }
410
-
411
- private getBfdForHeight(height: number): BulkFileData | undefined {
412
- if (!Number.isInteger(height) || height < 0)
413
- throw new WERR_INVALID_PARAMETER('height', `a non-negative integer (${height}).`)
414
- const file = this.bfds.find(f => f.firstHeight <= height && f.firstHeight + f.count > height)
415
- return file
416
- }
417
-
418
- private getLastBfd(fromEnd = 1): BulkFileData | undefined {
419
- if (this.bfds.length < fromEnd) return undefined
420
- const bfd = this.bfds[this.bfds.length - fromEnd]
421
- return bfd
422
- }
423
-
424
- async getLastFile(fromEnd = 1): Promise<BulkHeaderFileInfo | undefined> {
425
- return this.lock.withReadLock(async () => this.getLastFileNoLock(fromEnd))
426
- }
427
-
428
- private getLastFileNoLock(fromEnd = 1): BulkHeaderFileInfo | undefined {
429
- const bfd = this.getLastBfd(fromEnd)
430
- if (!bfd) return undefined
431
- return bfdToInfo(bfd)
432
- }
433
-
434
- private async getDataByFileHash(fileHash: string): Promise<Uint8Array | undefined> {
435
- const index = this.fileHashToIndex[fileHash]
436
- if (index === undefined)
437
- throw new WERR_INVALID_PARAMETER('fileHash', `known to the BulkFileDataManager. ${fileHash} is unknown.`)
438
- const bfd = this.bfds[index]
439
- const data = await this.ensureData(bfd)
440
- return data
441
- }
442
-
443
- private async getDataByFileId(fileId: number): Promise<Uint8Array | undefined> {
444
- const bfd = this.bfds.find(f => f.fileId === fileId)
445
- if (bfd === undefined)
446
- throw new WERR_INVALID_PARAMETER('fileId', `known to the BulkFileDataManager. ${fileId} is unknown.`)
447
- const data = await this.ensureData(bfd)
448
- return data
449
- }
450
-
451
- private async validateFileInfo(file: BulkHeaderFileInfo): Promise<BulkFileData> {
452
- if (file.chain !== this.chain) throw new WERR_INVALID_PARAMETER('chain', `${this.chain}`)
453
- if (file.count <= 0)
454
- throw new WERR_INVALID_PARAMETER('bf.count', `expected count to be greater than 0, but got ${file.count}`)
455
- if (file.count > this.maxPerFile && file.fileName !== 'incremental')
456
- throw new WERR_INVALID_PARAMETER('count', `less than or equal to maxPerFile ${this.maxPerFile}`)
457
- if (!file.fileHash) throw new WERR_INVALID_PARAMETER('fileHash', `defined`)
458
- if (!file.sourceUrl && !file.fileId && !file.data)
459
- throw new WERR_INVALID_PARAMETER('data', `defined when sourceUrl and fileId are undefined`)
460
-
461
- let bfd: BulkFileData = {
462
- ...file,
463
- fileHash: file.fileHash,
464
- mru: Date.now()
465
- }
466
-
467
- if (!bfd.validated) {
468
- await this.ensureData(bfd)
469
-
470
- if (!bfd.data || bfd.data.length !== bfd.count * 80)
471
- throw new WERR_INVALID_PARAMETER(
472
- 'file.data',
473
- `bulk file ${bfd.fileName} data length ${bfd.data?.length} does not match expected count ${bfd.count}`
474
- )
475
-
476
- bfd.fileHash = asString(Hash.sha256(asArray(bfd.data)), 'base64')
477
- if (file.fileHash && file.fileHash !== bfd.fileHash)
478
- throw new WERR_INVALID_PARAMETER('file.fileHash', `expected ${file.fileHash} but got ${bfd.fileHash}`)
479
-
480
- if (!isKnownValidBulkHeaderFile(bfd)) {
481
- const pbf = bfd.firstHeight > 0 ? this.getBfdForHeight(bfd.firstHeight - 1) : undefined
482
- const prevHash = pbf ? pbf.lastHash! : '00'.repeat(32)
483
- const prevChainWork = pbf ? pbf.lastChainWork : '00'.repeat(32)
484
-
485
- const { lastHeaderHash, lastChainWork } = validateBufferOfHeaders(
486
- bfd.data,
487
- prevHash,
488
- 0,
489
- undefined,
490
- prevChainWork
491
- )
492
-
493
- if (bfd.lastHash && bfd.lastHash !== lastHeaderHash)
494
- throw new WERR_INVALID_PARAMETER('file.lastHash', `expected ${bfd.lastHash} but got ${lastHeaderHash}`)
495
- if (bfd.lastChainWork && bfd.lastChainWork !== lastChainWork)
496
- throw new WERR_INVALID_PARAMETER(
497
- 'file.lastChainWork',
498
- `expected ${bfd.lastChainWork} but got ${lastChainWork}`
499
- )
500
-
501
- bfd.lastHash = lastHeaderHash
502
- bfd.lastChainWork = lastChainWork!
503
-
504
- if (bfd.firstHeight === 0) {
505
- validateGenesisHeader(bfd.data, bfd.chain!)
506
- }
507
- }
508
- bfd.validated = true
509
- }
510
-
511
- return bfd
512
- }
513
-
514
- async ReValidate(): Promise<void> {
515
- return this.lock.withReadLock(async () => this.ReValidateNoLock())
516
- }
517
-
518
- private async ReValidateNoLock(): Promise<void> {
519
- for (const file of this.bfds) {
520
- await this.ensureData(file)
521
- file.validated = false // Reset validation to re-validate on next access
522
- const bfd = await this.validateFileInfo(file)
523
- if (!bfd.validated) throw new WERR_INTERNAL(`BulkFileDataManager.ReValidate failed for file ${bfd.fileName}`)
524
- file.validated = true
525
- }
526
- }
527
-
528
- private validateBfdForAdd(bfd: BulkFileData): void {
529
- if (this.bfds.length === 0 && bfd.firstHeight !== 0)
530
- throw new WERR_INVALID_PARAMETER('firstHeight', `0 for the first file`)
531
- if (this.bfds.length > 0) {
532
- const last = this.bfds[this.bfds.length - 1]
533
- if (bfd.firstHeight !== last.firstHeight + last.count)
534
- throw new WERR_INVALID_PARAMETER('firstHeight', `the last file's firstHeight + count`)
535
- if (bfd.prevHash !== last.lastHash || bfd.prevChainWork !== last.lastChainWork)
536
- throw new WERR_INVALID_PARAMETER('prevHash/prevChainWork', `the last file's lastHash/lastChainWork`)
537
- }
538
- }
539
-
540
- private async add(bfd: BulkFileData): Promise<BulkHeaderFileInfo> {
541
- this.validateBfdForAdd(bfd)
542
- const index = this.bfds.length
543
- this.bfds.push(bfd)
544
- this.fileHashToIndex[bfd.fileHash] = index
545
- this.ensureMaxRetained()
546
- const info = bfdToInfo(bfd, true)
547
- if (this.storage) {
548
- info.fileId = bfd.fileId = await this.storage.insertBulkFile(info)
549
- }
550
- return info
551
- }
552
-
553
- private replaceBfdAtIndex(index: number, update: BulkFileData): void {
554
- const oldBfd = this.bfds[index]
555
- delete this.fileHashToIndex[oldBfd.fileHash]
556
- this.bfds[index] = update
557
- this.fileHashToIndex[update.fileHash] = index
558
- }
559
-
560
- /**
561
- * Updating an existing file occurs in two specific contexts:
562
- *
563
- * 1. CDN Update: CDN files of a specific `maxPerFile` series typically ends in a partial file
564
- * which may periodically add more headers until the next file is started.
565
- * If the CDN update is the second to last file (followed by an incremental file),
566
- * then the incremental file is updated or deleted and also returned as the result (with a count of zero if deleted).
567
- *
568
- * 2. Incremental Update: The last bulk file is almost always an "incremental" file
569
- * which is not limited by "maxPerFile" and holds all non-CDN bulk headers.
570
- * If is updated with new bulk headers which come either from non CDN ingestors or from live header migration to bulk.
571
- *
572
- * Updating preserves the following properties:
573
- *
574
- * - Any existing headers following this update are preserved and must form an unbroken chain.
575
- * - There can be at most one incremental file and it must be the last file.
576
- * - The update start conditions (height, prevHash, prevChainWork) must match an existing file which may be either CDN or internal.
577
- * - The update fileId must match, it may be undefind.
578
- * - The fileName does not need to match.
579
- * - The incremental file must always have fileName "incremental" and sourceUrl must be undefined.
580
- * - The update count must be greater than 0.
581
- * - The update count must be greater than current count for CDN to CDN update.
582
- *
583
- * @param update new validated BulkFileData to update.
584
- * @param hbf corresponding existing BulkFileData to update.
585
- */
586
- private async update(update: BulkFileData, hbf: BulkFileData, r: BulkFileDataManagerMergeResult): Promise<void> {
587
- if (
588
- !hbf ||
589
- hbf.firstHeight !== update.firstHeight ||
590
- hbf.prevChainWork !== update.prevChainWork ||
591
- hbf.prevHash !== update.prevHash
592
- )
593
- throw new WERR_INVALID_PARAMETER('file', `an existing file by height, prevChainWork and prevHash`)
594
- if (isBdfCdn(update) === isBdfCdn(hbf) && update.count <= hbf.count)
595
- throw new WERR_INVALID_PARAMETER('file.count', `greater than the current count ${hbf.count}`)
596
-
597
- const lbf = this.getLastBfd()!
598
- let index = this.bfds.length - 1
599
- let truncate: BulkFileData | undefined = undefined
600
- let replaced: BulkFileData | undefined = undefined
601
- let drop: BulkFileData | undefined = undefined
602
-
603
- if (hbf.firstHeight === lbf.firstHeight) {
604
- // If the update is for the last file, there are three cases:
605
-
606
- if (isBdfIncremental(update)) {
607
- // 1. Incremental file may only be extended with more incremental headers.
608
- if (!isBdfIncremental(lbf))
609
- throw new WERR_INVALID_PARAMETER('file', `an incremental file to update an existing incremental file`)
610
- } else {
611
- // The update is a CDN bulk file.
612
- if (isBdfCdn(lbf)) {
613
- // 2. An updated CDN file replaces a partial CDN file.
614
- if (update.count <= lbf.count)
615
- throw new WERR_INVALID_PARAMETER(
616
- 'update.count',
617
- `CDN update must have more headers. ${update.count} <= ${lbf.count}`
618
- )
619
- } else {
620
- // 3. A new CDN file replaces some or all of current incremental file.
621
- // Retain extra incremental headers if any.
622
- if (update.count < lbf.count) {
623
- // The new CDN partially replaces the last incremental file, prepare to shift work and re-add it.
624
- await this.ensureData(lbf)
625
- truncate = lbf
626
- }
627
- }
628
- }
629
- } else {
630
- // If the update is NOT for the last file, then it MUST be for the second to last file which MUST be a CDN file:
631
- // - it must be a CDN file update with more headers than the current CDN file.
632
- // - the last file must be an incremental file which is updated or deleted. The updated (or deleted) last file is returned.
633
- const lbf2 = this.getLastBfd(2)
634
- if (!lbf2 || hbf.firstHeight !== lbf2.firstHeight)
635
- throw new WERR_INVALID_PARAMETER('file', `an update to last or second to last file`)
636
- if (!isBdfCdn(update) || !isBdfCdn(lbf2) || update.count <= lbf2.count)
637
- throw new WERR_INVALID_PARAMETER('file', `a CDN file update with more headers than the current CDN file`)
638
- if (!isBdfIncremental(lbf))
639
- throw new WERR_INVALID_PARAMETER('file', `a CDN file update followed by an incremental file`)
640
- if (!update.fileId) update.fileId = lbf2.fileId // Update fileId if not provided
641
- if (update.count >= lbf2.count + lbf.count) {
642
- // The current last file is fully replaced by the CDN update.
643
- drop = lbf
644
- } else {
645
- // If the update doesn't fully replace the last incremental file, make sure data is available to be truncated.
646
- await this.ensureData(lbf)
647
- truncate = lbf
648
- // The existing second to last file is fully replaced by the update.
649
- replaced = lbf2
650
- }
651
-
652
- index = index - 1 // The update replaces the second to last file.
653
- }
654
-
655
- // In all cases the bulk file at the current fileId if any is updated.
656
- this.replaceBfdAtIndex(index, update)
657
- if (truncate) {
658
- // If there is a bulk file to be truncated, it becomes the new (reduced) last file.
659
- await this.shiftWork(update, truncate, replaced)
660
- }
661
- if (drop) {
662
- this.dropLastBulkFile(drop)
663
- }
664
-
665
- const updateInfo = bfdToInfo(update, true)
666
- const truncateInfo = truncate ? bfdToInfo(truncate, true) : undefined
667
-
668
- if (this.storage) {
669
- // Keep storage in sync.
670
- if (update.fileId) {
671
- await this.storage.updateBulkFile(update.fileId, updateInfo)
672
- }
673
- if (truncate && truncateInfo) {
674
- if (replaced) {
675
- await this.storage.updateBulkFile(truncate.fileId!, truncateInfo)
676
- } else {
677
- truncateInfo.fileId = undefined // Make sure truncate is a new file.
678
- truncate.fileId = await this.storage.insertBulkFile(truncateInfo)
679
- }
680
- }
681
- if (drop && drop.fileId) {
682
- await this.storage.deleteBulkFile(drop.fileId)
683
- }
684
- }
685
-
686
- if (r) {
687
- // Update results for logging...
688
- r.updated.push(updateInfo)
689
- if (truncateInfo) {
690
- if (replaced) {
691
- r.updated.push(truncateInfo)
692
- } else {
693
- r.inserted.push(truncateInfo)
694
- }
695
- }
696
- if (drop) {
697
- r.dropped.push(bfdToInfo(drop))
698
- }
699
- }
700
-
701
- this.ensureMaxRetained()
702
- }
703
-
704
- private dropLastBulkFile(lbf: BulkFileData): void {
705
- delete this.fileHashToIndex[lbf.fileHash]
706
- const index = this.bfds.indexOf(lbf)
707
- if (index !== this.bfds.length - 1)
708
- throw new WERR_INTERNAL(`dropLastBulkFile requires lbf is the current last file.`)
709
- this.bfds.pop()
710
- }
711
-
712
- /**
713
- * Remove work (and headers) from `truncate` that now exists in `update`.
714
- * There are two scenarios:
715
- * 1. `replaced` is undefined: update is a CDN file that splits an incremental file that must be truncated.
716
- * 2. `replaced` is valid: update is a CDN update that replaced an existing CDN file and splits an incremental file that must be truncated.
717
- * @param update the new CDN update file.
718
- * @param truncate the incremental file to be truncated (losing work which now exists in `update`).
719
- * @param replaced the existing CDN file that was replaced by `update` (if any).
720
- */
721
- private async shiftWork(update: BulkFileData, truncate: BulkFileData, replaced?: BulkFileData): Promise<void> {
722
- const updateIndex = this.fileHashToIndex[update.fileHash]
723
- // replaced will be valid if the update replaced it and it must become the new last file.
724
- // truncateIndex will be updateIndex + 1 if the existing last file is being truncated and update is second to last.
725
- const truncateIndex = this.fileHashToIndex[truncate.fileHash]
726
- if (truncateIndex !== undefined && truncateIndex !== updateIndex + 1)
727
- throw new WERR_INTERNAL(`shiftWork requires update to have replaced truncate or truncate to follow update`)
728
- if (truncateIndex !== undefined && !replaced)
729
- throw new WERR_INTERNAL(`shiftWork requires valid replaced when update hasn't replaced truncate`)
730
-
731
- truncate.prevHash = update.lastHash!
732
- truncate.prevChainWork = update.lastChainWork
733
- // truncate.lastChainWork, truncate.lastHash remain unchanged
734
- let count = update.count
735
- if (replaced) {
736
- count -= replaced.count
737
- } else {
738
- // The truncated file is itself being replaced by the update and must be inserted as a new file.
739
- truncate.fileId = undefined
740
- this.bfds.push(truncate) // Add the truncated file as a new entry.
741
- }
742
- truncate.count -= count
743
- truncate.firstHeight += count
744
-
745
- truncate.data = truncate.data?.slice(count * 80)
746
- delete this.fileHashToIndex[truncate.fileHash]
747
- truncate.fileHash = asString(Hash.sha256(asArray(truncate.data!)), 'base64')
748
- this.fileHashToIndex[truncate.fileHash] = updateIndex + 1
749
- }
750
-
751
- /**
752
- *
753
- * @param bfd
754
- * @returns
755
- */
756
- private async ensureData(bfd: BulkFileData): Promise<Uint8Array> {
757
- if (bfd.data) return bfd.data
758
-
759
- if (this.storage && bfd.fileId) {
760
- bfd.data = await this.storage.getBulkFileData(bfd.fileId)
761
- if (!bfd.data) throw new WERR_INVALID_PARAMETER('fileId', `valid, data not found for fileId ${bfd.fileId}`)
762
- }
763
-
764
- if (!bfd.data && this.fetch && bfd.sourceUrl) {
765
- // TODO - restore this change
766
- const url = this.fetch.pathJoin(bfd.sourceUrl, bfd.fileName)
767
- //const url = this.fetch.pathJoin('http://localhost:8842/blockheaders', bfd.fileName)
768
-
769
- try {
770
- bfd.data = await this.fetch.download(url)
771
- } catch (err) {
772
- bfd.data = await this.fetch.download(url)
773
- }
774
- if (!bfd.data) throw new WERR_INVALID_PARAMETER('sourceUrl', `data not found for sourceUrl ${url}`)
775
- }
776
-
777
- if (!bfd.data) throw new WERR_INVALID_PARAMETER('data', `defined. Unable to retrieve data for ${bfd.fileName}`)
778
-
779
- bfd.mru = Date.now()
780
-
781
- // Validate retrieved data.
782
- const fileHash = asString(Hash.sha256(asArray(bfd.data)), 'base64')
783
- if (fileHash !== bfd.fileHash)
784
- throw new WERR_INVALID_PARAMETER('fileHash', `a match for retrieved data for ${bfd.fileName}`)
785
-
786
- this.ensureMaxRetained()
787
- return bfd.data
788
- }
789
-
790
- private ensureMaxRetained(): void {
791
- if (this.maxRetained === undefined) return
792
- let withData = this.bfds.filter(bfd => bfd.data && (bfd.fileId || bfd.sourceUrl))
793
- let countToRelease = withData.length - this.maxRetained
794
- if (countToRelease <= 0) return
795
- const sorted = withData.sort((a, b) => a.mru - b.mru)
796
- while (countToRelease-- > 0 && sorted.length > 0) {
797
- const oldest = sorted.shift()!
798
- // Release the least recently used data
799
- oldest.data = undefined // Release the data
800
- }
801
- }
802
-
803
- async exportHeadersToFs(
804
- toFs: ChaintracksFsApi,
805
- toHeadersPerFile: number,
806
- toFolder: string,
807
- sourceUrl?: string,
808
- maxHeight?: number
809
- ): Promise<void> {
810
- const chain = this.chain
811
- const toFileName = (i: number) => `${chain}Net_${i}.headers`
812
- const toPath = (i: number) => toFs.pathJoin(toFolder, toFileName(i))
813
- const toJsonPath = () => toFs.pathJoin(toFolder, `${chain}NetBlockHeaders.json`)
814
-
815
- const toBulkFiles: BulkHeaderFilesInfo = {
816
- rootFolder: sourceUrl || toFolder,
817
- jsonFilename: `${chain}NetBlockHeaders.json`,
818
- headersPerFile: toHeadersPerFile,
819
- files: []
820
- }
821
-
822
- let range = await this.getHeightRange()
823
- if (maxHeight) range = range.intersect(new HeightRange(0, maxHeight))
824
- const reader = await this.createReader(range, toHeadersPerFile * 80)
825
-
826
- let firstHeight = 0
827
- let lastHeaderHash = '00'.repeat(32)
828
- let lastChainWork = '00'.repeat(32)
829
-
830
- let i = -1
831
- for (;;) {
832
- i++
833
- const data = await reader.read()
834
- if (!data || data.length === 0) {
835
- break
836
- }
837
-
838
- const last = validateBufferOfHeaders(data, lastHeaderHash, 0, undefined, lastChainWork)
839
-
840
- await toFs.writeFile(toPath(i), data)
841
-
842
- const fileHash = asString(Hash.sha256(asArray(data)), 'base64')
843
- const file: BulkHeaderFileInfo = {
844
- chain,
845
- count: data.length / 80,
846
- fileHash,
847
- fileName: toFileName(i),
848
- firstHeight,
849
- lastChainWork: last.lastChainWork!,
850
- lastHash: last.lastHeaderHash,
851
- prevChainWork: lastChainWork,
852
- prevHash: lastHeaderHash,
853
- sourceUrl
854
- }
855
- toBulkFiles.files.push(file)
856
- firstHeight += file.count
857
- lastHeaderHash = file.lastHash!
858
- lastChainWork = file.lastChainWork!
859
- }
860
-
861
- await toFs.writeFile(toJsonPath(), asUint8Array(JSON.stringify(toBulkFiles), 'utf8'))
862
- }
863
- }
864
-
865
- interface BulkFileData extends BulkHeaderFileInfo {
866
- mru: number
867
- fileHash: string
868
- }
869
-
870
- export function selectBulkHeaderFiles(
871
- files: BulkHeaderFileInfo[],
872
- chain: Chain,
873
- maxPerFile: number
874
- ): BulkHeaderFileInfo[] {
875
- const r: BulkHeaderFileInfo[] = []
876
- let height = 0
877
- for (;;) {
878
- const choices = files.filter(f => f.firstHeight === height && f.count <= maxPerFile && f.chain === chain)
879
- // Pick the file with the maximum count
880
- const choice = choices.reduce((a, b) => (a.count > b.count ? a : b), choices[0])
881
- if (!choice) break // no more files to select
882
- r.push(choice)
883
- height += choice.count
884
- }
885
- return r
886
- }
887
-
888
- function isBdfIncremental(bfd: BulkFileData | BulkHeaderFileInfo): boolean {
889
- return bfd.fileName === 'incremental' && !bfd.sourceUrl
890
- }
891
-
892
- function isBdfCdn(bfd: BulkFileData | BulkHeaderFileInfo): boolean {
893
- return !isBdfIncremental(bfd)
894
- }
895
-
896
- function bfdToInfo(bfd: BulkFileData, keepData?: boolean): BulkHeaderFileInfo {
897
- return {
898
- chain: bfd.chain,
899
- fileHash: bfd.fileHash,
900
- fileName: bfd.fileName,
901
- sourceUrl: bfd.sourceUrl,
902
- fileId: bfd.fileId,
903
- count: bfd.count,
904
- prevChainWork: bfd.prevChainWork,
905
- lastChainWork: bfd.lastChainWork,
906
- firstHeight: bfd.firstHeight,
907
- prevHash: bfd.prevHash,
908
- lastHash: bfd.lastHash,
909
- validated: bfd.validated || false,
910
- data: keepData ? bfd.data : undefined
911
- }
912
- }
913
-
914
- export interface BulkFileDataManagerMergeResult {
915
- unchanged: BulkHeaderFileInfo[]
916
- inserted: BulkHeaderFileInfo[]
917
- updated: BulkHeaderFileInfo[]
918
- dropped: BulkHeaderFileInfo[]
919
- }
920
-
921
- export class BulkFileDataReader {
922
- readonly manager: BulkFileDataManager
923
- readonly range: HeightRange
924
- readonly maxBufferSize: number
925
- nextHeight: number
926
-
927
- constructor(manager: BulkFileDataManager, range: HeightRange, maxBufferSize: number) {
928
- this.manager = manager
929
- this.range = range
930
- this.maxBufferSize = maxBufferSize
931
- this.nextHeight = range.minHeight
932
- }
933
-
934
- /**
935
- * Returns the Buffer of block headers from the given `file` for the given `range`.
936
- * If `range` is undefined, the file's full height range is read.
937
- * The returned Buffer will only contain headers in `file` and in `range`
938
- * @param file
939
- * @param range
940
- */
941
- private async readBufferFromFile(file: BulkHeaderFileInfo, range?: HeightRange): Promise<Uint8Array | undefined> {
942
- // Constrain the range to the file's contents...
943
- let fileRange = new HeightRange(file.firstHeight, file.firstHeight + file.count - 1)
944
- if (range) fileRange = fileRange.intersect(range)
945
- if (fileRange.isEmpty) return undefined
946
- const offset = (fileRange.minHeight - file.firstHeight) * 80
947
- const length = fileRange.length * 80
948
- return await this.manager.getDataFromFile(file, offset, length)
949
- }
950
-
951
- /**
952
- * @returns an array containing the next `maxBufferSize` bytes of headers from the files.
953
- */
954
- async read(): Promise<Uint8Array | undefined> {
955
- if (this.nextHeight === undefined || !this.range || this.range.isEmpty || this.nextHeight > this.range.maxHeight)
956
- return undefined
957
- let lastHeight = this.nextHeight + this.maxBufferSize / 80 - 1
958
- lastHeight = Math.min(lastHeight, this.range.maxHeight)
959
- let file = await this.manager.getFileForHeight(this.nextHeight)
960
- if (!file) throw new WERR_INTERNAL(`logic error`)
961
- const readRange = new HeightRange(this.nextHeight, lastHeight)
962
- let buffers = new Uint8Array(readRange.length * 80)
963
- let offset = 0
964
- while (file) {
965
- const buffer = await this.readBufferFromFile(file, readRange)
966
- if (!buffer) break
967
- buffers.set(buffer, offset)
968
- offset += buffer.length
969
- file = await this.manager.getFileForHeight(file.firstHeight + file.count)
970
- }
971
- if (!buffers.length || offset !== readRange.length * 80) return undefined
972
- this.nextHeight = lastHeight + 1
973
- return buffers
974
- }
975
- }