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.
- package/README.md +62 -2
- package/SECURITY.md +9 -6
- package/cli/commandHandler.js +272 -0
- package/cli/handlers.js +210 -0
- package/cli/interactive.js +182 -0
- package/msb.mjs +7 -8
- package/package.json +33 -11
- package/rpc/create_server.js +44 -44
- package/rpc/handlers.js +43 -56
- package/rpc/routes/index.js +8 -8
- package/rpc/rpc_server.js +6 -2
- package/rpc/utils/helpers.js +46 -66
- package/scripts/pear-runner.js +170 -0
- package/src/config/args.js +60 -13
- package/src/config/config.js +163 -14
- package/src/config/env.js +57 -25
- package/src/core/network/Network.js +121 -56
- package/src/core/network/protocols/LegacyProtocol.js +21 -11
- package/src/core/network/protocols/NetworkMessages.js +38 -17
- package/src/core/network/protocols/ProtocolInterface.js +15 -3
- package/src/core/network/protocols/ProtocolSession.js +144 -17
- package/src/core/network/protocols/V1Protocol.js +37 -18
- package/src/core/network/protocols/connectionPolicies.js +174 -0
- package/src/core/network/protocols/legacy/NetworkMessageRouter.js +26 -20
- package/src/core/network/protocols/{shared/handlers/base/BaseOperationHandler.js → legacy/handlers/BaseStateOperationHandler.js} +25 -14
- package/src/core/network/protocols/legacy/handlers/{GetRequestHandler.js → LegacyGetRequestHandler.js} +9 -9
- package/src/core/network/protocols/legacy/handlers/LegacyResponseHandler.js +23 -0
- package/src/core/network/protocols/{shared/handlers/RoleOperationHandler.js → legacy/handlers/LegacyRoleOperationHandler.js} +19 -12
- package/src/core/network/protocols/{shared/handlers/SubnetworkOperationHandler.js → legacy/handlers/LegacySubnetworkOperationHandler.js} +29 -18
- package/src/core/network/protocols/{shared/handlers/TransferOperationHandler.js → legacy/handlers/LegacyTransferOperationHandler.js} +18 -12
- package/src/core/network/protocols/legacy/validators/base/BaseResponse.js +7 -10
- package/src/core/network/protocols/shared/validators/{PartialBootstrapDeployment.js → PartialBootstrapDeploymentValidator.js} +9 -4
- package/src/core/network/protocols/shared/validators/{base/PartialOperation.js → PartialOperationValidator.js} +53 -31
- package/src/core/network/protocols/shared/validators/{PartialRoleAccess.js → PartialRoleAccessValidator.js} +51 -17
- package/src/core/network/protocols/shared/validators/{PartialTransaction.js → PartialTransactionValidator.js} +21 -7
- package/src/core/network/protocols/shared/validators/{PartialTransfer.js → PartialTransferValidator.js} +32 -14
- package/src/core/network/protocols/v1/NetworkMessageRouter.js +91 -7
- package/src/core/network/protocols/v1/V1ProtocolError.js +27 -0
- package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +66 -0
- package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +272 -0
- package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +88 -0
- package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionErrorMapper.js +84 -0
- package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionOperationStrategies.js +128 -0
- package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionPayloadUtils.js +26 -0
- package/src/core/network/protocols/v1/validators/V1BaseOperation.js +212 -0
- package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +28 -0
- package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +260 -0
- package/src/core/network/protocols/v1/validators/V1LivenessRequest.js +15 -0
- package/src/core/network/protocols/v1/validators/V1LivenessResponse.js +17 -0
- package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +210 -0
- package/src/core/network/services/ConnectionManager.js +149 -96
- package/src/core/network/services/MessageOrchestrator.js +197 -37
- package/src/core/network/services/PendingRequestService.js +175 -0
- package/src/core/network/services/TransactionCommitService.js +149 -0
- package/src/core/network/services/TransactionPoolService.js +129 -18
- package/src/core/network/services/TransactionRateLimiterService.js +57 -35
- package/src/core/network/services/ValidatorHealthCheckService.js +127 -0
- package/src/core/network/services/ValidatorObserverService.js +400 -121
- package/src/core/state/State.js +259 -156
- package/src/core/state/utils/address.js +4 -9
- package/src/core/state/utils/balance.js +7 -7
- package/src/core/state/utils/roles.js +1 -1
- package/src/index.js +320 -278
- package/src/messages/network/v1/NetworkMessageBuilder.js +71 -100
- package/src/messages/network/v1/NetworkMessageDirector.js +16 -50
- package/src/messages/network/v1/networkMessageFactory.js +1 -1
- package/src/messages/state/ApplyStateMessageBuilder.js +6 -6
- package/src/messages/state/applyStateMessageFactory.js +1 -1
- package/src/utils/Scheduler.js +0 -8
- package/src/utils/buffer.js +1 -1
- package/src/utils/check.js +12 -13
- package/src/utils/constants.js +78 -5
- package/src/utils/deepEqualApplyPayload.js +40 -0
- package/src/utils/errors.js +20 -0
- package/src/utils/fileUtils.js +12 -3
- package/src/utils/helpers.js +10 -1
- package/src/utils/logger.js +25 -0
- package/src/utils/migrationUtils.js +3 -3
- package/src/utils/normalizers.js +38 -0
- package/src/utils/protobuf/networkV1.generated.cjs +2460 -0
- package/src/utils/protobuf/operationHelpers.js +24 -3
- package/.dockerignore +0 -16
- package/.github/workflows/acceptance-tests.yml +0 -38
- package/.github/workflows/lint-pr-title.yml +0 -26
- package/.github/workflows/publish.yml +0 -33
- package/.github/workflows/unit-tests.yml +0 -34
- package/CODE_OF_CONDUCT.md +0 -128
- package/docker-compose.yml +0 -17
- package/dockerfile +0 -41
- package/docs/fee_distribution.md +0 -89
- package/docs/trac_network_http_api.openapi.yaml +0 -889
- package/migration/.gitkeep +0 -0
- package/proto/applyOperations.proto +0 -117
- package/proto/network.proto +0 -74
- package/rpc/rpc_services.js +0 -163
- package/scripts/generate-protobufs.js +0 -42
- package/src/core/network/identity/NetworkWalletFactory.js +0 -77
- package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +0 -37
- package/src/utils/cli.js +0 -130
- package/src/utils/cliCommands.js +0 -280
- package/src/utils/protobuf/network.cjs +0 -840
- package/tests/acceptance/v1/account/account.test.mjs +0 -123
- package/tests/acceptance/v1/balance/balance.test.mjs +0 -54
- package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +0 -116
- package/tests/acceptance/v1/confirmed-length/confirmed-length.test.mjs +0 -19
- package/tests/acceptance/v1/fee/fee.test.mjs +0 -11
- package/tests/acceptance/v1/health/health.test.mjs +0 -33
- package/tests/acceptance/v1/rpc.test.mjs +0 -95
- package/tests/acceptance/v1/tx/tx.test.mjs +0 -111
- package/tests/acceptance/v1/tx-details/tx-details.test.mjs +0 -213
- package/tests/acceptance/v1/tx-hashes/tx-hashes.test.mjs +0 -72
- package/tests/acceptance/v1/tx-payloads-bulk/tx-payloads-bulk.test.mjs +0 -27
- package/tests/acceptance/v1/txv/txv.test.mjs +0 -11
- package/tests/acceptance/v1/unconfirmed-length/unconfirmed-length.test.mjs +0 -11
- package/tests/fixtures/apply.fixtures.js +0 -77
- package/tests/fixtures/assembleMessage.fixtures.js +0 -41
- package/tests/fixtures/check.fixtures.js +0 -428
- package/tests/fixtures/networkV1.fixtures.js +0 -85
- package/tests/fixtures/protobuf.fixtures.js +0 -388
- package/tests/helpers/StateNetworkFactory.js +0 -155
- package/tests/helpers/address.js +0 -6
- package/tests/helpers/autobaseTestHelpers.js +0 -419
- package/tests/helpers/config.js +0 -4
- package/tests/helpers/createTestSignature.js +0 -13
- package/tests/helpers/regexHelper.js +0 -3
- package/tests/helpers/setupApplyTests.js +0 -587
- package/tests/helpers/transactionPayloads.mjs +0 -92
- package/tests/helpers/wrapper.js +0 -28
- package/tests/unit/messages/messages.test.js +0 -12
- package/tests/unit/messages/network/NetworkMessageBuilder.test.js +0 -276
- package/tests/unit/messages/network/NetworkMessageDirector.test.js +0 -201
- package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +0 -525
- package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +0 -237
- package/tests/unit/network/ConnectionManager.test.js +0 -191
- package/tests/unit/network/NetworkWalletFactory.test.js +0 -156
- package/tests/unit/network/networkModule.test.js +0 -10
- package/tests/unit/state/State.test.js +0 -80
- package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +0 -42
- package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +0 -276
- package/tests/unit/state/apply/addAdmin/adminEntryEncodingFailureScenario.js +0 -30
- package/tests/unit/state/apply/addAdmin/adminEntryExistsScenario.js +0 -78
- package/tests/unit/state/apply/addAdmin/nodeEntryInitializationFailureScenario.js +0 -30
- package/tests/unit/state/apply/addAdmin/nonBootstrapNodeScenario.js +0 -68
- package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +0 -159
- package/tests/unit/state/apply/addIndexer/addIndexerHappyPathScenario.js +0 -39
- package/tests/unit/state/apply/addIndexer/addIndexerMultipleIndexersInTheNetworkScenario.js +0 -167
- package/tests/unit/state/apply/addIndexer/addIndexerPretenderAlreadyIndexerScenario.js +0 -21
- package/tests/unit/state/apply/addIndexer/addIndexerPretenderNotWriterScenario.js +0 -21
- package/tests/unit/state/apply/addIndexer/addIndexerRemoveAndReAddScenario.js +0 -186
- package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +0 -443
- package/tests/unit/state/apply/addIndexer/addIndexerWriterKeyAlreadyRegisteredScenario.js +0 -32
- package/tests/unit/state/apply/addIndexer/state.apply.addIndexer.test.js +0 -297
- package/tests/unit/state/apply/addWriter/addWriterHappyPathScenario.js +0 -41
- package/tests/unit/state/apply/addWriter/addWriterInvalidValidatorSignatureScenario.js +0 -32
- package/tests/unit/state/apply/addWriter/addWriterNewWkScenario.js +0 -149
- package/tests/unit/state/apply/addWriter/addWriterRequesterAlreadyWriterScenario.js +0 -21
- package/tests/unit/state/apply/addWriter/addWriterRequesterBalanceInsufficientScenario.js +0 -21
- package/tests/unit/state/apply/addWriter/addWriterRequesterEntryDecodeFailureScenario.js +0 -19
- package/tests/unit/state/apply/addWriter/addWriterRequesterEntryMissingScenario.js +0 -19
- package/tests/unit/state/apply/addWriter/addWriterRequesterIndexerScenario.js +0 -21
- package/tests/unit/state/apply/addWriter/addWriterRequesterNotWhitelistedScenario.js +0 -21
- package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +0 -766
- package/tests/unit/state/apply/addWriter/addWriterStakeBalanceUpdateFailureScenario.js +0 -50
- package/tests/unit/state/apply/addWriter/addWriterStakeInsufficientBalanceScenario.js +0 -29
- package/tests/unit/state/apply/addWriter/addWriterStakeInvalidBalanceScenario.js +0 -29
- package/tests/unit/state/apply/addWriter/addWriterStakeInvalidEntryScenario.js +0 -21
- package/tests/unit/state/apply/addWriter/addWriterStakeStakedBalanceFailureScenario.js +0 -37
- package/tests/unit/state/apply/addWriter/addWriterStakeSubtractFailureScenario.js +0 -42
- package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +0 -106
- package/tests/unit/state/apply/addWriter/addWriterWriterKeyMismatchScenario.js +0 -54
- package/tests/unit/state/apply/addWriter/addWriterWriterKeyOwnershipScenario.js +0 -54
- package/tests/unit/state/apply/addWriter/addWriterZeroWriterKeyScenario.js +0 -29
- package/tests/unit/state/apply/addWriter/state.apply.addWriter.test.js +0 -309
- package/tests/unit/state/apply/adminRecovery/adminRecoveryHappyPathScenario.js +0 -30
- package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +0 -881
- package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +0 -435
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistBanAndReapplyScenario.js +0 -78
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistExistingReaderHappyPathScenario.js +0 -98
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistFeeAfterDisableScenario.js +0 -66
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistHappyPathScenario.js +0 -55
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistInsufficientAdminBalanceScenario.js +0 -103
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistNodeAlreadyWhitelistedScenario.js +0 -60
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +0 -189
- package/tests/unit/state/apply/appendWhitelist/state.apply.appendWhitelist.test.js +0 -220
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationHappyPathScenario.js +0 -82
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +0 -111
- package/tests/unit/state/apply/balanceInitialization/invalidAmountScenario.js +0 -45
- package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +0 -82
- package/tests/unit/state/apply/balanceInitialization/state.apply.balanceInitialization.test.js +0 -189
- package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +0 -156
- package/tests/unit/state/apply/banValidator/banValidatorHappyPathScenario.js +0 -36
- package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +0 -531
- package/tests/unit/state/apply/banValidator/banValidatorSequentialBansScenario.js +0 -74
- package/tests/unit/state/apply/banValidator/banValidatorTargetDecodeFailureScenario.js +0 -19
- package/tests/unit/state/apply/banValidator/banValidatorTargetIndexerScenario.js +0 -32
- package/tests/unit/state/apply/banValidator/banValidatorTargetNodeEntryMissingScenario.js +0 -19
- package/tests/unit/state/apply/banValidator/banValidatorTargetRoleUpdateFailureScenario.js +0 -19
- package/tests/unit/state/apply/banValidator/banValidatorWhitelistedNonWriterScenario.js +0 -38
- package/tests/unit/state/apply/banValidator/banValidatorWhitelistedZeroBalanceScenario.js +0 -91
- package/tests/unit/state/apply/banValidator/banValidatorWithdrawFailureScenario.js +0 -19
- package/tests/unit/state/apply/banValidator/state.apply.banValidator.test.js +0 -266
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +0 -143
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentHappyPathScenario.js +0 -26
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentIncompleteOperationScenario.js +0 -94
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentInvalidDeploymentEntryScenario.js +0 -37
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentMultipleBootstrapScenario.js +0 -86
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +0 -347
- package/tests/unit/state/apply/bootstrapDeployment/invalidValidatorNodeEntryScenario.js +0 -57
- package/tests/unit/state/apply/bootstrapDeployment/state.apply.bootstrapDeployment.test.js +0 -429
- package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +0 -120
- package/tests/unit/state/apply/common/access-control/adminEntryDecodeFailureScenario.js +0 -130
- package/tests/unit/state/apply/common/access-control/adminEntryExistsScenario.js +0 -93
- package/tests/unit/state/apply/common/access-control/adminEntryMissingScenario.js +0 -108
- package/tests/unit/state/apply/common/access-control/adminOnlyGuardScenario.js +0 -126
- package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +0 -121
- package/tests/unit/state/apply/common/access-control/roleAccessOperationValidationScenario.js +0 -50
- package/tests/unit/state/apply/common/adminControlOperationValidationScenario.js +0 -56
- package/tests/unit/state/apply/common/balances/adminEntryUpdateFailureScenario.js +0 -52
- package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +0 -198
- package/tests/unit/state/apply/common/balances/feeDecodeFailureScenario.js +0 -52
- package/tests/unit/state/apply/common/balances/requesterBalanceDecodeFailureScenario.js +0 -15
- package/tests/unit/state/apply/common/balances/requesterBalanceFeeApplicationFailureScenario.js +0 -11
- package/tests/unit/state/apply/common/balances/requesterBalanceInsufficientScenario.js +0 -15
- package/tests/unit/state/apply/common/balances/requesterBalanceUpdateFailureScenario.js +0 -11
- package/tests/unit/state/apply/common/balances/validatorEntryRewardFailureScenario.js +0 -11
- package/tests/unit/state/apply/common/balances/validatorEntryUpdateFailureScenario.js +0 -11
- package/tests/unit/state/apply/common/balances/validatorNodeEntryDecodeFailureScenario.js +0 -40
- package/tests/unit/state/apply/common/base/OperationValidationScenarioBase.js +0 -114
- package/tests/unit/state/apply/common/commonScenarioHelper.js +0 -103
- package/tests/unit/state/apply/common/indexer/indexerNodeEntryDecodeFailureScenario.js +0 -36
- package/tests/unit/state/apply/common/indexer/indexerNodeEntryMissingScenario.js +0 -36
- package/tests/unit/state/apply/common/indexer/indexerRoleUpdateFailureScenario.js +0 -29
- package/tests/unit/state/apply/common/indexer/indexerSequenceStateInvalidScenario.js +0 -66
- package/tests/unit/state/apply/common/invalidMessageComponentValidationScenario.js +0 -84
- package/tests/unit/state/apply/common/nodeEntryInitializationFailureScenario.js +0 -47
- package/tests/unit/state/apply/common/operationAlreadyAppliedScenario.js +0 -85
- package/tests/unit/state/apply/common/payload-structure/addressWithInvalidPublicKeyScenario.js +0 -52
- package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +0 -54
- package/tests/unit/state/apply/common/payload-structure/invalidAddressValidationScenario.js +0 -73
- package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +0 -71
- package/tests/unit/state/apply/common/payload-structure/invalidPayloadValidationScenario.js +0 -31
- package/tests/unit/state/apply/common/payload-structure/invalidSignatureValidationScenario.js +0 -142
- package/tests/unit/state/apply/common/payload-structure/partialOperationValidationScenario.js +0 -87
- package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +0 -71
- package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +0 -73
- package/tests/unit/state/apply/common/requester/requesterNodeEntryMissingScenario.js +0 -36
- package/tests/unit/state/apply/common/requesterAddressValidationScenario.js +0 -44
- package/tests/unit/state/apply/common/requesterPublicKeyValidationScenario.js +0 -25
- package/tests/unit/state/apply/common/transactionValidityMismatchScenario.js +0 -98
- package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +0 -202
- package/tests/unit/state/apply/common/validatorConsistency/validatorEntryDecodeFailureScenario.js +0 -17
- package/tests/unit/state/apply/common/validatorConsistency/validatorEntryMissingScenario.js +0 -44
- package/tests/unit/state/apply/common/validatorConsistency/validatorInactiveScenario.js +0 -19
- package/tests/unit/state/apply/common/validatorConsistency/validatorWriterKeyMismatchScenario.js +0 -18
- package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +0 -315
- package/tests/unit/state/apply/common/validatorEntryValidation/validatorEntryInvalidBalanceScenario.js +0 -18
- package/tests/unit/state/apply/common/writerKeyExistsValidationScenario.js +0 -43
- package/tests/unit/state/apply/disableInitialization/disableInitializationAlreadyDisabledScenario.js +0 -53
- package/tests/unit/state/apply/disableInitialization/disableInitializationHappyPathScenario.js +0 -24
- package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +0 -204
- package/tests/unit/state/apply/disableInitialization/state.apply.disableInitialization.test.js +0 -161
- package/tests/unit/state/apply/missing-tests.md +0 -18
- package/tests/unit/state/apply/removeIndexer/removeIndexerHappyPathScenario.js +0 -58
- package/tests/unit/state/apply/removeIndexer/removeIndexerReAddAndRemoveAgainScenario.js +0 -98
- package/tests/unit/state/apply/removeIndexer/removeIndexerRemoveMultipleIndexersScenario.js +0 -167
- package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +0 -429
- package/tests/unit/state/apply/removeIndexer/removeIndexerTargetNotIndexerScenario.js +0 -22
- package/tests/unit/state/apply/removeIndexer/removeIndexerWriterKeyMissingScenario.js +0 -20
- package/tests/unit/state/apply/removeIndexer/state.apply.removeIndexer.test.js +0 -291
- package/tests/unit/state/apply/removeWriter/removeWriterAndAddWriterAgainScenario.js +0 -87
- package/tests/unit/state/apply/removeWriter/removeWriterHappyPathScenario.js +0 -38
- package/tests/unit/state/apply/removeWriter/removeWriterInvalidValidatorSignatureScenario.js +0 -32
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterBalanceInsufficientScenario.js +0 -21
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryDecodeFailureScenario.js +0 -19
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryMissingScenario.js +0 -19
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterIndexerScenario.js +0 -21
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterNotWriterScenario.js +0 -21
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterRoleUpdateFailureScenario.js +0 -19
- package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +0 -348
- package/tests/unit/state/apply/removeWriter/removeWriterThroughWriterValidatorScenario.js +0 -113
- package/tests/unit/state/apply/removeWriter/removeWriterUnstakeFailureScenario.js +0 -33
- package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyMismatchScenario.js +0 -21
- package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyOwnershipScenario.js +0 -26
- package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyRegistryMissingScenario.js +0 -22
- package/tests/unit/state/apply/removeWriter/state.apply.removeWriter.test.js +0 -307
- package/tests/unit/state/apply/state.apply.test.js +0 -24
- package/tests/unit/state/apply/transfer/state.apply.transfer.test.js +0 -819
- package/tests/unit/state/apply/transfer/transferContractSchemaValidationScenario.js +0 -22
- package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +0 -146
- package/tests/unit/state/apply/transfer/transferDoubleSpendSameBatchScenario.js +0 -63
- package/tests/unit/state/apply/transfer/transferDoubleSpendSingleValidatorScenario.js +0 -67
- package/tests/unit/state/apply/transfer/transferExistingRecipientAmountScenario.js +0 -31
- package/tests/unit/state/apply/transfer/transferExistingRecipientZeroAmountScenario.js +0 -31
- package/tests/unit/state/apply/transfer/transferHandlerGuardScenarios.js +0 -22
- package/tests/unit/state/apply/transfer/transferHappyPathScenario.js +0 -8
- package/tests/unit/state/apply/transfer/transferInvalidIncomingDataScenario.js +0 -66
- package/tests/unit/state/apply/transfer/transferNewRecipientAmountScenario.js +0 -31
- package/tests/unit/state/apply/transfer/transferNewRecipientZeroAmountScenario.js +0 -31
- package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +0 -1170
- package/tests/unit/state/apply/transfer/transferSelfTransferAmountScenario.js +0 -38
- package/tests/unit/state/apply/transfer/transferSelfTransferZeroAmountScenario.js +0 -38
- package/tests/unit/state/apply/transfer/transferValidatorRecipientAmountScenario.js +0 -38
- package/tests/unit/state/apply/transfer/transferValidatorRecipientZeroAmountScenario.js +0 -38
- package/tests/unit/state/apply/txOperation/state.apply.txOperation.test.js +0 -318
- package/tests/unit/state/apply/txOperation/txOperationBootstrapNotRegisteredScenario.js +0 -70
- package/tests/unit/state/apply/txOperation/txOperationDifferentValidatorCreatorHappyPathScenario.js +0 -23
- package/tests/unit/state/apply/txOperation/txOperationInvalidDeploymentEntryScenario.js +0 -48
- package/tests/unit/state/apply/txOperation/txOperationInvalidFeeAmountScenario.js +0 -39
- package/tests/unit/state/apply/txOperation/txOperationInvalidSubnetCreatorAddressScenario.js +0 -46
- package/tests/unit/state/apply/txOperation/txOperationRequesterCreatorHappyPathScenario.js +0 -21
- package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +0 -432
- package/tests/unit/state/apply/txOperation/txOperationStandardHappyPathScenario.js +0 -21
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddCreatorBalanceFailureScenario.js +0 -26
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBalanceFailureScenario.js +0 -25
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBonusFailureScenario.js +0 -27
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeCreatorEntryScenario.js +0 -18
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeRequesterEntryScenario.js +0 -17
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeValidatorEntryScenario.js +0 -31
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardBypassScenario.js +0 -49
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +0 -93
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInsufficientRequesterBalanceScenario.js +0 -28
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidCreatorBalanceScenario.js +0 -29
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterBalanceScenario.js +0 -28
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterEntryScenario.js +0 -17
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidValidatorBalanceScenario.js +0 -33
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeMissingCreatorEntryScenario.js +0 -18
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeSubtractFailureScenario.js +0 -25
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateCreatorBalanceFailureScenario.js +0 -26
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateFailureScenario.js +0 -25
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBalanceFailureScenario.js +0 -26
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBonusFailureScenario.js +0 -27
- package/tests/unit/state/apply/txOperation/txOperationValidatorCreatorHappyPathScenario.js +0 -21
- package/tests/unit/state/stateModule.test.js +0 -23
- package/tests/unit/state/stateTestUtils.js +0 -32
- package/tests/unit/state/utils/address.test.js +0 -63
- package/tests/unit/state/utils/adminEntry.test.js +0 -52
- package/tests/unit/state/utils/balance.test.js +0 -320
- package/tests/unit/state/utils/lengthEntry.test.js +0 -54
- package/tests/unit/state/utils/nodeEntry.test.js +0 -298
- package/tests/unit/state/utils/roles.test.js +0 -44
- package/tests/unit/unit.test.js +0 -14
- package/tests/unit/utils/amountSerialization/amountSerialization.test.js +0 -237
- package/tests/unit/utils/buffer/buffer.test.js +0 -251
- package/tests/unit/utils/check/adminControlOperation.test.js +0 -156
- package/tests/unit/utils/check/balanceInitializationOperation.test.js +0 -54
- package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +0 -104
- package/tests/unit/utils/check/check.test.js +0 -17
- package/tests/unit/utils/check/common.test.js +0 -419
- package/tests/unit/utils/check/coreAdminOperation.test.js +0 -95
- package/tests/unit/utils/check/roleAccessOperation.test.js +0 -255
- package/tests/unit/utils/check/transactionOperation.test.js +0 -107
- package/tests/unit/utils/check/transferOperation.test.js +0 -102
- package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +0 -95
- package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +0 -149
- package/tests/unit/utils/helpers/helpers.test.js +0 -11
- package/tests/unit/utils/helpers/isHexString.test.js +0 -12
- package/tests/unit/utils/helpers/normalizeHex.test.js +0 -82
- package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +0 -100
- package/tests/unit/utils/normalizers/normalizers.test.js +0 -469
- package/tests/unit/utils/protobuf/applyOperations.test.js +0 -91
- package/tests/unit/utils/protobuf/operationHelpers.test.js +0 -305
- package/tests/unit/utils/protobuf/protobuf.test.js +0 -12
- package/tests/unit/utils/type/type.test.js +0 -25
- package/tests/unit/utils/utils.test.js +0 -20
- package/whitelist/.gitkeep +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import b4a from 'b4a';
|
|
2
|
-
import {OperationType} from "../../../../../utils/constants.js";
|
|
2
|
+
import {OperationType, ResultCode} from "../../../../../utils/constants.js";
|
|
3
3
|
import {bufferToAddress} from "../../../../state/utils/address.js";
|
|
4
|
-
import
|
|
4
|
+
import PartialOperationValidator from './PartialOperationValidator.js';
|
|
5
5
|
import {bufferToBigInt} from "../../../../../utils/amountSerialization.js";
|
|
6
|
+
import {V1ProtocolError} from '../../v1/V1ProtocolError.js';
|
|
6
7
|
|
|
7
|
-
class
|
|
8
|
+
class PartialRoleAccessValidator extends PartialOperationValidator {
|
|
8
9
|
#config;
|
|
9
10
|
|
|
10
11
|
constructor(state, selfAddress, config) {
|
|
@@ -42,17 +43,26 @@ class PartialRoleAccess extends PartialOperation {
|
|
|
42
43
|
const nodeAddress = bufferToAddress(payload.address, this.#config.addressPrefix);
|
|
43
44
|
const nodeEntry = await this.state.getNodeEntry(nodeAddress);
|
|
44
45
|
if (!nodeEntry) {
|
|
45
|
-
throw new
|
|
46
|
+
throw new V1ProtocolError(
|
|
47
|
+
ResultCode.ROLE_NODE_ENTRY_NOT_FOUND,
|
|
48
|
+
`Node with address ${nodeAddress} entry does not exist.`
|
|
49
|
+
);
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
const isNodeAlreadyWriter = nodeEntry.isWriter;
|
|
49
53
|
if (isNodeAlreadyWriter) {
|
|
50
|
-
throw new
|
|
54
|
+
throw new V1ProtocolError(
|
|
55
|
+
ResultCode.ROLE_NODE_ALREADY_WRITER,
|
|
56
|
+
`Node with address ${nodeAddress} is already a writer.`
|
|
57
|
+
);
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
const isNodeWhitelisted = nodeEntry.isWhitelisted;
|
|
54
61
|
if (!isNodeWhitelisted) {
|
|
55
|
-
throw new
|
|
62
|
+
throw new V1ProtocolError(
|
|
63
|
+
ResultCode.ROLE_NODE_NOT_WHITELISTED,
|
|
64
|
+
`Node with address ${nodeAddress} is not whitelisted.`
|
|
65
|
+
);
|
|
56
66
|
}
|
|
57
67
|
return;
|
|
58
68
|
|
|
@@ -60,24 +70,33 @@ class PartialRoleAccess extends PartialOperation {
|
|
|
60
70
|
const nodeAddress = bufferToAddress(payload.address, this.#config.addressPrefix);
|
|
61
71
|
const nodeEntry = await this.state.getNodeEntry(nodeAddress);
|
|
62
72
|
if (!nodeEntry) {
|
|
63
|
-
throw new
|
|
73
|
+
throw new V1ProtocolError(
|
|
74
|
+
ResultCode.ROLE_NODE_ENTRY_NOT_FOUND,
|
|
75
|
+
`Node with address ${nodeAddress} entry does not exist.`
|
|
76
|
+
);
|
|
64
77
|
}
|
|
65
78
|
|
|
66
79
|
const isAlreadyWriter = nodeEntry.isWriter;
|
|
67
80
|
if (!isAlreadyWriter) {
|
|
68
|
-
throw new
|
|
81
|
+
throw new V1ProtocolError(
|
|
82
|
+
ResultCode.ROLE_NODE_NOT_WRITER,
|
|
83
|
+
`Node with address ${nodeAddress} is not a writer.`
|
|
84
|
+
);
|
|
69
85
|
}
|
|
70
86
|
|
|
71
87
|
const isAlreadyIndexer = nodeEntry.isIndexer;
|
|
72
88
|
if (isAlreadyIndexer) {
|
|
73
|
-
throw new
|
|
89
|
+
throw new V1ProtocolError(
|
|
90
|
+
ResultCode.ROLE_NODE_IS_INDEXER,
|
|
91
|
+
`Node with address ${nodeAddress} is an indexer.`
|
|
92
|
+
);
|
|
74
93
|
}
|
|
75
94
|
return;
|
|
76
95
|
|
|
77
96
|
} else if (type === OperationType.ADMIN_RECOVERY) {
|
|
78
97
|
const adminEntry = await this.state.getAdminEntry();
|
|
79
98
|
if (!adminEntry) {
|
|
80
|
-
throw new
|
|
99
|
+
throw new V1ProtocolError(ResultCode.ROLE_ADMIN_ENTRY_MISSING, 'Admin entry does not exist.');
|
|
81
100
|
}
|
|
82
101
|
|
|
83
102
|
const adminAddressBuffer = payload.address;
|
|
@@ -87,20 +106,29 @@ class PartialRoleAccess extends PartialOperation {
|
|
|
87
106
|
!b4a.equals(payload.rao.iw, adminEntry.wk)
|
|
88
107
|
);
|
|
89
108
|
if (!isRecoveryCase) {
|
|
90
|
-
throw new
|
|
109
|
+
throw new V1ProtocolError(
|
|
110
|
+
ResultCode.ROLE_INVALID_RECOVERY_CASE,
|
|
111
|
+
`Node with address ${adminAddress} is not a valid recovery case.`
|
|
112
|
+
);
|
|
91
113
|
}
|
|
92
114
|
|
|
93
115
|
return;
|
|
94
116
|
}
|
|
95
117
|
|
|
96
|
-
throw new
|
|
118
|
+
throw new V1ProtocolError(
|
|
119
|
+
ResultCode.ROLE_UNKNOWN_OPERATION,
|
|
120
|
+
`Unknown role access operation type: ${type}`
|
|
121
|
+
);
|
|
97
122
|
}
|
|
98
123
|
|
|
99
124
|
async validateWriterKey(payload) {
|
|
100
125
|
const requesterAddress = bufferToAddress(payload.address, this.#config.addressPrefix);
|
|
101
126
|
const nodeEntry = await this.state.getNodeEntry(requesterAddress);
|
|
102
127
|
if (!nodeEntry) {
|
|
103
|
-
throw new
|
|
128
|
+
throw new V1ProtocolError(
|
|
129
|
+
ResultCode.REQUESTER_NOT_FOUND,
|
|
130
|
+
`Node entry not found for address ${requesterAddress}`
|
|
131
|
+
);
|
|
104
132
|
}
|
|
105
133
|
|
|
106
134
|
const writerKey = payload.rao.iw.toString('hex');
|
|
@@ -111,7 +139,10 @@ class PartialRoleAccess extends PartialOperation {
|
|
|
111
139
|
const isOwner = b4a.equals(addressFromRegisteredWritingKey, payload.address);
|
|
112
140
|
|
|
113
141
|
if (!isCurrentWk || !isOwner) {
|
|
114
|
-
throw new
|
|
142
|
+
throw new V1ProtocolError(
|
|
143
|
+
ResultCode.ROLE_INVALID_WRITER_KEY,
|
|
144
|
+
'Invalid writer key: either not owned by requester or different from assigned key'
|
|
145
|
+
);
|
|
115
146
|
}
|
|
116
147
|
}
|
|
117
148
|
}
|
|
@@ -126,15 +157,18 @@ class PartialRoleAccess extends PartialOperation {
|
|
|
126
157
|
}
|
|
127
158
|
|
|
128
159
|
if (!requesterEntry) {
|
|
129
|
-
throw new
|
|
160
|
+
throw new V1ProtocolError(ResultCode.REQUESTER_NOT_FOUND, 'Requester address not found in state');
|
|
130
161
|
}
|
|
131
162
|
const requesterBalance = bufferToBigInt(requesterEntry.balance);
|
|
132
163
|
|
|
133
164
|
const requiredBalance = this.fee * 11n;
|
|
134
165
|
if (requesterBalance < requiredBalance) {
|
|
135
|
-
throw new
|
|
166
|
+
throw new V1ProtocolError(
|
|
167
|
+
ResultCode.ROLE_INSUFFICIENT_FEE_BALANCE,
|
|
168
|
+
'Insufficient requester balance to cover role access operation FEE.'
|
|
169
|
+
);
|
|
136
170
|
}
|
|
137
171
|
}
|
|
138
172
|
}
|
|
139
173
|
|
|
140
|
-
export default
|
|
174
|
+
export default PartialRoleAccessValidator;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import b4a from 'b4a';
|
|
2
2
|
import {safeDecodeApplyOperation} from "../../../../../utils/protobuf/operationHelpers.js";
|
|
3
3
|
import deploymentEntryUtils from "../../../../state/utils/deploymentEntry.js";
|
|
4
|
-
import
|
|
4
|
+
import PartialOperationValidator from './PartialOperationValidator.js';
|
|
5
|
+
import {ResultCode} from "../../../../../utils/constants.js";
|
|
6
|
+
import {V1ProtocolError} from '../../v1/V1ProtocolError.js';
|
|
5
7
|
|
|
6
|
-
class
|
|
8
|
+
class PartialTransactionValidator extends PartialOperationValidator {
|
|
7
9
|
#config
|
|
8
10
|
|
|
9
11
|
constructor(state, selfAddress, config) {
|
|
@@ -32,14 +34,20 @@ class PartialTransaction extends PartialOperation {
|
|
|
32
34
|
|
|
33
35
|
validateMsbBootstrap(payload) {
|
|
34
36
|
if (!b4a.equals(this.#config.bootstrap, payload.txo.mbs)) {
|
|
35
|
-
throw new
|
|
37
|
+
throw new V1ProtocolError(
|
|
38
|
+
ResultCode.MSB_BOOTSTRAP_MISMATCH,
|
|
39
|
+
`Declared MSB bootstrap is different than network bootstrap in transaction operation: ${payload.txo.mbs.toString('hex')}`
|
|
40
|
+
);
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
async validateIfExternalBootstrapHasBeenDeployed(payload) {
|
|
40
45
|
const externalBootstrapResult = await this.state.getRegisteredBootstrapEntry(payload.txo.bs.toString('hex'));
|
|
41
46
|
if (externalBootstrapResult === null) {
|
|
42
|
-
throw new
|
|
47
|
+
throw new V1ProtocolError(
|
|
48
|
+
ResultCode.EXTERNAL_BOOTSTRAP_NOT_DEPLOYED,
|
|
49
|
+
`External bootstrap with hash ${payload.txo.bs.toString('hex')} is not registered as deployment entry.`
|
|
50
|
+
);
|
|
43
51
|
}
|
|
44
52
|
|
|
45
53
|
const decodedPayload = deploymentEntryUtils.decode(externalBootstrapResult, this.#config.addressLength);
|
|
@@ -47,17 +55,23 @@ class PartialTransaction extends PartialOperation {
|
|
|
47
55
|
const getBootstrapTransactionTxPayload = await this.state.get(txHash.toString('hex'));
|
|
48
56
|
|
|
49
57
|
if (getBootstrapTransactionTxPayload === null) {
|
|
50
|
-
throw new
|
|
58
|
+
throw new V1ProtocolError(
|
|
59
|
+
ResultCode.EXTERNAL_BOOTSTRAP_TX_MISSING,
|
|
60
|
+
`External bootstrap is not registered as usual tx ${externalBootstrapResult.toString('hex')}: ${payload}`
|
|
61
|
+
);
|
|
51
62
|
}
|
|
52
63
|
|
|
53
64
|
const decodedBootstrapDeployment = safeDecodeApplyOperation(getBootstrapTransactionTxPayload)
|
|
54
65
|
|
|
55
66
|
// edge case
|
|
56
67
|
if (!b4a.equals(decodedBootstrapDeployment.bdo.bs, payload.txo.bs)) {
|
|
57
|
-
throw new
|
|
68
|
+
throw new V1ProtocolError(
|
|
69
|
+
ResultCode.EXTERNAL_BOOTSTRAP_MISMATCH,
|
|
70
|
+
`External bootstrap does not match the one in the transaction payload: ${decodedBootstrapDeployment.bdo.bs.toString('hex')} !== ${payload.txo.bs.toString('hex')}`
|
|
71
|
+
);
|
|
58
72
|
}
|
|
59
73
|
}
|
|
60
74
|
|
|
61
75
|
}
|
|
62
76
|
|
|
63
|
-
export default
|
|
77
|
+
export default PartialTransactionValidator;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import PeerWallet from 'trac-wallet';
|
|
2
|
-
|
|
3
1
|
import {bufferToAddress} from "../../../../state/utils/address.js";
|
|
4
2
|
import {bufferToBigInt} from "../../../../../utils/amountSerialization.js";
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import {ResultCode} from "../../../../../utils/constants.js";
|
|
4
|
+
import { NULL_BUFFER } from '../../../../../utils/buffer.js';
|
|
5
|
+
import PartialOperationValidator from './PartialOperationValidator.js';
|
|
6
|
+
import {V1ProtocolError} from '../../v1/V1ProtocolError.js';
|
|
7
|
+
import tracCryptoApi from "trac-crypto-api";
|
|
8
|
+
import b4a from 'b4a';
|
|
9
|
+
|
|
10
|
+
class PartialTransferValidator extends PartialOperationValidator {
|
|
8
11
|
#config
|
|
9
12
|
|
|
10
13
|
constructor(state, selfAddress, config) {
|
|
@@ -31,12 +34,18 @@ class PartialTransfer extends PartialOperation {
|
|
|
31
34
|
#validateRecipientAddress(payload) {
|
|
32
35
|
const incomingAddress = bufferToAddress(payload.tro.to, this.#config.addressPrefix);
|
|
33
36
|
if (!incomingAddress) {
|
|
34
|
-
throw new
|
|
37
|
+
throw new V1ProtocolError(
|
|
38
|
+
ResultCode.TRANSFER_RECIPIENT_ADDRESS_INVALID,
|
|
39
|
+
'Invalid recipient address in transfer payload.'
|
|
40
|
+
);
|
|
35
41
|
}
|
|
36
42
|
|
|
37
|
-
const incomingPublicKey =
|
|
38
|
-
if (incomingPublicKey
|
|
39
|
-
throw new
|
|
43
|
+
const incomingPublicKey = tracCryptoApi.address.decodeSafe(incomingAddress);
|
|
44
|
+
if (b4a.equals(incomingPublicKey, NULL_BUFFER)) {
|
|
45
|
+
throw new V1ProtocolError(
|
|
46
|
+
ResultCode.TRANSFER_RECIPIENT_PUBLIC_KEY_INVALID,
|
|
47
|
+
'Invalid recipient public key in transfer payload.'
|
|
48
|
+
);
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
}
|
|
@@ -47,7 +56,10 @@ class PartialTransfer extends PartialOperation {
|
|
|
47
56
|
|
|
48
57
|
const transferAmount = bufferToBigInt(payload.tro.am);
|
|
49
58
|
if (transferAmount > this.max_amount) {
|
|
50
|
-
throw new
|
|
59
|
+
throw new V1ProtocolError(
|
|
60
|
+
ResultCode.TRANSFER_AMOUNT_TOO_LARGE,
|
|
61
|
+
'Transfer amount exceeds maximum allowed value'
|
|
62
|
+
);
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
const isSelfTransfer = senderAddress === recipientAddress;
|
|
@@ -55,12 +67,15 @@ class PartialTransfer extends PartialOperation {
|
|
|
55
67
|
|
|
56
68
|
const senderEntry = await this.state.getNodeEntryUnsigned(senderAddress);
|
|
57
69
|
if (!senderEntry) {
|
|
58
|
-
throw new
|
|
70
|
+
throw new V1ProtocolError(ResultCode.TRANSFER_SENDER_NOT_FOUND, 'Sender account not found');
|
|
59
71
|
}
|
|
60
72
|
|
|
61
73
|
const senderBalance = bufferToBigInt(senderEntry.balance);
|
|
62
74
|
if (!(senderBalance >= totalDeductedAmount)) {
|
|
63
|
-
throw new
|
|
75
|
+
throw new V1ProtocolError(
|
|
76
|
+
ResultCode.TRANSFER_INSUFFICIENT_BALANCE,
|
|
77
|
+
'Insufficient balance for transfer' + (isSelfTransfer ? ' fee' : ' + fee')
|
|
78
|
+
);
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
if (!isSelfTransfer) {
|
|
@@ -69,11 +84,14 @@ class PartialTransfer extends PartialOperation {
|
|
|
69
84
|
const recipientBalance = bufferToBigInt(recipientEntry.balance);
|
|
70
85
|
const newRecipientBalance = recipientBalance + transferAmount;
|
|
71
86
|
if (newRecipientBalance > this.max_amount) {
|
|
72
|
-
throw new
|
|
87
|
+
throw new V1ProtocolError(
|
|
88
|
+
ResultCode.TRANSFER_RECIPIENT_BALANCE_OVERFLOW,
|
|
89
|
+
'Transfer would cause recipient balance to exceed maximum allowed value'
|
|
90
|
+
);
|
|
73
91
|
}
|
|
74
92
|
}
|
|
75
93
|
}
|
|
76
94
|
}
|
|
77
95
|
}
|
|
78
96
|
|
|
79
|
-
export default
|
|
97
|
+
export default PartialTransferValidator;
|
|
@@ -1,15 +1,99 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { decodeV1networkOperation } from '../../../../utils/protobuf/operationHelpers.js'
|
|
2
|
+
import b4a from 'b4a'
|
|
3
|
+
import { NetworkOperationType, V1_PROTOCOL_PAYLOAD_MAX_SIZE } from '../../../../utils/constants.js'
|
|
4
|
+
import { publicKeyToAddress } from '../../../../utils/helpers.js'
|
|
5
|
+
import V1LivenessOperationHandler from './handlers/V1LivenessOperationHandler.js'
|
|
6
|
+
import V1BroadcastTransactionOperationHandler from './handlers/V1BroadcastTransactionOperationHandler.js'
|
|
2
7
|
|
|
3
8
|
class NetworkMessageRouterV1 {
|
|
4
|
-
#config
|
|
9
|
+
#config
|
|
10
|
+
#livenessRequestHandler
|
|
11
|
+
#broadcastTransactionHandler
|
|
5
12
|
|
|
6
|
-
constructor(
|
|
7
|
-
|
|
13
|
+
constructor(
|
|
14
|
+
state,
|
|
15
|
+
wallet,
|
|
16
|
+
rateLimiterService,
|
|
17
|
+
txPoolService,
|
|
18
|
+
pendingRequestsService,
|
|
19
|
+
transactionCommitService,
|
|
20
|
+
config
|
|
21
|
+
) {
|
|
22
|
+
this.#config = config
|
|
23
|
+
this.#livenessRequestHandler = new V1LivenessOperationHandler(
|
|
24
|
+
wallet,
|
|
25
|
+
rateLimiterService,
|
|
26
|
+
pendingRequestsService,
|
|
27
|
+
config
|
|
28
|
+
);
|
|
29
|
+
this.#broadcastTransactionHandler = new V1BroadcastTransactionOperationHandler(
|
|
30
|
+
state,
|
|
31
|
+
wallet,
|
|
32
|
+
rateLimiterService,
|
|
33
|
+
txPoolService,
|
|
34
|
+
pendingRequestsService,
|
|
35
|
+
transactionCommitService,
|
|
36
|
+
config
|
|
37
|
+
);
|
|
8
38
|
}
|
|
9
39
|
|
|
10
|
-
async route(incomingMessage) {
|
|
11
|
-
|
|
40
|
+
async route(incomingMessage, connection) {
|
|
41
|
+
if (!this.#preValidate(incomingMessage)) {
|
|
42
|
+
this.#disconnect(connection, 'Pre-validation failed for incoming V1 message')
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
let decodedMessage;
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
decodedMessage = decodeV1networkOperation(incomingMessage)
|
|
49
|
+
} catch (error) {
|
|
50
|
+
this.#disconnect(connection, `Failed to decode incoming V1 message: ${error.message}`)
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// TODO: Decide if we really need to check decodedMessage.type here, since this is done
|
|
55
|
+
// again in the next switch statement
|
|
56
|
+
if (!decodedMessage || !Number.isInteger(decodedMessage.type) || decodedMessage.type <= 0) {
|
|
57
|
+
this.#disconnect(connection, `Invalid V1 message type: ${decodedMessage?.type}`)
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// We received a v1 message, so we set the connection protocol accordingly
|
|
62
|
+
connection.protocolSession.setV1AsPreferredProtocol()
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
switch (decodedMessage.type) {
|
|
66
|
+
case NetworkOperationType.LIVENESS_REQUEST:
|
|
67
|
+
await this.#livenessRequestHandler.handleRequest(decodedMessage, connection);
|
|
68
|
+
break;
|
|
69
|
+
case NetworkOperationType.LIVENESS_RESPONSE:
|
|
70
|
+
await this.#livenessRequestHandler.handleResponse(decodedMessage, connection);
|
|
71
|
+
break;
|
|
72
|
+
|
|
73
|
+
case NetworkOperationType.BROADCAST_TRANSACTION_REQUEST:
|
|
74
|
+
await this.#broadcastTransactionHandler.handleRequest(decodedMessage, connection);
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
case NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE:
|
|
78
|
+
await this.#broadcastTransactionHandler.handleResponse(decodedMessage, connection);
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
this.#disconnect(connection, `Unsupported V1 message type: ${decodedMessage.type}`)
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
this.#disconnect(connection, `Unhandled error while routing V1 message: ${error.message}`)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#preValidate(incomingMessage) {
|
|
89
|
+
return !(!incomingMessage || !b4a.isBuffer(incomingMessage) || incomingMessage.length === 0 || incomingMessage.length > V1_PROTOCOL_PAYLOAD_MAX_SIZE);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
#disconnect(connection, reason) {
|
|
93
|
+
const sender = publicKeyToAddress(connection.remotePublicKey, this.#config)
|
|
94
|
+
console.error(`NetworkMessageRouterV1: ${reason}, sender: ${sender}`)
|
|
95
|
+
connection.end();
|
|
12
96
|
}
|
|
13
97
|
}
|
|
14
98
|
|
|
15
|
-
export default NetworkMessageRouterV1
|
|
99
|
+
export default NetworkMessageRouterV1
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {ResultCode} from '../../../../utils/constants.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* V1 protocol error type.
|
|
5
|
+
*
|
|
6
|
+
* `V1ProtocolError` is the v1 base class used by handlers/validators to attach:
|
|
7
|
+
* - `resultCode`: a stable `ResultCode` enum value for programmatic handling
|
|
8
|
+
*/
|
|
9
|
+
export class V1ProtocolError extends Error {
|
|
10
|
+
/**
|
|
11
|
+
* @param {number} resultCode Stable rejection reason (a `ResultCode` enum value).
|
|
12
|
+
* @param {string} message Human-readable error message.
|
|
13
|
+
*/
|
|
14
|
+
constructor(resultCode, message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = this.constructor.name;
|
|
17
|
+
this.resultCode = resultCode;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getResultCode(err) {
|
|
22
|
+
return err instanceof V1ProtocolError ? err.resultCode : ResultCode.UNEXPECTED_ERROR;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function shouldEndConnection(err) {
|
|
26
|
+
return err instanceof V1ProtocolError ? Boolean(err.endConnection) : false;
|
|
27
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {ResultCode} from "../../../../../utils/constants.js";
|
|
2
|
+
import {publicKeyToAddress} from "../../../../../utils/helpers.js";
|
|
3
|
+
import {V1ProtocolError} from "../V1ProtocolError.js";
|
|
4
|
+
|
|
5
|
+
class V1BaseOperationHandler {
|
|
6
|
+
#rateLimiterService;
|
|
7
|
+
#pendingRequestService;
|
|
8
|
+
#config;
|
|
9
|
+
|
|
10
|
+
constructor(rateLimiterService, pendingRequestService, config) {
|
|
11
|
+
this.#rateLimiterService = rateLimiterService;
|
|
12
|
+
this.#pendingRequestService = pendingRequestService;
|
|
13
|
+
this.#config = config;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get config() {
|
|
17
|
+
return this.#config;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
applyRateLimit(connection) {
|
|
21
|
+
if (!this.#config.disableRateLimit) {
|
|
22
|
+
this.#rateLimiterService.v1HandleRateLimit(connection);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async resolvePendingResponse(message, connection, validator, extractResultCode) {
|
|
27
|
+
const pendingRequestServiceEntry = this.#pendingRequestService.getPendingRequest(message.id);
|
|
28
|
+
if (!pendingRequestServiceEntry) return false;
|
|
29
|
+
|
|
30
|
+
this.#pendingRequestService.stopPendingRequestTimeout(message.id);
|
|
31
|
+
await validator.validate(message, connection, pendingRequestServiceEntry);
|
|
32
|
+
|
|
33
|
+
const resultCode = extractResultCode(message);
|
|
34
|
+
this.#pendingRequestService.resolvePendingRequest(message.id, resultCode);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
handlePendingResponseError(messageId, connection, error, step) {
|
|
39
|
+
const protocolError = this.#toProtocolError(error);
|
|
40
|
+
const rejected = this.#pendingRequestService.rejectPendingRequest(messageId, protocolError);
|
|
41
|
+
if (!rejected) return;
|
|
42
|
+
this.displayError(step, connection.remotePublicKey, protocolError);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async sendResponseAndMaybeClose(connection, response, endConnection) {
|
|
46
|
+
connection.protocolSession.sendAndForget(response);
|
|
47
|
+
if (!endConnection) return;
|
|
48
|
+
|
|
49
|
+
await connection.flush();
|
|
50
|
+
connection.end();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
displayError(step = "undefined step", senderPublicKey, error) {
|
|
54
|
+
const errorMessage = error?.message ?? 'Unexpected error';
|
|
55
|
+
console.error(`${this.constructor.name}: ${step} ${publicKeyToAddress(senderPublicKey, this.#config)}: ${errorMessage}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#toProtocolError(error) {
|
|
59
|
+
if (error instanceof V1ProtocolError) {
|
|
60
|
+
return error;
|
|
61
|
+
}
|
|
62
|
+
return new V1ProtocolError(ResultCode.UNEXPECTED_ERROR, error?.message ?? 'Unexpected error');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default V1BaseOperationHandler;
|