Skip to content

Commit

Permalink
Merge pull request #323 from multiversx/more-refund-tests-2024.08.14
Browse files Browse the repository at this point in the history
More refund tests 2024.08.14
  • Loading branch information
iulianpascalau authored Aug 16, 2024
2 parents 216db92 + 57ce198 commit a718794
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 52 deletions.
2 changes: 1 addition & 1 deletion executors/multiversx/scCallsExecutor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func createTestProxySCCompleteCallData(token string) parsers.ProxySCCompleteCall
Type: 1,
Function: "callMe",
GasLimit: 5000000,
Arguments: []interface{}{"arg1", "arg2"},
Arguments: []string{"arg1", "arg2"},
}),
From: common.Address{},
Token: token,
Expand Down
7 changes: 6 additions & 1 deletion integrationTests/relayers/slowTests/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
"github.com/multiversx/mx-bridge-eth-go/integrationTests/relayers/slowTests/framework"
"github.com/multiversx/mx-bridge-eth-go/parsers"
"github.com/multiversx/mx-bridge-eth-go/testsCommon"
logger "github.com/multiversx/mx-chain-logger-go"
)

var (
log = logger.GetOrCreate("integrationTests/relayers/slowTests")
)

// GenerateTestUSDCToken will generate a test USDC token
Expand Down Expand Up @@ -93,7 +98,7 @@ func GenerateTestMEMEToken() framework.TestTokenParams {
}
}

