From 5fb4112ed28ddf4f437cde3e1a744b762682f2cf Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 24 May 2023 16:52:21 +0300 Subject: [PATCH 1/9] - added semi-integration test --- .../vm/txsFee/relayedMoveBalance_test.go | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/integrationTests/vm/txsFee/relayedMoveBalance_test.go b/integrationTests/vm/txsFee/relayedMoveBalance_test.go index e0e52bc1e4b..7d63b44f246 100644 --- a/integrationTests/vm/txsFee/relayedMoveBalance_test.go +++ b/integrationTests/vm/txsFee/relayedMoveBalance_test.go @@ -9,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" "github.com/multiversx/mx-chain-go/process" vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -154,3 +155,32 @@ func TestRelayedMoveBalanceInvalidUserTxValueShouldConsumeGas(t *testing.T) { accumulatedFees := testContext.TxFeeHandler.GetAccumulatedFees() require.Equal(t, big.NewInt(275), accumulatedFees) } + +func TestRelayedMoveBalanceInvalidNonce(t *testing.T) { + testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) + require.Nil(t, err) + defer testContext.Close() + + relayerAddr := []byte("12345678901234567890123456789033") + sndAddr := []byte("12345678901234567890123456789012") + rcvAddr := []byte("12345678901234567890123456789022") + + _, _ = vm.CreateAccount(testContext.Accounts, sndAddr, 0, big.NewInt(0)) + userTx := vm.CreateTransaction(100, big.NewInt(150), sndAddr, rcvAddr, 1, 100, []byte("aaaa")) + + _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(3000)) + + rtxData := utils.PrepareRelayerTxData(userTx) + rTxGasLimit := 1 + userTx.GasLimit + uint64(len(rtxData)) + rtx := vm.CreateTransaction(0, big.NewInt(100), relayerAddr, sndAddr, 1, rTxGasLimit, rtxData) + + retCode, _ := testContext.TxProcessor.ProcessTransaction(rtx) + require.Equal(t, vmcommon.UserError, retCode) + + _, err = testContext.Accounts.Commit() + require.Nil(t, err) + + senderAccount, _ := testContext.Accounts.GetExistingAccount(sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, uint64(0), senderAccount.GetNonce()) +} From 0b96f7568f7992e882adcef7e02e4110e494bacd Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 24 May 2023 17:04:06 +0300 Subject: [PATCH 2/9] - added another semi-integration test --- .../vm/txsFee/relayedMoveBalance_test.go | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/integrationTests/vm/txsFee/relayedMoveBalance_test.go b/integrationTests/vm/txsFee/relayedMoveBalance_test.go index 7d63b44f246..ed24ec2cb47 100644 --- a/integrationTests/vm/txsFee/relayedMoveBalance_test.go +++ b/integrationTests/vm/txsFee/relayedMoveBalance_test.go @@ -156,7 +156,7 @@ func TestRelayedMoveBalanceInvalidUserTxValueShouldConsumeGas(t *testing.T) { require.Equal(t, big.NewInt(275), accumulatedFees) } -func TestRelayedMoveBalanceInvalidNonce(t *testing.T) { +func TestRelayedMoveBalanceHigherNonce(t *testing.T) { testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) require.Nil(t, err) defer testContext.Close() @@ -184,3 +184,32 @@ func TestRelayedMoveBalanceInvalidNonce(t *testing.T) { require.NotNil(t, senderAccount) assert.Equal(t, uint64(0), senderAccount.GetNonce()) } + +func TestRelayedMoveBalanceLowerNonce(t *testing.T) { + testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) + require.Nil(t, err) + defer testContext.Close() + + relayerAddr := []byte("12345678901234567890123456789033") + sndAddr := []byte("12345678901234567890123456789012") + rcvAddr := []byte("12345678901234567890123456789022") + + _, _ = vm.CreateAccount(testContext.Accounts, sndAddr, 5, big.NewInt(0)) + userTx := vm.CreateTransaction(4, big.NewInt(150), sndAddr, rcvAddr, 1, 100, []byte("aaaa")) + + _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(3000)) + + rtxData := utils.PrepareRelayerTxData(userTx) + rTxGasLimit := 1 + userTx.GasLimit + uint64(len(rtxData)) + rtx := vm.CreateTransaction(0, big.NewInt(100), relayerAddr, sndAddr, 1, rTxGasLimit, rtxData) + + retCode, _ := testContext.TxProcessor.ProcessTransaction(rtx) + require.Equal(t, vmcommon.UserError, retCode) + + _, err = testContext.Accounts.Commit() + require.Nil(t, err) + + senderAccount, _ := testContext.Accounts.GetExistingAccount(sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, uint64(5), senderAccount.GetNonce()) +} From 0ab048f66171049fba8d255b651b6394cd6fb2b5 Mon Sep 17 00:00:00 2001 From: AdoAdoAdo Date: Wed, 24 May 2023 20:25:21 +0300 Subject: [PATCH 3/9] conditionaly increase nonce on relayed user tx --- cmd/node/config/enableEpochs.toml | 3 +++ common/enablers/enableEpochsHandler.go | 6 +++++ common/enablers/epochFlags.go | 7 ++++++ common/interface.go | 1 + config/epochConfig.go | 1 + .../vm/txsFee/relayedMoveBalance_test.go | 4 +++- process/transaction/shardProcess.go | 23 ++++++++++++++++--- sharding/mock/enableEpochsHandlerMock.go | 5 ++++ testscommon/enableEpochsHandlerStub.go | 9 ++++++++ 9 files changed, 55 insertions(+), 4 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index 7a2bf067ddd..8ec97f60376 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -242,6 +242,9 @@ # RuntimeCodeSizeFixEnableEpoch represents the epoch when the code size fix in the VM is enabled RuntimeCodeSizeFixEnableEpoch = 1 + # RelayedNonceFixEnableEpoch represents the epoch when the nonce fix for relayed txs is enabled + RelayedNonceFixEnableEpoch = 2 + # BLSMultiSignerEnableEpoch represents the activation epoch for different types of BLS multi-signers BLSMultiSignerEnableEpoch = [ { EnableEpoch = 0, Type = "no-KOSK"}, diff --git a/common/enablers/enableEpochsHandler.go b/common/enablers/enableEpochsHandler.go index b9017bdcd4e..f821bcb4653 100644 --- a/common/enablers/enableEpochsHandler.go +++ b/common/enablers/enableEpochsHandler.go @@ -118,6 +118,7 @@ func (handler *enableEpochsHandler) EpochConfirmed(epoch uint32, _ uint64) { handler.setFlagValue(epoch >= handler.enableEpochsConfig.MaxBlockchainHookCountersEnableEpoch, handler.maxBlockchainHookCountersFlag, "maxBlockchainHookCountersFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.WipeSingleNFTLiquidityDecreaseEnableEpoch, handler.wipeSingleNFTLiquidityDecreaseFlag, "wipeSingleNFTLiquidityDecreaseFlag") handler.setFlagValue(epoch >= handler.enableEpochsConfig.AlwaysSaveTokenMetaDataEnableEpoch, handler.alwaysSaveTokenMetaDataFlag, "alwaysSaveTokenMetaDataFlag") + handler.setFlagValue(epoch >= handler.enableEpochsConfig.RelayedNonceFixEnableEpoch, handler.relayedNonceFixFlag, "relayedNonceFixFlag") } func (handler *enableEpochsHandler) setFlagValue(value bool, flag *atomic.Flag, flagName string) { @@ -215,6 +216,11 @@ func (handler *enableEpochsHandler) RefactorPeersMiniBlocksEnableEpoch() uint32 return handler.enableEpochsConfig.RefactorPeersMiniBlocksEnableEpoch } +// RelayedNonceFixEnableEpoch returns the epoch when relayed nonce fix becomes active +func (handler *enableEpochsHandler) RelayedNonceFixEnableEpoch() uint32 { + return handler.enableEpochsConfig.RelayedNonceFixEnableEpoch +} + // IsInterfaceNil returns true if there is no value under the interface func (handler *enableEpochsHandler) IsInterfaceNil() bool { return handler == nil diff --git a/common/enablers/epochFlags.go b/common/enablers/epochFlags.go index fe11469f4bb..9a6d3e6e9f1 100644 --- a/common/enablers/epochFlags.go +++ b/common/enablers/epochFlags.go @@ -90,6 +90,7 @@ type epochFlagsHolder struct { maxBlockchainHookCountersFlag *atomic.Flag wipeSingleNFTLiquidityDecreaseFlag *atomic.Flag alwaysSaveTokenMetaDataFlag *atomic.Flag + relayedNonceFixFlag *atomic.Flag } func newEpochFlagsHolder() *epochFlagsHolder { @@ -179,6 +180,7 @@ func newEpochFlagsHolder() *epochFlagsHolder { maxBlockchainHookCountersFlag: &atomic.Flag{}, wipeSingleNFTLiquidityDecreaseFlag: &atomic.Flag{}, alwaysSaveTokenMetaDataFlag: &atomic.Flag{}, + relayedNonceFixFlag: &atomic.Flag{}, } } @@ -659,3 +661,8 @@ func (holder *epochFlagsHolder) IsWipeSingleNFTLiquidityDecreaseEnabled() bool { func (holder *epochFlagsHolder) IsAlwaysSaveTokenMetaDataEnabled() bool { return holder.alwaysSaveTokenMetaDataFlag.IsSet() } + +// IsRelayedNonceFixEnabled returns true if relayedNonceFixFlag is enabled +func (holder *epochFlagsHolder) IsRelayedNonceFixEnabled() bool { + return holder.relayedNonceFixFlag.IsSet() +} diff --git a/common/interface.go b/common/interface.go index a58b6aa94db..625a6d4ff7e 100644 --- a/common/interface.go +++ b/common/interface.go @@ -327,6 +327,7 @@ type EnableEpochsHandler interface { IsMaxBlockchainHookCountersFlagEnabled() bool IsWipeSingleNFTLiquidityDecreaseEnabled() bool IsAlwaysSaveTokenMetaDataEnabled() bool + IsRelayedNonceFixEnabled() bool IsInterfaceNil() bool } diff --git a/config/epochConfig.go b/config/epochConfig.go index e729f362d91..ef4592a319f 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -93,6 +93,7 @@ type EnableEpochs struct { MaxBlockchainHookCountersEnableEpoch uint32 WipeSingleNFTLiquidityDecreaseEnableEpoch uint32 AlwaysSaveTokenMetaDataEnableEpoch uint32 + RelayedNonceFixEnableEpoch uint32 BLSMultiSignerEnableEpoch []MultiSignerConfig } diff --git a/integrationTests/vm/txsFee/relayedMoveBalance_test.go b/integrationTests/vm/txsFee/relayedMoveBalance_test.go index 7d63b44f246..141f736d8a1 100644 --- a/integrationTests/vm/txsFee/relayedMoveBalance_test.go +++ b/integrationTests/vm/txsFee/relayedMoveBalance_test.go @@ -157,7 +157,9 @@ func TestRelayedMoveBalanceInvalidUserTxValueShouldConsumeGas(t *testing.T) { } func TestRelayedMoveBalanceInvalidNonce(t *testing.T) { - testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) + testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 0, + }) require.Nil(t, err) defer testContext.Close() diff --git a/process/transaction/shardProcess.go b/process/transaction/shardProcess.go index 06d20701ed4..42d570f2c0d 100644 --- a/process/transaction/shardProcess.go +++ b/process/transaction/shardProcess.go @@ -672,6 +672,7 @@ func (txProc *txProcessor) computeRelayedTxFees(tx *transaction.Transaction) rel func (txProc *txProcessor) removeValueAndConsumedFeeFromUser( userTx *transaction.Transaction, relayedTxValue *big.Int, + executionErr error, ) error { userAcnt, err := txProc.getAccountFromAddress(userTx.SndAddr) if err != nil { @@ -690,7 +691,10 @@ func (txProc *txProcessor) removeValueAndConsumedFeeFromUser( if err != nil { return err } - userAcnt.IncreaseNonce(1) + + if txProc.shouldIncreaseNonce(executionErr) { + userAcnt.IncreaseNonce(1) + } err = txProc.accounts.SaveAccount(userAcnt) if err != nil { @@ -735,7 +739,7 @@ func (txProc *txProcessor) processUserTx( txType, dstShardTxType := txProc.txTypeHandler.ComputeTransactionType(userTx) err = txProc.checkTxValues(userTx, acntSnd, acntDst, true) if err != nil { - errRemove := txProc.removeValueAndConsumedFeeFromUser(userTx, relayedTxValue) + errRemove := txProc.removeValueAndConsumedFeeFromUser(userTx, relayedTxValue, err) if errRemove != nil { return vmcommon.UserError, errRemove } @@ -787,7 +791,7 @@ func (txProc *txProcessor) processUserTx( returnCode, err = txProc.scProcessor.ExecuteBuiltInFunction(scrFromTx, acntSnd, acntDst) default: err = process.ErrWrongTransaction - errRemove := txProc.removeValueAndConsumedFeeFromUser(userTx, relayedTxValue) + errRemove := txProc.removeValueAndConsumedFeeFromUser(userTx, relayedTxValue, err) if errRemove != nil { return vmcommon.UserError, errRemove } @@ -940,6 +944,19 @@ func (txProc *txProcessor) executeFailedRelayedUserTx( return nil } +func (txProc *txProcessor) shouldIncreaseNonce(executionErr error) bool { + if !txProc.enableEpochsHandler.IsRelayedTransactionsFlagEnabled() { + return true + } + + // todo add not executable for guardians + if errors.Is(executionErr, process.ErrLowerNonceInTransaction) || errors.Is(executionErr, process.ErrHigherNonceInTransaction) { + return false + } + + return true +} + // IsInterfaceNil returns true if there is no value under the interface func (txProc *txProcessor) IsInterfaceNil() bool { return txProc == nil diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 6173c091e32..759989fac3c 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -566,6 +566,11 @@ func (mock *EnableEpochsHandlerMock) IsAlwaysSaveTokenMetaDataEnabled() bool { return false } +// IsRelayedNonceFixEnableEpoch - +func (mock *EnableEpochsHandlerMock) IsRelayedNonceFixEnableEpoch() bool { + return true +} + // IsInterfaceNil returns true if there is no value under the interface func (mock *EnableEpochsHandlerMock) IsInterfaceNil() bool { return mock == nil diff --git a/testscommon/enableEpochsHandlerStub.go b/testscommon/enableEpochsHandlerStub.go index 092131f8ebc..afdbe189320 100644 --- a/testscommon/enableEpochsHandlerStub.go +++ b/testscommon/enableEpochsHandlerStub.go @@ -117,6 +117,7 @@ type EnableEpochsHandlerStub struct { IsMaxBlockchainHookCountersFlagEnabledField bool IsWipeSingleNFTLiquidityDecreaseEnabledField bool IsAlwaysSaveTokenMetaDataEnabledField bool + IsRelayedNonceFixEnabledField bool } // ResetPenalizedTooMuchGasFlag - @@ -1014,6 +1015,14 @@ func (stub *EnableEpochsHandlerStub) IsAlwaysSaveTokenMetaDataEnabled() bool { return stub.IsAlwaysSaveTokenMetaDataEnabledField } +// IsRelayedNonceFixEnabled - +func (stub *EnableEpochsHandlerStub) IsRelayedNonceFixEnabled() bool { + stub.RLock() + defer stub.RUnlock() + + return stub.IsRelayedNonceFixEnabledField +} + // IsInterfaceNil - func (stub *EnableEpochsHandlerStub) IsInterfaceNil() bool { return stub == nil From 3ef20d63c0f6b6bbaea195e4649b60da68404afc Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 24 May 2023 20:33:28 +0300 Subject: [PATCH 4/9] - refactored tests --- integrationTests/testInitializer.go | 20 +++ .../relayedBuiltInFunctions_test.go | 2 +- .../multiShard/relayedMoveBalance_test.go | 13 +- .../txsFee/multiShard/relayedScDeploy_test.go | 3 +- .../multiShard/relayedTxScCalls_test.go | 5 +- .../vm/txsFee/relayedAsyncCall_test.go | 3 +- .../vm/txsFee/relayedAsyncESDT_test.go | 7 +- .../vm/txsFee/relayedBuiltInFunctions_test.go | 10 +- integrationTests/vm/txsFee/relayedDns_test.go | 7 +- .../vm/txsFee/relayedESDT_test.go | 5 +- .../vm/txsFee/relayedMoveBalance_test.go | 129 ++++++++++++++---- .../vm/txsFee/relayedScCalls_test.go | 11 +- .../vm/txsFee/relayedScDeploy_test.go | 10 +- integrationTests/vm/txsFee/utils/utils.go | 7 - 14 files changed, 162 insertions(+), 70 deletions(-) diff --git a/integrationTests/testInitializer.go b/integrationTests/testInitializer.go index a44cf3c6828..edfcf26a070 100644 --- a/integrationTests/testInitializer.go +++ b/integrationTests/testInitializer.go @@ -59,6 +59,7 @@ import ( testStorage "github.com/multiversx/mx-chain-go/testscommon/state" "github.com/multiversx/mx-chain-go/testscommon/statusHandler" statusHandlerMock "github.com/multiversx/mx-chain-go/testscommon/statusHandler" + "github.com/multiversx/mx-chain-go/testscommon/txDataBuilder" "github.com/multiversx/mx-chain-go/trie" "github.com/multiversx/mx-chain-go/trie/hashesHolder" "github.com/multiversx/mx-chain-go/vm" @@ -2538,3 +2539,22 @@ func SaveDelegationContractsList(nodes []*TestProcessorNode) { _, _ = n.AccntState.Commit() } } + +// PrepareRelayedTxDataV1 repares the data for a relayed transaction V1 +func PrepareRelayedTxDataV1(innerTx *transaction.Transaction) []byte { + userTxBytes, _ := TestMarshalizer.Marshal(innerTx) + return []byte(core.RelayedTransaction + "@" + hex.EncodeToString(userTxBytes)) +} + +// PrepareRelayedTxDataV2 prepares the data for a relayed transaction V2 +func PrepareRelayedTxDataV2(innerTx *transaction.Transaction) []byte { + dataBuilder := txDataBuilder.NewBuilder() + txData := dataBuilder. + Func(core.RelayedTransactionV2). + Bytes(innerTx.RcvAddr). + Int64(int64(innerTx.Nonce)). + Bytes(innerTx.Data). + Bytes(innerTx.Signature) + + return txData.ToBytes() +} diff --git a/integrationTests/vm/txsFee/multiShard/relayedBuiltInFunctions_test.go b/integrationTests/vm/txsFee/multiShard/relayedBuiltInFunctions_test.go index 2fdeb14eeb9..56d97f9546b 100644 --- a/integrationTests/vm/txsFee/multiShard/relayedBuiltInFunctions_test.go +++ b/integrationTests/vm/txsFee/multiShard/relayedBuiltInFunctions_test.go @@ -56,7 +56,7 @@ func TestRelayedBuiltInFunctionExecuteOnRelayerAndDstShardShouldWork(t *testing. _, _ = vm.CreateAccount(testContextRelayer.Accounts, relayerAddr, 0, big.NewInt(15000)) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, owner, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/multiShard/relayedMoveBalance_test.go b/integrationTests/vm/txsFee/multiShard/relayedMoveBalance_test.go index bdb65593459..2dd36161143 100644 --- a/integrationTests/vm/txsFee/multiShard/relayedMoveBalance_test.go +++ b/integrationTests/vm/txsFee/multiShard/relayedMoveBalance_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -34,7 +35,7 @@ func TestRelayedMoveBalanceRelayerShard0InnerTxSenderAndReceiverShard1ShouldWork userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, rcvAddr, gasPrice, gasLimit, []byte("aaaa")) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -80,7 +81,7 @@ func TestRelayedMoveBalanceRelayerAndInnerTxSenderShard0ReceiverShard1(t *testin userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, scAddrBytes, gasPrice, gasLimit, nil) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -131,7 +132,7 @@ func TestRelayedMoveBalanceExecuteOnSourceAndDestination(t *testing.T) { userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, scAddrBytes, gasPrice, gasLimit, nil) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -193,7 +194,7 @@ func TestRelayedMoveBalanceExecuteOnSourceAndDestinationRelayerAndInnerTxSenderS userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, rcvAddr, gasPrice, gasLimit, nil) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -253,7 +254,7 @@ func TestRelayedMoveBalanceRelayerAndInnerTxReceiverShard0SenderShard1(t *testin innerTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, rcvAddr, gasPrice, gasLimit, nil) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -329,7 +330,7 @@ func TestMoveBalanceRelayerShard0InnerTxSenderShard1InnerTxReceiverShard2ShouldW innerTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, rcvAddr, gasPrice, gasLimit, nil) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/multiShard/relayedScDeploy_test.go b/integrationTests/vm/txsFee/multiShard/relayedScDeploy_test.go index 0a82260631d..82bf9fc370f 100644 --- a/integrationTests/vm/txsFee/multiShard/relayedScDeploy_test.go +++ b/integrationTests/vm/txsFee/multiShard/relayedScDeploy_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" "github.com/multiversx/mx-chain-go/integrationTests/vm/wasm" @@ -39,7 +40,7 @@ func TestRelayedSCDeployShouldWork(t *testing.T) { scCode := wasm.GetSCCode(contractPath) userTx := vm.CreateTransaction(0, big.NewInt(0), sndAddr, vm.CreateEmptyAddress(), gasPrice, gasLimit, []byte(wasm.CreateDeployTxData(scCode))) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, big.NewInt(0), relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/multiShard/relayedTxScCalls_test.go b/integrationTests/vm/txsFee/multiShard/relayedTxScCalls_test.go index f9849be4720..1c37b9624c3 100644 --- a/integrationTests/vm/txsFee/multiShard/relayedTxScCalls_test.go +++ b/integrationTests/vm/txsFee/multiShard/relayedTxScCalls_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -57,7 +58,7 @@ func TestRelayedTxScCallMultiShardShouldWork(t *testing.T) { gasLimit := uint64(500) innerTx := vm.CreateTransaction(0, big.NewInt(0), sndAddr, scAddr, gasPrice, gasLimit, []byte("increment")) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -162,7 +163,7 @@ func TestRelayedTxScCallMultiShardFailOnInnerTxDst(t *testing.T) { gasLimit := uint64(500) innerTx := vm.CreateTransaction(0, big.NewInt(0), sndAddr, scAddr, gasPrice, gasLimit, []byte("incremeno")) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/relayedAsyncCall_test.go b/integrationTests/vm/txsFee/relayedAsyncCall_test.go index 7cf8c80d82c..36b739007a3 100644 --- a/integrationTests/vm/txsFee/relayedAsyncCall_test.go +++ b/integrationTests/vm/txsFee/relayedAsyncCall_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -48,7 +49,7 @@ func TestRelayedAsyncCallShouldWork(t *testing.T) { innerTx := vm.CreateTransaction(0, big.NewInt(0), senderAddr, secondSCAddress, gasPrice, gasLimit, []byte("doSomething")) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, senderAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/relayedAsyncESDT_test.go b/integrationTests/vm/txsFee/relayedAsyncESDT_test.go index 15db4d3b331..9ef738063fb 100644 --- a/integrationTests/vm/txsFee/relayedAsyncESDT_test.go +++ b/integrationTests/vm/txsFee/relayedAsyncESDT_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -54,7 +55,7 @@ func TestRelayedAsyncESDTCallShouldWork(t *testing.T) { innerTx := utils.CreateESDTTransferTx(0, sndAddr, firstSCAddress, token, big.NewInt(5000), gasPrice, gasLimit) innerTx.Data = []byte(string(innerTx.Data) + "@" + hex.EncodeToString([]byte("transferToSecondContractHalf"))) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -113,7 +114,7 @@ func TestRelayedAsyncESDTCall_InvalidCallFirstContract(t *testing.T) { innerTx := utils.CreateESDTTransferTx(0, sndAddr, firstSCAddress, token, big.NewInt(5000), gasPrice, gasLimit) innerTx.Data = []byte(string(innerTx.Data) + "@" + hex.EncodeToString([]byte("transferToSecondContractRejected"))) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -172,7 +173,7 @@ func TestRelayedAsyncESDTCall_InvalidOutOfGas(t *testing.T) { innerTx := utils.CreateESDTTransferTx(0, sndAddr, firstSCAddress, token, big.NewInt(5000), gasPrice, gasLimit) innerTx.Data = []byte(string(innerTx.Data) + "@" + hex.EncodeToString([]byte("transferToSecondContractHalf"))) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/relayedBuiltInFunctions_test.go b/integrationTests/vm/txsFee/relayedBuiltInFunctions_test.go index 72d972b07ff..b4be8665953 100644 --- a/integrationTests/vm/txsFee/relayedBuiltInFunctions_test.go +++ b/integrationTests/vm/txsFee/relayedBuiltInFunctions_test.go @@ -42,7 +42,7 @@ func TestRelayedBuildInFunctionChangeOwnerCallShouldWork(t *testing.T) { _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(30000)) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, owner, gasPrice, rTxGasLimit, rtxData) @@ -89,7 +89,7 @@ func TestRelayedBuildInFunctionChangeOwnerCallWrongOwnerShouldConsumeGas(t *test _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(30000)) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, owner, gasPrice, rTxGasLimit, rtxData) @@ -135,7 +135,7 @@ func TestRelayedBuildInFunctionChangeOwnerInvalidAddressShouldConsumeGas(t *test _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(30000)) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, owner, gasPrice, rTxGasLimit, rtxData) @@ -180,7 +180,7 @@ func TestRelayedBuildInFunctionChangeOwnerCallInsufficientGasLimitShouldConsumeG _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(30000)) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, owner, gasPrice, rTxGasLimit, rtxData) @@ -225,7 +225,7 @@ func TestRelayedBuildInFunctionChangeOwnerCallOutOfGasShouldConsumeGas(t *testin _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(30000)) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, owner, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/relayedDns_test.go b/integrationTests/vm/txsFee/relayedDns_test.go index 31867df3330..6f440a2bc41 100644 --- a/integrationTests/vm/txsFee/relayedDns_test.go +++ b/integrationTests/vm/txsFee/relayedDns_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -40,7 +41,7 @@ func TestRelayedTxDnsTransaction_ShouldWork(t *testing.T) { // create user name for sender innerTx := vm.CreateTransaction(0, big.NewInt(0), sndAddr, scAddress, gasPrice, gasLimit, txData) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -62,7 +63,7 @@ func TestRelayedTxDnsTransaction_ShouldWork(t *testing.T) { // create user name for receiver innerTx = vm.CreateTransaction(0, big.NewInt(0), rcvAddr, scAddress, gasPrice, gasLimit, txData) - rtxData = utils.PrepareRelayerTxData(innerTx) + rtxData = integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit = 1 + gasLimit + uint64(len(rtxData)) rtx = vm.CreateTransaction(1, innerTx.Value, relayerAddr, rcvAddr, gasPrice, rTxGasLimit, rtxData) @@ -84,7 +85,7 @@ func TestRelayedTxDnsTransaction_ShouldWork(t *testing.T) { innerTx.SndUserName = sndAddrUserName innerTx.RcvUserName = rcvAddrUserName - rtxData = utils.PrepareRelayerTxData(innerTx) + rtxData = integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit = 1 + gasLimit + uint64(len(rtxData)) rtx = vm.CreateTransaction(2, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/relayedESDT_test.go b/integrationTests/vm/txsFee/relayedESDT_test.go index 80e4b0e0462..3c5ffef15ce 100644 --- a/integrationTests/vm/txsFee/relayedESDT_test.go +++ b/integrationTests/vm/txsFee/relayedESDT_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -35,7 +36,7 @@ func TestRelayedESDTTransferShouldWork(t *testing.T) { gasLimit := uint64(40) innerTx := utils.CreateESDTTransferTx(0, sndAddr, rcvAddr, token, big.NewInt(100), gasPrice, gasLimit) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -81,7 +82,7 @@ func TestTestRelayedESTTransferNotEnoughESTValueShouldConsumeGas(t *testing.T) { gasLimit := uint64(40) innerTx := utils.CreateESDTTransferTx(0, sndAddr, rcvAddr, token, big.NewInt(100000001), gasPrice, gasLimit) - rtxData := utils.PrepareRelayerTxData(innerTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(innerTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, innerTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/relayedMoveBalance_test.go b/integrationTests/vm/txsFee/relayedMoveBalance_test.go index ed24ec2cb47..49b19bae3d1 100644 --- a/integrationTests/vm/txsFee/relayedMoveBalance_test.go +++ b/integrationTests/vm/txsFee/relayedMoveBalance_test.go @@ -4,9 +4,11 @@ import ( "math/big" "testing" + "github.com/multiversx/mx-chain-core-go/data/block" + dataTransaction "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" - "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" "github.com/multiversx/mx-chain-go/process" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/assert" @@ -33,7 +35,7 @@ func TestRelayedMoveBalanceShouldWork(t *testing.T) { // gas consumed = 50 userTx := vm.CreateTransaction(senderNonce, big.NewInt(100), sndAddr, rcvAddr, gasPrice, gasLimit, []byte("aaaa")) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -74,7 +76,7 @@ func TestRelayedMoveBalanceInvalidGasLimitShouldConsumeGas(t *testing.T) { _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(3000)) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 2 + userTx.GasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, 1, rTxGasLimit, rtxData) @@ -106,7 +108,7 @@ func TestRelayedMoveBalanceInvalidUserTxShouldConsumeGas(t *testing.T) { _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(3000)) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + userTx.GasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, 1, rTxGasLimit, rtxData) @@ -138,7 +140,7 @@ func TestRelayedMoveBalanceInvalidUserTxValueShouldConsumeGas(t *testing.T) { _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(3000)) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + userTx.GasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, big.NewInt(100), relayerAddr, sndAddr, 1, rTxGasLimit, rtxData) @@ -166,23 +168,44 @@ func TestRelayedMoveBalanceHigherNonce(t *testing.T) { rcvAddr := []byte("12345678901234567890123456789022") _, _ = vm.CreateAccount(testContext.Accounts, sndAddr, 0, big.NewInt(0)) - userTx := vm.CreateTransaction(100, big.NewInt(150), sndAddr, rcvAddr, 1, 100, []byte("aaaa")) - _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(3000)) + userTx := vm.CreateTransaction(100, big.NewInt(150), sndAddr, rcvAddr, 1, 100, nil) - rtxData := utils.PrepareRelayerTxData(userTx) - rTxGasLimit := 1 + userTx.GasLimit + uint64(len(rtxData)) - rtx := vm.CreateTransaction(0, big.NewInt(100), relayerAddr, sndAddr, 1, rTxGasLimit, rtxData) + t.Run("inactive flag should increment", func(t *testing.T) { + initialSenderNonce := getAccount(t, testContext, sndAddr).GetNonce() - retCode, _ := testContext.TxProcessor.ProcessTransaction(rtx) - require.Equal(t, vmcommon.UserError, retCode) + rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr) - _, err = testContext.Accounts.Commit() - require.Nil(t, err) + senderAccount := getAccount(t, testContext, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce+1, senderAccount.GetNonce()) + + rtxDataV2 := integrationTests.PrepareRelayedTxDataV2(userTx) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr) - senderAccount, _ := testContext.Accounts.GetExistingAccount(sndAddr) - require.NotNil(t, senderAccount) - assert.Equal(t, uint64(0), senderAccount.GetNonce()) + senderAccount = getAccount(t, testContext, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce+2, senderAccount.GetNonce()) + }) + t.Run("active flag should not increment", func(t *testing.T) { + testContext.EpochNotifier.CheckEpoch(&block.Header{Epoch: 1}) + initialSenderNonce := getAccount(t, testContext, sndAddr).GetNonce() + + rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr) + + senderAccount := getAccount(t, testContext, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce, senderAccount.GetNonce()) + + rtxDataV2 := integrationTests.PrepareRelayedTxDataV2(userTx) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr) + + senderAccount = getAccount(t, testContext, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce, senderAccount.GetNonce()) + }) } func TestRelayedMoveBalanceLowerNonce(t *testing.T) { @@ -195,21 +218,69 @@ func TestRelayedMoveBalanceLowerNonce(t *testing.T) { rcvAddr := []byte("12345678901234567890123456789022") _, _ = vm.CreateAccount(testContext.Accounts, sndAddr, 5, big.NewInt(0)) - userTx := vm.CreateTransaction(4, big.NewInt(150), sndAddr, rcvAddr, 1, 100, []byte("aaaa")) - _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(3000)) + userTx := vm.CreateTransaction(4, big.NewInt(150), sndAddr, rcvAddr, 1, 100, nil) - rtxData := utils.PrepareRelayerTxData(userTx) - rTxGasLimit := 1 + userTx.GasLimit + uint64(len(rtxData)) - rtx := vm.CreateTransaction(0, big.NewInt(100), relayerAddr, sndAddr, 1, rTxGasLimit, rtxData) + t.Run("inactive flag should increment", func(t *testing.T) { + initialSenderNonce := getAccount(t, testContext, sndAddr).GetNonce() - retCode, _ := testContext.TxProcessor.ProcessTransaction(rtx) - require.Equal(t, vmcommon.UserError, retCode) + rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr) - _, err = testContext.Accounts.Commit() - require.Nil(t, err) + senderAccount := getAccount(t, testContext, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce+1, senderAccount.GetNonce()) + + rtxDataV2 := integrationTests.PrepareRelayedTxDataV2(userTx) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr) + + senderAccount = getAccount(t, testContext, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce+2, senderAccount.GetNonce()) + }) + t.Run("active flag should not increment", func(t *testing.T) { + testContext.EpochNotifier.CheckEpoch(&block.Header{Epoch: 1}) + initialSenderNonce := getAccount(t, testContext, sndAddr).GetNonce() + + rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr) + + senderAccount := getAccount(t, testContext, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce, senderAccount.GetNonce()) + + rtxDataV2 := integrationTests.PrepareRelayedTxDataV2(userTx) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr) + + senderAccount = getAccount(t, testContext, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce, senderAccount.GetNonce()) + }) +} + +func executeRelayedTransaction( + tb testing.TB, + testContext *vm.VMTestContext, + relayerAddress []byte, + userTx *dataTransaction.Transaction, + userTxPrepared []byte, + value *big.Int, + senderAddress []byte, +) { + relayerAccount := getAccount(tb, testContext, relayerAddress) + gasLimit := 1 + userTx.GasLimit + uint64(len(userTxPrepared)) + + relayedTx := vm.CreateTransaction(relayerAccount.GetNonce(), value, relayerAddress, senderAddress, 1, gasLimit, userTxPrepared) + retCode, _ := testContext.TxProcessor.ProcessTransaction(relayedTx) + require.Equal(tb, vmcommon.UserError, retCode) + + _, err := testContext.Accounts.Commit() + require.Nil(tb, err) +} + +func getAccount(tb testing.TB, testContext *vm.VMTestContext, address []byte) vmcommon.UserAccountHandler { + account, err := testContext.Accounts.LoadAccount(address) + require.Nil(tb, err) - senderAccount, _ := testContext.Accounts.GetExistingAccount(sndAddr) - require.NotNil(t, senderAccount) - assert.Equal(t, uint64(5), senderAccount.GetNonce()) + return account.(vmcommon.UserAccountHandler) } diff --git a/integrationTests/vm/txsFee/relayedScCalls_test.go b/integrationTests/vm/txsFee/relayedScCalls_test.go index 24b1ca74787..5108a313f44 100644 --- a/integrationTests/vm/txsFee/relayedScCalls_test.go +++ b/integrationTests/vm/txsFee/relayedScCalls_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" @@ -35,7 +36,7 @@ func TestRelayedScCallShouldWork(t *testing.T) { userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, scAddress, gasPrice, gasLimit, []byte("increment")) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -78,7 +79,7 @@ func TestRelayedScCallContractNotFoundShouldConsumeGas(t *testing.T) { userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, scAddrBytes, gasPrice, gasLimit, []byte("increment")) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -118,7 +119,7 @@ func TestRelayedScCallInvalidMethodShouldConsumeGas(t *testing.T) { userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, scAddress, gasPrice, gasLimit, []byte("invalidMethod")) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -158,7 +159,7 @@ func TestRelayedScCallInsufficientGasLimitShouldConsumeGas(t *testing.T) { userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, scAddress, gasPrice, gasLimit, []byte("increment")) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -197,7 +198,7 @@ func TestRelayedScCallOutOfGasShouldConsumeGas(t *testing.T) { userTx := vm.CreateTransaction(0, big.NewInt(100), sndAddr, scAddress, gasPrice, gasLimit, []byte("increment")) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/relayedScDeploy_test.go b/integrationTests/vm/txsFee/relayedScDeploy_test.go index d56071d61ec..d1eac0ce8d0 100644 --- a/integrationTests/vm/txsFee/relayedScDeploy_test.go +++ b/integrationTests/vm/txsFee/relayedScDeploy_test.go @@ -10,8 +10,8 @@ import ( "testing" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" - "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" "github.com/multiversx/mx-chain-go/integrationTests/vm/wasm" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/require" @@ -36,7 +36,7 @@ func TestRelayedScDeployShouldWork(t *testing.T) { scCode := wasm.GetSCCode("../wasm/testdata/misc/fib_wasm/output/fib_wasm.wasm") userTx := vm.CreateTransaction(senderNonce, big.NewInt(0), sndAddr, vm.CreateEmptyAddress(), gasPrice, gasLimit, []byte(wasm.CreateDeployTxData(scCode))) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, big.NewInt(0), relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -79,7 +79,7 @@ func TestRelayedScDeployInvalidCodeShouldConsumeGas(t *testing.T) { scCodeBytes = append(scCodeBytes, []byte("aaaaa")...) userTx := vm.CreateTransaction(senderNonce, big.NewInt(0), sndAddr, vm.CreateEmptyAddress(), gasPrice, gasLimit, scCodeBytes) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, big.NewInt(0), relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -119,7 +119,7 @@ func TestRelayedScDeployInsufficientGasLimitShouldConsumeGas(t *testing.T) { scCode := wasm.GetSCCode("../wasm/testdata/misc/fib_wasm/output/fib_wasm.wasm") userTx := vm.CreateTransaction(senderNonce, big.NewInt(0), sndAddr, vm.CreateEmptyAddress(), gasPrice, gasLimit, []byte(wasm.CreateDeployTxData(scCode))) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, big.NewInt(0), relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) @@ -159,7 +159,7 @@ func TestRelayedScDeployOutOfGasShouldConsumeGas(t *testing.T) { scCode := wasm.GetSCCode("../wasm/testdata/misc/fib_wasm/output/fib_wasm.wasm") userTx := vm.CreateTransaction(senderNonce, big.NewInt(0), sndAddr, vm.CreateEmptyAddress(), gasPrice, gasLimit, []byte(wasm.CreateDeployTxData(scCode))) - rtxData := utils.PrepareRelayerTxData(userTx) + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) rtx := vm.CreateTransaction(0, big.NewInt(0), relayerAddr, sndAddr, gasPrice, rTxGasLimit, rtxData) diff --git a/integrationTests/vm/txsFee/utils/utils.go b/integrationTests/vm/txsFee/utils/utils.go index 1d9e114d8c2..8947805befa 100644 --- a/integrationTests/vm/txsFee/utils/utils.go +++ b/integrationTests/vm/txsFee/utils/utils.go @@ -11,7 +11,6 @@ import ( "strings" "testing" - "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/scheduled" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" @@ -257,12 +256,6 @@ func DoDeployDNS(t *testing.T, testContext *vm.VMTestContext, pathToContract str return scAddr, owner } -// PrepareRelayerTxData - -func PrepareRelayerTxData(innerTx *transaction.Transaction) []byte { - userTxBytes, _ := protoMarshalizer.Marshal(innerTx) - return []byte(core.RelayedTransaction + "@" + hex.EncodeToString(userTxBytes)) -} - // CheckOwnerAddr - func CheckOwnerAddr(t *testing.T, testContext *vm.VMTestContext, scAddr []byte, owner []byte) { acc, err := testContext.Accounts.GetExistingAccount(scAddr) From 7fc3e90340199dc6fa1b4e1f66abc168e140d4aa Mon Sep 17 00:00:00 2001 From: AdoAdoAdo Date: Wed, 24 May 2023 20:52:08 +0300 Subject: [PATCH 5/9] fix tests and use correct flag --- .../multiShard/relayedTx/edgecases/edgecases_test.go | 4 ++-- process/transaction/shardProcess.go | 2 +- sharding/mock/enableEpochsHandlerMock.go | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/integrationTests/multiShard/relayedTx/edgecases/edgecases_test.go b/integrationTests/multiShard/relayedTx/edgecases/edgecases_test.go index b81667b041d..246a81fbe15 100644 --- a/integrationTests/multiShard/relayedTx/edgecases/edgecases_test.go +++ b/integrationTests/multiShard/relayedTx/edgecases/edgecases_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestRelayedTransactionInMultiShardEnvironmentWithNormalTxButWrongNonce(t *testing.T) { +func TestRelayedTransactionInMultiShardEnvironmentWithNormalTxButWrongNonceShouldNotIncrementUserAccNonce(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") } @@ -68,7 +68,7 @@ func TestRelayedTransactionInMultiShardEnvironmentWithNormalTxButWrongNonce(t *t for _, player := range players { account := relayedTx.GetUserAccount(nodes, player.Address) assert.True(t, account.GetBalance().Cmp(big.NewInt(0)) == 0) - assert.Equal(t, uint64(nrRoundsToTest)*2, account.GetNonce()) + assert.Equal(t, uint64(0), account.GetNonce()) } expectedBalance := big.NewInt(0).Sub(relayerInitialValue, totalFees) diff --git a/process/transaction/shardProcess.go b/process/transaction/shardProcess.go index 42d570f2c0d..9c3472a94cb 100644 --- a/process/transaction/shardProcess.go +++ b/process/transaction/shardProcess.go @@ -945,7 +945,7 @@ func (txProc *txProcessor) executeFailedRelayedUserTx( } func (txProc *txProcessor) shouldIncreaseNonce(executionErr error) bool { - if !txProc.enableEpochsHandler.IsRelayedTransactionsFlagEnabled() { + if !txProc.enableEpochsHandler.IsRelayedNonceFixEnabled() { return true } diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 759989fac3c..978fbb0a202 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -566,9 +566,8 @@ func (mock *EnableEpochsHandlerMock) IsAlwaysSaveTokenMetaDataEnabled() bool { return false } -// IsRelayedNonceFixEnableEpoch - -func (mock *EnableEpochsHandlerMock) IsRelayedNonceFixEnableEpoch() bool { - return true +func (mock *EnableEpochsHandlerMock) IsRelayedNonceFixEnabled() bool { + return false } // IsInterfaceNil returns true if there is no value under the interface From 824ec7c6ff083f9d5360e440b57ffea0c4650ac5 Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 24 May 2023 20:53:15 +0300 Subject: [PATCH 6/9] - fixed tests --- integrationTests/vm/txsFee/relayedMoveBalance_test.go | 8 +++++--- process/transaction/shardProcess.go | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/integrationTests/vm/txsFee/relayedMoveBalance_test.go b/integrationTests/vm/txsFee/relayedMoveBalance_test.go index e57ebbc3daf..e2334a800e2 100644 --- a/integrationTests/vm/txsFee/relayedMoveBalance_test.go +++ b/integrationTests/vm/txsFee/relayedMoveBalance_test.go @@ -127,7 +127,9 @@ func TestRelayedMoveBalanceInvalidUserTxShouldConsumeGas(t *testing.T) { } func TestRelayedMoveBalanceInvalidUserTxValueShouldConsumeGas(t *testing.T) { - testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) + testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 1, + }) require.Nil(t, err) defer testContext.Close() @@ -160,7 +162,7 @@ func TestRelayedMoveBalanceInvalidUserTxValueShouldConsumeGas(t *testing.T) { func TestRelayedMoveBalanceHigherNonce(t *testing.T) { testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{ - RelayedNonceFixEnableEpoch: 0, + RelayedNonceFixEnableEpoch: 1, }) require.Nil(t, err) defer testContext.Close() @@ -212,7 +214,7 @@ func TestRelayedMoveBalanceHigherNonce(t *testing.T) { func TestRelayedMoveBalanceLowerNonce(t *testing.T) { testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{ - RelayedNonceFixEnableEpoch: 0, + RelayedNonceFixEnableEpoch: 1, }) require.Nil(t, err) defer testContext.Close() diff --git a/process/transaction/shardProcess.go b/process/transaction/shardProcess.go index 42d570f2c0d..9c3472a94cb 100644 --- a/process/transaction/shardProcess.go +++ b/process/transaction/shardProcess.go @@ -945,7 +945,7 @@ func (txProc *txProcessor) executeFailedRelayedUserTx( } func (txProc *txProcessor) shouldIncreaseNonce(executionErr error) bool { - if !txProc.enableEpochsHandler.IsRelayedTransactionsFlagEnabled() { + if !txProc.enableEpochsHandler.IsRelayedNonceFixEnabled() { return true } From db2d71dccd38109517212c68af52688a9b7a86cc Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 24 May 2023 21:11:58 +0300 Subject: [PATCH 7/9] - changed existing tests --- .../vm/txsFee/relayedAsyncCall_test.go | 28 +++++++++++++++++-- .../vm/txsFee/relayedBuiltInFunctions_test.go | 25 +++++++++++++++-- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/integrationTests/vm/txsFee/relayedAsyncCall_test.go b/integrationTests/vm/txsFee/relayedAsyncCall_test.go index 36b739007a3..4a15cba4334 100644 --- a/integrationTests/vm/txsFee/relayedAsyncCall_test.go +++ b/integrationTests/vm/txsFee/relayedAsyncCall_test.go @@ -15,16 +15,36 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestRelayedAsyncCallShouldWork(t *testing.T) { - testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) + senderAddr := []byte("12345678901234567890123456789011") + + t.Run("nonce fix is disabled, should increase the sender's nonce", func(t *testing.T) { + testContext := testRelayedAsyncCallShouldWork(t, config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 100000, + }, senderAddr) + + senderAccount := getAccount(t, testContext, senderAddr) + assert.Equal(t, uint64(1), senderAccount.GetNonce()) + }) + t.Run("nonce fix is enabled, should still increase the sender's nonce", func(t *testing.T) { + testContext := testRelayedAsyncCallShouldWork(t, config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 0, + }, senderAddr) + + senderAccount := getAccount(t, testContext, senderAddr) + assert.Equal(t, uint64(1), senderAccount.GetNonce()) + }) +} + +func testRelayedAsyncCallShouldWork(t *testing.T, enableEpochs config.EnableEpochs, senderAddr []byte) *vm.VMTestContext { + testContext, err := vm.CreatePreparedTxProcessorWithVMs(enableEpochs) require.Nil(t, err) - defer testContext.Close() egldBalance := big.NewInt(100000000) - senderAddr := []byte("12345678901234567890123456789011") ownerAddr := []byte("12345678901234567890123456789010") relayerAddr := []byte("12345678901234567890123456789017") @@ -70,4 +90,6 @@ func TestRelayedAsyncCallShouldWork(t *testing.T) { require.Equal(t, big.NewInt(50001950), testContext.TxFeeHandler.GetAccumulatedFees()) require.Equal(t, big.NewInt(4999988), testContext.TxFeeHandler.GetDeveloperFees()) + + return testContext } diff --git a/integrationTests/vm/txsFee/relayedBuiltInFunctions_test.go b/integrationTests/vm/txsFee/relayedBuiltInFunctions_test.go index b4be8665953..0e62c0cd303 100644 --- a/integrationTests/vm/txsFee/relayedBuiltInFunctions_test.go +++ b/integrationTests/vm/txsFee/relayedBuiltInFunctions_test.go @@ -162,7 +162,28 @@ func TestRelayedBuildInFunctionChangeOwnerInvalidAddressShouldConsumeGas(t *test } func TestRelayedBuildInFunctionChangeOwnerCallInsufficientGasLimitShouldConsumeGas(t *testing.T) { - testContext, err := vm.CreatePreparedTxProcessorWithVMs(config.EnableEpochs{}) + t.Run("nonce fix is disabled, should increase the sender's nonce", func(t *testing.T) { + testRelayedBuildInFunctionChangeOwnerCallInsufficientGasLimitShouldConsumeGas(t, + config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 1000, + }, + 2) + }) + t.Run("nonce fix is enabled, should still increase the sender's nonce", func(t *testing.T) { + testRelayedBuildInFunctionChangeOwnerCallInsufficientGasLimitShouldConsumeGas(t, + config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 0, + }, + 2) + }) +} + +func testRelayedBuildInFunctionChangeOwnerCallInsufficientGasLimitShouldConsumeGas( + t *testing.T, + enableEpochs config.EnableEpochs, + expectedOwnerNonce uint64, +) { + testContext, err := vm.CreatePreparedTxProcessorWithVMs(enableEpochs) require.Nil(t, err) defer testContext.Close() @@ -196,7 +217,7 @@ func TestRelayedBuildInFunctionChangeOwnerCallInsufficientGasLimitShouldConsumeG vm.TestAccount(t, testContext.Accounts, relayerAddr, 1, expectedBalanceRelayer) expectedBalance := big.NewInt(89030) - vm.TestAccount(t, testContext.Accounts, owner, 2, expectedBalance) + vm.TestAccount(t, testContext.Accounts, owner, expectedOwnerNonce, expectedBalance) // check accumulated fees accumulatedFees := testContext.TxFeeHandler.GetAccumulatedFees() From 25c2a4f9b68ec101456792ee11f78b64664d7088 Mon Sep 17 00:00:00 2001 From: jules01 Date: Wed, 24 May 2023 21:30:26 +0300 Subject: [PATCH 8/9] - finalized PR, added unit tests --- common/enablers/enableEpochsHandler_test.go | 9 ++++-- config/tomlConfig_test.go | 4 +++ process/transaction/export_test.go | 5 +++ process/transaction/shardProcess_test.go | 35 +++++++++++++++++++++ sharding/mock/enableEpochsHandlerMock.go | 1 + 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/common/enablers/enableEpochsHandler_test.go b/common/enablers/enableEpochsHandler_test.go index 661d684f010..aeb4639241a 100644 --- a/common/enablers/enableEpochsHandler_test.go +++ b/common/enablers/enableEpochsHandler_test.go @@ -1,6 +1,7 @@ package enablers import ( + "math" "testing" "github.com/multiversx/mx-chain-core-go/core/check" @@ -91,6 +92,7 @@ func createEnableEpochsConfig() config.EnableEpochs { WipeSingleNFTLiquidityDecreaseEnableEpoch: 75, AlwaysSaveTokenMetaDataEnableEpoch: 76, RuntimeCodeSizeFixEnableEpoch: 77, + RelayedNonceFixEnableEpoch: 78, } } @@ -129,7 +131,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { handler, _ := NewEnableEpochsHandler(cfg, &epochNotifier.EpochNotifierStub{}) require.False(t, check.IfNil(handler)) - handler.EpochConfirmed(77, 0) + handler.EpochConfirmed(math.MaxUint32, 0) assert.Equal(t, cfg.BlockGasAndFeesReCheckEnableEpoch, handler.BlockGasAndFeesReCheckEnableEpoch()) assert.True(t, handler.IsSCDeployFlagEnabled()) @@ -213,11 +215,12 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsMaxBlockchainHookCountersFlagEnabled()) assert.True(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) assert.True(t, handler.IsRuntimeCodeSizeFixEnabled()) + assert.True(t, handler.IsRelayedNonceFixEnabled()) }) t.Run("flags with == condition should be set, along with all >=", func(t *testing.T) { t.Parallel() - epoch := uint32(78) + epoch := uint32(math.MaxUint32) cfg := createEnableEpochsConfig() cfg.StakingV2EnableEpoch = epoch cfg.ESDTEnableEpoch = epoch @@ -313,6 +316,7 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.True(t, handler.IsWipeSingleNFTLiquidityDecreaseEnabled()) assert.True(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) assert.True(t, handler.IsRuntimeCodeSizeFixEnabled()) + assert.True(t, handler.IsRelayedNonceFixEnabled()) }) t.Run("flags with < should be set", func(t *testing.T) { t.Parallel() @@ -408,5 +412,6 @@ func TestNewEnableEpochsHandler_EpochConfirmed(t *testing.T) { assert.False(t, handler.IsWipeSingleNFTLiquidityDecreaseEnabled()) assert.False(t, handler.IsAlwaysSaveTokenMetaDataEnabled()) assert.False(t, handler.IsRuntimeCodeSizeFixEnabled()) + assert.False(t, handler.IsRelayedNonceFixEnabled()) }) } diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index a3cc8c949dc..f46ce8d2514 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -684,6 +684,9 @@ func TestEnableEpochConfig(t *testing.T) { # RuntimeMemStoreLimitEnableEpoch represents the epoch when the condition for Runtime MemStore is enabled RuntimeMemStoreLimitEnableEpoch = 63 + # RelayedNonceFixEnableEpoch represents the epoch when the nonce fix for relayed txs is enabled + RelayedNonceFixEnableEpoch = 64 + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 44, MaxNumNodes = 2169, NodesToShufflePerShard = 80 }, @@ -779,6 +782,7 @@ func TestEnableEpochConfig(t *testing.T) { AlwaysSaveTokenMetaDataEnableEpoch: 61, RuntimeCodeSizeFixEnableEpoch: 62, RuntimeMemStoreLimitEnableEpoch: 63, + RelayedNonceFixEnableEpoch: 64, BLSMultiSignerEnableEpoch: []MultiSignerConfig{ { EnableEpoch: 0, diff --git a/process/transaction/export_test.go b/process/transaction/export_test.go index 742fc618b6d..e98a9faa4f3 100644 --- a/process/transaction/export_test.go +++ b/process/transaction/export_test.go @@ -79,3 +79,8 @@ func (txProc *txProcessor) ExecuteFailedRelayedTransaction( originalTxHash, errorMsg) } + +// ShouldIncreaseNonce - +func (txProc *txProcessor) ShouldIncreaseNonce(executionErr error) bool { + return txProc.shouldIncreaseNonce(executionErr) +} diff --git a/process/transaction/shardProcess_test.go b/process/transaction/shardProcess_test.go index 8a881499a4b..c7492965e91 100644 --- a/process/transaction/shardProcess_test.go +++ b/process/transaction/shardProcess_test.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "encoding/hex" "errors" + "fmt" "math/big" "testing" @@ -3236,3 +3237,37 @@ func TestTxProcessor_ExecuteFailingRelayedTxShouldNotHaveNegativeFee(t *testing. assert.Nil(t, err) assert.False(t, negativeCost) } + +func TestTxProcessor_shouldIncreaseNonce(t *testing.T) { + t.Parallel() + + t.Run("fix not enabled, should return true", func(t *testing.T) { + args := createArgsForTxProcessor() + args.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{ + IsRelayedNonceFixEnabledField: false, + } + txProc, _ := txproc.NewTxProcessor(args) + + assert.True(t, txProc.ShouldIncreaseNonce(nil)) + }) + t.Run("fix enabled, different errors should return true", func(t *testing.T) { + args := createArgsForTxProcessor() + args.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{ + IsRelayedNonceFixEnabledField: true, + } + txProc, _ := txproc.NewTxProcessor(args) + + assert.True(t, txProc.ShouldIncreaseNonce(nil)) + assert.True(t, txProc.ShouldIncreaseNonce(fmt.Errorf("random error"))) + }) + t.Run("fix enabled, errors for an un-executable transaction should return false", func(t *testing.T) { + args := createArgsForTxProcessor() + args.EnableEpochsHandler = &testscommon.EnableEpochsHandlerStub{ + IsRelayedNonceFixEnabledField: true, + } + txProc, _ := txproc.NewTxProcessor(args) + + assert.False(t, txProc.ShouldIncreaseNonce(process.ErrLowerNonceInTransaction)) + assert.False(t, txProc.ShouldIncreaseNonce(process.ErrHigherNonceInTransaction)) + }) +} diff --git a/sharding/mock/enableEpochsHandlerMock.go b/sharding/mock/enableEpochsHandlerMock.go index 978fbb0a202..c57f7e899e8 100644 --- a/sharding/mock/enableEpochsHandlerMock.go +++ b/sharding/mock/enableEpochsHandlerMock.go @@ -566,6 +566,7 @@ func (mock *EnableEpochsHandlerMock) IsAlwaysSaveTokenMetaDataEnabled() bool { return false } +// IsRelayedNonceFixEnabled - func (mock *EnableEpochsHandlerMock) IsRelayedNonceFixEnabled() bool { return false } From 9c9c3958ad4b3c46c25b4a2ee3af744567e32ef0 Mon Sep 17 00:00:00 2001 From: jules01 Date: Thu, 25 May 2023 16:38:34 +0300 Subject: [PATCH 9/9] - fixed tests & added a cross shard scenario --- .../vm/txsFee/relayedAsyncCall_test.go | 2 + .../vm/txsFee/relayedMoveBalance_test.go | 72 ++++++++++++++++--- .../vm/txsFee/relayedScCalls_test.go | 72 +++++++++++++++++++ 3 files changed, 137 insertions(+), 9 deletions(-) diff --git a/integrationTests/vm/txsFee/relayedAsyncCall_test.go b/integrationTests/vm/txsFee/relayedAsyncCall_test.go index 4a15cba4334..39a3dbc8f12 100644 --- a/integrationTests/vm/txsFee/relayedAsyncCall_test.go +++ b/integrationTests/vm/txsFee/relayedAsyncCall_test.go @@ -26,6 +26,7 @@ func TestRelayedAsyncCallShouldWork(t *testing.T) { testContext := testRelayedAsyncCallShouldWork(t, config.EnableEpochs{ RelayedNonceFixEnableEpoch: 100000, }, senderAddr) + defer testContext.Close() senderAccount := getAccount(t, testContext, senderAddr) assert.Equal(t, uint64(1), senderAccount.GetNonce()) @@ -34,6 +35,7 @@ func TestRelayedAsyncCallShouldWork(t *testing.T) { testContext := testRelayedAsyncCallShouldWork(t, config.EnableEpochs{ RelayedNonceFixEnableEpoch: 0, }, senderAddr) + defer testContext.Close() senderAccount := getAccount(t, testContext, senderAddr) assert.Equal(t, uint64(1), senderAccount.GetNonce()) diff --git a/integrationTests/vm/txsFee/relayedMoveBalance_test.go b/integrationTests/vm/txsFee/relayedMoveBalance_test.go index e2334a800e2..07cdb9d5932 100644 --- a/integrationTests/vm/txsFee/relayedMoveBalance_test.go +++ b/integrationTests/vm/txsFee/relayedMoveBalance_test.go @@ -10,6 +10,8 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests" "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/testscommon/integrationtests" vmcommon "github.com/multiversx/mx-chain-vm-common-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -179,14 +181,14 @@ func TestRelayedMoveBalanceHigherNonce(t *testing.T) { initialSenderNonce := getAccount(t, testContext, sndAddr).GetNonce() rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) - executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr, vmcommon.UserError) senderAccount := getAccount(t, testContext, sndAddr) require.NotNil(t, senderAccount) assert.Equal(t, initialSenderNonce+1, senderAccount.GetNonce()) rtxDataV2 := integrationTests.PrepareRelayedTxDataV2(userTx) - executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr, vmcommon.UserError) senderAccount = getAccount(t, testContext, sndAddr) require.NotNil(t, senderAccount) @@ -197,14 +199,14 @@ func TestRelayedMoveBalanceHigherNonce(t *testing.T) { initialSenderNonce := getAccount(t, testContext, sndAddr).GetNonce() rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) - executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr, vmcommon.UserError) senderAccount := getAccount(t, testContext, sndAddr) require.NotNil(t, senderAccount) assert.Equal(t, initialSenderNonce, senderAccount.GetNonce()) rtxDataV2 := integrationTests.PrepareRelayedTxDataV2(userTx) - executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr, vmcommon.UserError) senderAccount = getAccount(t, testContext, sndAddr) require.NotNil(t, senderAccount) @@ -231,14 +233,14 @@ func TestRelayedMoveBalanceLowerNonce(t *testing.T) { initialSenderNonce := getAccount(t, testContext, sndAddr).GetNonce() rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) - executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr, vmcommon.UserError) senderAccount := getAccount(t, testContext, sndAddr) require.NotNil(t, senderAccount) assert.Equal(t, initialSenderNonce+1, senderAccount.GetNonce()) rtxDataV2 := integrationTests.PrepareRelayedTxDataV2(userTx) - executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr, vmcommon.UserError) senderAccount = getAccount(t, testContext, sndAddr) require.NotNil(t, senderAccount) @@ -249,14 +251,14 @@ func TestRelayedMoveBalanceLowerNonce(t *testing.T) { initialSenderNonce := getAccount(t, testContext, sndAddr).GetNonce() rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) - executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr, vmcommon.UserError) senderAccount := getAccount(t, testContext, sndAddr) require.NotNil(t, senderAccount) assert.Equal(t, initialSenderNonce, senderAccount.GetNonce()) rtxDataV2 := integrationTests.PrepareRelayedTxDataV2(userTx) - executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr) + executeRelayedTransaction(t, testContext, relayerAddr, userTx, rtxDataV2, big.NewInt(0), sndAddr, vmcommon.UserError) senderAccount = getAccount(t, testContext, sndAddr) require.NotNil(t, senderAccount) @@ -264,6 +266,57 @@ func TestRelayedMoveBalanceLowerNonce(t *testing.T) { }) } +func TestRelayedMoveBalanceHigherNonceWithActivatedFixCrossShard(t *testing.T) { + enableEpochs := config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 0, + } + + shardCoordinator0, _ := sharding.NewMultiShardCoordinator(2, 0) + testContext0, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGas( + enableEpochs, + shardCoordinator0, + integrationtests.CreateMemUnit(), + vm.CreateMockGasScheduleNotifier(), + ) + require.Nil(t, err) + + shardCoordinator1, _ := sharding.NewMultiShardCoordinator(2, 1) + testContext1, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinatorDBAndGas( + enableEpochs, + shardCoordinator1, + integrationtests.CreateMemUnit(), + vm.CreateMockGasScheduleNotifier(), + ) + require.Nil(t, err) + defer testContext0.Close() + defer testContext1.Close() + + relayerAddr := []byte("relayer-000000000000000000000000") + assert.Equal(t, uint32(0), shardCoordinator0.ComputeId(relayerAddr)) // shard 0 + sndAddr := []byte("sender-1111111111111111111111111") + assert.Equal(t, uint32(1), shardCoordinator0.ComputeId(sndAddr)) // shard 1 + rcvAddr := []byte("receiver-22222222222222222222222") + assert.Equal(t, uint32(0), shardCoordinator0.ComputeId(rcvAddr)) // shard 0 + + _, _ = vm.CreateAccount(testContext0.Accounts, relayerAddr, 0, big.NewInt(3000)) // create relayer in shard 0 + _, _ = vm.CreateAccount(testContext1.Accounts, sndAddr, 0, big.NewInt(0)) // create sender in shard 1 + + userTx := vm.CreateTransaction(1, big.NewInt(150), sndAddr, rcvAddr, 1, 100, nil) + initialSenderNonce := getAccount(t, testContext1, sndAddr).GetNonce() + + rtxDataV1 := integrationTests.PrepareRelayedTxDataV1(userTx) + executeRelayedTransaction(t, testContext0, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr, vmcommon.Ok) + + results := testContext0.GetIntermediateTransactions(t) + assert.Equal(t, 0, len(results)) // no scrs, the exact relayed tx will be executed on the receiver shard + + executeRelayedTransaction(t, testContext1, relayerAddr, userTx, rtxDataV1, big.NewInt(100), sndAddr, vmcommon.UserError) + + senderAccount := getAccount(t, testContext1, sndAddr) + require.NotNil(t, senderAccount) + assert.Equal(t, initialSenderNonce, senderAccount.GetNonce()) +} + func executeRelayedTransaction( tb testing.TB, testContext *vm.VMTestContext, @@ -272,13 +325,14 @@ func executeRelayedTransaction( userTxPrepared []byte, value *big.Int, senderAddress []byte, + expectedReturnCode vmcommon.ReturnCode, ) { relayerAccount := getAccount(tb, testContext, relayerAddress) gasLimit := 1 + userTx.GasLimit + uint64(len(userTxPrepared)) relayedTx := vm.CreateTransaction(relayerAccount.GetNonce(), value, relayerAddress, senderAddress, 1, gasLimit, userTxPrepared) retCode, _ := testContext.TxProcessor.ProcessTransaction(relayedTx) - require.Equal(tb, vmcommon.UserError, retCode) + require.Equal(tb, expectedReturnCode, retCode) _, err := testContext.Accounts.Commit() require.Nil(tb, err) diff --git a/integrationTests/vm/txsFee/relayedScCalls_test.go b/integrationTests/vm/txsFee/relayedScCalls_test.go index 5108a313f44..45736d7771e 100644 --- a/integrationTests/vm/txsFee/relayedScCalls_test.go +++ b/integrationTests/vm/txsFee/relayedScCalls_test.go @@ -15,6 +15,7 @@ import ( "github.com/multiversx/mx-chain-go/integrationTests/vm" "github.com/multiversx/mx-chain-go/integrationTests/vm/txsFee/utils" vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -219,3 +220,74 @@ func TestRelayedScCallOutOfGasShouldConsumeGas(t *testing.T) { developerFees := testContext.TxFeeHandler.GetDeveloperFees() require.Equal(t, big.NewInt(368), developerFees) } + +func TestRelayedDeployInvalidContractShouldIncrementNonceOnSender(t *testing.T) { + senderAddr := []byte("12345678901234567890123456789011") + + t.Run("nonce fix is disabled, should increase the sender's nonce if inner tx has correct nonce", func(t *testing.T) { + testContext := testRelayedDeployInvalidContractShouldIncrementNonceOnSender(t, config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 100000, + }, + senderAddr, + 0) + defer testContext.Close() + + senderAccount := getAccount(t, testContext, senderAddr) + assert.Equal(t, uint64(1), senderAccount.GetNonce()) + }) + t.Run("nonce fix is enabled, should still increase the sender's nonce if inner tx has correct nonce", func(t *testing.T) { + testContext := testRelayedDeployInvalidContractShouldIncrementNonceOnSender(t, config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 0, + }, + senderAddr, + 0) + defer testContext.Close() + + senderAccount := getAccount(t, testContext, senderAddr) + assert.Equal(t, uint64(1), senderAccount.GetNonce()) + }) + t.Run("nonce fix is enabled, should not increase the sender's nonce if inner tx has higher nonce", func(t *testing.T) { + testContext := testRelayedDeployInvalidContractShouldIncrementNonceOnSender(t, config.EnableEpochs{ + RelayedNonceFixEnableEpoch: 0, + }, + senderAddr, + 1) // higher nonce, the current is 0 + defer testContext.Close() + + senderAccount := getAccount(t, testContext, senderAddr) + assert.Equal(t, uint64(0), senderAccount.GetNonce()) + }) +} + +func testRelayedDeployInvalidContractShouldIncrementNonceOnSender( + t *testing.T, + enableEpochs config.EnableEpochs, + senderAddr []byte, + senderNonce uint64, +) *vm.VMTestContext { + testContext, err := vm.CreatePreparedTxProcessorWithVMs(enableEpochs) + require.Nil(t, err) + + relayerAddr := []byte("12345678901234567890123456789033") + gasPrice := uint64(10) + gasLimit := uint64(20) + + _, _ = vm.CreateAccount(testContext.Accounts, senderAddr, 0, big.NewInt(0)) + _, _ = vm.CreateAccount(testContext.Accounts, relayerAddr, 0, big.NewInt(30000)) + + emptyAddress := make([]byte, len(senderAddr)) + userTx := vm.CreateTransaction(senderNonce, big.NewInt(100), senderAddr, emptyAddress, gasPrice, gasLimit, nil) + + rtxData := integrationTests.PrepareRelayedTxDataV1(userTx) + rTxGasLimit := 1 + gasLimit + uint64(len(rtxData)) + rtx := vm.CreateTransaction(0, userTx.Value, relayerAddr, senderAddr, gasPrice, rTxGasLimit, rtxData) + + retCode, err := testContext.TxProcessor.ProcessTransaction(rtx) + require.Equal(t, vmcommon.UserError, retCode) + require.Nil(t, err) + + _, err = testContext.Accounts.Commit() + require.Nil(t, err) + + return testContext +}