trac-msb 0.2.18 → 0.2.20

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 (381) 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 +25 -8
  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 +138 -10
  16. package/src/config/env.js +36 -18
  17. package/src/core/network/Network.js +130 -34
  18. package/src/core/network/protocols/ProtocolInterface.js +5 -5
  19. package/src/core/network/protocols/connectionPolicies.js +86 -0
  20. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +1 -1
  21. package/src/core/network/protocols/legacy/handlers/BaseStateOperationHandler.js +2 -2
  22. package/src/core/network/protocols/legacy/handlers/LegacyGetRequestHandler.js +3 -3
  23. package/src/core/network/protocols/legacy/handlers/LegacyRoleOperationHandler.js +1 -1
  24. package/src/core/network/protocols/legacy/handlers/LegacySubnetworkOperationHandler.js +1 -1
  25. package/src/core/network/protocols/legacy/handlers/LegacyTransferOperationHandler.js +1 -1
  26. package/src/core/network/protocols/legacy/validators/base/BaseResponse.js +7 -10
  27. package/src/core/network/protocols/shared/validators/PartialBootstrapDeploymentValidator.js +2 -2
  28. package/src/core/network/protocols/shared/validators/PartialOperationValidator.js +23 -23
  29. package/src/core/network/protocols/shared/validators/PartialRoleAccessValidator.js +14 -14
  30. package/src/core/network/protocols/shared/validators/PartialTransactionValidator.js +5 -5
  31. package/src/core/network/protocols/shared/validators/PartialTransferValidator.js +12 -11
  32. package/src/core/network/protocols/v1/V1ProtocolError.js +5 -69
  33. package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +3 -2
  34. package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +130 -247
  35. package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +6 -5
  36. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionErrorMapper.js +84 -0
  37. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionOperationStrategies.js +128 -0
  38. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionPayloadUtils.js +26 -0
  39. package/src/core/network/protocols/v1/validators/V1BaseOperation.js +32 -31
  40. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +5 -3
  41. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +34 -50
  42. package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +1 -1
  43. package/src/core/network/services/ConnectionManager.js +11 -10
  44. package/src/core/network/services/MessageOrchestrator.js +53 -17
  45. package/src/core/network/services/PendingRequestService.js +22 -19
  46. package/src/core/network/services/TransactionCommitService.js +36 -36
  47. package/src/core/network/services/TransactionPoolService.js +39 -39
  48. package/src/core/network/services/TransactionRateLimiterService.js +8 -4
  49. package/src/core/network/services/ValidatorObserverService.js +397 -110
  50. package/src/core/state/State.js +190 -138
  51. package/src/core/state/utils/address.js +4 -9
  52. package/src/core/state/utils/balance.js +7 -7
  53. package/src/core/state/utils/roles.js +1 -1
  54. package/src/index.js +316 -275
  55. package/src/messages/network/v1/NetworkMessageBuilder.js +12 -21
  56. package/src/messages/network/v1/networkMessageFactory.js +1 -1
  57. package/src/messages/state/ApplyStateMessageBuilder.js +6 -6
  58. package/src/messages/state/applyStateMessageFactory.js +1 -1
  59. package/src/utils/buffer.js +1 -1
  60. package/src/utils/check.js +12 -13
  61. package/src/utils/constants.js +7 -0
  62. package/src/utils/errors.js +20 -0
  63. package/src/utils/fileUtils.js +12 -3
  64. package/src/utils/helpers.js +2 -2
  65. package/src/utils/migrationUtils.js +3 -3
  66. package/.dockerignore +0 -16
  67. package/CODE_OF_CONDUCT.md +0 -128
  68. package/docker-compose.yml +0 -17
  69. package/dockerfile +0 -41
  70. package/docs/fee_distribution.md +0 -89
  71. package/docs/trac_network_http_api.openapi.yaml +0 -889
  72. package/migration/.gitkeep +0 -0
  73. package/proto/applyOperations.proto +0 -117
  74. package/proto/network/v1/enums/message_type.proto +0 -16
  75. package/proto/network/v1/enums/result_code.proto +0 -84
  76. package/proto/network/v1/messages/broadcast_transaction_request.proto +0 -9
  77. package/proto/network/v1/messages/broadcast_transaction_response.proto +0 -13
  78. package/proto/network/v1/messages/liveness_request.proto +0 -8
  79. package/proto/network/v1/messages/liveness_response.proto +0 -11
  80. package/proto/network/v1/network_message.proto +0 -22
  81. package/rpc/rpc_services.js +0 -181
  82. package/scripts/generate-protobufs.js +0 -67
  83. package/src/core/network/identity/NetworkWalletFactory.js +0 -77
  84. package/src/core/network/protocols/shared/errors/SharedValidatorRejectionError.js +0 -27
  85. package/src/utils/cli.js +0 -130
  86. package/src/utils/cliCommands.js +0 -280
  87. package/tests/acceptance/v1/account/account.test.mjs +0 -129
  88. package/tests/acceptance/v1/balance/balance.test.mjs +0 -54
  89. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +0 -116
  90. package/tests/acceptance/v1/confirmed-length/confirmed-length.test.mjs +0 -19
  91. package/tests/acceptance/v1/fee/fee.test.mjs +0 -11
  92. package/tests/acceptance/v1/health/health.test.mjs +0 -33
  93. package/tests/acceptance/v1/rpc.test.mjs +0 -95
  94. package/tests/acceptance/v1/tx/tx.test.mjs +0 -133
  95. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +0 -241
  96. package/tests/acceptance/v1/tx-hashes/tx-hashes.test.mjs +0 -72
  97. package/tests/acceptance/v1/tx-payloads-bulk/tx-payloads-bulk.test.mjs +0 -27
  98. package/tests/acceptance/v1/txv/txv.test.mjs +0 -11
  99. package/tests/acceptance/v1/unconfirmed-length/unconfirmed-length.test.mjs +0 -11
  100. package/tests/fixtures/apply.fixtures.js +0 -77
  101. package/tests/fixtures/assembleMessage.fixtures.js +0 -41
  102. package/tests/fixtures/check.fixtures.js +0 -428
  103. package/tests/fixtures/networkV1.fixtures.js +0 -59
  104. package/tests/fixtures/protobuf.fixtures.js +0 -388
  105. package/tests/helpers/StateNetworkFactory.js +0 -155
  106. package/tests/helpers/address.js +0 -6
  107. package/tests/helpers/autobaseTestHelpers.js +0 -419
  108. package/tests/helpers/config.js +0 -4
  109. package/tests/helpers/createTestSignature.js +0 -13
  110. package/tests/helpers/regexHelper.js +0 -3
  111. package/tests/helpers/setupApplyTests.js +0 -587
  112. package/tests/helpers/transactionPayloads.mjs +0 -92
  113. package/tests/helpers/wrapper.js +0 -28
  114. package/tests/unit/messages/messages.test.js +0 -12
  115. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +0 -436
  116. package/tests/unit/messages/network/NetworkMessageDirector.test.js +0 -347
  117. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +0 -525
  118. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +0 -237
  119. package/tests/unit/network/LegacyNetworkMessageRouter.test.js +0 -54
  120. package/tests/unit/network/NetworkWalletFactory.test.js +0 -156
  121. package/tests/unit/network/ProtocolSession.test.js +0 -127
  122. package/tests/unit/network/networkModule.test.js +0 -13
  123. package/tests/unit/network/services/ConnectionManager.test.js +0 -450
  124. package/tests/unit/network/services/MessageOrchestrator.test.js +0 -445
  125. package/tests/unit/network/services/PendingRequestService.test.js +0 -431
  126. package/tests/unit/network/services/TransactionCommitService.test.js +0 -246
  127. package/tests/unit/network/services/TransactionPoolService.test.js +0 -489
  128. package/tests/unit/network/services/TransactionRateLimiterService.test.js +0 -139
  129. package/tests/unit/network/services/ValidatorHealthCheckService.test.js +0 -115
  130. package/tests/unit/network/services/services.test.js +0 -17
  131. package/tests/unit/network/utils/v1TestUtils.js +0 -153
  132. package/tests/unit/network/v1/NetworkMessageRouterV1.test.js +0 -151
  133. package/tests/unit/network/v1/V1BaseOperation.test.js +0 -356
  134. package/tests/unit/network/v1/V1BroadcastTransactionOperationHandler.test.js +0 -129
  135. package/tests/unit/network/v1/V1BroadcastTransactionRequest.test.js +0 -53
  136. package/tests/unit/network/v1/V1BroadcastTransactionResponse.test.js +0 -512
  137. package/tests/unit/network/v1/V1LivenessRequest.test.js +0 -32
  138. package/tests/unit/network/v1/V1LivenessResponse.test.js +0 -45
  139. package/tests/unit/network/v1/V1ResultCode.test.js +0 -84
  140. package/tests/unit/network/v1/V1ValidationSchema.test.js +0 -13
  141. package/tests/unit/network/v1/connectionPolicies.test.js +0 -49
  142. package/tests/unit/network/v1/handlers/V1BaseOperationHandler.test.js +0 -284
  143. package/tests/unit/network/v1/handlers/V1BroadcastTransactionOperationHandler.test.js +0 -794
  144. package/tests/unit/network/v1/handlers/V1LivenessOperationHandler.test.js +0 -193
  145. package/tests/unit/network/v1/v1.handlers.test.js +0 -15
  146. package/tests/unit/network/v1/v1.test.js +0 -19
  147. package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionRequest.test.js +0 -119
  148. package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionResponse.test.js +0 -136
  149. package/tests/unit/network/v1/v1ValidationSchema/common.test.js +0 -308
  150. package/tests/unit/network/v1/v1ValidationSchema/livenessRequest.test.js +0 -90
  151. package/tests/unit/network/v1/v1ValidationSchema/livenessResponse.test.js +0 -133
  152. package/tests/unit/state/State.test.js +0 -80
  153. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +0 -42
  154. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +0 -276
  155. package/tests/unit/state/apply/addAdmin/adminEntryEncodingFailureScenario.js +0 -30
  156. package/tests/unit/state/apply/addAdmin/adminEntryExistsScenario.js +0 -78
  157. package/tests/unit/state/apply/addAdmin/nodeEntryInitializationFailureScenario.js +0 -30
  158. package/tests/unit/state/apply/addAdmin/nonBootstrapNodeScenario.js +0 -68
  159. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +0 -159
  160. package/tests/unit/state/apply/addIndexer/addIndexerHappyPathScenario.js +0 -39
  161. package/tests/unit/state/apply/addIndexer/addIndexerMultipleIndexersInTheNetworkScenario.js +0 -167
  162. package/tests/unit/state/apply/addIndexer/addIndexerPretenderAlreadyIndexerScenario.js +0 -21
  163. package/tests/unit/state/apply/addIndexer/addIndexerPretenderNotWriterScenario.js +0 -21
  164. package/tests/unit/state/apply/addIndexer/addIndexerRemoveAndReAddScenario.js +0 -186
  165. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +0 -443
  166. package/tests/unit/state/apply/addIndexer/addIndexerWriterKeyAlreadyRegisteredScenario.js +0 -32
  167. package/tests/unit/state/apply/addIndexer/state.apply.addIndexer.test.js +0 -297
  168. package/tests/unit/state/apply/addWriter/addWriterHappyPathScenario.js +0 -41
  169. package/tests/unit/state/apply/addWriter/addWriterInvalidValidatorSignatureScenario.js +0 -32
  170. package/tests/unit/state/apply/addWriter/addWriterNewWkScenario.js +0 -149
  171. package/tests/unit/state/apply/addWriter/addWriterRequesterAlreadyWriterScenario.js +0 -21
  172. package/tests/unit/state/apply/addWriter/addWriterRequesterBalanceInsufficientScenario.js +0 -21
  173. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryDecodeFailureScenario.js +0 -19
  174. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryMissingScenario.js +0 -19
  175. package/tests/unit/state/apply/addWriter/addWriterRequesterIndexerScenario.js +0 -21
  176. package/tests/unit/state/apply/addWriter/addWriterRequesterNotWhitelistedScenario.js +0 -21
  177. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +0 -766
  178. package/tests/unit/state/apply/addWriter/addWriterStakeBalanceUpdateFailureScenario.js +0 -50
  179. package/tests/unit/state/apply/addWriter/addWriterStakeInsufficientBalanceScenario.js +0 -29
  180. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidBalanceScenario.js +0 -29
  181. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidEntryScenario.js +0 -21
  182. package/tests/unit/state/apply/addWriter/addWriterStakeStakedBalanceFailureScenario.js +0 -37
  183. package/tests/unit/state/apply/addWriter/addWriterStakeSubtractFailureScenario.js +0 -42
  184. package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +0 -106
  185. package/tests/unit/state/apply/addWriter/addWriterWriterKeyMismatchScenario.js +0 -54
  186. package/tests/unit/state/apply/addWriter/addWriterWriterKeyOwnershipScenario.js +0 -54
  187. package/tests/unit/state/apply/addWriter/addWriterZeroWriterKeyScenario.js +0 -29
  188. package/tests/unit/state/apply/addWriter/state.apply.addWriter.test.js +0 -309
  189. package/tests/unit/state/apply/adminRecovery/adminRecoveryHappyPathScenario.js +0 -30
  190. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +0 -881
  191. package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +0 -435
  192. package/tests/unit/state/apply/appendWhitelist/appendWhitelistBanAndReapplyScenario.js +0 -78
  193. package/tests/unit/state/apply/appendWhitelist/appendWhitelistExistingReaderHappyPathScenario.js +0 -98
  194. package/tests/unit/state/apply/appendWhitelist/appendWhitelistFeeAfterDisableScenario.js +0 -66
  195. package/tests/unit/state/apply/appendWhitelist/appendWhitelistHappyPathScenario.js +0 -55
  196. package/tests/unit/state/apply/appendWhitelist/appendWhitelistInsufficientAdminBalanceScenario.js +0 -103
  197. package/tests/unit/state/apply/appendWhitelist/appendWhitelistNodeAlreadyWhitelistedScenario.js +0 -60
  198. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +0 -189
  199. package/tests/unit/state/apply/appendWhitelist/state.apply.appendWhitelist.test.js +0 -220
  200. package/tests/unit/state/apply/balanceInitialization/balanceInitializationHappyPathScenario.js +0 -82
  201. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +0 -111
  202. package/tests/unit/state/apply/balanceInitialization/invalidAmountScenario.js +0 -45
  203. package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +0 -82
  204. package/tests/unit/state/apply/balanceInitialization/state.apply.balanceInitialization.test.js +0 -189
  205. package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +0 -156
  206. package/tests/unit/state/apply/banValidator/banValidatorHappyPathScenario.js +0 -36
  207. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +0 -531
  208. package/tests/unit/state/apply/banValidator/banValidatorSequentialBansScenario.js +0 -74
  209. package/tests/unit/state/apply/banValidator/banValidatorTargetDecodeFailureScenario.js +0 -19
  210. package/tests/unit/state/apply/banValidator/banValidatorTargetIndexerScenario.js +0 -32
  211. package/tests/unit/state/apply/banValidator/banValidatorTargetNodeEntryMissingScenario.js +0 -19
  212. package/tests/unit/state/apply/banValidator/banValidatorTargetRoleUpdateFailureScenario.js +0 -19
  213. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedNonWriterScenario.js +0 -38
  214. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedZeroBalanceScenario.js +0 -91
  215. package/tests/unit/state/apply/banValidator/banValidatorWithdrawFailureScenario.js +0 -19
  216. package/tests/unit/state/apply/banValidator/state.apply.banValidator.test.js +0 -266
  217. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +0 -143
  218. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentHappyPathScenario.js +0 -26
  219. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentIncompleteOperationScenario.js +0 -94
  220. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentInvalidDeploymentEntryScenario.js +0 -37
  221. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentMultipleBootstrapScenario.js +0 -86
  222. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +0 -347
  223. package/tests/unit/state/apply/bootstrapDeployment/invalidValidatorNodeEntryScenario.js +0 -57
  224. package/tests/unit/state/apply/bootstrapDeployment/state.apply.bootstrapDeployment.test.js +0 -429
  225. package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +0 -120
  226. package/tests/unit/state/apply/common/access-control/adminEntryDecodeFailureScenario.js +0 -130
  227. package/tests/unit/state/apply/common/access-control/adminEntryExistsScenario.js +0 -93
  228. package/tests/unit/state/apply/common/access-control/adminEntryMissingScenario.js +0 -108
  229. package/tests/unit/state/apply/common/access-control/adminOnlyGuardScenario.js +0 -126
  230. package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +0 -121
  231. package/tests/unit/state/apply/common/access-control/roleAccessOperationValidationScenario.js +0 -50
  232. package/tests/unit/state/apply/common/adminControlOperationValidationScenario.js +0 -56
  233. package/tests/unit/state/apply/common/balances/adminEntryUpdateFailureScenario.js +0 -52
  234. package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +0 -198
  235. package/tests/unit/state/apply/common/balances/feeDecodeFailureScenario.js +0 -52
  236. package/tests/unit/state/apply/common/balances/requesterBalanceDecodeFailureScenario.js +0 -15
  237. package/tests/unit/state/apply/common/balances/requesterBalanceFeeApplicationFailureScenario.js +0 -11
  238. package/tests/unit/state/apply/common/balances/requesterBalanceInsufficientScenario.js +0 -15
  239. package/tests/unit/state/apply/common/balances/requesterBalanceUpdateFailureScenario.js +0 -11
  240. package/tests/unit/state/apply/common/balances/validatorEntryRewardFailureScenario.js +0 -11
  241. package/tests/unit/state/apply/common/balances/validatorEntryUpdateFailureScenario.js +0 -11
  242. package/tests/unit/state/apply/common/balances/validatorNodeEntryDecodeFailureScenario.js +0 -40
  243. package/tests/unit/state/apply/common/base/OperationValidationScenarioBase.js +0 -114
  244. package/tests/unit/state/apply/common/commonScenarioHelper.js +0 -103
  245. package/tests/unit/state/apply/common/indexer/indexerNodeEntryDecodeFailureScenario.js +0 -36
  246. package/tests/unit/state/apply/common/indexer/indexerNodeEntryMissingScenario.js +0 -36
  247. package/tests/unit/state/apply/common/indexer/indexerRoleUpdateFailureScenario.js +0 -29
  248. package/tests/unit/state/apply/common/indexer/indexerSequenceStateInvalidScenario.js +0 -66
  249. package/tests/unit/state/apply/common/invalidMessageComponentValidationScenario.js +0 -84
  250. package/tests/unit/state/apply/common/nodeEntryInitializationFailureScenario.js +0 -47
  251. package/tests/unit/state/apply/common/operationAlreadyAppliedScenario.js +0 -85
  252. package/tests/unit/state/apply/common/payload-structure/addressWithInvalidPublicKeyScenario.js +0 -52
  253. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +0 -54
  254. package/tests/unit/state/apply/common/payload-structure/invalidAddressValidationScenario.js +0 -73
  255. package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +0 -71
  256. package/tests/unit/state/apply/common/payload-structure/invalidPayloadValidationScenario.js +0 -31
  257. package/tests/unit/state/apply/common/payload-structure/invalidSignatureValidationScenario.js +0 -142
  258. package/tests/unit/state/apply/common/payload-structure/partialOperationValidationScenario.js +0 -87
  259. package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +0 -71
  260. package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +0 -73
  261. package/tests/unit/state/apply/common/requester/requesterNodeEntryMissingScenario.js +0 -36
  262. package/tests/unit/state/apply/common/requesterAddressValidationScenario.js +0 -44
  263. package/tests/unit/state/apply/common/requesterPublicKeyValidationScenario.js +0 -25
  264. package/tests/unit/state/apply/common/transactionValidityMismatchScenario.js +0 -98
  265. package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +0 -202
  266. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryDecodeFailureScenario.js +0 -17
  267. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryMissingScenario.js +0 -44
  268. package/tests/unit/state/apply/common/validatorConsistency/validatorInactiveScenario.js +0 -19
  269. package/tests/unit/state/apply/common/validatorConsistency/validatorWriterKeyMismatchScenario.js +0 -18
  270. package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +0 -315
  271. package/tests/unit/state/apply/common/validatorEntryValidation/validatorEntryInvalidBalanceScenario.js +0 -18
  272. package/tests/unit/state/apply/common/writerKeyExistsValidationScenario.js +0 -43
  273. package/tests/unit/state/apply/disableInitialization/disableInitializationAlreadyDisabledScenario.js +0 -53
  274. package/tests/unit/state/apply/disableInitialization/disableInitializationHappyPathScenario.js +0 -24
  275. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +0 -204
  276. package/tests/unit/state/apply/disableInitialization/state.apply.disableInitialization.test.js +0 -161
  277. package/tests/unit/state/apply/missing-tests.md +0 -18
  278. package/tests/unit/state/apply/removeIndexer/removeIndexerHappyPathScenario.js +0 -58
  279. package/tests/unit/state/apply/removeIndexer/removeIndexerReAddAndRemoveAgainScenario.js +0 -98
  280. package/tests/unit/state/apply/removeIndexer/removeIndexerRemoveMultipleIndexersScenario.js +0 -167
  281. package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +0 -429
  282. package/tests/unit/state/apply/removeIndexer/removeIndexerTargetNotIndexerScenario.js +0 -22
  283. package/tests/unit/state/apply/removeIndexer/removeIndexerWriterKeyMissingScenario.js +0 -20
  284. package/tests/unit/state/apply/removeIndexer/state.apply.removeIndexer.test.js +0 -291
  285. package/tests/unit/state/apply/removeWriter/removeWriterAndAddWriterAgainScenario.js +0 -87
  286. package/tests/unit/state/apply/removeWriter/removeWriterHappyPathScenario.js +0 -38
  287. package/tests/unit/state/apply/removeWriter/removeWriterInvalidValidatorSignatureScenario.js +0 -32
  288. package/tests/unit/state/apply/removeWriter/removeWriterRequesterBalanceInsufficientScenario.js +0 -21
  289. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryDecodeFailureScenario.js +0 -19
  290. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryMissingScenario.js +0 -19
  291. package/tests/unit/state/apply/removeWriter/removeWriterRequesterIndexerScenario.js +0 -21
  292. package/tests/unit/state/apply/removeWriter/removeWriterRequesterNotWriterScenario.js +0 -21
  293. package/tests/unit/state/apply/removeWriter/removeWriterRequesterRoleUpdateFailureScenario.js +0 -19
  294. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +0 -348
  295. package/tests/unit/state/apply/removeWriter/removeWriterThroughWriterValidatorScenario.js +0 -113
  296. package/tests/unit/state/apply/removeWriter/removeWriterUnstakeFailureScenario.js +0 -33
  297. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyMismatchScenario.js +0 -21
  298. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyOwnershipScenario.js +0 -26
  299. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyRegistryMissingScenario.js +0 -22
  300. package/tests/unit/state/apply/removeWriter/state.apply.removeWriter.test.js +0 -307
  301. package/tests/unit/state/apply/state.apply.test.js +0 -24
  302. package/tests/unit/state/apply/transfer/state.apply.transfer.test.js +0 -819
  303. package/tests/unit/state/apply/transfer/transferContractSchemaValidationScenario.js +0 -22
  304. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +0 -146
  305. package/tests/unit/state/apply/transfer/transferDoubleSpendSameBatchScenario.js +0 -63
  306. package/tests/unit/state/apply/transfer/transferDoubleSpendSingleValidatorScenario.js +0 -67
  307. package/tests/unit/state/apply/transfer/transferExistingRecipientAmountScenario.js +0 -31
  308. package/tests/unit/state/apply/transfer/transferExistingRecipientZeroAmountScenario.js +0 -31
  309. package/tests/unit/state/apply/transfer/transferHandlerGuardScenarios.js +0 -22
  310. package/tests/unit/state/apply/transfer/transferHappyPathScenario.js +0 -8
  311. package/tests/unit/state/apply/transfer/transferInvalidIncomingDataScenario.js +0 -66
  312. package/tests/unit/state/apply/transfer/transferNewRecipientAmountScenario.js +0 -31
  313. package/tests/unit/state/apply/transfer/transferNewRecipientZeroAmountScenario.js +0 -31
  314. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +0 -1170
  315. package/tests/unit/state/apply/transfer/transferSelfTransferAmountScenario.js +0 -38
  316. package/tests/unit/state/apply/transfer/transferSelfTransferZeroAmountScenario.js +0 -38
  317. package/tests/unit/state/apply/transfer/transferValidatorRecipientAmountScenario.js +0 -38
  318. package/tests/unit/state/apply/transfer/transferValidatorRecipientZeroAmountScenario.js +0 -38
  319. package/tests/unit/state/apply/txOperation/state.apply.txOperation.test.js +0 -318
  320. package/tests/unit/state/apply/txOperation/txOperationBootstrapNotRegisteredScenario.js +0 -70
  321. package/tests/unit/state/apply/txOperation/txOperationDifferentValidatorCreatorHappyPathScenario.js +0 -23
  322. package/tests/unit/state/apply/txOperation/txOperationInvalidDeploymentEntryScenario.js +0 -48
  323. package/tests/unit/state/apply/txOperation/txOperationInvalidFeeAmountScenario.js +0 -39
  324. package/tests/unit/state/apply/txOperation/txOperationInvalidSubnetCreatorAddressScenario.js +0 -46
  325. package/tests/unit/state/apply/txOperation/txOperationRequesterCreatorHappyPathScenario.js +0 -21
  326. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +0 -432
  327. package/tests/unit/state/apply/txOperation/txOperationStandardHappyPathScenario.js +0 -21
  328. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddCreatorBalanceFailureScenario.js +0 -26
  329. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBalanceFailureScenario.js +0 -25
  330. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBonusFailureScenario.js +0 -27
  331. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeCreatorEntryScenario.js +0 -18
  332. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeRequesterEntryScenario.js +0 -17
  333. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeValidatorEntryScenario.js +0 -31
  334. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardBypassScenario.js +0 -49
  335. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +0 -93
  336. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInsufficientRequesterBalanceScenario.js +0 -28
  337. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidCreatorBalanceScenario.js +0 -29
  338. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterBalanceScenario.js +0 -28
  339. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterEntryScenario.js +0 -17
  340. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidValidatorBalanceScenario.js +0 -33
  341. package/tests/unit/state/apply/txOperation/txOperationTransferFeeMissingCreatorEntryScenario.js +0 -18
  342. package/tests/unit/state/apply/txOperation/txOperationTransferFeeSubtractFailureScenario.js +0 -25
  343. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateCreatorBalanceFailureScenario.js +0 -26
  344. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateFailureScenario.js +0 -25
  345. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBalanceFailureScenario.js +0 -26
  346. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBonusFailureScenario.js +0 -27
  347. package/tests/unit/state/apply/txOperation/txOperationValidatorCreatorHappyPathScenario.js +0 -21
  348. package/tests/unit/state/stateModule.test.js +0 -23
  349. package/tests/unit/state/stateTestUtils.js +0 -32
  350. package/tests/unit/state/utils/address.test.js +0 -63
  351. package/tests/unit/state/utils/adminEntry.test.js +0 -52
  352. package/tests/unit/state/utils/balance.test.js +0 -320
  353. package/tests/unit/state/utils/lengthEntry.test.js +0 -54
  354. package/tests/unit/state/utils/nodeEntry.test.js +0 -298
  355. package/tests/unit/state/utils/roles.test.js +0 -44
  356. package/tests/unit/unit.test.js +0 -14
  357. package/tests/unit/utils/amountSerialization/amountSerialization.test.js +0 -237
  358. package/tests/unit/utils/buffer/buffer.test.js +0 -251
  359. package/tests/unit/utils/check/adminControlOperation.test.js +0 -156
  360. package/tests/unit/utils/check/balanceInitializationOperation.test.js +0 -54
  361. package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +0 -104
  362. package/tests/unit/utils/check/check.test.js +0 -17
  363. package/tests/unit/utils/check/common.test.js +0 -419
  364. package/tests/unit/utils/check/coreAdminOperation.test.js +0 -95
  365. package/tests/unit/utils/check/roleAccessOperation.test.js +0 -255
  366. package/tests/unit/utils/check/transactionOperation.test.js +0 -107
  367. package/tests/unit/utils/check/transferOperation.test.js +0 -102
  368. package/tests/unit/utils/deepEqualApplyPayload/deepEqualApplyPayload.test.js +0 -102
  369. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +0 -95
  370. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +0 -149
  371. package/tests/unit/utils/helpers/helpers.test.js +0 -11
  372. package/tests/unit/utils/helpers/isHexString.test.js +0 -12
  373. package/tests/unit/utils/helpers/normalizeHex.test.js +0 -82
  374. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +0 -100
  375. package/tests/unit/utils/normalizers/normalizers.test.js +0 -469
  376. package/tests/unit/utils/protobuf/applyOperations.test.js +0 -91
  377. package/tests/unit/utils/protobuf/operationHelpers.test.js +0 -303
  378. package/tests/unit/utils/protobuf/protobuf.test.js +0 -12
  379. package/tests/unit/utils/type/type.test.js +0 -25
  380. package/tests/unit/utils/utils.test.js +0 -21
  381. package/whitelist/.gitkeep +0 -0
