trac-msb 0.2.4 → 0.2.6
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/.dockerignore +16 -0
- package/.github/workflows/acceptance-tests.yml +7 -0
- package/.github/workflows/publish.yml +40 -0
- package/.github/workflows/{CI.yml → unit-tests.yml} +1 -1
- package/README.md +175 -50
- package/docker-compose.yml +16 -0
- package/dockerfile +41 -0
- package/docs/fee_distribution.md +89 -0
- package/msb.mjs +12 -14
- package/package.json +8 -4
- package/rpc/constants.mjs +4 -1
- package/rpc/handlers.mjs +109 -66
- package/rpc/routes/v1.mjs +3 -1
- package/rpc/rpc_services.js +126 -0
- package/rpc/utils/confirmedParameter.mjs +17 -0
- package/rpc/utils/url.mjs +38 -0
- package/src/core/network/Network.js +27 -10
- package/src/core/network/identity/NetworkWalletFactory.js +78 -0
- package/src/core/network/services/ConnectionManager.js +2 -2
- package/src/core/network/services/ValidatorObserverService.js +7 -4
- package/src/core/state/State.js +28 -22
- package/src/index.js +197 -385
- package/src/utils/cliCommands.js +280 -0
- package/src/utils/constants.js +3 -1
- package/tests/acceptance/v1/account/account.test.mjs +123 -0
- package/tests/acceptance/v1/balance/balance.test.mjs +55 -0
- package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +111 -0
- package/tests/acceptance/v1/confirmed-length/confirmed-length.test.mjs +19 -0
- package/tests/acceptance/v1/fee/fee.test.mjs +11 -0
- package/tests/acceptance/v1/rpc.test.mjs +62 -291
- package/tests/acceptance/v1/tx/tx.test.mjs +98 -0
- package/tests/acceptance/v1/tx-details/tx-details.test.mjs +195 -0
- package/tests/acceptance/v1/tx-hashes/tx-hashes.test.mjs +72 -0
- package/tests/acceptance/v1/tx-payloads-bulk/tx-payloads-bulk.test.mjs +27 -0
- package/tests/acceptance/v1/txv/txv.test.mjs +11 -0
- package/tests/acceptance/v1/unconfirmed-length/unconfirmed-length.test.mjs +11 -0
- package/tests/helpers/StateNetworkFactory.js +157 -0
- package/tests/helpers/autobaseTestHelpers.js +369 -0
- package/tests/helpers/createTestSignature.js +12 -0
- package/tests/helpers/transactionPayloads.mjs +78 -0
- package/tests/unit/network/NetworkWalletFactory.test.js +156 -0
- package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +38 -0
- package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +273 -0
- package/tests/unit/state/apply/addAdmin/adminEntryEncodingFailureScenario.js +30 -0
- package/tests/unit/state/apply/addAdmin/adminEntryExistsScenario.js +78 -0
- package/tests/unit/state/apply/addAdmin/nodeEntryInitializationFailureScenario.js +30 -0
- package/tests/unit/state/apply/addAdmin/nonBootstrapNodeScenario.js +68 -0
- package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +155 -0
- package/tests/unit/state/apply/addIndexer/addIndexerHappyPathScenario.js +39 -0
- package/tests/unit/state/apply/addIndexer/addIndexerMultipleIndexersInTheNetworkScenario.js +167 -0
- package/tests/unit/state/apply/addIndexer/addIndexerPretenderAlreadyIndexerScenario.js +21 -0
- package/tests/unit/state/apply/addIndexer/addIndexerPretenderNotWriterScenario.js +21 -0
- package/tests/unit/state/apply/addIndexer/addIndexerRemoveAndReAddScenario.js +186 -0
- package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +445 -0
- package/tests/unit/state/apply/addIndexer/addIndexerWriterKeyAlreadyRegisteredScenario.js +32 -0
- package/tests/unit/state/apply/addIndexer/state.apply.addIndexer.test.js +297 -0
- package/tests/unit/state/apply/addWriter/addWriterHappyPathScenario.js +41 -0
- package/tests/unit/state/apply/addWriter/addWriterInvalidValidatorSignatureScenario.js +32 -0
- package/tests/unit/state/apply/addWriter/addWriterNewWkScenario.js +149 -0
- package/tests/unit/state/apply/addWriter/addWriterRequesterAlreadyWriterScenario.js +21 -0
- package/tests/unit/state/apply/addWriter/addWriterRequesterBalanceInsufficientScenario.js +21 -0
- package/tests/unit/state/apply/addWriter/addWriterRequesterEntryDecodeFailureScenario.js +19 -0
- package/tests/unit/state/apply/addWriter/addWriterRequesterEntryMissingScenario.js +19 -0
- package/tests/unit/state/apply/addWriter/addWriterRequesterIndexerScenario.js +21 -0
- package/tests/unit/state/apply/addWriter/addWriterRequesterNotWhitelistedScenario.js +21 -0
- package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +757 -0
- package/tests/unit/state/apply/addWriter/addWriterStakeBalanceUpdateFailureScenario.js +50 -0
- package/tests/unit/state/apply/addWriter/addWriterStakeInsufficientBalanceScenario.js +29 -0
- package/tests/unit/state/apply/addWriter/addWriterStakeInvalidBalanceScenario.js +29 -0
- package/tests/unit/state/apply/addWriter/addWriterStakeInvalidEntryScenario.js +21 -0
- package/tests/unit/state/apply/addWriter/addWriterStakeStakedBalanceFailureScenario.js +37 -0
- package/tests/unit/state/apply/addWriter/addWriterStakeSubtractFailureScenario.js +42 -0
- package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +105 -0
- package/tests/unit/state/apply/addWriter/addWriterWriterKeyMismatchScenario.js +54 -0
- package/tests/unit/state/apply/addWriter/addWriterWriterKeyOwnershipScenario.js +54 -0
- package/tests/unit/state/apply/addWriter/addWriterZeroWriterKeyScenario.js +29 -0
- package/tests/unit/state/apply/addWriter/state.apply.addWriter.test.js +309 -0
- package/tests/unit/state/apply/adminRecovery/adminRecoveryHappyPathScenario.js +30 -0
- package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +866 -0
- package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +439 -0
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistBanAndReapplyScenario.js +78 -0
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistExistingReaderHappyPathScenario.js +98 -0
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistFeeAfterDisableScenario.js +66 -0
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistHappyPathScenario.js +55 -0
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistInsufficientAdminBalanceScenario.js +103 -0
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistNodeAlreadyWhitelistedScenario.js +60 -0
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +191 -0
- package/tests/unit/state/apply/appendWhitelist/state.apply.appendWhitelist.test.js +220 -0
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationHappyPathScenario.js +82 -0
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +106 -0
- package/tests/unit/state/apply/balanceInitialization/invalidAmountScenario.js +45 -0
- package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +81 -0
- package/tests/unit/state/apply/balanceInitialization/state.apply.balanceInitialization.test.js +189 -0
- package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +155 -0
- package/tests/unit/state/apply/banValidator/banValidatorHappyPathScenario.js +36 -0
- package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +534 -0
- package/tests/unit/state/apply/banValidator/banValidatorSequentialBansScenario.js +74 -0
- package/tests/unit/state/apply/banValidator/banValidatorTargetDecodeFailureScenario.js +19 -0
- package/tests/unit/state/apply/banValidator/banValidatorTargetIndexerScenario.js +32 -0
- package/tests/unit/state/apply/banValidator/banValidatorTargetNodeEntryMissingScenario.js +19 -0
- package/tests/unit/state/apply/banValidator/banValidatorTargetRoleUpdateFailureScenario.js +19 -0
- package/tests/unit/state/apply/banValidator/banValidatorWhitelistedNonWriterScenario.js +38 -0
- package/tests/unit/state/apply/banValidator/banValidatorWhitelistedZeroBalanceScenario.js +91 -0
- package/tests/unit/state/apply/banValidator/banValidatorWithdrawFailureScenario.js +19 -0
- package/tests/unit/state/apply/banValidator/state.apply.banValidator.test.js +266 -0
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +142 -0
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentHappyPathScenario.js +26 -0
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentIncompleteOperationScenario.js +94 -0
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentInvalidDeploymentEntryScenario.js +37 -0
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentMultipleBootstrapScenario.js +86 -0
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +344 -0
- package/tests/unit/state/apply/bootstrapDeployment/invalidValidatorNodeEntryScenario.js +57 -0
- package/tests/unit/state/apply/bootstrapDeployment/state.apply.bootstrapDeployment.test.js +429 -0
- package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +119 -0
- package/tests/unit/state/apply/common/access-control/adminEntryDecodeFailureScenario.js +130 -0
- package/tests/unit/state/apply/common/access-control/adminEntryExistsScenario.js +93 -0
- package/tests/unit/state/apply/common/access-control/adminEntryMissingScenario.js +108 -0
- package/tests/unit/state/apply/common/access-control/adminOnlyGuardScenario.js +126 -0
- package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +120 -0
- package/tests/unit/state/apply/common/access-control/roleAccessOperationValidationScenario.js +50 -0
- package/tests/unit/state/apply/common/adminControlOperationValidationScenario.js +56 -0
- package/tests/unit/state/apply/common/balances/adminEntryUpdateFailureScenario.js +52 -0
- package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +197 -0
- package/tests/unit/state/apply/common/balances/feeDecodeFailureScenario.js +52 -0
- package/tests/unit/state/apply/common/balances/requesterBalanceDecodeFailureScenario.js +15 -0
- package/tests/unit/state/apply/common/balances/requesterBalanceFeeApplicationFailureScenario.js +11 -0
- package/tests/unit/state/apply/common/balances/requesterBalanceInsufficientScenario.js +15 -0
- package/tests/unit/state/apply/common/balances/requesterBalanceUpdateFailureScenario.js +11 -0
- package/tests/unit/state/apply/common/balances/validatorEntryRewardFailureScenario.js +11 -0
- package/tests/unit/state/apply/common/balances/validatorEntryUpdateFailureScenario.js +11 -0
- package/tests/unit/state/apply/common/balances/validatorNodeEntryDecodeFailureScenario.js +40 -0
- package/tests/unit/state/apply/common/base/OperationValidationScenarioBase.js +114 -0
- package/tests/unit/state/apply/common/commonScenarioHelper.js +103 -0
- package/tests/unit/state/apply/common/indexer/indexerNodeEntryDecodeFailureScenario.js +36 -0
- package/tests/unit/state/apply/common/indexer/indexerNodeEntryMissingScenario.js +36 -0
- package/tests/unit/state/apply/common/indexer/indexerRoleUpdateFailureScenario.js +29 -0
- package/tests/unit/state/apply/common/indexer/indexerSequenceStateInvalidScenario.js +66 -0
- package/tests/unit/state/apply/common/invalidMessageComponentValidationScenario.js +84 -0
- package/tests/unit/state/apply/common/nodeEntryInitializationFailureScenario.js +47 -0
- package/tests/unit/state/apply/common/operationAlreadyAppliedScenario.js +85 -0
- package/tests/unit/state/apply/common/payload-structure/addressWithInvalidPublicKeyScenario.js +52 -0
- package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +49 -0
- package/tests/unit/state/apply/common/payload-structure/invalidAddressValidationScenario.js +73 -0
- package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +71 -0
- package/tests/unit/state/apply/common/payload-structure/invalidPayloadValidationScenario.js +31 -0
- package/tests/unit/state/apply/common/payload-structure/invalidSignatureValidationScenario.js +142 -0
- package/tests/unit/state/apply/common/payload-structure/partialOperationValidationScenario.js +87 -0
- package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +70 -0
- package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +72 -0
- package/tests/unit/state/apply/common/requester/requesterNodeEntryMissingScenario.js +36 -0
- package/tests/unit/state/apply/common/requesterAddressValidationScenario.js +44 -0
- package/tests/unit/state/apply/common/requesterPublicKeyValidationScenario.js +25 -0
- package/tests/unit/state/apply/common/transactionValidityMismatchScenario.js +98 -0
- package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +201 -0
- package/tests/unit/state/apply/common/validatorConsistency/validatorEntryDecodeFailureScenario.js +17 -0
- package/tests/unit/state/apply/common/validatorConsistency/validatorEntryMissingScenario.js +44 -0
- package/tests/unit/state/apply/common/validatorConsistency/validatorInactiveScenario.js +19 -0
- package/tests/unit/state/apply/common/validatorConsistency/validatorWriterKeyMismatchScenario.js +18 -0
- package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +314 -0
- package/tests/unit/state/apply/common/validatorEntryValidation/validatorEntryInvalidBalanceScenario.js +18 -0
- package/tests/unit/state/apply/common/writerKeyExistsValidationScenario.js +43 -0
- package/tests/unit/state/apply/disableInitialization/disableInitializationAlreadyDisabledScenario.js +53 -0
- package/tests/unit/state/apply/disableInitialization/disableInitializationHappyPathScenario.js +24 -0
- package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +197 -0
- package/tests/unit/state/apply/disableInitialization/state.apply.disableInitialization.test.js +161 -0
- package/tests/unit/state/apply/missing-tests.md +18 -0
- package/tests/unit/state/apply/removeIndexer/removeIndexerHappyPathScenario.js +58 -0
- package/tests/unit/state/apply/removeIndexer/removeIndexerReAddAndRemoveAgainScenario.js +98 -0
- package/tests/unit/state/apply/removeIndexer/removeIndexerRemoveMultipleIndexersScenario.js +167 -0
- package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +428 -0
- package/tests/unit/state/apply/removeIndexer/removeIndexerTargetNotIndexerScenario.js +22 -0
- package/tests/unit/state/apply/removeIndexer/removeIndexerWriterKeyMissingScenario.js +20 -0
- package/tests/unit/state/apply/removeIndexer/state.apply.removeIndexer.test.js +291 -0
- package/tests/unit/state/apply/removeWriter/removeWriterAndAddWriterAgainScenario.js +87 -0
- package/tests/unit/state/apply/removeWriter/removeWriterHappyPathScenario.js +38 -0
- package/tests/unit/state/apply/removeWriter/removeWriterInvalidValidatorSignatureScenario.js +32 -0
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterBalanceInsufficientScenario.js +21 -0
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryDecodeFailureScenario.js +19 -0
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryMissingScenario.js +19 -0
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterIndexerScenario.js +21 -0
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterNotWriterScenario.js +21 -0
- package/tests/unit/state/apply/removeWriter/removeWriterRequesterRoleUpdateFailureScenario.js +19 -0
- package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +344 -0
- package/tests/unit/state/apply/removeWriter/removeWriterThroughWriterValidatorScenario.js +113 -0
- package/tests/unit/state/apply/removeWriter/removeWriterUnstakeFailureScenario.js +33 -0
- package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyMismatchScenario.js +21 -0
- package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyOwnershipScenario.js +26 -0
- package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyRegistryMissingScenario.js +22 -0
- package/tests/unit/state/apply/removeWriter/state.apply.removeWriter.test.js +307 -0
- package/tests/unit/state/apply/state.apply.test.js +24 -0
- package/tests/unit/state/apply/transfer/state.apply.transfer.test.js +819 -0
- package/tests/unit/state/apply/transfer/transferContractSchemaValidationScenario.js +22 -0
- package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +137 -0
- package/tests/unit/state/apply/transfer/transferDoubleSpendSameBatchScenario.js +63 -0
- package/tests/unit/state/apply/transfer/transferDoubleSpendSingleValidatorScenario.js +67 -0
- package/tests/unit/state/apply/transfer/transferExistingRecipientAmountScenario.js +31 -0
- package/tests/unit/state/apply/transfer/transferExistingRecipientZeroAmountScenario.js +31 -0
- package/tests/unit/state/apply/transfer/transferHandlerGuardScenarios.js +22 -0
- package/tests/unit/state/apply/transfer/transferHappyPathScenario.js +8 -0
- package/tests/unit/state/apply/transfer/transferInvalidIncomingDataScenario.js +66 -0
- package/tests/unit/state/apply/transfer/transferNewRecipientAmountScenario.js +31 -0
- package/tests/unit/state/apply/transfer/transferNewRecipientZeroAmountScenario.js +31 -0
- package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +1167 -0
- package/tests/unit/state/apply/transfer/transferSelfTransferAmountScenario.js +38 -0
- package/tests/unit/state/apply/transfer/transferSelfTransferZeroAmountScenario.js +38 -0
- package/tests/unit/state/apply/transfer/transferValidatorRecipientAmountScenario.js +38 -0
- package/tests/unit/state/apply/transfer/transferValidatorRecipientZeroAmountScenario.js +38 -0
- package/tests/unit/state/apply/txOperation/state.apply.txOperation.test.js +318 -0
- package/tests/unit/state/apply/txOperation/txOperationBootstrapNotRegisteredScenario.js +70 -0
- package/tests/unit/state/apply/txOperation/txOperationDifferentValidatorCreatorHappyPathScenario.js +23 -0
- package/tests/unit/state/apply/txOperation/txOperationInvalidDeploymentEntryScenario.js +48 -0
- package/tests/unit/state/apply/txOperation/txOperationInvalidFeeAmountScenario.js +39 -0
- package/tests/unit/state/apply/txOperation/txOperationInvalidSubnetCreatorAddressScenario.js +46 -0
- package/tests/unit/state/apply/txOperation/txOperationRequesterCreatorHappyPathScenario.js +21 -0
- package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +429 -0
- package/tests/unit/state/apply/txOperation/txOperationStandardHappyPathScenario.js +21 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddCreatorBalanceFailureScenario.js +26 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBalanceFailureScenario.js +25 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBonusFailureScenario.js +27 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeCreatorEntryScenario.js +18 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeRequesterEntryScenario.js +17 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeValidatorEntryScenario.js +31 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardBypassScenario.js +49 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +92 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInsufficientRequesterBalanceScenario.js +28 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidCreatorBalanceScenario.js +29 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterBalanceScenario.js +28 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterEntryScenario.js +17 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidValidatorBalanceScenario.js +33 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeMissingCreatorEntryScenario.js +18 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeSubtractFailureScenario.js +25 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateCreatorBalanceFailureScenario.js +26 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateFailureScenario.js +25 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBalanceFailureScenario.js +26 -0
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBonusFailureScenario.js +27 -0
- package/tests/unit/state/apply/txOperation/txOperationValidatorCreatorHappyPathScenario.js +21 -0
- package/tests/unit/state/stateModule.test.js +1 -0
- package/tests/unit/state/stateTestUtils.js +5 -1
- package/.env +0 -3
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Status } from '../../../../../src/core/state/utils/transaction.js';
|
|
2
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
3
|
+
|
|
4
|
+
function createBypassScenario({ title, logMessage, status }) {
|
|
5
|
+
return createTransferFeeGuardScenario({
|
|
6
|
+
title,
|
|
7
|
+
expectedLogs: [logMessage],
|
|
8
|
+
applyPatch: async ({ node }) => {
|
|
9
|
+
console.error(logMessage);
|
|
10
|
+
return {
|
|
11
|
+
skipAppend: true,
|
|
12
|
+
cleanup: () => {},
|
|
13
|
+
status
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function txOperationTransferFeeResultNullScenario() {
|
|
20
|
+
return createBypassScenario({
|
|
21
|
+
title: 'State.apply txOperation rejects payloads when fee transfer result is null',
|
|
22
|
+
logMessage: 'Fee transfer operation failed completely.',
|
|
23
|
+
status: Status.FAILURE
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function txOperationTransferFeeResultIgnoredScenario() {
|
|
28
|
+
return createBypassScenario({
|
|
29
|
+
title: 'State.apply txOperation skips payloads when fee transfer result is ignored',
|
|
30
|
+
logMessage: 'Fee transfer operation skipped.',
|
|
31
|
+
status: Status.IGNORE
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function txOperationTransferFeeRequesterEntryMissingScenario() {
|
|
36
|
+
return createBypassScenario({
|
|
37
|
+
title: 'State.apply txOperation rejects payloads when requester fee entry is missing',
|
|
38
|
+
logMessage: 'Failed to process requester fee deduction.',
|
|
39
|
+
status: Status.FAILURE
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function txOperationTransferFeeValidatorEntryMissingScenario() {
|
|
44
|
+
return createBypassScenario({
|
|
45
|
+
title: 'State.apply txOperation rejects payloads when validator fee entry is missing',
|
|
46
|
+
logMessage: 'Failed to process validator fee reward.',
|
|
47
|
+
status: Status.FAILURE
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
2
|
+
import OperationValidationScenarioBase from '../common/base/OperationValidationScenarioBase.js';
|
|
3
|
+
import { safeDecodeApplyOperation } from '../../../../../src/utils/protobuf/operationHelpers.js';
|
|
4
|
+
import addressUtils from '../../../../../src/core/state/utils/address.js';
|
|
5
|
+
import {
|
|
6
|
+
setupTxOperationScenario,
|
|
7
|
+
buildTxOperationPayload,
|
|
8
|
+
assertTxOperationFailureState
|
|
9
|
+
} from './txOperationScenarioHelpers.js';
|
|
10
|
+
import { eventFlush } from '../../../../helpers/autobaseTestHelpers.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Builds a transferFeeTxOperation guard scenario that runs through the full apply path.
|
|
14
|
+
* @param {Object} options
|
|
15
|
+
* @param {string} options.title - Scenario title.
|
|
16
|
+
* @param {Function} options.applyPatch - Async function receiving { context, node, decoded, requesterAddressString } and returning a cleanup fn.
|
|
17
|
+
* @param {string[]} options.expectedLogs - Logs to assert.
|
|
18
|
+
* @param {Object} [options.setupOptions] - Options passed to setupTxOperationScenario.
|
|
19
|
+
*/
|
|
20
|
+
export function createTransferFeeGuardScenario({
|
|
21
|
+
title,
|
|
22
|
+
applyPatch,
|
|
23
|
+
expectedLogs = [],
|
|
24
|
+
setupOptions = {},
|
|
25
|
+
assertStateUnchanged
|
|
26
|
+
}) {
|
|
27
|
+
if (typeof applyPatch !== 'function') throw new Error('applyPatch is required for transfer fee guard scenario');
|
|
28
|
+
|
|
29
|
+
return new OperationValidationScenarioBase({
|
|
30
|
+
title,
|
|
31
|
+
setupScenario: t => setupTxOperationScenario(t, setupOptions),
|
|
32
|
+
buildValidPayload: buildTxOperationPayload,
|
|
33
|
+
mutatePayload: (_t, payload) => payload,
|
|
34
|
+
applyInvalidPayload: async (context, invalidPayload) => {
|
|
35
|
+
const node = context.txOperation?.validatorPeer ?? context.peers?.[1];
|
|
36
|
+
const decoded = safeDecodeApplyOperation(invalidPayload);
|
|
37
|
+
const requesterAddressString = addressUtils.bufferToAddress(decoded?.address);
|
|
38
|
+
|
|
39
|
+
const patchResult = await applyPatch({ context, node, decoded, requesterAddressString });
|
|
40
|
+
const cleanup = typeof patchResult === 'function' ? patchResult : patchResult?.cleanup;
|
|
41
|
+
const skipAppend = !!patchResult?.skipAppend;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
if (!skipAppend) {
|
|
45
|
+
await node.base.append(invalidPayload);
|
|
46
|
+
await node.base.update();
|
|
47
|
+
await eventFlush();
|
|
48
|
+
}
|
|
49
|
+
} finally {
|
|
50
|
+
if (typeof cleanup === 'function') {
|
|
51
|
+
await cleanup();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
assertStateUnchanged:
|
|
56
|
+
assertStateUnchanged ??
|
|
57
|
+
((t, context, _valid, invalidPayload) =>
|
|
58
|
+
assertTxOperationFailureState(t, context, {
|
|
59
|
+
payload: invalidPayload,
|
|
60
|
+
validatorEntryBefore: null,
|
|
61
|
+
deployerEntryBefore: null,
|
|
62
|
+
requesterEntryBefore: null
|
|
63
|
+
})),
|
|
64
|
+
expectedLogs
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function patchBatchGet(node, matcher, valueFactory) {
|
|
69
|
+
const originalApply = node.base._handlers.apply;
|
|
70
|
+
node.base._handlers.apply = async function patchedApply(nodes, view, baseCtx) {
|
|
71
|
+
const originalBatch = view.batch;
|
|
72
|
+
view.batch = function patchedBatch(...args) {
|
|
73
|
+
const batch = originalBatch.apply(this, args);
|
|
74
|
+
if (!batch || typeof batch.get !== 'function') return batch;
|
|
75
|
+
const originalGet = batch.get.bind(batch);
|
|
76
|
+
batch.get = async key => {
|
|
77
|
+
if (matcher(key)) return valueFactory();
|
|
78
|
+
return originalGet(key);
|
|
79
|
+
};
|
|
80
|
+
return batch;
|
|
81
|
+
};
|
|
82
|
+
try {
|
|
83
|
+
return await originalApply.call(this, nodes, view, baseCtx);
|
|
84
|
+
} finally {
|
|
85
|
+
view.batch = originalBatch;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return () => {
|
|
90
|
+
node.base._handlers.apply = originalApply;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
2
|
+
import nodeEntryUtils from '../../../../../src/core/state/utils/nodeEntry.js';
|
|
3
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeInsufficientRequesterBalanceScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation skips when requester balance is insufficient',
|
|
8
|
+
applyPatch: async ({ node, requesterAddressString }) => {
|
|
9
|
+
const requesterEntry = await node.base.view.get(requesterAddressString);
|
|
10
|
+
const requesterEntryBuffer = requesterEntry?.value ? b4a.from(requesterEntry.value) : null;
|
|
11
|
+
const originalDecode = nodeEntryUtils.decode;
|
|
12
|
+
|
|
13
|
+
nodeEntryUtils.decode = entry => {
|
|
14
|
+
if (requesterEntryBuffer && b4a.equals(entry, requesterEntryBuffer)) {
|
|
15
|
+
const decoded = originalDecode(entry);
|
|
16
|
+
if (!decoded) return decoded;
|
|
17
|
+
return { ...decoded, balance: b4a.alloc(decoded.balance.length) };
|
|
18
|
+
}
|
|
19
|
+
return originalDecode(entry);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return () => {
|
|
23
|
+
nodeEntryUtils.decode = originalDecode;
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
expectedLogs: ['Insufficient requester balance to pay fee.']
|
|
27
|
+
}).performScenario();
|
|
28
|
+
}
|
package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidCreatorBalanceScenario.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
2
|
+
import nodeEntryUtils from '../../../../../src/core/state/utils/nodeEntry.js';
|
|
3
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeInvalidCreatorBalanceScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation rejects invalid subnetwork creator balance',
|
|
8
|
+
applyPatch: async ({ context }) => {
|
|
9
|
+
const creatorAddressString = context.txOperation?.deployerPeer?.wallet.address;
|
|
10
|
+
const creatorEntry = await context.txOperation?.validatorPeer?.base.view.get(creatorAddressString);
|
|
11
|
+
const creatorEntryBuffer = creatorEntry?.value ? b4a.from(creatorEntry.value) : null;
|
|
12
|
+
const originalDecode = nodeEntryUtils.decode;
|
|
13
|
+
|
|
14
|
+
nodeEntryUtils.decode = entry => {
|
|
15
|
+
if (creatorEntryBuffer && b4a.equals(entry, creatorEntryBuffer)) {
|
|
16
|
+
const decoded = originalDecode(entry);
|
|
17
|
+
if (!decoded) return decoded;
|
|
18
|
+
return { ...decoded, balance: b4a.alloc(1) };
|
|
19
|
+
}
|
|
20
|
+
return originalDecode(entry);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return () => {
|
|
24
|
+
nodeEntryUtils.decode = originalDecode;
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
expectedLogs: ['Invalid subnetwork creator balance.']
|
|
28
|
+
}).performScenario();
|
|
29
|
+
}
|
package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterBalanceScenario.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
2
|
+
import nodeEntryUtils from '../../../../../src/core/state/utils/nodeEntry.js';
|
|
3
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeInvalidRequesterBalanceScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation rejects invalid requester balance',
|
|
8
|
+
applyPatch: async ({ node, requesterAddressString }) => {
|
|
9
|
+
const requesterEntry = await node.base.view.get(requesterAddressString);
|
|
10
|
+
const requesterEntryBuffer = requesterEntry?.value ? b4a.from(requesterEntry.value) : null;
|
|
11
|
+
const originalDecode = nodeEntryUtils.decode;
|
|
12
|
+
|
|
13
|
+
nodeEntryUtils.decode = entry => {
|
|
14
|
+
if (requesterEntryBuffer && b4a.equals(entry, requesterEntryBuffer)) {
|
|
15
|
+
const decoded = originalDecode(entry);
|
|
16
|
+
if (!decoded) return decoded;
|
|
17
|
+
return { ...decoded, balance: b4a.alloc(1) };
|
|
18
|
+
}
|
|
19
|
+
return originalDecode(entry);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return () => {
|
|
23
|
+
nodeEntryUtils.decode = originalDecode;
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
expectedLogs: ['Invalid requester balance.']
|
|
27
|
+
}).performScenario();
|
|
28
|
+
}
|
package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterEntryScenario.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
2
|
+
import { createTransferFeeGuardScenario, patchBatchGet } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
3
|
+
|
|
4
|
+
export default function txOperationTransferFeeInvalidRequesterEntryScenario() {
|
|
5
|
+
createTransferFeeGuardScenario({
|
|
6
|
+
title: 'State.transferFeeTxOperation rejects missing requester node entry buffer',
|
|
7
|
+
applyPatch: async ({ node, decoded, requesterAddressString }) => {
|
|
8
|
+
const matcher = key => {
|
|
9
|
+
if (!requesterAddressString) return false;
|
|
10
|
+
if (typeof key === 'string') return key === requesterAddressString;
|
|
11
|
+
return b4a.isBuffer(key) && b4a.toString(key, 'ascii') === requesterAddressString;
|
|
12
|
+
};
|
|
13
|
+
return patchBatchGet(node, matcher, () => null);
|
|
14
|
+
},
|
|
15
|
+
expectedLogs: ['Invalid requester node entry buffer.']
|
|
16
|
+
}).performScenario();
|
|
17
|
+
}
|
package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidValidatorBalanceScenario.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
2
|
+
import nodeEntryUtils from '../../../../../src/core/state/utils/nodeEntry.js';
|
|
3
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeInvalidValidatorBalanceScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation rejects invalid validator balance',
|
|
8
|
+
applyPatch: async ({ node, decoded }) => {
|
|
9
|
+
const validatorAddressString = decoded?.txo?.va
|
|
10
|
+
? decoded.txo.va.toString('ascii')
|
|
11
|
+
: node.wallet.address;
|
|
12
|
+
const validatorEntry = await node.base.view.get(validatorAddressString);
|
|
13
|
+
const validatorEntryBuffer = validatorEntry?.value ? b4a.from(validatorEntry.value) : null;
|
|
14
|
+
const originalDecode = nodeEntryUtils.decode;
|
|
15
|
+
let calls = 0;
|
|
16
|
+
|
|
17
|
+
nodeEntryUtils.decode = entry => {
|
|
18
|
+
if (validatorEntryBuffer && b4a.equals(entry, validatorEntryBuffer)) {
|
|
19
|
+
calls += 1;
|
|
20
|
+
const decodedEntry = originalDecode(entry);
|
|
21
|
+
if (!decodedEntry) return decodedEntry;
|
|
22
|
+
if (calls === 2) return { ...decodedEntry, balance: b4a.alloc(1) }; // fail on transfer step
|
|
23
|
+
}
|
|
24
|
+
return originalDecode(entry);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return () => {
|
|
28
|
+
nodeEntryUtils.decode = originalDecode;
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
expectedLogs: ['Invalid validator balance.']
|
|
32
|
+
}).performScenario();
|
|
33
|
+
}
|
package/tests/unit/state/apply/txOperation/txOperationTransferFeeMissingCreatorEntryScenario.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
2
|
+
import { createTransferFeeGuardScenario, patchBatchGet } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
3
|
+
|
|
4
|
+
export default function txOperationTransferFeeMissingCreatorEntryScenario() {
|
|
5
|
+
createTransferFeeGuardScenario({
|
|
6
|
+
title: 'State.transferFeeTxOperation rejects when subnetwork creator entry is missing',
|
|
7
|
+
applyPatch: async ({ context, node }) => {
|
|
8
|
+
const creatorAddressString = context.txOperation?.deployerPeer?.wallet.address;
|
|
9
|
+
const matcher = key => {
|
|
10
|
+
if (!creatorAddressString) return false;
|
|
11
|
+
if (typeof key === 'string') return key === creatorAddressString;
|
|
12
|
+
return b4a.isBuffer(key) && b4a.toString(key, 'ascii') === creatorAddressString;
|
|
13
|
+
};
|
|
14
|
+
return patchBatchGet(node, matcher, () => null);
|
|
15
|
+
},
|
|
16
|
+
expectedLogs: ['Invalid subnetwork creator - it does not exists']
|
|
17
|
+
}).performScenario();
|
|
18
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
2
|
+
import { toBalance } from '../../../../../src/core/state/utils/balance.js';
|
|
3
|
+
import transactionUtils from '../../../../../src/core/state/utils/transaction.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeSubtractFailureScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation rejects when fee deduction fails',
|
|
8
|
+
applyPatch: async () => {
|
|
9
|
+
const feeAmount = toBalance(transactionUtils.FEE);
|
|
10
|
+
const balanceProto = Object.getPrototypeOf(feeAmount);
|
|
11
|
+
const originalSub = balanceProto.sub;
|
|
12
|
+
let calls = 0;
|
|
13
|
+
balanceProto.sub = function (...args) {
|
|
14
|
+
calls += 1;
|
|
15
|
+
if (calls === 1) return null;
|
|
16
|
+
return originalSub.apply(this, args);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
return () => {
|
|
20
|
+
balanceProto.sub = originalSub;
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
expectedLogs: ['Failed to deduct fee from requester balance.']
|
|
24
|
+
}).performScenario();
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
2
|
+
import { toBalance } from '../../../../../src/core/state/utils/balance.js';
|
|
3
|
+
import transactionUtils from '../../../../../src/core/state/utils/transaction.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeUpdateCreatorBalanceFailureScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation rejects when subnetwork creator balance update fails',
|
|
8
|
+
applyPatch: async () => {
|
|
9
|
+
const feeAmount = toBalance(transactionUtils.FEE);
|
|
10
|
+
const balanceProto = Object.getPrototypeOf(feeAmount);
|
|
11
|
+
const originalUpdate = balanceProto.update;
|
|
12
|
+
let calls = 0;
|
|
13
|
+
balanceProto.update = function (...args) {
|
|
14
|
+
calls += 1;
|
|
15
|
+
// requester update (1) ok, validator update (2) ok, creator update (3) fails
|
|
16
|
+
if (calls === 3) return null;
|
|
17
|
+
return originalUpdate.apply(this, args);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
balanceProto.update = originalUpdate;
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
expectedLogs: ['Failed to update subnetwork creator node balance.']
|
|
25
|
+
}).performScenario();
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
2
|
+
import { toBalance } from '../../../../../src/core/state/utils/balance.js';
|
|
3
|
+
import transactionUtils from '../../../../../src/core/state/utils/transaction.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeUpdateFailureScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation rejects when requester balance update fails',
|
|
8
|
+
applyPatch: async () => {
|
|
9
|
+
const feeAmount = toBalance(transactionUtils.FEE);
|
|
10
|
+
const balanceProto = Object.getPrototypeOf(feeAmount);
|
|
11
|
+
const originalUpdate = balanceProto.update;
|
|
12
|
+
let calls = 0;
|
|
13
|
+
balanceProto.update = function (...args) {
|
|
14
|
+
calls += 1;
|
|
15
|
+
if (calls === 1) return null; // requester update fails
|
|
16
|
+
return originalUpdate.apply(this, args);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
return () => {
|
|
20
|
+
balanceProto.update = originalUpdate;
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
expectedLogs: ['Failed to update requester node balance.']
|
|
24
|
+
}).performScenario();
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
2
|
+
import { toBalance } from '../../../../../src/core/state/utils/balance.js';
|
|
3
|
+
import transactionUtils from '../../../../../src/core/state/utils/transaction.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeUpdateValidatorBalanceFailureScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation rejects when validator balance update fails',
|
|
8
|
+
applyPatch: async () => {
|
|
9
|
+
const feeAmount = toBalance(transactionUtils.FEE);
|
|
10
|
+
const balanceProto = Object.getPrototypeOf(feeAmount);
|
|
11
|
+
const originalUpdate = balanceProto.update;
|
|
12
|
+
let calls = 0;
|
|
13
|
+
balanceProto.update = function (...args) {
|
|
14
|
+
calls += 1;
|
|
15
|
+
// requester update (1) succeeds, validator update (2) fails
|
|
16
|
+
if (calls === 2) return null;
|
|
17
|
+
return originalUpdate.apply(this, args);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
balanceProto.update = originalUpdate;
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
expectedLogs: ['Failed to update validator node balance.']
|
|
25
|
+
}).performScenario();
|
|
26
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createTransferFeeGuardScenario } from './txOperationTransferFeeGuardScenarioFactory.js';
|
|
2
|
+
import { toBalance } from '../../../../../src/core/state/utils/balance.js';
|
|
3
|
+
import transactionUtils from '../../../../../src/core/state/utils/transaction.js';
|
|
4
|
+
|
|
5
|
+
export default function txOperationTransferFeeUpdateValidatorBonusFailureScenario() {
|
|
6
|
+
createTransferFeeGuardScenario({
|
|
7
|
+
title: 'State.transferFeeTxOperation rejects when validator bonus balance update fails',
|
|
8
|
+
setupOptions: { creatorPeerKind: 'validator' },
|
|
9
|
+
applyPatch: async () => {
|
|
10
|
+
const feeAmount = toBalance(transactionUtils.FEE);
|
|
11
|
+
const balanceProto = Object.getPrototypeOf(feeAmount);
|
|
12
|
+
const originalUpdate = balanceProto.update;
|
|
13
|
+
let calls = 0;
|
|
14
|
+
balanceProto.update = function (...args) {
|
|
15
|
+
calls += 1;
|
|
16
|
+
// requester (1) ok, validator (2) ok, bonus update (3) fails
|
|
17
|
+
if (calls === 3) return null;
|
|
18
|
+
return originalUpdate.apply(this, args);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
return () => {
|
|
22
|
+
balanceProto.update = originalUpdate;
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
expectedLogs: ['Failed to update validator node balance with bonus.']
|
|
26
|
+
}).performScenario();
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { test } from 'brittle';
|
|
2
|
+
import {
|
|
3
|
+
setupTxOperationScenario,
|
|
4
|
+
buildTxOperationPayload,
|
|
5
|
+
assertTxOperationSuccessState
|
|
6
|
+
} from './txOperationScenarioHelpers.js';
|
|
7
|
+
import { eventFlush } from '../../../../helpers/autobaseTestHelpers.js';
|
|
8
|
+
|
|
9
|
+
export default function txOperationValidatorCreatorHappyPathScenario() {
|
|
10
|
+
test('State.apply txOperation rewards validator as subnetwork creator (75% fee)', async t => {
|
|
11
|
+
const context = await setupTxOperationScenario(t, { creatorPeerKind: 'validator' });
|
|
12
|
+
const payload = await buildTxOperationPayload(context);
|
|
13
|
+
const validatorPeer = context.txOperation?.validatorPeer ?? context.adminBootstrap;
|
|
14
|
+
|
|
15
|
+
await validatorPeer.base.append(payload);
|
|
16
|
+
await validatorPeer.base.update();
|
|
17
|
+
await eventFlush();
|
|
18
|
+
|
|
19
|
+
await assertTxOperationSuccessState(t, context, { payload, distribution: 'validatorIsCreator' });
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -13,6 +13,7 @@ async function runStateTests() {
|
|
|
13
13
|
await import('./utils/roles.test.js');
|
|
14
14
|
// These tests are skipped temoporarily because the mock library sinon does not work with bare.
|
|
15
15
|
// TODO: replace esmock, sinon is actually fine
|
|
16
|
+
await import('./apply/state.apply.test.js');
|
|
16
17
|
if (!isBare()) {
|
|
17
18
|
await import('./State.test.js');
|
|
18
19
|
}
|
|
@@ -21,4 +21,8 @@ export const TEN_THOUSAND_VALUE = b4a.from([
|
|
|
21
21
|
|
|
22
22
|
export const tokenUnits = units => units * 10n ** TOKEN_DECIMALS
|
|
23
23
|
|
|
24
|
-
export const isBare = () =>
|
|
24
|
+
export const isBare = () => {
|
|
25
|
+
if (global.Pear === undefined) return true;
|
|
26
|
+
const pearApp = global.Pear.app ?? global.Pear.config;
|
|
27
|
+
return pearApp?.options?.type === 'terminal';
|
|
28
|
+
}
|
package/.env
DELETED