trac-msb 0.2.17 → 0.2.19

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 (365) hide show
  1. package/README.md +62 -2
  2. package/SECURITY.md +9 -6
  3. package/cli/commandHandler.js +272 -0
  4. package/cli/handlers.js +210 -0
  5. package/cli/interactive.js +182 -0
  6. package/msb.mjs +7 -8
  7. package/package.json +33 -11
  8. package/rpc/create_server.js +44 -44
  9. package/rpc/handlers.js +43 -56
  10. package/rpc/routes/index.js +8 -8
  11. package/rpc/rpc_server.js +6 -2
  12. package/rpc/utils/helpers.js +46 -66
  13. package/scripts/pear-runner.js +170 -0
  14. package/src/config/args.js +60 -13
  15. package/src/config/config.js +163 -14
  16. package/src/config/env.js +57 -25
  17. package/src/core/network/Network.js +121 -56
  18. package/src/core/network/protocols/LegacyProtocol.js +21 -11
  19. package/src/core/network/protocols/NetworkMessages.js +38 -17
  20. package/src/core/network/protocols/ProtocolInterface.js +15 -3
  21. package/src/core/network/protocols/ProtocolSession.js +144 -17
  22. package/src/core/network/protocols/V1Protocol.js +37 -18
  23. package/src/core/network/protocols/connectionPolicies.js +174 -0
  24. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +26 -20
  25. package/src/core/network/protocols/{shared/handlers/base/BaseOperationHandler.js → legacy/handlers/BaseStateOperationHandler.js} +25 -14
  26. package/src/core/network/protocols/legacy/handlers/{GetRequestHandler.js → LegacyGetRequestHandler.js} +9 -9
  27. package/src/core/network/protocols/legacy/handlers/LegacyResponseHandler.js +23 -0
  28. package/src/core/network/protocols/{shared/handlers/RoleOperationHandler.js → legacy/handlers/LegacyRoleOperationHandler.js} +19 -12
  29. package/src/core/network/protocols/{shared/handlers/SubnetworkOperationHandler.js → legacy/handlers/LegacySubnetworkOperationHandler.js} +29 -18
  30. package/src/core/network/protocols/{shared/handlers/TransferOperationHandler.js → legacy/handlers/LegacyTransferOperationHandler.js} +18 -12
  31. package/src/core/network/protocols/legacy/validators/base/BaseResponse.js +7 -10
  32. package/src/core/network/protocols/shared/validators/{PartialBootstrapDeployment.js → PartialBootstrapDeploymentValidator.js} +9 -4
  33. package/src/core/network/protocols/shared/validators/{base/PartialOperation.js → PartialOperationValidator.js} +53 -31
  34. package/src/core/network/protocols/shared/validators/{PartialRoleAccess.js → PartialRoleAccessValidator.js} +51 -17
  35. package/src/core/network/protocols/shared/validators/{PartialTransaction.js → PartialTransactionValidator.js} +21 -7
  36. package/src/core/network/protocols/shared/validators/{PartialTransfer.js → PartialTransferValidator.js} +32 -14
  37. package/src/core/network/protocols/v1/NetworkMessageRouter.js +91 -7
  38. package/src/core/network/protocols/v1/V1ProtocolError.js +27 -0
  39. package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +66 -0
  40. package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +272 -0
  41. package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +88 -0
  42. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionErrorMapper.js +84 -0
  43. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionOperationStrategies.js +128 -0
  44. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionPayloadUtils.js +26 -0
  45. package/src/core/network/protocols/v1/validators/V1BaseOperation.js +212 -0
  46. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +28 -0
  47. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +260 -0
  48. package/src/core/network/protocols/v1/validators/V1LivenessRequest.js +15 -0
  49. package/src/core/network/protocols/v1/validators/V1LivenessResponse.js +17 -0
  50. package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +210 -0
  51. package/src/core/network/services/ConnectionManager.js +149 -96
  52. package/src/core/network/services/MessageOrchestrator.js +197 -37
  53. package/src/core/network/services/PendingRequestService.js +175 -0
  54. package/src/core/network/services/TransactionCommitService.js +149 -0
  55. package/src/core/network/services/TransactionPoolService.js +129 -18
  56. package/src/core/network/services/TransactionRateLimiterService.js +57 -35
  57. package/src/core/network/services/ValidatorHealthCheckService.js +127 -0
  58. package/src/core/network/services/ValidatorObserverService.js +400 -121
  59. package/src/core/state/State.js +259 -156
  60. package/src/core/state/utils/address.js +4 -9
  61. package/src/core/state/utils/balance.js +7 -7
  62. package/src/core/state/utils/roles.js +1 -1
  63. package/src/index.js +320 -278
  64. package/src/messages/network/v1/NetworkMessageBuilder.js +71 -100
  65. package/src/messages/network/v1/NetworkMessageDirector.js +16 -50
  66. package/src/messages/network/v1/networkMessageFactory.js +1 -1
  67. package/src/messages/state/ApplyStateMessageBuilder.js +6 -6
  68. package/src/messages/state/applyStateMessageFactory.js +1 -1
  69. package/src/utils/Scheduler.js +0 -8
  70. package/src/utils/buffer.js +1 -1
  71. package/src/utils/check.js +12 -13
  72. package/src/utils/constants.js +78 -5
  73. package/src/utils/deepEqualApplyPayload.js +40 -0
  74. package/src/utils/errors.js +20 -0
  75. package/src/utils/fileUtils.js +12 -3
  76. package/src/utils/helpers.js +10 -1
  77. package/src/utils/logger.js +25 -0
  78. package/src/utils/migrationUtils.js +3 -3
  79. package/src/utils/normalizers.js +38 -0
  80. package/src/utils/protobuf/networkV1.generated.cjs +2460 -0
  81. package/src/utils/protobuf/operationHelpers.js +24 -3
  82. package/.dockerignore +0 -16
  83. package/.github/workflows/acceptance-tests.yml +0 -38
  84. package/.github/workflows/lint-pr-title.yml +0 -26
  85. package/.github/workflows/publish.yml +0 -33
  86. package/.github/workflows/unit-tests.yml +0 -34
  87. package/CODE_OF_CONDUCT.md +0 -128
  88. package/docker-compose.yml +0 -17
  89. package/dockerfile +0 -41
  90. package/docs/fee_distribution.md +0 -89
  91. package/docs/trac_network_http_api.openapi.yaml +0 -889
  92. package/migration/.gitkeep +0 -0
  93. package/proto/applyOperations.proto +0 -117
  94. package/proto/network.proto +0 -74
  95. package/rpc/rpc_services.js +0 -163
  96. package/scripts/generate-protobufs.js +0 -42
  97. package/src/core/network/identity/NetworkWalletFactory.js +0 -77
  98. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +0 -37
  99. package/src/utils/cli.js +0 -130
  100. package/src/utils/cliCommands.js +0 -280
  101. package/src/utils/protobuf/network.cjs +0 -840
  102. package/tests/acceptance/v1/account/account.test.mjs +0 -123
  103. package/tests/acceptance/v1/balance/balance.test.mjs +0 -54
  104. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +0 -116
  105. package/tests/acceptance/v1/confirmed-length/confirmed-length.test.mjs +0 -19
  106. package/tests/acceptance/v1/fee/fee.test.mjs +0 -11
  107. package/tests/acceptance/v1/health/health.test.mjs +0 -33
  108. package/tests/acceptance/v1/rpc.test.mjs +0 -95
  109. package/tests/acceptance/v1/tx/tx.test.mjs +0 -111
  110. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +0 -213
  111. package/tests/acceptance/v1/tx-hashes/tx-hashes.test.mjs +0 -72
  112. package/tests/acceptance/v1/tx-payloads-bulk/tx-payloads-bulk.test.mjs +0 -27
  113. package/tests/acceptance/v1/txv/txv.test.mjs +0 -11
  114. package/tests/acceptance/v1/unconfirmed-length/unconfirmed-length.test.mjs +0 -11
  115. package/tests/fixtures/apply.fixtures.js +0 -77
  116. package/tests/fixtures/assembleMessage.fixtures.js +0 -41
  117. package/tests/fixtures/check.fixtures.js +0 -428
  118. package/tests/fixtures/networkV1.fixtures.js +0 -85
  119. package/tests/fixtures/protobuf.fixtures.js +0 -388
  120. package/tests/helpers/StateNetworkFactory.js +0 -155
  121. package/tests/helpers/address.js +0 -6
  122. package/tests/helpers/autobaseTestHelpers.js +0 -419
  123. package/tests/helpers/config.js +0 -4
  124. package/tests/helpers/createTestSignature.js +0 -13
  125. package/tests/helpers/regexHelper.js +0 -3
  126. package/tests/helpers/setupApplyTests.js +0 -587
  127. package/tests/helpers/transactionPayloads.mjs +0 -92
  128. package/tests/helpers/wrapper.js +0 -28
  129. package/tests/unit/messages/messages.test.js +0 -12
  130. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +0 -276
  131. package/tests/unit/messages/network/NetworkMessageDirector.test.js +0 -201
  132. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +0 -525
  133. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +0 -237
  134. package/tests/unit/network/ConnectionManager.test.js +0 -191
  135. package/tests/unit/network/NetworkWalletFactory.test.js +0 -156
  136. package/tests/unit/network/networkModule.test.js +0 -10
  137. package/tests/unit/state/State.test.js +0 -80
  138. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +0 -42
  139. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +0 -276
  140. package/tests/unit/state/apply/addAdmin/adminEntryEncodingFailureScenario.js +0 -30
  141. package/tests/unit/state/apply/addAdmin/adminEntryExistsScenario.js +0 -78
  142. package/tests/unit/state/apply/addAdmin/nodeEntryInitializationFailureScenario.js +0 -30
  143. package/tests/unit/state/apply/addAdmin/nonBootstrapNodeScenario.js +0 -68
  144. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +0 -159
  145. package/tests/unit/state/apply/addIndexer/addIndexerHappyPathScenario.js +0 -39
  146. package/tests/unit/state/apply/addIndexer/addIndexerMultipleIndexersInTheNetworkScenario.js +0 -167
  147. package/tests/unit/state/apply/addIndexer/addIndexerPretenderAlreadyIndexerScenario.js +0 -21
  148. package/tests/unit/state/apply/addIndexer/addIndexerPretenderNotWriterScenario.js +0 -21
  149. package/tests/unit/state/apply/addIndexer/addIndexerRemoveAndReAddScenario.js +0 -186
  150. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +0 -443
  151. package/tests/unit/state/apply/addIndexer/addIndexerWriterKeyAlreadyRegisteredScenario.js +0 -32
  152. package/tests/unit/state/apply/addIndexer/state.apply.addIndexer.test.js +0 -297
  153. package/tests/unit/state/apply/addWriter/addWriterHappyPathScenario.js +0 -41
  154. package/tests/unit/state/apply/addWriter/addWriterInvalidValidatorSignatureScenario.js +0 -32
  155. package/tests/unit/state/apply/addWriter/addWriterNewWkScenario.js +0 -149
  156. package/tests/unit/state/apply/addWriter/addWriterRequesterAlreadyWriterScenario.js +0 -21
  157. package/tests/unit/state/apply/addWriter/addWriterRequesterBalanceInsufficientScenario.js +0 -21
  158. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryDecodeFailureScenario.js +0 -19
  159. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryMissingScenario.js +0 -19
  160. package/tests/unit/state/apply/addWriter/addWriterRequesterIndexerScenario.js +0 -21
  161. package/tests/unit/state/apply/addWriter/addWriterRequesterNotWhitelistedScenario.js +0 -21
  162. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +0 -766
  163. package/tests/unit/state/apply/addWriter/addWriterStakeBalanceUpdateFailureScenario.js +0 -50
  164. package/tests/unit/state/apply/addWriter/addWriterStakeInsufficientBalanceScenario.js +0 -29
  165. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidBalanceScenario.js +0 -29
  166. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidEntryScenario.js +0 -21
  167. package/tests/unit/state/apply/addWriter/addWriterStakeStakedBalanceFailureScenario.js +0 -37
  168. package/tests/unit/state/apply/addWriter/addWriterStakeSubtractFailureScenario.js +0 -42
  169. package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +0 -106
  170. package/tests/unit/state/apply/addWriter/addWriterWriterKeyMismatchScenario.js +0 -54
  171. package/tests/unit/state/apply/addWriter/addWriterWriterKeyOwnershipScenario.js +0 -54
  172. package/tests/unit/state/apply/addWriter/addWriterZeroWriterKeyScenario.js +0 -29
  173. package/tests/unit/state/apply/addWriter/state.apply.addWriter.test.js +0 -309
  174. package/tests/unit/state/apply/adminRecovery/adminRecoveryHappyPathScenario.js +0 -30
  175. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +0 -881
  176. package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +0 -435
  177. package/tests/unit/state/apply/appendWhitelist/appendWhitelistBanAndReapplyScenario.js +0 -78
  178. package/tests/unit/state/apply/appendWhitelist/appendWhitelistExistingReaderHappyPathScenario.js +0 -98
  179. package/tests/unit/state/apply/appendWhitelist/appendWhitelistFeeAfterDisableScenario.js +0 -66
  180. package/tests/unit/state/apply/appendWhitelist/appendWhitelistHappyPathScenario.js +0 -55
  181. package/tests/unit/state/apply/appendWhitelist/appendWhitelistInsufficientAdminBalanceScenario.js +0 -103
  182. package/tests/unit/state/apply/appendWhitelist/appendWhitelistNodeAlreadyWhitelistedScenario.js +0 -60
  183. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +0 -189
  184. package/tests/unit/state/apply/appendWhitelist/state.apply.appendWhitelist.test.js +0 -220
  185. package/tests/unit/state/apply/balanceInitialization/balanceInitializationHappyPathScenario.js +0 -82
  186. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +0 -111
  187. package/tests/unit/state/apply/balanceInitialization/invalidAmountScenario.js +0 -45
  188. package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +0 -82
  189. package/tests/unit/state/apply/balanceInitialization/state.apply.balanceInitialization.test.js +0 -189
  190. package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +0 -156
  191. package/tests/unit/state/apply/banValidator/banValidatorHappyPathScenario.js +0 -36
  192. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +0 -531
  193. package/tests/unit/state/apply/banValidator/banValidatorSequentialBansScenario.js +0 -74
  194. package/tests/unit/state/apply/banValidator/banValidatorTargetDecodeFailureScenario.js +0 -19
  195. package/tests/unit/state/apply/banValidator/banValidatorTargetIndexerScenario.js +0 -32
  196. package/tests/unit/state/apply/banValidator/banValidatorTargetNodeEntryMissingScenario.js +0 -19
  197. package/tests/unit/state/apply/banValidator/banValidatorTargetRoleUpdateFailureScenario.js +0 -19
  198. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedNonWriterScenario.js +0 -38
  199. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedZeroBalanceScenario.js +0 -91
  200. package/tests/unit/state/apply/banValidator/banValidatorWithdrawFailureScenario.js +0 -19
  201. package/tests/unit/state/apply/banValidator/state.apply.banValidator.test.js +0 -266
  202. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +0 -143
  203. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentHappyPathScenario.js +0 -26
  204. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentIncompleteOperationScenario.js +0 -94
  205. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentInvalidDeploymentEntryScenario.js +0 -37
  206. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentMultipleBootstrapScenario.js +0 -86
  207. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +0 -347
  208. package/tests/unit/state/apply/bootstrapDeployment/invalidValidatorNodeEntryScenario.js +0 -57
  209. package/tests/unit/state/apply/bootstrapDeployment/state.apply.bootstrapDeployment.test.js +0 -429
  210. package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +0 -120
  211. package/tests/unit/state/apply/common/access-control/adminEntryDecodeFailureScenario.js +0 -130
  212. package/tests/unit/state/apply/common/access-control/adminEntryExistsScenario.js +0 -93
  213. package/tests/unit/state/apply/common/access-control/adminEntryMissingScenario.js +0 -108
  214. package/tests/unit/state/apply/common/access-control/adminOnlyGuardScenario.js +0 -126
  215. package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +0 -121
  216. package/tests/unit/state/apply/common/access-control/roleAccessOperationValidationScenario.js +0 -50
  217. package/tests/unit/state/apply/common/adminControlOperationValidationScenario.js +0 -56
  218. package/tests/unit/state/apply/common/balances/adminEntryUpdateFailureScenario.js +0 -52
  219. package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +0 -198
  220. package/tests/unit/state/apply/common/balances/feeDecodeFailureScenario.js +0 -52
  221. package/tests/unit/state/apply/common/balances/requesterBalanceDecodeFailureScenario.js +0 -15
  222. package/tests/unit/state/apply/common/balances/requesterBalanceFeeApplicationFailureScenario.js +0 -11
  223. package/tests/unit/state/apply/common/balances/requesterBalanceInsufficientScenario.js +0 -15
  224. package/tests/unit/state/apply/common/balances/requesterBalanceUpdateFailureScenario.js +0 -11
  225. package/tests/unit/state/apply/common/balances/validatorEntryRewardFailureScenario.js +0 -11
  226. package/tests/unit/state/apply/common/balances/validatorEntryUpdateFailureScenario.js +0 -11
  227. package/tests/unit/state/apply/common/balances/validatorNodeEntryDecodeFailureScenario.js +0 -40
  228. package/tests/unit/state/apply/common/base/OperationValidationScenarioBase.js +0 -114
  229. package/tests/unit/state/apply/common/commonScenarioHelper.js +0 -103
  230. package/tests/unit/state/apply/common/indexer/indexerNodeEntryDecodeFailureScenario.js +0 -36
  231. package/tests/unit/state/apply/common/indexer/indexerNodeEntryMissingScenario.js +0 -36
  232. package/tests/unit/state/apply/common/indexer/indexerRoleUpdateFailureScenario.js +0 -29
  233. package/tests/unit/state/apply/common/indexer/indexerSequenceStateInvalidScenario.js +0 -66
  234. package/tests/unit/state/apply/common/invalidMessageComponentValidationScenario.js +0 -84
  235. package/tests/unit/state/apply/common/nodeEntryInitializationFailureScenario.js +0 -47
  236. package/tests/unit/state/apply/common/operationAlreadyAppliedScenario.js +0 -85
  237. package/tests/unit/state/apply/common/payload-structure/addressWithInvalidPublicKeyScenario.js +0 -52
  238. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +0 -54
  239. package/tests/unit/state/apply/common/payload-structure/invalidAddressValidationScenario.js +0 -73
  240. package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +0 -71
  241. package/tests/unit/state/apply/common/payload-structure/invalidPayloadValidationScenario.js +0 -31
  242. package/tests/unit/state/apply/common/payload-structure/invalidSignatureValidationScenario.js +0 -142
  243. package/tests/unit/state/apply/common/payload-structure/partialOperationValidationScenario.js +0 -87
  244. package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +0 -71
  245. package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +0 -73
  246. package/tests/unit/state/apply/common/requester/requesterNodeEntryMissingScenario.js +0 -36
  247. package/tests/unit/state/apply/common/requesterAddressValidationScenario.js +0 -44
  248. package/tests/unit/state/apply/common/requesterPublicKeyValidationScenario.js +0 -25
  249. package/tests/unit/state/apply/common/transactionValidityMismatchScenario.js +0 -98
  250. package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +0 -202
  251. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryDecodeFailureScenario.js +0 -17
  252. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryMissingScenario.js +0 -44
  253. package/tests/unit/state/apply/common/validatorConsistency/validatorInactiveScenario.js +0 -19
  254. package/tests/unit/state/apply/common/validatorConsistency/validatorWriterKeyMismatchScenario.js +0 -18
  255. package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +0 -315
  256. package/tests/unit/state/apply/common/validatorEntryValidation/validatorEntryInvalidBalanceScenario.js +0 -18
  257. package/tests/unit/state/apply/common/writerKeyExistsValidationScenario.js +0 -43
  258. package/tests/unit/state/apply/disableInitialization/disableInitializationAlreadyDisabledScenario.js +0 -53
  259. package/tests/unit/state/apply/disableInitialization/disableInitializationHappyPathScenario.js +0 -24
  260. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +0 -204
  261. package/tests/unit/state/apply/disableInitialization/state.apply.disableInitialization.test.js +0 -161
  262. package/tests/unit/state/apply/missing-tests.md +0 -18
  263. package/tests/unit/state/apply/removeIndexer/removeIndexerHappyPathScenario.js +0 -58
  264. package/tests/unit/state/apply/removeIndexer/removeIndexerReAddAndRemoveAgainScenario.js +0 -98
  265. package/tests/unit/state/apply/removeIndexer/removeIndexerRemoveMultipleIndexersScenario.js +0 -167
  266. package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +0 -429
  267. package/tests/unit/state/apply/removeIndexer/removeIndexerTargetNotIndexerScenario.js +0 -22
  268. package/tests/unit/state/apply/removeIndexer/removeIndexerWriterKeyMissingScenario.js +0 -20
  269. package/tests/unit/state/apply/removeIndexer/state.apply.removeIndexer.test.js +0 -291
  270. package/tests/unit/state/apply/removeWriter/removeWriterAndAddWriterAgainScenario.js +0 -87
  271. package/tests/unit/state/apply/removeWriter/removeWriterHappyPathScenario.js +0 -38
  272. package/tests/unit/state/apply/removeWriter/removeWriterInvalidValidatorSignatureScenario.js +0 -32
  273. package/tests/unit/state/apply/removeWriter/removeWriterRequesterBalanceInsufficientScenario.js +0 -21
  274. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryDecodeFailureScenario.js +0 -19
  275. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryMissingScenario.js +0 -19
  276. package/tests/unit/state/apply/removeWriter/removeWriterRequesterIndexerScenario.js +0 -21
  277. package/tests/unit/state/apply/removeWriter/removeWriterRequesterNotWriterScenario.js +0 -21
  278. package/tests/unit/state/apply/removeWriter/removeWriterRequesterRoleUpdateFailureScenario.js +0 -19
  279. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +0 -348
  280. package/tests/unit/state/apply/removeWriter/removeWriterThroughWriterValidatorScenario.js +0 -113
  281. package/tests/unit/state/apply/removeWriter/removeWriterUnstakeFailureScenario.js +0 -33
  282. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyMismatchScenario.js +0 -21
  283. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyOwnershipScenario.js +0 -26
  284. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyRegistryMissingScenario.js +0 -22
  285. package/tests/unit/state/apply/removeWriter/state.apply.removeWriter.test.js +0 -307
  286. package/tests/unit/state/apply/state.apply.test.js +0 -24
  287. package/tests/unit/state/apply/transfer/state.apply.transfer.test.js +0 -819
  288. package/tests/unit/state/apply/transfer/transferContractSchemaValidationScenario.js +0 -22
  289. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +0 -146
  290. package/tests/unit/state/apply/transfer/transferDoubleSpendSameBatchScenario.js +0 -63
  291. package/tests/unit/state/apply/transfer/transferDoubleSpendSingleValidatorScenario.js +0 -67
  292. package/tests/unit/state/apply/transfer/transferExistingRecipientAmountScenario.js +0 -31
  293. package/tests/unit/state/apply/transfer/transferExistingRecipientZeroAmountScenario.js +0 -31
  294. package/tests/unit/state/apply/transfer/transferHandlerGuardScenarios.js +0 -22
  295. package/tests/unit/state/apply/transfer/transferHappyPathScenario.js +0 -8
  296. package/tests/unit/state/apply/transfer/transferInvalidIncomingDataScenario.js +0 -66
  297. package/tests/unit/state/apply/transfer/transferNewRecipientAmountScenario.js +0 -31
  298. package/tests/unit/state/apply/transfer/transferNewRecipientZeroAmountScenario.js +0 -31
  299. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +0 -1170
  300. package/tests/unit/state/apply/transfer/transferSelfTransferAmountScenario.js +0 -38
  301. package/tests/unit/state/apply/transfer/transferSelfTransferZeroAmountScenario.js +0 -38
  302. package/tests/unit/state/apply/transfer/transferValidatorRecipientAmountScenario.js +0 -38
  303. package/tests/unit/state/apply/transfer/transferValidatorRecipientZeroAmountScenario.js +0 -38
  304. package/tests/unit/state/apply/txOperation/state.apply.txOperation.test.js +0 -318
  305. package/tests/unit/state/apply/txOperation/txOperationBootstrapNotRegisteredScenario.js +0 -70
  306. package/tests/unit/state/apply/txOperation/txOperationDifferentValidatorCreatorHappyPathScenario.js +0 -23
  307. package/tests/unit/state/apply/txOperation/txOperationInvalidDeploymentEntryScenario.js +0 -48
  308. package/tests/unit/state/apply/txOperation/txOperationInvalidFeeAmountScenario.js +0 -39
  309. package/tests/unit/state/apply/txOperation/txOperationInvalidSubnetCreatorAddressScenario.js +0 -46
  310. package/tests/unit/state/apply/txOperation/txOperationRequesterCreatorHappyPathScenario.js +0 -21
  311. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +0 -432
  312. package/tests/unit/state/apply/txOperation/txOperationStandardHappyPathScenario.js +0 -21
  313. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddCreatorBalanceFailureScenario.js +0 -26
  314. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBalanceFailureScenario.js +0 -25
  315. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBonusFailureScenario.js +0 -27
  316. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeCreatorEntryScenario.js +0 -18
  317. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeRequesterEntryScenario.js +0 -17
  318. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeValidatorEntryScenario.js +0 -31
  319. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardBypassScenario.js +0 -49
  320. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +0 -93
  321. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInsufficientRequesterBalanceScenario.js +0 -28
  322. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidCreatorBalanceScenario.js +0 -29
  323. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterBalanceScenario.js +0 -28
  324. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterEntryScenario.js +0 -17
  325. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidValidatorBalanceScenario.js +0 -33
  326. package/tests/unit/state/apply/txOperation/txOperationTransferFeeMissingCreatorEntryScenario.js +0 -18
  327. package/tests/unit/state/apply/txOperation/txOperationTransferFeeSubtractFailureScenario.js +0 -25
  328. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateCreatorBalanceFailureScenario.js +0 -26
  329. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateFailureScenario.js +0 -25
  330. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBalanceFailureScenario.js +0 -26
  331. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBonusFailureScenario.js +0 -27
  332. package/tests/unit/state/apply/txOperation/txOperationValidatorCreatorHappyPathScenario.js +0 -21
  333. package/tests/unit/state/stateModule.test.js +0 -23
  334. package/tests/unit/state/stateTestUtils.js +0 -32
  335. package/tests/unit/state/utils/address.test.js +0 -63
  336. package/tests/unit/state/utils/adminEntry.test.js +0 -52
  337. package/tests/unit/state/utils/balance.test.js +0 -320
  338. package/tests/unit/state/utils/lengthEntry.test.js +0 -54
  339. package/tests/unit/state/utils/nodeEntry.test.js +0 -298
  340. package/tests/unit/state/utils/roles.test.js +0 -44
  341. package/tests/unit/unit.test.js +0 -14
  342. package/tests/unit/utils/amountSerialization/amountSerialization.test.js +0 -237
  343. package/tests/unit/utils/buffer/buffer.test.js +0 -251
  344. package/tests/unit/utils/check/adminControlOperation.test.js +0 -156
  345. package/tests/unit/utils/check/balanceInitializationOperation.test.js +0 -54
  346. package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +0 -104
  347. package/tests/unit/utils/check/check.test.js +0 -17
  348. package/tests/unit/utils/check/common.test.js +0 -419
  349. package/tests/unit/utils/check/coreAdminOperation.test.js +0 -95
  350. package/tests/unit/utils/check/roleAccessOperation.test.js +0 -255
  351. package/tests/unit/utils/check/transactionOperation.test.js +0 -107
  352. package/tests/unit/utils/check/transferOperation.test.js +0 -102
  353. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +0 -95
  354. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +0 -149
  355. package/tests/unit/utils/helpers/helpers.test.js +0 -11
  356. package/tests/unit/utils/helpers/isHexString.test.js +0 -12
  357. package/tests/unit/utils/helpers/normalizeHex.test.js +0 -82
  358. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +0 -100
  359. package/tests/unit/utils/normalizers/normalizers.test.js +0 -469
  360. package/tests/unit/utils/protobuf/applyOperations.test.js +0 -91
  361. package/tests/unit/utils/protobuf/operationHelpers.test.js +0 -305
  362. package/tests/unit/utils/protobuf/protobuf.test.js +0 -12
  363. package/tests/unit/utils/type/type.test.js +0 -25
  364. package/tests/unit/utils/utils.test.js +0 -20
  365. package/whitelist/.gitkeep +0 -0