@@ -1,167 +0,0 @@
1
- import b4a from 'b4a';
2
- import { test } from 'brittle';
3
- import nodeEntryUtils from '../../../../../src/core/state/utils/nodeEntry.js';
4
- import { EntryType } from '../../../../../src/utils/constants.js';
5
- import lengthEntryUtils from '../../../../../src/core/state/utils/lengthEntry.js';
6
- import { eventFlush } from '../../../../helpers/autobaseTestHelpers.js';
7
- import { initializeBalances, whitelistAddress } from '../common/commonScenarioHelper.js';
8
- import { promotePeerToWriter } from '../addWriter/addWriterScenarioHelpers.js';
9
- import {
10
- setupAddIndexerScenario,
11
- selectIndexerCandidatePeer,
12
- buildAddIndexerPayload,
13
- assertAddIndexerSuccessState,
14
- ensureIndexerRegistration
15
- } from '../addIndexer/addIndexerScenarioHelpers.js';
16
- import { buildRemoveIndexerPayload, assertRemoveIndexerSuccessState } from './removeIndexerScenarioHelpers.js';
17
-
18
- export default function removeIndexerRemoveMultipleIndexersScenario() {
19
- test('State.apply removeIndexer removes multiple indexers sequentially, leaving only admin', async t => {
20
- const context = await setupAddIndexerScenario(t, { nodes: 4 });
21
- const adminPeer = context.adminBootstrap;
22
- const initialIndexerCount = getIndexerCount(adminPeer.base);
23
-
24
- const candidates = [
25
- selectIndexerCandidatePeer(context, 0),
26
- selectIndexerCandidatePeer(context, 1),
27
- selectIndexerCandidatePeer(context, 2)
28
- ];
29
-
30
- for (const peer of candidates.slice(1)) {
31
- await prepareWriterCandidate(t, context, peer);
32
- }
33
-
34
- for (const peer of candidates) {
35
- await promoteWriterToIndexer(t, context, peer);
36
- }
37
-
38
- for (const peer of candidates) {
39
- const writersLengthBefore = await readWritersLength(adminPeer.base);
40
- const indexerEntryBefore = await adminPeer.base.view.get(peer.wallet.address);
41
- const adminEntryBefore = await adminPeer.base.view.get(adminPeer.wallet.address);
42
-
43
- ensureIndexerRegistration(adminPeer.base, peer.base.local.key);
44
-
45
- const payload = await buildRemoveIndexerPayload(context, {
46
- indexerPeer: peer,
47
- adminPeer
48
- });
49
-
50
- await adminPeer.base.append(payload);
51
- await adminPeer.base.update();
52
- await eventFlush();
53
-
54
- await assertRemoveIndexerSuccessState(t, context, {
55
- indexerPeer: peer,
56
- adminPeer,
57
- indexerEntryBefore: { value: b4a.from(indexerEntryBefore.value) },
58
- adminEntryBefore: { value: b4a.from(adminEntryBefore.value) },
59
- payload,
60
- writersLengthBefore,
61
- skipSync: true
62
- });
63
-
64
- }
65
-
66
- assertIndexerCount(t, context, 1);
67
- await assertOnlyAdminIsIndexer(t, context);
68
- });
69
- }
70
-
71
- async function prepareWriterCandidate(t, context, peer) {
72
- const funding = context.addWriterScenario?.writerInitialBalance;
73
- if (!funding) {
74
- throw new Error('addIndexer scenarios require writerInitialBalance buffer.');
75
- }
76
- const expectedWriterIndex = await deriveNextWriterIndex(context.adminBootstrap.base);
77
- await initializeBalances(context, [[peer.wallet.address, funding]]);
78
- await whitelistAddress(context, peer.wallet.address);
79
- await promotePeerToWriter(t, context, { readerPeer: peer, expectedWriterIndex });
80
- }
81
-
82
- async function promoteWriterToIndexer(t, context, writerPeer) {
83
- const adminPeer = context.adminBootstrap;
84
- const writerAddress = writerPeer.wallet.address;
85
-
86
- const writerEntryBefore = await adminPeer.base.view.get(writerAddress);
87
- t.ok(writerEntryBefore, 'writer entry exists before addIndexer');
88
- const adminEntryBefore = await adminPeer.base.view.get(adminPeer.wallet.address);
89
- t.ok(adminEntryBefore, 'admin entry exists before addIndexer');
90
-
91
- const payload = await buildAddIndexerPayload(context, {
92
- writerPeer,
93
- adminPeer
94
- });
95
-
96
- await adminPeer.base.append(payload);
97
- await adminPeer.base.update();
98
- await eventFlush();
99
-
100
- await assertAddIndexerSuccessState(t, context, {
101
- writerPeer,
102
- adminPeer,
103
- writerEntryBefore: { value: b4a.from(writerEntryBefore.value) },
104
- adminEntryBefore: { value: b4a.from(adminEntryBefore.value) },
105
- payload,
106
- skipSync: true
107
- });
108
- }
109
-
110
- function getIndexerCount(base) {
111
- return Object.values(base.system.indexers ?? {}).length;
112
- }
113
-
114
- function assertIndexerCount(t, context, expectedCount) {
115
- const base = context.adminBootstrap.base;
116
- const count = getIndexerCount(base);
117
- t.is(count, expectedCount, 'admin observes expected indexer count');
118
- }
119
-
120
- async function assertOnlyAdminIsIndexer(t, context) {
121
- const adminKey = context.adminBootstrap.base.local.key;
122
- const membership = Object.values(context.adminBootstrap.base.system.indexers ?? {});
123
- t.is(membership.length, 1, 'admin retains a single indexer');
124
- const onlyEntry = membership[0]?.key;
125
- t.ok(onlyEntry && b4a.equals(onlyEntry, adminKey), 'admin stays sole indexer');
126
-
127
- // Removed indexers should now be writers without validator membership (admin view).
128
- for (const candidate of context.peers.slice(1, 4)) {
129
- await assertNodeIsWriterNonIndexer(t, candidate, [context.adminBootstrap]);
130
- }
131
- }
132
-
133
- async function assertNodeIsWriterNonIndexer(t, targetPeer, allPeers) {
134
- const writingKey = targetPeer.base.local.key;
135
- for (const peer of allPeers) {
136
- const entry = await peer.base.view.get(targetPeer.wallet.address);
137
- t.ok(entry, `${peer.name} sees downgraded entry for ${targetPeer.wallet.address}`);
138
- const decoded = nodeEntryUtils.decode(entry?.value);
139
- t.ok(decoded, `${peer.name} decodes downgraded entry for ${targetPeer.wallet.address}`);
140
- if (!decoded) continue;
141
- t.is(decoded.isIndexer, false, `${peer.name} marks ${targetPeer.wallet.address} as non-indexer`);
142
- t.is(decoded.isWriter, true, `${peer.name} keeps ${targetPeer.wallet.address} as writer`);
143
- t.is(decoded.isWhitelisted, true, `${peer.name} keeps ${targetPeer.wallet.address} whitelisted`);
144
- const hasMembership = indexerMembershipIncludes(peer.base, writingKey);
145
- t.is(hasMembership, false, `${peer.name} does not keep ${targetPeer.wallet.address} in validator set`);
146
- }
147
- }
148
-
149
- async function readWritersLength(base) {
150
- const entry = await base.view.get(EntryType.WRITERS_LENGTH);
151
- if (!entry?.value) return 0;
152
- return entry.value.readUInt32BE();
153
- }
154
-
155
- async function deriveNextWriterIndex(base) {
156
- const entry = await base.view.get(EntryType.WRITERS_LENGTH);
157
- if (!entry?.value) {
158
- return 0;
159
- }
160
- return lengthEntryUtils.decodeBE(entry.value);
161
- }
162
-
163
- function indexerMembershipIncludes(base, writingKey) {
164
- const entries = base?.system?.indexers;
165
- if (!entries) return false;
166
- return Object.values(entries).some(entry => entry?.key && b4a.equals(entry.key, writingKey));
167
- }
@@ -1,429 +0,0 @@
1
- import b4a from 'b4a';
2
- import nodeEntryUtils from '../../../../../src/core/state/utils/nodeEntry.js';
3
- import { BALANCE_FEE, toBalance } from '../../../../../src/core/state/utils/balance.js';
4
- import addressUtils from '../../../../../src/core/state/utils/address.js';
5
- import nodeRoleUtils from '../../../../../src/core/state/utils/roles.js';
6
- import { EntryType } from '../../../../../src/utils/constants.js';
7
- import { safeDecodeApplyOperation } from '../../../../../src/utils/protobuf/operationHelpers.js';
8
- import { eventFlush } from '../../../../helpers/autobaseTestHelpers.js';
9
- import {
10
- setupAddIndexerScenario,
11
- selectIndexerCandidatePeer,
12
- buildAddIndexerPayload,
13
- buildRemoveIndexerPayload as buildRemoveIndexerPayloadFromAddHelper,
14
- buildRemoveIndexerPayloadWithTxValidity as buildRemoveIndexerPayloadWithTxValidityFromAddHelper,
15
- assertAddIndexerSuccessState
16
- } from '../addIndexer/addIndexerScenarioHelpers.js';
17
- import { config } from '../../../../helpers/config.js';
18
-
19
- export async function setupRemoveIndexerScenario(t, options = {}) {
20
- const context = await setupAddIndexerScenario(t, options);
21
- const adminPeer = context.adminBootstrap;
22
- const indexerPeer = selectIndexerCandidatePeer(context);
23
-
24
- const writerEntryBefore = await adminPeer.base.view.get(indexerPeer.wallet.address);
25
- if (!writerEntryBefore?.value) {
26
- throw new Error('setupRemoveIndexerScenario requires a writer entry before promotion.');
27
- }
28
- const adminEntryBefore = await adminPeer.base.view.get(adminPeer.wallet.address);
29
- if (!adminEntryBefore?.value) {
30
- throw new Error('setupRemoveIndexerScenario requires an admin entry before promotion.');
31
- }
32
-
33
- const addPayload = await buildAddIndexerPayload(context, { writerPeer: indexerPeer, adminPeer });
34
- await adminPeer.base.append(addPayload);
35
- await adminPeer.base.update();
36
- await eventFlush();
37
-
38
- await assertAddIndexerSuccessState(t, context, {
39
- writerPeer: indexerPeer,
40
- adminPeer,
41
- writerEntryBefore: { value: b4a.from(writerEntryBefore.value) },
42
- adminEntryBefore: { value: b4a.from(adminEntryBefore.value) },
43
- payload: addPayload
44
- });
45
-
46
- const indexerEntryBeforeRemoval = await adminPeer.base.view.get(indexerPeer.wallet.address);
47
- const adminEntryBeforeRemoval = await adminPeer.base.view.get(adminPeer.wallet.address);
48
- const writersLengthBeforeRemoval = await readWritersLength(adminPeer.base);
49
-
50
- context.removeIndexerScenario = {
51
- ...(context.removeIndexerScenario ?? {}),
52
- indexerPeer,
53
- indexerEntryBeforeRemoval: indexerEntryBeforeRemoval
54
- ? { value: b4a.from(indexerEntryBeforeRemoval.value) }
55
- : null,
56
- adminEntryBeforeRemoval: adminEntryBeforeRemoval
57
- ? { value: b4a.from(adminEntryBeforeRemoval.value) }
58
- : null,
59
- writersLengthBeforeRemoval
60
- };
61
-
62
- return context;
63
- }
64
-
65
- export async function buildRemoveIndexerPayload(context, options = {}) {
66
- return buildRemoveIndexerPayloadFromAddHelper(context, options);
67
- }
68
-
69
- export async function buildRemoveIndexerPayloadWithTxValidity(context, mutatedTxValidity, options = {}) {
70
- return buildRemoveIndexerPayloadWithTxValidityFromAddHelper(context, mutatedTxValidity, options);
71
- }
72
-
73
- export async function applyWithRemoveIndexerRoleUpdateFailure(context, invalidPayload) {
74
- const adminPeer = context.adminBootstrap ?? context.bootstrap ?? context.peers?.[0] ?? null;
75
- if (!adminPeer?.base) {
76
- throw new Error('RemoveIndexer role mutation failure scenario requires a writable node.');
77
- }
78
-
79
- const originalSetter = nodeEntryUtils.setRoleAndWriterKey;
80
- let shouldFail = true;
81
- nodeEntryUtils.setRoleAndWriterKey = function patchedSetRoleAndWriterKey(...args) {
82
- if (shouldFail) {
83
- shouldFail = false;
84
- return null;
85
- }
86
- return originalSetter.apply(this, args);
87
- };
88
-
89
- try {
90
- await adminPeer.base.append(invalidPayload);
91
- await adminPeer.base.update();
92
- await eventFlush();
93
- } finally {
94
- nodeEntryUtils.setRoleAndWriterKey = originalSetter;
95
- }
96
- }
97
-
98
- export async function applyWithoutIndexerMembership(context, invalidPayload) {
99
- const adminPeer = context.adminBootstrap ?? context.bootstrap ?? context.peers?.[0] ?? null;
100
- const indexerPeer = context.removeIndexerScenario?.indexerPeer ?? selectIndexerCandidatePeer(context);
101
- if (!adminPeer?.base || !indexerPeer?.wallet?.address) {
102
- throw new Error('RemoveIndexer missing indexer membership scenario requires a writable admin and indexer peer.');
103
- }
104
-
105
- const targetAddress = indexerPeer.wallet.address;
106
- const targetAddressBuffer = addressUtils.addressToBuffer(targetAddress, config.addressPrefix);
107
- if (!targetAddressBuffer) {
108
- throw new Error('RemoveIndexer missing indexer membership scenario requires a decodable indexer address.');
109
- }
110
-
111
- const replacementWriterKey = b4a.alloc(32, 0xaa);
112
- const originalApply = adminPeer.base._handlers.apply;
113
-
114
- adminPeer.base._handlers.apply = async function patchedApply(nodes, view, baseCtx) {
115
- let mutatedOnce = false;
116
- const originalBatch = view.batch;
117
- view.batch = function patchedBatch(...args) {
118
- const batch = originalBatch.apply(this, args);
119
- if (!batch?.get) return batch;
120
-
121
- const originalGet = batch.get.bind(batch);
122
- batch.get = async key => {
123
- if (mutatedOnce) return originalGet(key);
124
-
125
- const isTarget =
126
- (typeof key === 'string' && key === targetAddress) ||
127
- (b4a.isBuffer(key) && b4a.equals(key, targetAddressBuffer));
128
- if (!isTarget) return originalGet(key);
129
-
130
- const entry = await originalGet(key);
131
- if (!entry?.value) {
132
- throw new Error('RemoveIndexer missing indexer membership scenario requires an existing indexer entry.');
133
- }
134
-
135
- const mutated = nodeEntryUtils.setRoleAndWriterKey(
136
- b4a.from(entry.value),
137
- nodeRoleUtils.NodeRole.INDEXER,
138
- replacementWriterKey
139
- );
140
- if (!mutated) {
141
- throw new Error('Failed to mutate indexer writing key.');
142
- }
143
-
144
- mutatedOnce = true;
145
- return { ...entry, value: mutated };
146
- };
147
-
148
- return batch;
149
- };
150
-
151
- try {
152
- return await originalApply.call(this, nodes, view, baseCtx);
153
- } finally {
154
- view.batch = originalBatch;
155
- }
156
- };
157
-
158
- try {
159
- await adminPeer.base.append(invalidPayload);
160
- await adminPeer.base.update();
161
- await eventFlush();
162
- } finally {
163
- adminPeer.base._handlers.apply = originalApply;
164
- }
165
- }
166
-
167
- export async function assertRemoveIndexerSuccessState(
168
- t,
169
- context,
170
- {
171
- indexerPeer = context.removeIndexerScenario?.indexerPeer ?? selectIndexerCandidatePeer(context),
172
- adminPeer = context.adminBootstrap,
173
- indexerEntryBefore = context.removeIndexerScenario?.indexerEntryBeforeRemoval,
174
- adminEntryBefore = context.removeIndexerScenario?.adminEntryBeforeRemoval,
175
- payload,
176
- writersLengthBefore = context.removeIndexerScenario?.writersLengthBeforeRemoval,
177
- skipSync = false
178
- } = {}
179
- ) {
180
- if (!indexerEntryBefore?.value) {
181
- throw new Error('assertRemoveIndexerSuccessState requires the indexer entry before removal.');
182
- }
183
- if (!adminEntryBefore?.value) {
184
- throw new Error('assertRemoveIndexerSuccessState requires the admin entry before removal.');
185
- }
186
- if (!payload) {
187
- throw new Error('assertRemoveIndexerSuccessState requires the removeIndexer payload.');
188
- }
189
- if (typeof writersLengthBefore !== 'number') {
190
- throw new Error('assertRemoveIndexerSuccessState requires writersLengthBefore.');
191
- }
192
-
193
- const decodedBefore = nodeEntryUtils.decode(indexerEntryBefore.value);
194
- t.ok(decodedBefore, 'indexer entry before removeIndexer decodes');
195
- if (!decodedBefore) return;
196
- t.is(decodedBefore.isWhitelisted, true, 'indexer is whitelisted before removal');
197
- t.is(decodedBefore.isWriter, true, 'indexer retains writer role before removal');
198
- t.is(decodedBefore.isIndexer, true, 'indexer role set before removal');
199
-
200
- const indexerEntryAfter = await adminPeer.base.view.get(indexerPeer.wallet.address);
201
- t.ok(indexerEntryAfter, 'indexer entry exists after removeIndexer');
202
- const decodedAfter = nodeEntryUtils.decode(indexerEntryAfter?.value);
203
- t.ok(decodedAfter, 'indexer entry decodes after removeIndexer');
204
- if (!decodedAfter) return;
205
- t.is(decodedAfter.isWhitelisted, true, 'indexer remains whitelisted after removal');
206
- t.is(decodedAfter.isWriter, true, 'node downgraded to writer after removeIndexer');
207
- t.is(decodedAfter.isIndexer, false, 'indexer flag cleared after removeIndexer');
208
- t.ok(b4a.equals(decodedAfter.wk, decodedBefore.wk), 'writer key preserved after removeIndexer');
209
- t.ok(
210
- b4a.equals(decodedAfter.balance, decodedBefore.balance),
211
- 'node balance preserved after removeIndexer'
212
- );
213
- t.ok(
214
- b4a.equals(decodedAfter.stakedBalance, decodedBefore.stakedBalance),
215
- 'node staked balance preserved after removeIndexer'
216
- );
217
- t.ok(b4a.equals(decodedAfter.license, decodedBefore.license), 'license preserved after removeIndexer');
218
-
219
- await assertWriterRegistry(t, adminPeer.base, decodedBefore.wk, indexerPeer.wallet.address);
220
- await assertWriterIndexUpdates(t, adminPeer.base, writersLengthBefore, indexerPeer.wallet.address);
221
- await assertAdminFeeDeducted(t, adminPeer.base, adminEntryBefore.value, adminPeer.wallet.address);
222
- await assertRemoveIndexerPayloadMetadata(
223
- t,
224
- adminPeer.base,
225
- payload,
226
- adminPeer.wallet.address,
227
- indexerPeer.wallet.address
228
- );
229
- assertIndexerMembershipRemoved(t, adminPeer.base, decodedBefore.wk);
230
-
231
- if (!skipSync) {
232
- await context.sync();
233
- await assertDemotedNodeState(t, indexerPeer.base, indexerPeer.wallet.address, decodedBefore.wk);
234
- }
235
- }
236
-
237
- export async function assertRemoveIndexerFailureState(
238
- t,
239
- context,
240
- {
241
- indexerPeer = context.removeIndexerScenario?.indexerPeer ?? selectIndexerCandidatePeer(context),
242
- adminPeer = context.adminBootstrap,
243
- writersLengthBefore = context.removeIndexerScenario?.writersLengthBeforeRemoval,
244
- skipSync = false
245
- } = {}
246
- ) {
247
- const base = adminPeer.base;
248
- const writersLength = typeof writersLengthBefore === 'number'
249
- ? writersLengthBefore
250
- : await readWritersLength(base);
251
-
252
- await assertIndexerStillRegistered(t, base, indexerPeer, writersLength);
253
-
254
- if (!skipSync) {
255
- await context.sync();
256
- await assertIndexerStillRegistered(t, indexerPeer.base, indexerPeer, writersLength);
257
- }
258
- }
259
-
260
- export async function assertRemoveIndexerGuardFailureState(
261
- t,
262
- context,
263
- {
264
- indexerPeer = context.removeIndexerScenario?.indexerPeer ?? selectIndexerCandidatePeer(context),
265
- adminPeer = context.adminBootstrap,
266
- skipSync = false
267
- } = {}
268
- ) {
269
- await assertMinimalIndexerState(t, adminPeer.base, indexerPeer);
270
-
271
- if (!skipSync) {
272
- await context.sync();
273
- await assertMinimalIndexerState(t, indexerPeer.base, indexerPeer);
274
- }
275
- }
276
-
277
- async function assertWriterRegistry(t, base, writingKey, expectedAddress) {
278
- const registryKey = EntryType.WRITER_ADDRESS + writingKey.toString('hex');
279
- const entry = await base.view.get(registryKey);
280
- t.ok(entry, 'writer registry entry exists after removeIndexer');
281
- const addressBuffer = addressUtils.addressToBuffer(expectedAddress, config.addressPrefix);
282
- t.ok(addressBuffer, 'indexer address encodes to buffer');
283
- if (!entry?.value || !addressBuffer) return;
284
- t.ok(
285
- b4a.equals(entry.value, addressBuffer),
286
- 'writer registry maps writing key to downgraded writer address'
287
- );
288
- }
289
-
290
- async function assertWriterIndexUpdates(t, base, lengthBefore, expectedAddress) {
291
- const lengthAfter = await readWritersLength(base);
292
- t.is(lengthAfter, lengthBefore + 1, 'writers length increments after removeIndexer');
293
-
294
- const indexEntry = await base.view.get(EntryType.WRITERS_INDEX + lengthBefore);
295
- t.ok(indexEntry, 'writers index entry stored after removeIndexer');
296
- const addressBuffer = addressUtils.addressToBuffer(expectedAddress, config.addressPrefix);
297
- if (!indexEntry?.value || !addressBuffer) return;
298
- t.ok(
299
- b4a.equals(indexEntry.value, addressBuffer),
300
- 'writers index entry stores downgraded writer address'
301
- );
302
- }
303
-
304
- async function assertAdminFeeDeducted(t, base, adminEntryBeforeValue, adminAddress) {
305
- const decodedAdminBefore = nodeEntryUtils.decode(adminEntryBeforeValue);
306
- t.ok(decodedAdminBefore, 'admin entry before removeIndexer decodes');
307
- if (!decodedAdminBefore) return;
308
-
309
- const adminBalanceBefore = toBalance(decodedAdminBefore.balance);
310
- t.ok(adminBalanceBefore, 'admin balance before removeIndexer decodes');
311
- if (!adminBalanceBefore) return;
312
-
313
- const adminEntryAfter = await base.view.get(adminAddress);
314
- t.ok(adminEntryAfter, 'admin entry exists after removeIndexer');
315
- const decodedAdminAfter = nodeEntryUtils.decode(adminEntryAfter?.value);
316
- t.ok(decodedAdminAfter, 'admin entry decodes after removeIndexer');
317
- if (!decodedAdminAfter) return;
318
-
319
- const adminBalanceAfter = toBalance(decodedAdminAfter.balance);
320
- t.ok(adminBalanceAfter, 'admin balance after removeIndexer decodes');
321
- if (!adminBalanceAfter) return;
322
-
323
- const expectedBalance = adminBalanceBefore.sub(BALANCE_FEE);
324
- t.ok(expectedBalance, 'admin balance after fee computation succeeds');
325
- if (!expectedBalance) return;
326
-
327
- t.ok(
328
- b4a.equals(decodedAdminAfter.balance, expectedBalance.value),
329
- 'admin balance reduced by removeIndexer fee'
330
- );
331
- t.ok(
332
- b4a.equals(decodedAdminAfter.stakedBalance, decodedAdminBefore.stakedBalance),
333
- 'admin staked balance remains unchanged after removeIndexer'
334
- );
335
- }
336
-
337
- async function assertRemoveIndexerPayloadMetadata(t, base, payload, expectedAdmin, expectedTarget) {
338
- const decodedOperation = safeDecodeApplyOperation(payload);
339
- t.ok(decodedOperation, 'removeIndexer payload decodes');
340
- if (!decodedOperation) return;
341
-
342
- const requesterAddressBuffer = decodedOperation.address;
343
- t.ok(requesterAddressBuffer, 'removeIndexer payload contains requester address');
344
- const requesterAddress = addressUtils.bufferToAddress(requesterAddressBuffer, config.addressPrefix);
345
- t.ok(requesterAddress, 'removeIndexer requester address decodes');
346
- if (requesterAddress) {
347
- t.is(requesterAddress, expectedAdmin, 'removeIndexer payload signed by admin');
348
- }
349
-
350
- const targetAddressBuffer = decodedOperation?.aco?.ia;
351
- t.ok(targetAddressBuffer, 'removeIndexer payload contains target indexer address');
352
- const targetAddress = addressUtils.bufferToAddress(targetAddressBuffer, config.addressPrefix);
353
- t.ok(targetAddress, 'removeIndexer target address decodes');
354
- if (targetAddress) {
355
- t.is(targetAddress, expectedTarget, 'removeIndexer payload nominates expected indexer');
356
- }
357
-
358
- const txHashBuffer = decodedOperation?.aco?.tx;
359
- t.ok(txHashBuffer, 'removeIndexer tx hash extracted');
360
- if (txHashBuffer) {
361
- const txEntry = await base.view.get(txHashBuffer.toString('hex'));
362
- t.ok(txEntry, 'removeIndexer transaction recorded for replay protection');
363
- }
364
- }
365
-
366
- function assertIndexerMembershipRemoved(t, base, writingKey) {
367
- const hasMembership = indexerMembershipIncludes(base, writingKey);
368
- t.is(hasMembership, false, 'indexer writer key removed from validator set');
369
- }
370
-
371
- async function assertDemotedNodeState(t, base, address, writingKey) {
372
- const entry = await base.view.get(address);
373
- t.ok(entry, 'downgraded entry exists after removeIndexer');
374
- const decoded = nodeEntryUtils.decode(entry?.value);
375
- t.ok(decoded, 'downgraded entry decodes after removeIndexer');
376
- if (!decoded) return;
377
- t.is(decoded.isIndexer, false, 'node remains non-indexer after removeIndexer sync');
378
- t.is(decoded.isWriter, true, 'node remains writer after removeIndexer sync');
379
- t.is(decoded.isWhitelisted, true, 'node remains whitelisted after removeIndexer sync');
380
- t.ok(b4a.equals(decoded.wk, writingKey), 'writer key preserved after removeIndexer sync');
381
- assertIndexerMembershipRemoved(t, base, writingKey);
382
- }
383
-
384
- async function assertIndexerStillRegistered(t, base, indexerPeer, writersLengthBefore) {
385
- const entry = await base.view.get(indexerPeer.wallet.address);
386
- t.ok(entry, 'indexer entry persists after failed removeIndexer');
387
- const decoded = nodeEntryUtils.decode(entry?.value);
388
- t.ok(decoded, 'indexer entry decodes after failed removeIndexer');
389
- if (!decoded) return;
390
-
391
- t.is(decoded.isIndexer, true, 'indexer role preserved after failed removeIndexer');
392
- t.is(decoded.isWriter, true, 'writer role preserved after failed removeIndexer');
393
- t.is(decoded.isWhitelisted, true, 'whitelist flag preserved after failed removeIndexer');
394
- assertIndexerMembershipPresent(t, base, decoded.wk);
395
-
396
- if (typeof writersLengthBefore === 'number') {
397
- const writersLengthAfter = await readWritersLength(base);
398
- t.is(
399
- writersLengthAfter,
400
- writersLengthBefore,
401
- 'writers length unchanged after failed removeIndexer'
402
- );
403
- }
404
- }
405
-
406
- function assertIndexerMembershipPresent(t, base, writingKey) {
407
- const hasMembership = indexerMembershipIncludes(base, writingKey);
408
- t.ok(hasMembership, 'indexer writer key remains in validator set');
409
- }
410
-
411
- async function assertMinimalIndexerState(t, base, indexerPeer) {
412
- const entry = await base.view.get(indexerPeer.wallet.address);
413
- t.ok(entry, 'indexer entry persists after failed removeIndexer');
414
- const decoded = nodeEntryUtils.decode(entry?.value);
415
- t.ok(decoded, 'indexer entry decodes after failed removeIndexer');
416
- if (!decoded) return;
417
- }
418
-
419
- async function readWritersLength(base) {
420
- const entry = await base.view.get(EntryType.WRITERS_LENGTH);
421
- if (!entry?.value) return 0;
422
- return entry.value.readUInt32BE();
423
- }
424
-
425
- function indexerMembershipIncludes(base, writingKey) {
426
- const entries = base?.system?.indexers;
427
- if (!entries) return false;
428
- return Object.values(entries).some(entry => entry?.key && b4a.equals(entry.key, writingKey));
429
- }
@@ -1,22 +0,0 @@
1
- import { test } from 'brittle';
2
- import nodeRoleUtils from '../../../../../src/core/state/utils/roles.js';
3
- import OperationValidationScenarioBase from '../common/base/OperationValidationScenarioBase.js';
4
- import { applyWithPretenderRoleMutation } from '../addIndexer/addIndexerScenarioHelpers.js';
5
- import {
6
- setupRemoveIndexerScenario,
7
- buildRemoveIndexerPayload,
8
- assertRemoveIndexerFailureState
9
- } from './removeIndexerScenarioHelpers.js';
10
-
11
- export default function removeIndexerTargetNotIndexerScenario() {
12
- new OperationValidationScenarioBase({
13
- title: 'State.apply removeIndexer rejects payloads when target is not an indexer',
14
- setupScenario: setupRemoveIndexerScenario,
15
- buildValidPayload: context => buildRemoveIndexerPayload(context),
16
- mutatePayload: (_t, payload) => payload,
17
- applyInvalidPayload: (context, invalidPayload) =>
18
- applyWithPretenderRoleMutation(context, invalidPayload, nodeRoleUtils.NodeRole.WRITER),
19
- assertStateUnchanged: (t, context) => assertRemoveIndexerFailureState(t, context, { skipSync: true }),
20
- expectedLogs: ['Node must be an indexer.']
21
- }).performScenario(test);
22
- }
@@ -1,20 +0,0 @@
1
- import OperationValidationScenarioBase from '../common/base/OperationValidationScenarioBase.js';
2
- import {
3
- setupRemoveIndexerScenario,
4
- buildRemoveIndexerPayload,
5
- assertRemoveIndexerGuardFailureState,
6
- applyWithoutIndexerMembership
7
- } from './removeIndexerScenarioHelpers.js';
8
-
9
- export default function removeIndexerWriterKeyMissingScenario() {
10
- new OperationValidationScenarioBase({
11
- title: 'State.apply removeIndexer rejects payloads when writer key is missing from indexer list',
12
- setupScenario: setupRemoveIndexerScenario,
13
- buildValidPayload: context => buildRemoveIndexerPayload(context),
14
- mutatePayload: (_t, payload) => payload,
15
- applyInvalidPayload: (context, invalidPayload) =>
16
- applyWithoutIndexerMembership(context, invalidPayload),
17
- assertStateUnchanged: (t, context) => assertRemoveIndexerGuardFailureState(t, context, { skipSync: true }),
18
- expectedLogs: ['Writer key does not exist in indexer list.']
19
- }).performScenario();
20
- }