func createScCallData(function string, gasLimit uint64, args ...interface{}) []byte {
func createScCallData(function string, gasLimit uint64, args ...string) []byte {
codec := testsCommon.TestMultiversXCodec{}
callData := parsers.CallData{
Type: bridgeCore.DataPresentProtocolMarker,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,59 @@ package slowTests

import (
"context"
"encoding/binary"
"errors"
"fmt"
"math/big"
"os"
"strings"
"testing"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/multiversx/mx-bridge-eth-go/integrationTests/mock"
"github.com/multiversx/mx-bridge-eth-go/integrationTests/relayers/slowTests/framework"
logger "github.com/multiversx/mx-chain-logger-go"
"github.com/multiversx/mx-sdk-go/data"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const (
timeout = time.Minute * 15
)

var (
log = logger.GetOrCreate("integrationTests/relayers/slowTests")
)

func TestRelayersShouldExecuteTransfers(t *testing.T) {
testRelayersWithChainSimulatorAndTokens(
_ = testRelayersWithChainSimulatorAndTokens(
t,
make(chan error),
GenerateTestUSDCToken(),
GenerateTestMEMEToken(),
)
}

func TestRelayersShouldExecuteTransfersWithSCCallsWithParameters(t *testing.T) {
dummyAddress := strings.Repeat("2", 32)
dummyUint64 := string([]byte{37})

callData := createScCallData("callPayableWithParams", 50000000, dummyUint64, dummyAddress)

usdcToken := GenerateTestUSDCToken()
usdcToken.TestOperations[2].MvxSCCallData = callData

memeToken := GenerateTestMEMEToken()
memeToken.TestOperations[2].MvxSCCallData = callData

testSetup := testRelayersWithChainSimulatorAndTokens(
t,
make(chan error),
usdcToken,
memeToken,
)

testCallPayableWithParamsWasCalled(testSetup, 37, usdcToken.AbstractTokenIdentifier, memeToken.AbstractTokenIdentifier)
}

func TestRelayerShouldExecuteTransfersAndNotCatchErrors(t *testing.T) {
errorString := "ERROR"
mockLogObserver := mock.NewMockLogObserver(errorString)
Expand All @@ -63,14 +85,14 @@ func TestRelayerShouldExecuteTransfersAndNotCatchErrors(t *testing.T) {
}
}()

testRelayersWithChainSimulatorAndTokens(
_ = testRelayersWithChainSimulatorAndTokens(
t,
stopChan,
GenerateTestMEMEToken(),
)
}

func testRelayersWithChainSimulatorAndTokens(tb testing.TB, manualStopChan chan error, tokens ...framework.TestTokenParams) {
func testRelayersWithChainSimulatorAndTokens(tb testing.TB, manualStopChan chan error, tokens ...framework.TestTokenParams) *framework.TestSetup {
startsFromEthFlow, startsFromMvXFlow := createFlowsBasedOnToken(tb, tokens...)

setupFunc := func(tb testing.TB, setup *framework.TestSetup) {
Expand Down Expand Up @@ -100,7 +122,7 @@ func testRelayersWithChainSimulatorAndTokens(tb testing.TB, manualStopChan chan
return false
}

testRelayersWithChainSimulator(tb,
return testRelayersWithChainSimulator(tb,
setupFunc,
processFunc,
manualStopChan,
Expand Down Expand Up @@ -138,7 +160,7 @@ func testRelayersWithChainSimulator(tb testing.TB,
setupFunc func(tb testing.TB, setup *framework.TestSetup),
processLoopFunc func(tb testing.TB, setup *framework.TestSetup) bool,
stopChan chan error,
) {
) *framework.TestSetup {
defer func() {
r := recover()
if r != nil {
Expand All @@ -159,17 +181,17 @@ func testRelayersWithChainSimulator(tb testing.TB,
select {
case <-interrupt:
require.Fail(tb, "signal interrupted")
return
return testSetup
case <-time.After(timeout):
require.Fail(tb, "time out")
return
return testSetup
case err := <-stopChan:
require.Nil(tb, err)
return
return testSetup
default:
testDone := processLoopFunc(tb, testSetup)
if testDone {
return
return testSetup
}
}
}
Expand Down Expand Up @@ -317,7 +339,7 @@ func testRelayersShouldNotExecuteTransfers(
}
}()

testRelayersWithChainSimulator(tb, setupFunc, processFunc, stopChan)
_ = testRelayersWithChainSimulator(tb, setupFunc, processFunc, stopChan)
}

func testEthContractsShouldError(tb testing.TB, testToken framework.TestTokenParams) {
Expand All @@ -341,9 +363,43 @@ func testEthContractsShouldError(tb testing.TB, testToken framework.TestTokenPar
return true
}

testRelayersWithChainSimulator(tb,
_ = testRelayersWithChainSimulator(tb,
setupFunc,
processFunc,
make(chan error),
)
}

func testCallPayableWithParamsWasCalled(testSetup *framework.TestSetup, value uint64, tokens ...string) {
if len(tokens) == 0 {
return
}

vmRequest := &data.VmValueRequest{
Address: testSetup.MultiversxHandler.TestCallerAddress.Bech32(),
FuncName: "getCalledDataParams",
}

vmResponse, err := testSetup.ChainSimulator.Proxy().ExecuteVMQuery(context.Background(), vmRequest)
require.Nil(testSetup, err)

returnedData := vmResponse.Data.ReturnData
require.Equal(testSetup, len(tokens), len(returnedData))

for i, token := range tokens {
buff := returnedData[i]
parsedValue, parsedToken := processCalledDataParams(buff)
assert.Equal(testSetup, value, parsedValue)
assert.Contains(testSetup, parsedToken, token)
}
}

func processCalledDataParams(buff []byte) (uint64, string) {
valBuff := buff[:8]
value := binary.BigEndian.Uint64(valBuff)

buff = buff[8+32+4:] // trim the nonce, address and length of the token
token := string(buff)

return value, token
}
Original file line number Diff line number Diff line change
Expand Up @@ -188,20 +188,6 @@ func (instance *chainSimulatorWrapper) GenerateBlocksUntilTxProcessed(ctx contex
}
}

func (instance *chainSimulatorWrapper) getTxInfoWithResultsIfTxProcessingFinished(ctx context.Context, hash string) (transaction.TxStatus, *data.TransactionOnNetwork) {
txStatus, err := instance.proxyInstance.ProcessTransactionStatus(ctx, hash)
require.Nil(instance, err)

if txStatus != transaction.TxStatusSuccess {
return txStatus, nil
}

txResult, errGet := instance.proxyInstance.GetTransactionInfoWithResults(ctx, hash)
require.Nil(instance, errGet)

return txStatus, &txResult.Data.Transaction
}

// ScCall will make the provided sc call
func (instance *chainSimulatorWrapper) ScCall(ctx context.Context, senderSK []byte, contract *MvxAddress, value string, gasLimit uint64, function string, parameters []string) (string, *data.TransactionOnNetwork) {
params := []string{function}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package slowTests

import (
"math/big"
"strings"
"testing"

bridgeCore "github.com/multiversx/mx-bridge-eth-go/core"
Expand Down Expand Up @@ -142,6 +143,90 @@ func TestRelayersShouldExecuteTransfersWithRefund(t *testing.T) {
memeToken.TestOperations[2].MvxSCCallData = callData
memeToken.TestOperations[2].MvxFaultySCCall = true

testRelayersWithChainSimulatorAndTokensAndRefund(
t,
make(chan error),
usdcToken,
memeToken,
)
})
t.Run("no arguments should refund", func(t *testing.T) {
callData := createScCallData("callPayableWithParams", 50000000)
usdcToken := GenerateTestUSDCToken()
usdcToken.TestOperations[2].MvxSCCallData = callData
usdcToken.TestOperations[2].MvxFaultySCCall = true
usdcToken.EthTestAddrExtraBalance = big.NewInt(-5000 + 2500 - 50 - 7000 + 300 - 50 - 1000 + 950) // -(eth->mvx) + (mvx->eth) - fees + revert after bad SC call
usdcToken.ESDTSafeExtraBalance = big.NewInt(150) // extra is just for the fees for the 2 transfers mvx->eth and the failed eth->mvx that needed refund

memeToken := GenerateTestMEMEToken()
memeToken.TestOperations[2].MvxSCCallData = callData
memeToken.TestOperations[2].MvxFaultySCCall = true

testRelayersWithChainSimulatorAndTokensAndRefund(
t,
make(chan error),
usdcToken,
memeToken,
)
})
t.Run("wrong number of arguments should refund", func(t *testing.T) {
callData := createScCallData("callPayableWithParams", 50000000, string([]byte{37}))
usdcToken := GenerateTestUSDCToken()
usdcToken.TestOperations[2].MvxSCCallData = callData
usdcToken.TestOperations[2].MvxFaultySCCall = true
usdcToken.EthTestAddrExtraBalance = big.NewInt(-5000 + 2500 - 50 - 7000 + 300 - 50 - 1000 + 950) // -(eth->mvx) + (mvx->eth) - fees + revert after bad SC call
usdcToken.ESDTSafeExtraBalance = big.NewInt(150) // extra is just for the fees for the 2 transfers mvx->eth and the failed eth->mvx that needed refund

memeToken := GenerateTestMEMEToken()
memeToken.TestOperations[2].MvxSCCallData = callData
memeToken.TestOperations[2].MvxFaultySCCall = true

testRelayersWithChainSimulatorAndTokensAndRefund(
t,
make(chan error),
usdcToken,
memeToken,
)
})
t.Run("not an uint64 argument should refund", func(t *testing.T) {
malformedUint64String := string([]byte{37, 36, 35, 34, 33, 32, 31, 32, 33}) // 9 bytes instead of 8
dummyAddress := strings.Repeat("2", 32)

callData := createScCallData("callPayableWithParams", 50000000, malformedUint64String, dummyAddress)
usdcToken := GenerateTestUSDCToken()
usdcToken.TestOperations[2].MvxSCCallData = callData
usdcToken.TestOperations[2].MvxFaultySCCall = true
usdcToken.EthTestAddrExtraBalance = big.NewInt(-5000 + 2500 - 50 - 7000 + 300 - 50 - 1000 + 950) // -(eth->mvx) + (mvx->eth) - fees + revert after bad SC call
usdcToken.ESDTSafeExtraBalance = big.NewInt(150) // extra is just for the fees for the 2 transfers mvx->eth and the failed eth->mvx that needed refund

memeToken := GenerateTestMEMEToken()
memeToken.TestOperations[2].MvxSCCallData = callData
memeToken.TestOperations[2].MvxFaultySCCall = true

testRelayersWithChainSimulatorAndTokensAndRefund(
t,
make(chan error),
usdcToken,
memeToken,
)
})
t.Run("wrong arguments encoding should refund", func(t *testing.T) {
callData := createScCallData("callPayableWithParams", 50000000)
// the last byte is the data missing marker, we will replace that
callData[len(callData)-1] = bridgeCore.DataPresentProtocolMarker
// add garbage data
callData = append(callData, []byte{5, 4, 55}...)

usdcToken := GenerateTestUSDCToken()
usdcToken.TestOperations[2].MvxSCCallData = callData
usdcToken.TestOperations[2].MvxFaultySCCall = true
usdcToken.EthTestAddrExtraBalance = big.NewInt(-5000 + 2500 - 50 - 7000 + 300 - 50 - 1000 + 950) // -(eth->mvx) + (mvx->eth) - fees + revert after bad SC call
usdcToken.ESDTSafeExtraBalance = big.NewInt(150) // extra is just for the fees for the 2 transfers mvx->eth and the failed eth->mvx that needed refund

memeToken := GenerateTestMEMEToken()
memeToken.TestOperations[2].MvxSCCallData = callData
memeToken.TestOperations[2].MvxFaultySCCall = true

testRelayersWithChainSimulatorAndTokensAndRefund(
t,
make(chan error),
Expand Down Expand Up @@ -181,7 +266,7 @@ func testRelayersWithChainSimulatorAndTokensAndRefund(tb testing.TB, manualStopC
return false
}

testRelayersWithChainSimulator(tb,
_ = testRelayersWithChainSimulator(tb,
setupFunc,
processFunc,
manualStopChan,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,56 @@
"mutability": "mutable",
"inputs": [],
"outputs": []
},
{
"name": "callPayableWithParams",
"mutability": "readonly",
"payableInTokens": [
"*"
],
"inputs": [
{
"name": "size",
"type": "u64"
},
{
"name": "address",
"type": "Address"
}
],
"outputs": []
},
{
"name": "getCalledDataParams",
"mutability": "readonly",
"inputs": [],
"outputs": [
{
"type": "variadic<CalledData>",
"multi_result": true
}
]
}
],
"esdtAttributes": [],
"hasCallback": false,
"types": {}
"types": {
"CalledData": {
"type": "struct",
"fields": [
{
"name": "size",
"type": "u64"
},
{
"name": "address",
"type": "Address"
},
{
"name": "token_identifier",
"type": "TokenIdentifier"
}
]
}
}
}
Binary file not shown.
Loading

0 comments on commit a718794

Please sign in to comment.