@@ -1,766 +0,0 @@
1
- import b4a from 'b4a';
2
- import { applyStateMessageFactory } from '../../../../../src/messages/state/applyStateMessageFactory.js';
3
- import { safeEncodeApplyOperation } from '../../../../../src/utils/protobuf/operationHelpers.js';
4
- import { deriveIndexerSequenceState, eventFlush } from '../../../../helpers/autobaseTestHelpers.js';
5
- import { safeDecodeApplyOperation } from '../../../../../src/utils/protobuf/operationHelpers.js';
6
- import nodeEntryUtils, { ZERO_LICENSE } from '../../../../../src/core/state/utils/nodeEntry.js';
7
- import lengthEntryUtils from '../../../../../src/core/state/utils/lengthEntry.js';
8
- import addressUtils from '../../../../../src/core/state/utils/address.js';
9
- import { EntryType } from '../../../../../src/utils/constants.js';
10
- import {
11
- toBalance,
12
- BALANCE_FEE,
13
- BALANCE_TO_STAKE,
14
- BALANCE_ZERO,
15
- PERCENT_75
16
- } from '../../../../../src/core/state/utils/balance.js';
17
- import { decimalStringToBigInt, bigIntTo16ByteBuffer } from '../../../../../src/utils/amountSerialization.js';
18
- import { setupAdminAndWhitelistedReaderNetwork } from '../common/commonScenarioHelper.js';
19
- import { config } from '../../../../helpers/config.js';
20
-
21
- const DEFAULT_WRITER_FUNDING = bigIntTo16ByteBuffer(decimalStringToBigInt('10'));
22
- const STAKE_ENTRY_MARK = Symbol('stake-entry-mark');
23
-
24
- export async function setupAddWriterScenario(
25
- t,
26
- { nodes = 2, writerInitialBalance = DEFAULT_WRITER_FUNDING } = {}
27
- ) {
28
- const context = await setupAdminAndWhitelistedReaderNetwork(t, {
29
- nodes: Math.max(nodes, 2),
30
- readerInitialBalance: writerInitialBalance
31
- });
32
- context.addWriterScenario = { writerInitialBalance };
33
- return context;
34
- }
35
-
36
- export function selectWriterPeer(context, offset = 0) {
37
- const candidates = context.peers.slice(1);
38
- if (!candidates.length) {
39
- throw new Error('AddWriter scenarios require at least one reader peer.');
40
- }
41
- return candidates[Math.min(offset, candidates.length - 1)];
42
- }
43
-
44
- export function selectValidatorPeerWithoutEntry(context) {
45
- const writerPeer = selectWriterPeer(context);
46
- return (
47
- context.peers.find(
48
- peer =>
49
- peer.wallet.address !== context.adminBootstrap.wallet.address &&
50
- peer.wallet.address !== writerPeer.wallet.address
51
- ) ?? null
52
- );
53
- }
54
-
55
- export async function promotePeerToWriter(
56
- t,
57
- context,
58
- {
59
- readerPeer = selectWriterPeer(context),
60
- validatorPeer = context.adminBootstrap,
61
- writerKeyBuffer = null,
62
- expectedWriterIndex = null
63
- } = {}
64
- ) {
65
- if (!readerPeer) {
66
- throw new Error('promotePeerToWriter requires a reader peer.');
67
- }
68
- if (!validatorPeer) {
69
- throw new Error('promotePeerToWriter requires a validator peer.');
70
- }
71
-
72
- const payload = await buildAddWriterPayload(context, {
73
- readerPeer,
74
- validatorPeer,
75
- writerKeyBuffer
76
- });
77
-
78
- await validatorPeer.base.append(payload);
79
- await validatorPeer.base.update();
80
- await eventFlush();
81
-
82
- const assertOptions = {
83
- readerPeer,
84
- validatorPeer,
85
- writerKeyBuffer,
86
- payload
87
- };
88
-
89
- if (typeof expectedWriterIndex === 'number') {
90
- assertOptions.expectedWriterIndex = expectedWriterIndex;
91
- }
92
-
93
- await assertAddWriterSuccessState(t, context, assertOptions);
94
-
95
- return payload;
96
- }
97
-
98
- export async function buildAddWriterPayload(
99
- context,
100
- {
101
- readerPeer = selectWriterPeer(context),
102
- validatorPeer = context.adminBootstrap,
103
- writerKeyBuffer = null
104
- } = {}
105
- ) {
106
- const txValidity = await deriveIndexerSequenceState(validatorPeer.base);
107
- const writingKey = writerKeyBuffer ?? readerPeer.base.local.key;
108
- const partial = await applyStateMessageFactory(readerPeer.wallet, config)
109
- .buildPartialAddWriterMessage(
110
- readerPeer.wallet.address,
111
- writingKey.toString('hex'),
112
- txValidity.toString('hex'),
113
- 'json'
114
- );
115
-
116
- const payload = await applyStateMessageFactory(validatorPeer.wallet, config)
117
- .buildCompleteAddWriterMessage(
118
- partial.address,
119
- b4a.from(partial.rao.tx, 'hex'),
120
- b4a.from(partial.rao.txv, 'hex'),
121
- b4a.from(partial.rao.iw, 'hex'),
122
- b4a.from(partial.rao.in, 'hex'),
123
- b4a.from(partial.rao.is, 'hex')
124
- );
125
- return safeEncodeApplyOperation(payload);
126
- }
127
-
128
- export async function buildAddWriterPayloadWithTxValidity(
129
- context,
130
- mutatedTxValidity,
131
- {
132
- readerPeer = selectWriterPeer(context),
133
- validatorPeer = context.adminBootstrap,
134
- writerKeyBuffer = null
135
- } = {}
136
- ) {
137
- if (!b4a.isBuffer(mutatedTxValidity)) {
138
- throw new Error('buildAddWriterPayloadWithTxValidity requires a tx validity buffer.');
139
- }
140
-
141
- const writingKey = writerKeyBuffer ?? readerPeer.base.local.key;
142
- const partial = await applyStateMessageFactory(readerPeer.wallet, config)
143
- .buildPartialAddWriterMessage(
144
- readerPeer.wallet.address,
145
- writingKey.toString('hex'),
146
- mutatedTxValidity.toString('hex'),
147
- 'json'
148
- );
149
-
150
- const payload = await applyStateMessageFactory(validatorPeer.wallet, config)
151
- .buildCompleteAddWriterMessage(
152
- partial.address,
153
- b4a.from(partial.rao.tx, 'hex'),
154
- mutatedTxValidity,
155
- b4a.from(partial.rao.iw, 'hex'),
156
- b4a.from(partial.rao.in, 'hex'),
157
- b4a.from(partial.rao.is, 'hex')
158
- );
159
- return safeEncodeApplyOperation(payload);
160
- }
161
-
162
- export async function buildRemoveWriterPayload(
163
- context,
164
- {
165
- readerPeer = selectWriterPeer(context),
166
- validatorPeer = context.adminBootstrap,
167
- writerKeyBuffer = null
168
- } = {}
169
- ) {
170
- const txValidity = await deriveIndexerSequenceState(validatorPeer.base);
171
- const writerKey = writerKeyBuffer ?? readerPeer.base.local.key;
172
- const partial = await applyStateMessageFactory(readerPeer.wallet, config)
173
- .buildPartialRemoveWriterMessage(
174
- readerPeer.wallet.address,
175
- writerKey.toString('hex'),
176
- txValidity.toString('hex'),
177
- 'json'
178
- );
179
-
180
- const payload = await applyStateMessageFactory(validatorPeer.wallet, config)
181
- .buildCompleteRemoveWriterMessage(
182
- partial.address,
183
- b4a.from(partial.rao.tx, 'hex'),
184
- b4a.from(partial.rao.txv, 'hex'),
185
- b4a.from(partial.rao.iw, 'hex'),
186
- b4a.from(partial.rao.in, 'hex'),
187
- b4a.from(partial.rao.is, 'hex')
188
- );
189
- return safeEncodeApplyOperation(payload);
190
- }
191
-
192
- export async function assertAddWriterSuccessState(
193
- t,
194
- context,
195
- {
196
- readerPeer = selectWriterPeer(context),
197
- validatorPeer = context.adminBootstrap,
198
- writerInitialBalance = context.addWriterScenario?.writerInitialBalance,
199
- validatorBalanceBefore = null,
200
- payload = null,
201
- expectedWriterIndex = 1,
202
- skipSync = false,
203
- writerKeyBuffer = null
204
- } = {}
205
- ) {
206
- if (!writerInitialBalance) {
207
- throw new Error('assertAddWriterSuccessState requires writerInitialBalance buffer.');
208
- }
209
-
210
- const writerInitial = toBalance(writerInitialBalance);
211
- const afterFee = writerInitial.sub(BALANCE_FEE);
212
- const expectedLiquid = afterFee?.sub(BALANCE_TO_STAKE);
213
- const expectedStaked = BALANCE_TO_STAKE.value;
214
- if (!expectedLiquid) {
215
- throw new Error('Failed to derive expected writer balance.');
216
- }
217
-
218
- const writerAddress = readerPeer.wallet.address;
219
- const writerAddressBuffer = addressUtils.addressToBuffer(writerAddress, config.addressPrefix);
220
- const writingKey = writerKeyBuffer ?? readerPeer.base.local.key;
221
- const writingKeyHex = writingKey.toString('hex');
222
-
223
- await assertWriterEntry(t, validatorPeer.base, writerAddress, writingKey, {
224
- expectedBalance: expectedLiquid.value,
225
- expectedStakedBalance: expectedStaked
226
- });
227
-
228
- await assertWriterRegistry(t, validatorPeer.base, writerAddressBuffer, writingKeyHex, expectedWriterIndex);
229
-
230
- if (validatorBalanceBefore) {
231
- await assertValidatorReward(t, validatorPeer, validatorBalanceBefore);
232
- }
233
-
234
- if (payload) {
235
- await assertReplayProtection(t, validatorPeer.base, payload);
236
- }
237
-
238
- if (!skipSync) {
239
- await context.sync();
240
- await assertWriterEntry(t, readerPeer.base, writerAddress, writingKey, {
241
- expectedBalance: expectedLiquid.value,
242
- expectedStakedBalance: expectedStaked
243
- });
244
- }
245
- }
246
-
247
- async function assertWriterEntry(
248
- t,
249
- base,
250
- address,
251
- writingKey,
252
- { expectedBalance, expectedStakedBalance }
253
- ) {
254
- const entry = await base.view.get(address);
255
- t.ok(entry, 'writer node entry exists');
256
- const decoded = nodeEntryUtils.decode(entry.value);
257
- t.ok(decoded, 'writer node entry decodes');
258
- t.is(decoded.isWhitelisted, true, 'writer remains whitelisted');
259
- t.is(decoded.isWriter, true, 'writer role assigned');
260
- t.is(decoded.isIndexer, false, 'writer not promoted to indexer');
261
- t.ok(b4a.equals(decoded.wk, writingKey), 'writer key stored on node entry');
262
- if (expectedBalance) {
263
- t.ok(
264
- b4a.equals(decoded.balance, expectedBalance),
265
- 'writer liquid balance reflects stake and fee deductions'
266
- );
267
- }
268
- if (expectedStakedBalance) {
269
- t.ok(
270
- b4a.equals(decoded.stakedBalance, expectedStakedBalance),
271
- 'writer staked balance recorded'
272
- );
273
- }
274
- }
275
-
276
- async function assertReaderNotPromoted(t, base, peer, { expectRegistryEntry = false } = {}) {
277
- const address = peer.wallet.address;
278
- const entry = await base.view.get(address);
279
- t.ok(entry, 'reader entry exists');
280
- const decoded = nodeEntryUtils.decode(entry.value);
281
- t.ok(decoded, 'reader entry decodes');
282
- t.is(decoded.isWhitelisted, true, 'reader stays whitelisted');
283
- t.is(decoded.isWriter, false, 'reader not promoted to writer');
284
- t.is(decoded.isIndexer, false, 'reader not an indexer');
285
- t.ok(
286
- b4a.equals(decoded.stakedBalance, BALANCE_ZERO.value),
287
- 'reader staked balance remains zero'
288
- );
289
- const registryEntry = await base.view.get(
290
- EntryType.WRITER_ADDRESS + peer.base.local.key.toString('hex')
291
- );
292
- if (expectRegistryEntry) {
293
- t.ok(registryEntry, 'writer registry entry persists for reader');
294
- } else {
295
- t.is(registryEntry, null, 'writer registry entry remains absent for reader');
296
- }
297
- }
298
-
299
- export async function assertAddWriterFailureState(
300
- t,
301
- context,
302
- { skipSync = false, expectRegistryEntry = false } = {}
303
- ) {
304
- const writerPeer = selectWriterPeer(context);
305
- const validatorPeer = context.adminBootstrap;
306
-
307
- await assertReaderNotPromoted(t, validatorPeer.base, writerPeer, { expectRegistryEntry });
308
-
309
- if (!skipSync) {
310
- await context.sync();
311
- await assertReaderNotPromoted(t, writerPeer.base, writerPeer, { expectRegistryEntry });
312
- }
313
- }
314
-
315
- async function assertWriterRegistry(t, base, addressBuffer, writingKeyHex, expectedWriterIndex) {
316
- const registryEntry = await base.view.get(EntryType.WRITER_ADDRESS + writingKeyHex);
317
- t.ok(registryEntry, 'writer registry entry exists');
318
- t.ok(
319
- b4a.equals(registryEntry.value, addressBuffer),
320
- 'writer registry links writing key to node address'
321
- );
322
-
323
- const writersLengthEntry = await base.view.get(EntryType.WRITERS_LENGTH);
324
- t.ok(writersLengthEntry, 'writers length entry exists');
325
- const writersLength = lengthEntryUtils.decodeBE(writersLengthEntry.value);
326
- t.is(writersLength, expectedWriterIndex + 1, 'writers length increments');
327
-
328
- const indexEntry = await base.view.get(`${EntryType.WRITERS_INDEX}${expectedWriterIndex}`);
329
- t.ok(indexEntry, 'writers index entry stored');
330
- t.ok(b4a.equals(indexEntry.value, addressBuffer), 'writer index stores node address');
331
- }
332
-
333
- export async function assertValidatorReward(t, validatorPeer, validatorBalanceBefore) {
334
- const validatorEntry = await validatorPeer.base.view.get(validatorPeer.wallet.address);
335
- t.ok(validatorEntry, 'validator entry exists');
336
- const decodedValidator = nodeEntryUtils.decode(validatorEntry.value);
337
- t.ok(decodedValidator, 'validator entry decodes');
338
- const initialBalance = toBalance(validatorBalanceBefore);
339
- const expected = initialBalance.add(BALANCE_FEE.percentage(PERCENT_75));
340
- const afterBalance = toBalance(decodedValidator.balance);
341
- t.ok(afterBalance, 'validator balance decodes');
342
- t.ok(
343
- b4a.equals(afterBalance.value, expected.value),
344
- 'validator receives 75% of the writer fee'
345
- );
346
- }
347
-
348
- async function assertReplayProtection(t, base, payload) {
349
- const decodedPayload = safeDecodeApplyOperation(payload);
350
- t.ok(decodedPayload, 'addWriter payload decodes');
351
- const txKey = decodedPayload?.rao?.tx?.toString('hex');
352
- t.ok(txKey, 'addWriter tx hash extracted');
353
- const txEntry = await base.view.get(txKey);
354
- t.ok(txEntry, 'addWriter transaction recorded for replay protection');
355
- }
356
-
357
- export async function assertWriterRemovalState(
358
- t,
359
- context,
360
- {
361
- readerPeer = selectWriterPeer(context),
362
- validatorPeer = context.adminBootstrap,
363
- writerKeyBuffer = null,
364
- expectedBalanceBuffer = null,
365
- expectedLicenseBuffer = null,
366
- payload = null,
367
- skipSync = false
368
- } = {}
369
- ) {
370
- const writerAddress = readerPeer.wallet.address;
371
- const writingKey = writerKeyBuffer ?? readerPeer.base.local.key;
372
- await assertWriterDowngradedEntry(
373
- t,
374
- validatorPeer.base,
375
- writerAddress,
376
- writingKey,
377
- expectedBalanceBuffer,
378
- expectedLicenseBuffer
379
- );
380
-
381
- if (payload) {
382
- await assertReplayProtection(t, validatorPeer.base, payload);
383
- }
384
-
385
- if (!skipSync) {
386
- await context.sync();
387
- await assertWriterDowngradedEntry(
388
- t,
389
- readerPeer.base,
390
- writerAddress,
391
- writingKey,
392
- expectedBalanceBuffer,
393
- expectedLicenseBuffer
394
- );
395
- }
396
- }
397
-
398
- export async function applyWithRoleAccessBypass(context, invalidPayload) {
399
- const node = context.bootstrap ?? context.adminBootstrap;
400
- const state = node.state;
401
- const originalValidate = state.check.validateRoleAccessOperation;
402
- state.check.validateRoleAccessOperation = () => true;
403
- try {
404
- await node.base.append(invalidPayload);
405
- await node.base.update();
406
- await eventFlush();
407
- } finally {
408
- state.check.validateRoleAccessOperation = originalValidate;
409
- }
410
- }
411
-
412
- export async function applyWithMissingComponentBypass(context, invalidPayload) {
413
- const node = context.bootstrap ?? context.adminBootstrap;
414
- const state = node.state;
415
- const originalValidate = state.check.validateRoleAccessOperation;
416
- const originalHasOwn = Object.hasOwn;
417
- Object.hasOwn = (obj, prop) => {
418
- if (prop === 'vs') return false;
419
- return originalHasOwn(obj, prop);
420
- };
421
- state.check.validateRoleAccessOperation = () => true;
422
- try {
423
- await node.base.append(invalidPayload);
424
- await node.base.update();
425
- await eventFlush();
426
- } finally {
427
- state.check.validateRoleAccessOperation = originalValidate;
428
- Object.hasOwn = originalHasOwn;
429
- }
430
- }
431
-
432
- export async function applyWithRequesterEntryRemoval(context, invalidPayload, { peer = null } = {}) {
433
- const writerPeer = peer ?? selectWriterPeer(context);
434
- await withPeerEntryOverrideOnApply({
435
- context,
436
- peer: writerPeer,
437
- mutateEntry: () => null,
438
- fn: async node => {
439
- await node.base.append(invalidPayload);
440
- await node.base.update();
441
- await eventFlush();
442
- }
443
- });
444
- }
445
-
446
- export async function applyWithRequesterEntryCorruption(
447
- context,
448
- invalidPayload,
449
- { peer = null } = {}
450
- ) {
451
- const writerPeer = peer ?? selectWriterPeer(context);
452
- await withPeerEntryOverrideOnApply({
453
- context,
454
- peer: writerPeer,
455
- mutateEntry: entry => {
456
- if (!entry?.value) {
457
- throw new Error('Requester entry corruption requires an existing entry.');
458
- }
459
- return { ...entry, value: b4a.alloc(1) };
460
- },
461
- fn: async node => {
462
- await node.base.append(invalidPayload);
463
- await node.base.update();
464
- await eventFlush();
465
- }
466
- });
467
- }
468
-
469
- export async function applyWithRequesterWriterKeyMismatch(context, invalidPayload) {
470
- const writerPeer = selectWriterPeer(context);
471
- await withPeerEntryOverrideOnApply({
472
- context,
473
- peer: writerPeer,
474
- mutateEntry: entry => {
475
- if (!entry?.value) {
476
- throw new Error('Requester writer key mutation requires an existing entry.');
477
- }
478
- const decoded = nodeEntryUtils.decode(entry.value);
479
- if (!decoded?.wk) {
480
- throw new Error('Requester writer key mutation requires a decodable entry.');
481
- }
482
- const mutatedWk = b4a.from(decoded.wk);
483
- mutatedWk[0] ^= 0xff;
484
- const mutatedEntry = nodeEntryUtils.setWritingKey(b4a.from(entry.value), mutatedWk);
485
- if (!mutatedEntry) {
486
- throw new Error('Failed to mutate requester writing key.');
487
- }
488
- return { ...entry, value: mutatedEntry };
489
- },
490
- fn: async node => {
491
- await node.base.append(invalidPayload);
492
- await node.base.update();
493
- await eventFlush();
494
- }
495
- });
496
- }
497
-
498
- export async function applyWithStakeEntryMutation(
499
- context,
500
- invalidPayload,
501
- mutateNodeEntryBuffer,
502
- mutateDecodedEntry = null
503
- ) {
504
- if (typeof mutateNodeEntryBuffer !== 'function') {
505
- throw new Error('Stake entry mutation requires a mutateNodeEntryBuffer function.');
506
- }
507
-
508
- const writerPeer = selectWriterPeer(context);
509
- const balancePrototype = Object.getPrototypeOf(BALANCE_ZERO);
510
- const originalUpdate = balancePrototype.update;
511
- const originalDecode = nodeEntryUtils.decode;
512
- let hasMutated = false;
513
-
514
- await withPeerEntryOverrideOnApply({
515
- context,
516
- peer: writerPeer,
517
- mutateEntry: entry => {
518
- if (!entry?.value) {
519
- throw new Error('Stake entry mutation requires an existing entry.');
520
- }
521
- return entry;
522
- },
523
- fn: async node => {
524
- balancePrototype.update = function patchedUpdate(nodeEntryBuffer) {
525
- const result = originalUpdate.call(this, nodeEntryBuffer);
526
- if (!hasMutated) {
527
- hasMutated = true;
528
- const mutatedEntry =
529
- mutateNodeEntryBuffer(result ?? nodeEntryBuffer, nodeEntryBuffer) ??
530
- result ??
531
- nodeEntryBuffer;
532
-
533
- if (mutateDecodedEntry && mutatedEntry && typeof mutatedEntry === 'object') {
534
- mutatedEntry[STAKE_ENTRY_MARK] = true;
535
- }
536
-
537
- return mutatedEntry;
538
- }
539
- return result;
540
- };
541
-
542
- if (typeof mutateDecodedEntry === 'function') {
543
- nodeEntryUtils.decode = function patchedDecode(buffer) {
544
- const decoded = originalDecode(buffer);
545
- if (buffer?.[STAKE_ENTRY_MARK]) {
546
- const mutatedDecoded = mutateDecodedEntry(decoded, buffer);
547
- if (mutatedDecoded && typeof mutatedDecoded === 'object') {
548
- return mutatedDecoded;
549
- }
550
- }
551
- return decoded;
552
- };
553
- }
554
-
555
- try {
556
- await node.base.append(invalidPayload);
557
- await node.base.update();
558
- await eventFlush();
559
- } finally {
560
- balancePrototype.update = originalUpdate;
561
- nodeEntryUtils.decode = originalDecode;
562
- }
563
- }
564
- });
565
- }
566
-
567
- async function assertWriterDowngradedEntry(
568
- t,
569
- base,
570
- address,
571
- writingKey,
572
- expectedBalanceBuffer,
573
- expectedLicenseBuffer
574
- ) {
575
- const entry = await base.view.get(address);
576
- t.ok(entry, 'writer node entry exists');
577
- const decoded = nodeEntryUtils.decode(entry.value);
578
- t.ok(decoded, 'writer node entry decodes');
579
- t.is(decoded.isWhitelisted, true, 'node remains whitelisted');
580
- t.is(decoded.isWriter, false, 'writer role removed');
581
- t.is(decoded.isIndexer, false, 'node not promoted to indexer');
582
- t.ok(b4a.equals(decoded.wk, writingKey), 'writer key preserved on entry');
583
- t.ok(
584
- b4a.equals(decoded.stakedBalance, BALANCE_ZERO.value),
585
- 'writer staked balance cleared'
586
- );
587
- t.ok(!b4a.equals(decoded.license, ZERO_LICENSE), 'license retained after downgrade');
588
- if (expectedLicenseBuffer) {
589
- t.ok(
590
- b4a.equals(decoded.license, expectedLicenseBuffer),
591
- 'writer license remains unchanged after downgrade'
592
- );
593
- }
594
- if (expectedBalanceBuffer) {
595
- t.ok(
596
- b4a.equals(decoded.balance, expectedBalanceBuffer),
597
- 'writer liquid balance matches expected amount after downgrade'
598
- );
599
- }
600
- const addressBuffer = addressUtils.addressToBuffer(address, config.addressPrefix);
601
- const writerRegistryEntry = await base.view.get(
602
- EntryType.WRITER_ADDRESS + writingKey.toString('hex')
603
- );
604
- t.ok(writerRegistryEntry, 'writer registry entry persists for ownership tracking');
605
- t.ok(
606
- b4a.equals(writerRegistryEntry.value, addressBuffer),
607
- 'writer registry continues to link downgraded node to its previous writing key'
608
- );
609
- }
610
-
611
- export const defaultWriterFunding = DEFAULT_WRITER_FUNDING;
612
-
613
- export default {
614
- setupAddWriterScenario,
615
- selectWriterPeer,
616
- selectValidatorPeerWithoutEntry,
617
- buildAddWriterPayload,
618
- buildAddWriterPayloadWithTxValidity,
619
- buildRemoveWriterPayload,
620
- assertAddWriterSuccessState,
621
- assertAddWriterFailureState,
622
- assertWriterRemovalState,
623
- assertValidatorReward,
624
- applyWithRoleAccessBypass,
625
- applyWithMissingComponentBypass,
626
- applyWithRequesterEntryRemoval,
627
- applyWithRequesterEntryCorruption,
628
- applyWithRequesterWriterKeyMismatch,
629
- applyWithRequesterRoleOverride,
630
- mutateValidatorEntry,
631
- defaultWriterFunding
632
- };
633
-
634
- function assertWritableNode(node) {
635
- if (!node.base.view.batch) {
636
- throw new Error('Validator entry mutation requires a writable node.');
637
- }
638
- return node;
639
- }
640
-
641
- async function writeValidatorEntry(base, key, value) {
642
- const batch = base.view.batch();
643
- await batch.put(key, value);
644
- await batch.flush();
645
- }
646
-
647
- async function withPeerEntryOverrideOnApply({
648
- context,
649
- peer,
650
- selectNode = defaultSelectNode,
651
- mutateEntry,
652
- fn
653
- }) {
654
- if (typeof mutateEntry !== 'function') {
655
- throw new Error('Peer entry override requires a mutateEntry function.');
656
- }
657
-
658
- const targetPeer = peer ?? selectWriterPeer(context);
659
- if (!targetPeer?.wallet?.address) {
660
- throw new Error('Peer entry override requires a target peer.');
661
- }
662
-
663
- const node = assertWritableNode(selectNode(context));
664
- const base = node.base;
665
- const targetAddress = targetPeer.wallet.address;
666
- const targetBuffer = addressUtils.addressToBuffer(targetAddress, config.addressPrefix);
667
- const originalApply = base._handlers.apply;
668
-
669
- base._handlers.apply = async function patchedApply(nodes, view, baseCtx) {
670
- const originalBatch = view.batch;
671
- view.batch = function patchedBatch(...args) {
672
- const batch = originalBatch.apply(this, args);
673
- if (!batch?.get) {
674
- return batch;
675
- }
676
-
677
- const originalGet = batch.get.bind(batch);
678
- batch.get = async key => {
679
- if (isTargetKey(key, targetAddress, targetBuffer)) {
680
- const entry = await originalGet(key);
681
- return mutateEntry(entry);
682
- }
683
- return originalGet(key);
684
- };
685
-
686
- return batch;
687
- };
688
-
689
- try {
690
- return await originalApply.call(this, nodes, view, baseCtx);
691
- } finally {
692
- view.batch = originalBatch;
693
- }
694
- };
695
-
696
- try {
697
- await fn(node, targetPeer);
698
- } finally {
699
- base._handlers.apply = originalApply;
700
- }
701
- }
702
-
703
- function isTargetKey(key, targetAddressString, targetAddressBuffer) {
704
- if (typeof key === 'string') {
705
- return key === targetAddressString;
706
- }
707
- if (b4a.isBuffer(key) && targetAddressBuffer) {
708
- return b4a.equals(key, targetAddressBuffer);
709
- }
710
- return false;
711
- }
712
-
713
- export async function applyWithRequesterRoleOverride(context, invalidPayload, role) {
714
- const writerPeer = selectWriterPeer(context);
715
- await withPeerEntryOverrideOnApply({
716
- context,
717
- peer: writerPeer,
718
- mutateEntry: entry => {
719
- if (!entry?.value) {
720
- throw new Error('Requester role override requires an existing entry.');
721
- }
722
- const mutatedValue = nodeEntryUtils.setRole(b4a.from(entry.value), role);
723
- if (!mutatedValue) {
724
- throw new Error('Failed to mutate requester role entry.');
725
- }
726
- return { ...entry, value: mutatedValue };
727
- },
728
- fn: async node => {
729
- await node.base.append(invalidPayload);
730
- await node.base.update();
731
- await eventFlush();
732
- }
733
- });
734
- }
735
-
736
- export async function mutateValidatorEntry({
737
- context,
738
- selectNode = defaultSelectNode,
739
- mutateValue,
740
- fn
741
- }) {
742
- const node = assertWritableNode(selectNode(context));
743
- const validatorAddress = node.wallet.address;
744
- const originalEntry = await node.base.view.get(validatorAddress);
745
- if (!originalEntry?.value) {
746
- throw new Error('Validator entry mutation requires an existing validator entry.');
747
- }
748
-
749
- const originalValue = b4a.from(originalEntry.value);
750
- const mutatedValue = mutateValue(b4a.from(originalValue));
751
- if (!b4a.isBuffer(mutatedValue) || mutatedValue.length === 0) {
752
- throw new Error('Validator entry mutation must return a non-empty buffer.');
753
- }
754
-
755
- await writeValidatorEntry(node.base, validatorAddress, mutatedValue);
756
-
757
- try {
758
- await fn(node);
759
- } finally {
760
- await writeValidatorEntry(node.base, validatorAddress, originalValue);
761
- }
762
- }
763
-
764
- function defaultSelectNode(context) {
765
- return context.adminBootstrap ?? context.bootstrap ?? context.peers?.[0] ?? null;
766
- }