From e1faabc58342644df7d1f8584390818e8ed0410f Mon Sep 17 00:00:00 2001 From: Eshel Date: Tue, 9 Aug 2022 17:06:20 +0300 Subject: [PATCH 01/15] building structure to test all variations of different calltypes and versions --- go.mod | 1 + go.sum | 1 + .../internal/keeper/secret_contracts_test.go | 151 ++++++++++++++++++ 3 files changed, 153 insertions(+) diff --git a/go.mod b/go.mod index 7221a851a..f4b74bf2b 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/tendermint/tendermint v0.34.19 github.com/tendermint/tm-db v0.6.7 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 + gonum.org/v1/gonum v0.8.2 google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3 google.golang.org/grpc v1.46.0 google.golang.org/protobuf v1.28.0 diff --git a/go.sum b/go.sum index cf7caa4ff..51023c406 100644 --- a/go.sum +++ b/go.sum @@ -1355,6 +1355,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index ebc5f6c5b..c33245ac7 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -25,6 +25,8 @@ import ( cosmwasm "github.com/enigmampc/SecretNetwork/go-cosmwasm/types" v010cosmwasm "github.com/enigmampc/SecretNetwork/go-cosmwasm/types/v010" "github.com/enigmampc/SecretNetwork/x/compute/internal/types" + + "gonum.org/v1/gonum/stat/combin" ) type ContractEvent []v010cosmwasm.LogAttribute @@ -316,6 +318,28 @@ func (wasmGasMeter *WasmCounterGasMeter) GetWasmCounter() uint64 { var _ sdk.GasMeter = (*WasmCounterGasMeter)(nil) // check interface +func multisetsFrom[t any](elements []t, size int) [][]t { + // init slice with 'size' elements, each one being the number of elements in the input slice + lengths := make([]int, size) + length := len(elements) + for i := 0; i < len(lengths); i++ { + lengths[i] = length + } + + product := combin.Cartesian(lengths) + // map indexes to element + result := make([][]t, 0) + for _, indexes := range product { + inner := make([]t, 0) + for _, j := range indexes { + inner = append(inner, elements[j]) + } + result = append(result, inner) + } + + return result +} + func queryHelper( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, input string, @@ -1969,6 +1993,8 @@ func TestContractSendFundsToInitCallbackNotEnough(t *testing.T) { contractCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr) walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + // The state here should have been reverted by the APP but in go-tests we create our own keeper + // so it is not reverted in this case. require.Equal(t, "17denom", contractCoinsAfter.String()) require.Equal(t, "199983denom", walletCoinsAfter.String()) }) @@ -2037,6 +2063,8 @@ func TestContractSendFundsToExecCallbackNotEnough(t *testing.T) { contract2CoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, addr2) walletCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + // The state here should have been reverted by the APP but in go-tests we create our own keeper + // so it is not reverted in this case. require.Equal(t, "17denom", contractCoinsAfter.String()) require.Equal(t, "", contract2CoinsAfter.String()) require.Equal(t, "199983denom", walletCoinsAfter.String()) @@ -3594,6 +3622,129 @@ func TestBankMsgSend(t *testing.T) { } } +func TestSendFunds(t *testing.T) { + for _, callTypes := range multisetsFrom([]string{"init", "exec", "user"}, 2) { + originType, destinationType := callTypes[0], callTypes[1] + fmt.Println("origin calltype:", originType, "destination calltype:", destinationType) + + t.Run(originType+"->"+destinationType, func(t *testing.T) { + userTestsToSkipDest := 0 + userTestsToSkipOrig := 0 + for _, currentSubjects := range multisetsFrom(testContracts, 2) { + originVersion, destinationVersion := currentSubjects[0], currentSubjects[1] + + // no need to test versions when one of the parties is a user account + if originType == "user" { + if userTestsToSkipOrig > 0 { + userTestsToSkipOrig-- + continue + } + userTestsToSkipOrig++ + originVersion.CosmWasmVersion = "user" + } + if destinationType == "user" { + if userTestsToSkipDest > 0 { + userTestsToSkipDest-- + continue + } + userTestsToSkipDest++ + destinationVersion.CosmWasmVersion = "user" + } + + t.Run(originVersion.CosmWasmVersion+"->"+destinationVersion.CosmWasmVersion, func(t *testing.T) { + //for _, test := range []struct { + // description string + // input string + // isSuccuss bool + // errorMsg string + // balancesBefore string + // balancesAfter string + //}{ + // { + // description: "regular", + // input: `[{"amount":"2","denom":"denom"}]`, + // isSuccuss: true, + // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + // balancesAfter: "4998assaf,199998denom 5000assaf,5002denom", + // }, + // { + // description: "multi-coin", + // input: `[{"amount":"1","denom":"assaf"},{"amount":"1","denom":"denom"}]`, + // isSuccuss: true, + // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + // balancesAfter: "4998assaf,199998denom 5001assaf,5001denom", + // }, + // { + // description: "zero", + // input: `[{"amount":"0","denom":"denom"}]`, + // isSuccuss: false, + // errorMsg: "encrypted: dispatch: submessages: 0denom: invalid coins", + // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + // balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + // }, + // { + // description: "insufficient funds", + // input: `[{"amount":"3","denom":"denom"}]`, + // isSuccuss: false, + // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + // balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + // errorMsg: "encrypted: dispatch: submessages: 2denom is smaller than 3denom: insufficient funds", + // }, + // { + // description: "non-existing denom", + // input: `[{"amount":"1","denom":"blabla"}]`, + // isSuccuss: false, + // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + // balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + // errorMsg: "encrypted: dispatch: submessages: 0blabla is smaller than 1blabla: insufficient funds", + // }, + // { + // description: "none", + // input: `[]`, + // isSuccuss: true, + // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", + // balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", + // }, + //} { + // t.Run(test.description, func(t *testing.T) { + // ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, contract.WasmFilePath, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) + // + // walletACoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + // walletBCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletB) + // + // require.Equal(t, test.balancesBefore, walletACoinsBefore.String()+" "+walletBCoinsBefore.String()) + // + // var err cosmwasm.StdError + // var contractAddress sdk.AccAddress + // + // if callType == "init" { + // _, _, _, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + // } else { + // _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + // + // _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, math.MaxUint64, 0) + // } + // + // if test.isSuccuss { + // require.Empty(t, err) + // } else { + // require.NotEmpty(t, err) + // require.Equal(t, err.Error(), test.errorMsg) + // } + // + // walletACoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + // walletBCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletB) + // + // require.Equal(t, test.balancesAfter, walletACoinsAfter.String()+" "+walletBCoinsAfter.String()) + // }) + //} + fmt.Println("pass the bus") + }) + } + }) + } +} + func TestWasmMsgStructure(t *testing.T) { for _, from := range testContracts { t.Run(fmt.Sprintf("from %s", from.CosmWasmVersion), func(t *testing.T) { From 9dc463d83860a6c15dee1ac5c7ba91de22ff53ce Mon Sep 17 00:00:00 2001 From: Eshel Date: Wed, 10 Aug 2022 10:32:18 +0300 Subject: [PATCH 02/15] finished context for test of spend funds --- .../internal/keeper/secret_contracts_test.go | 201 +++++++++--------- 1 file changed, 100 insertions(+), 101 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index c33245ac7..a2fd20c08 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3628,117 +3628,116 @@ func TestSendFunds(t *testing.T) { fmt.Println("origin calltype:", originType, "destination calltype:", destinationType) t.Run(originType+"->"+destinationType, func(t *testing.T) { - userTestsToSkipDest := 0 - userTestsToSkipOrig := 0 + + alreadyTested := make(map[string]bool) for _, currentSubjects := range multisetsFrom(testContracts, 2) { originVersion, destinationVersion := currentSubjects[0], currentSubjects[1] - // no need to test versions when one of the parties is a user account + // users don't have versions, so skip the repeating tests (user v1 = user v10) if originType == "user" { - if userTestsToSkipOrig > 0 { - userTestsToSkipOrig-- - continue - } - userTestsToSkipOrig++ originVersion.CosmWasmVersion = "user" } if destinationType == "user" { - if userTestsToSkipDest > 0 { - userTestsToSkipDest-- - continue - } - userTestsToSkipDest++ destinationVersion.CosmWasmVersion = "user" } + testTitle := originType + originVersion.CosmWasmVersion + "->" + destinationType + destinationVersion.CosmWasmVersion + if _, value := alreadyTested[testTitle]; value { + continue + } + alreadyTested[testTitle] = true + + t.Run(testTitle, func(t *testing.T) { + for _, test := range []struct { + description string + input string + isSuccess bool + errorMsg string + balancesBefore string + balancesAfter string + }{ + { + description: "one, has all", + input: `[{"amount":"20","denom":"one"}]`, + isSuccess: true, + balancesBefore: "5000one,200000denom", + balancesAfter: "4980one,200000denom", + }, + { + description: "one, missing", + input: `[{"amount":"20","denom":"one"}]`, + isSuccess: true, + balancesBefore: "5000another", + balancesAfter: "5000another", + }, + { + description: "one, not enough", + input: `[{"amount":"20","denom":"one"}]`, + isSuccess: true, + balancesBefore: "5000another,19one", + balancesAfter: "5000another,19one", + }, + { + description: "zero", + input: `[]`, + isSuccess: false, + errorMsg: "encrypted: dispatch: submessages: 0denom: invalid coins", + balancesBefore: "5000assaf,200000denom", + balancesAfter: "5000assaf,200000denom", + }, + { + description: "multi-coin, has all", + input: `[{"amount":"130","denom":"assaf"},{"amount":"15","denom":"denom"}]`, + isSuccess: true, + balancesBefore: "5000assaf,200000denom", + balancesAfter: "4870assaf,199985denom", + }, + { + description: "multi-coin, missing one", + input: `[{"amount":"130","denom":"assaf"},{"amount":"15","denom":"denom"}]`, + isSuccess: false, + balancesBefore: "200000denom", + balancesAfter: "200000denom", + }, + { + description: "multi-coin, not enough of one of them", + input: `[{"amount":"130","denom":"assaf"},{"amount":"15","denom":"denom"}]`, + isSuccess: false, + balancesBefore: "5000assaf,10denom", + balancesAfter: "5000assaf,10denom", + }, + } { + t.Run(test.description, func(t *testing.T) { + ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, contract.WasmFilePath, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) + + walletACoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) + walletBCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletB) + + require.Equal(t, test.balancesBefore, walletACoinsBefore.String()+" "+walletBCoinsBefore.String()) + + var err cosmwasm.StdError + var contractAddress sdk.AccAddress + + if callType == "init" { + _, _, _, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + } else { + _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) - t.Run(originVersion.CosmWasmVersion+"->"+destinationVersion.CosmWasmVersion, func(t *testing.T) { - //for _, test := range []struct { - // description string - // input string - // isSuccuss bool - // errorMsg string - // balancesBefore string - // balancesAfter string - //}{ - // { - // description: "regular", - // input: `[{"amount":"2","denom":"denom"}]`, - // isSuccuss: true, - // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", - // balancesAfter: "4998assaf,199998denom 5000assaf,5002denom", - // }, - // { - // description: "multi-coin", - // input: `[{"amount":"1","denom":"assaf"},{"amount":"1","denom":"denom"}]`, - // isSuccuss: true, - // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", - // balancesAfter: "4998assaf,199998denom 5001assaf,5001denom", - // }, - // { - // description: "zero", - // input: `[{"amount":"0","denom":"denom"}]`, - // isSuccuss: false, - // errorMsg: "encrypted: dispatch: submessages: 0denom: invalid coins", - // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", - // balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", - // }, - // { - // description: "insufficient funds", - // input: `[{"amount":"3","denom":"denom"}]`, - // isSuccuss: false, - // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", - // balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", - // errorMsg: "encrypted: dispatch: submessages: 2denom is smaller than 3denom: insufficient funds", - // }, - // { - // description: "non-existing denom", - // input: `[{"amount":"1","denom":"blabla"}]`, - // isSuccuss: false, - // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", - // balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", - // errorMsg: "encrypted: dispatch: submessages: 0blabla is smaller than 1blabla: insufficient funds", - // }, - // { - // description: "none", - // input: `[]`, - // isSuccuss: true, - // balancesBefore: "5000assaf,200000denom 5000assaf,5000denom", - // balancesAfter: "4998assaf,199998denom 5000assaf,5000denom", - // }, - //} { - // t.Run(test.description, func(t *testing.T) { - // ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, contract.WasmFilePath, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) - // - // walletACoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - // walletBCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletB) - // - // require.Equal(t, test.balancesBefore, walletACoinsBefore.String()+" "+walletBCoinsBefore.String()) - // - // var err cosmwasm.StdError - // var contractAddress sdk.AccAddress - // - // if callType == "init" { - // _, _, _, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) - // } else { - // _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) - // - // _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, math.MaxUint64, 0) - // } - // - // if test.isSuccuss { - // require.Empty(t, err) - // } else { - // require.NotEmpty(t, err) - // require.Equal(t, err.Error(), test.errorMsg) - // } - // - // walletACoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - // walletBCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletB) - // - // require.Equal(t, test.balancesAfter, walletACoinsAfter.String()+" "+walletBCoinsAfter.String()) - // }) - //} - fmt.Println("pass the bus") + _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, math.MaxUint64, 0) + } + + if test.isSuccess { + require.Empty(t, err) + } else { + require.NotEmpty(t, err) + require.Equal(t, err.Error(), test.errorMsg) + } + + walletACoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) + walletBCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletB) + + require.Equal(t, test.balancesAfter, walletACoinsAfter.String()+" "+walletBCoinsAfter.String()) + }) + } }) } }) From c05df418010cc0877fc85c6a7841f75c95e9037a Mon Sep 17 00:00:00 2001 From: Eshel Date: Wed, 10 Aug 2022 13:14:27 +0300 Subject: [PATCH 03/15] created a setuptest with no uploading of contract --- .../internal/keeper/secret_contracts_test.go | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index a2fd20c08..adb5585b2 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -73,7 +73,19 @@ func testEncrypt(t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress s return queryBz, nil } -func setupTest(t *testing.T, wasmPath string, additionalCoinsInWallets sdk.Coins) (sdk.Context, Keeper, uint64, string, sdk.AccAddress, crypto.PrivKey, sdk.AccAddress, crypto.PrivKey) { +func uploadCode(ctx sdk.Context, t *testing.T, keeper Keeper, wasmPath string, walletA sdk.AccAddress) (uint64, string) { + wasmCode, err := ioutil.ReadFile(wasmPath) + require.NoError(t, err) + + codeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") + require.NoError(t, err) + + codeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, codeID).CodeHash) + + return codeID, codeHash +} + +func setupBasicTest(t *testing.T, additionalCoinsInWallets sdk.Coins) (sdk.Context, Keeper, sdk.AccAddress, crypto.PrivKey, sdk.AccAddress, crypto.PrivKey) { encodingConfig := MakeEncodingConfig() var transferPortSource types.ICS20TransferPortSource transferPortSource = MockIBCTransferKeeper{GetPortFn: func(ctx sdk.Context) string { @@ -86,13 +98,13 @@ func setupTest(t *testing.T, wasmPath string, additionalCoinsInWallets sdk.Coins walletA, privKeyA := CreateFakeFundedAccount(ctx, accKeeper, keeper.bankKeeper, sdk.NewCoins(sdk.NewInt64Coin("denom", 200000)).Add(additionalCoinsInWallets...)) walletB, privKeyB := CreateFakeFundedAccount(ctx, accKeeper, keeper.bankKeeper, sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)).Add(additionalCoinsInWallets...)) - wasmCode, err := ioutil.ReadFile(wasmPath) - require.NoError(t, err) + return ctx, keeper, walletA, privKeyA, walletB, privKeyB +} - codeID, err := keeper.Create(ctx, walletA, wasmCode, "", "") - require.NoError(t, err) +func setupTest(t *testing.T, wasmPath string, additionalCoinsInWallets sdk.Coins) (sdk.Context, Keeper, uint64, string, sdk.AccAddress, crypto.PrivKey, sdk.AccAddress, crypto.PrivKey) { + ctx, keeper, walletA, privKeyA, walletB, privKeyB := setupBasicTest(t, additionalCoinsInWallets) - codeHash := hex.EncodeToString(keeper.GetCodeInfo(ctx, codeID).CodeHash) + codeID, codeHash := uploadCode(ctx, t, keeper, wasmPath, walletA) return ctx, keeper, codeID, codeHash, walletA, privKeyA, walletB, privKeyB } From de87e4d4a0d2d83735b648ba5c5c8682bcb79e94 Mon Sep 17 00:00:00 2001 From: Eshel Date: Wed, 10 Aug 2022 23:47:47 +0300 Subject: [PATCH 04/15] added execHelperWithMultipleCoins --- .../internal/keeper/secret_contracts_test.go | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index adb5585b2..583dedf23 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -9,6 +9,7 @@ import ( "io/ioutil" "math" "regexp" + "strings" "testing" "time" @@ -330,6 +331,37 @@ func (wasmGasMeter *WasmCounterGasMeter) GetWasmCounter() uint64 { var _ sdk.GasMeter = (*WasmCounterGasMeter)(nil) // check interface +func stringToCoins(balance string) sdk.Coins { + result := sdk.NewCoins() + + individualCoins := strings.Split(balance, ",") + for _, coin := range individualCoins { + var amount int64 + var denom string + fmt.Sscanf(coin, "%d%s", &amount, &denom) + result = result.Add(sdk.NewInt64Coin(denom, amount)) + } + + return result +} + +func CoinsToInput(coins sdk.Coins) string { + result := "[" + for i, coin := range coins { + result += `{"amount":"` + result += coin.Amount.String() + result += `","denom":"` + result += coin.Denom + result += `"}` + if i != len(coins)-1 { + result += `,` + } + } + result += "]" + + return result +} + func multisetsFrom[t any](elements []t, size int) [][]t { // init slice with 'size' elements, each one being the number of elements in the input slice lengths := make([]int, size) @@ -409,18 +441,26 @@ func queryHelperImpl( return string(resultBz), cosmwasm.StdError{} } +func execHelperMultipleCoins( + t *testing.T, keeper Keeper, ctx sdk.Context, + contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, + isErrorEncrypted bool, isV1Contract bool, gas uint64, coins sdk.Coins, shouldSkipAttributes ...bool, +) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { + return execHelperImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, coins, -1, shouldSkipAttributes...) +} + func execHelper( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, isErrorEncrypted bool, isV1Contract bool, gas uint64, coin int64, shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { - return execHelperImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, coin, -1, shouldSkipAttributes...) + return execHelperImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, sdk.NewCoins(sdk.NewInt64Coin("denom", coin)), -1, shouldSkipAttributes...) } func execHelperImpl( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, - isErrorEncrypted bool, isV1Contract bool, gas uint64, coin int64, wasmCallCount int64, shouldSkipAttributes ...bool, + isErrorEncrypted bool, isV1Contract bool, gas uint64, coins sdk.Coins, wasmCallCount int64, shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { hashStr := hex.EncodeToString(keeper.GetContractHash(ctx, contractAddress)) @@ -444,10 +484,10 @@ func execHelperImpl( log.NewNopLogger(), ).WithGasMeter(gasMeter) - ctx = PrepareExecSignedTx(t, keeper, ctx, txSender, senderPrivKey, execMsgBz, contractAddress, sdk.NewCoins(sdk.NewInt64Coin("denom", coin))) + ctx = PrepareExecSignedTx(t, keeper, ctx, txSender, senderPrivKey, execMsgBz, contractAddress, coins) gasBefore := ctx.GasMeter().GasConsumed() - execResult, err := keeper.Execute(ctx, contractAddress, txSender, execMsgBz, sdk.NewCoins(sdk.NewInt64Coin("denom", coin)), nil) + execResult, err := keeper.Execute(ctx, contractAddress, txSender, execMsgBz, coins, nil) gasAfter := ctx.GasMeter().GasConsumed() gasUsed := gasAfter - gasBefore From daacf86ff9dfce8b83b75572307dbcebe799cea0 Mon Sep 17 00:00:00 2001 From: Eshel Date: Wed, 10 Aug 2022 23:49:56 +0300 Subject: [PATCH 05/15] wip: implementing bulk of test send funds --- .../internal/keeper/secret_contracts_test.go | 193 +++++++++++++----- 1 file changed, 139 insertions(+), 54 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 583dedf23..13ed74ed3 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3682,7 +3682,9 @@ func TestSendFunds(t *testing.T) { t.Run(originType+"->"+destinationType, func(t *testing.T) { alreadyTested := make(map[string]bool) + alreadyTested["useruser->useruser"] = true // we are only testing contracts here for _, currentSubjects := range multisetsFrom(testContracts, 2) { + // [0] is source of transaction, [1] is destination todo remove comment if unnecessary originVersion, destinationVersion := currentSubjects[0], currentSubjects[1] // users don't have versions, so skip the repeating tests (user v1 = user v10) @@ -3700,81 +3702,163 @@ func TestSendFunds(t *testing.T) { t.Run(testTitle, func(t *testing.T) { for _, test := range []struct { - description string - input string - isSuccess bool - errorMsg string - balancesBefore string - balancesAfter string + description string + coinsToSend string + isSuccess bool + errorMsg string + balancesBefore string + balancesAfter string + destinationBalancesAfter string }{ { - description: "one, has all", - input: `[{"amount":"20","denom":"one"}]`, - isSuccess: true, - balancesBefore: "5000one,200000denom", - balancesAfter: "4980one,200000denom", + description: "one, has all", + coinsToSend: `20one`, + isSuccess: true, + balancesBefore: "5000one,200000denom", + balancesAfter: "4980one,200000denom", + destinationBalancesAfter: "20one", }, { - description: "one, missing", - input: `[{"amount":"20","denom":"one"}]`, - isSuccess: true, - balancesBefore: "5000another", - balancesAfter: "5000another", + description: "one, missing", + coinsToSend: `20one`, + isSuccess: false, + errorMsg: "todo define error", + balancesBefore: "5000another", + balancesAfter: "5000another", + destinationBalancesAfter: "", }, { - description: "one, not enough", - input: `[{"amount":"20","denom":"one"}]`, - isSuccess: true, - balancesBefore: "5000another,19one", - balancesAfter: "5000another,19one", + description: "one, not enough", + coinsToSend: `20one`, + isSuccess: false, + errorMsg: "todo define error", + balancesBefore: "5000another,19one", + balancesAfter: "5000another,19one", + destinationBalancesAfter: "", }, { - description: "zero", - input: `[]`, - isSuccess: false, - errorMsg: "encrypted: dispatch: submessages: 0denom: invalid coins", - balancesBefore: "5000assaf,200000denom", - balancesAfter: "5000assaf,200000denom", + description: "zero", + coinsToSend: ``, + isSuccess: true, + balancesBefore: "5000assaf,200000denom", + balancesAfter: "5000assaf,200000denom", + destinationBalancesAfter: "", + }, + { + description: "multi-coin, has all", + coinsToSend: `130assaf,15denom`, + isSuccess: true, + balancesBefore: "5000assaf,200000denom", + balancesAfter: "4870assaf,199985denom", + destinationBalancesAfter: "130assaf,15denom", }, { - description: "multi-coin, has all", - input: `[{"amount":"130","denom":"assaf"},{"amount":"15","denom":"denom"}]`, - isSuccess: true, - balancesBefore: "5000assaf,200000denom", - balancesAfter: "4870assaf,199985denom", + description: "multi-coin, missing one", + coinsToSend: `130assaf,15denom`, + isSuccess: false, + errorMsg: "todo define error", + balancesBefore: "200000denom", + balancesAfter: "200000denom", + destinationBalancesAfter: "", }, { - description: "multi-coin, missing one", - input: `[{"amount":"130","denom":"assaf"},{"amount":"15","denom":"denom"}]`, - isSuccess: false, - balancesBefore: "200000denom", - balancesAfter: "200000denom", + description: "multi-coin, not enough of one of them", + coinsToSend: `130assaf,15denom`, + isSuccess: false, + errorMsg: "todo define error", + balancesBefore: "5000assaf,10denom", + balancesAfter: "5000assaf,10denom", + destinationBalancesAfter: "", }, { - description: "multi-coin, not enough of one of them", - input: `[{"amount":"130","denom":"assaf"},{"amount":"15","denom":"denom"}]`, - isSuccess: false, - balancesBefore: "5000assaf,10denom", - balancesAfter: "5000assaf,10denom", + description: "multi-coin, not enough of all of them", + coinsToSend: `130assaf,15denom`, + isSuccess: false, + errorMsg: "todo define error", + balancesBefore: "12assaf,10denom", + balancesAfter: "12assaf,10denom", + destinationBalancesAfter: "", }, } { t.Run(test.description, func(t *testing.T) { - ctx, keeper, codeID, _, walletA, privKeyA, walletB, _ := setupTest(t, contract.WasmFilePath, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) + ctx, keeper, helperWallet, privKeyA, _, _ := setupBasicTest(t, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) - walletACoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletA) - walletBCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, walletB) + fundingWallet, fundingWalletPrivKey := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, stringToCoins(test.balancesBefore)) - require.Equal(t, test.balancesBefore, walletACoinsBefore.String()+" "+walletBCoinsBefore.String()) + receivingWallet, _ := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, sdk.NewCoins()) + + // todo remove: this is only to verify that the account was funded correctly + fundingWalletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, fundingWallet) + require.Equal(t, test.balancesBefore, fundingWalletCoinsBefore.String()) + + var originCodeId uint64 + if originType != "user" { + originCodeId, _ = uploadCode(ctx, t, keeper, originVersion.WasmFilePath, helperWallet) + } + + var destinationCodeId uint64 + var destinationHash string + var destinationAddr sdk.AccAddress + + // prepare receiving contract + if destinationType != "user" { + destinationCodeId, destinationHash = uploadCode(ctx, t, keeper, originVersion.WasmFilePath, helperWallet) + + if destinationType == "exec" { + _, _, destinationAddr, _, _ = initHelperImpl(t, keeper, ctx, destinationCodeId, helperWallet, privKeyA, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) + } + } var err cosmwasm.StdError - var contractAddress sdk.AccAddress + var originAddress sdk.AccAddress + + var msg string + if destinationType == "user" { + // todo replace sending from bank to simply sending if there's such a thing + msg = fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, receivingWallet.String(), test.coinsToSend) + destinationAddr = receivingWallet + } else if destinationType == "init" { + // todo add 'send_multiple_funds_to_init_callback' to contract + msg = fmt.Sprintf(`{"send_funds_to_init_callback":{"code_id":%d,"denom":"%s","amount":%d,"code_hash":"%s"}}`, destinationCodeId, "denom", 18, destinationHash) + // destination address will only be known after the contract is init + } else { + // todo add 'send_multiple_funds_to_exec_callback' to contract - if callType == "init" { - _, _, _, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + msg = fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, destinationAddr, "denom", 18, destinationHash) + } + + // todo remove one or both of these, if unnecessary (probably needed for extraction of destination address on init) + //var data []byte + //var wasmEvents []ContractEvent + + if originType == "init" { + // todo maybe extract data or wasmEvents, to know the receiving contract's address + _, _, _, _, _ = initHelperImpl(t, keeper, ctx, originCodeId, helperWallet, privKeyA, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) + + // verify that no coins where left in the intermediate contract + // todo this is incorrect since keeper does not revert first tx + //sendingContractCoins := keeper.bankKeeper.GetAllBalances(ctx, originAddress) + //require.Equal(t, sendingContractCoins.String(), "") + } else if originType == "exec" { + _, _, _, _, _ = initHelperImpl(t, keeper, ctx, originCodeId, helperWallet, privKeyA, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) + + // todo maybe extract data or wasmEvents, to know the receiving contract's address + _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, helperWallet, privKeyA, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) + + // verify that no coins where left in the intermediate contract + // todo this is incorrect since keeper does not revert first tx } else { - _, _, contractAddress, _, _ = initHelperImpl(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, false, contract.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins(sdk.NewInt64Coin("denom", 2), sdk.NewInt64Coin("assaf", 2))) + // user sends directly to contract + if destinationType == "exec" { + _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, "{no_logs:{}}", false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) + } else { + _, _, destinationAddr, _, _ = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.coinsToSend)) + } + } - _, _, _, _, _, err = execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, walletB.String(), test.input), false, contract.IsCosmWasmV1, math.MaxUint64, 0) + if destinationType == "init" || originType == "exec" { + // todo somehow retrieve destination address, which was not known in advance + destinationAddr = helperWallet } if test.isSuccess { @@ -3784,10 +3868,11 @@ func TestSendFunds(t *testing.T) { require.Equal(t, err.Error(), test.errorMsg) } - walletACoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletA) - walletBCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, walletB) + originCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, originAddress) + destinationCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, destinationAddr) - require.Equal(t, test.balancesAfter, walletACoinsAfter.String()+" "+walletBCoinsAfter.String()) + require.Equal(t, originCoinsAfter.String(), test.balancesAfter) + require.Equal(t, destinationCoinsAfter.String(), test.destinationBalancesAfter) }) } }) From 379ccb59a0d6ff774e11026fe3be0dae8537da61 Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 00:16:12 +0300 Subject: [PATCH 06/15] added execHelperWithMultipleCoinsImpl too, since the impl was used directly from other places --- x/compute/internal/keeper/secret_contracts_test.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 13ed74ed3..93a9410b7 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -446,7 +446,7 @@ func execHelperMultipleCoins( contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, isErrorEncrypted bool, isV1Contract bool, gas uint64, coins sdk.Coins, shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { - return execHelperImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, coins, -1, shouldSkipAttributes...) + return execHelperMultipleCoinsImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, coins, -1, shouldSkipAttributes...) } func execHelper( @@ -454,10 +454,18 @@ func execHelper( contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, isErrorEncrypted bool, isV1Contract bool, gas uint64, coin int64, shouldSkipAttributes ...bool, ) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { - return execHelperImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, sdk.NewCoins(sdk.NewInt64Coin("denom", coin)), -1, shouldSkipAttributes...) + return execHelperImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, coin, -1, shouldSkipAttributes...) } func execHelperImpl( + t *testing.T, keeper Keeper, ctx sdk.Context, + contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, + isErrorEncrypted bool, isV1Contract bool, gas uint64, coin int64, wasmCallCount int64, shouldSkipAttributes ...bool, +) ([]byte, sdk.Context, []byte, []ContractEvent, uint64, cosmwasm.StdError) { + return execHelperMultipleCoinsImpl(t, keeper, ctx, contractAddress, txSender, senderPrivKey, execMsg, isErrorEncrypted, isV1Contract, gas, sdk.NewCoins(sdk.NewInt64Coin("denom", coin)), wasmCallCount, shouldSkipAttributes...) +} + +func execHelperMultipleCoinsImpl( t *testing.T, keeper Keeper, ctx sdk.Context, contractAddress sdk.AccAddress, txSender sdk.AccAddress, senderPrivKey crypto.PrivKey, execMsg string, isErrorEncrypted bool, isV1Contract bool, gas uint64, coins sdk.Coins, wasmCallCount int64, shouldSkipAttributes ...bool, From 21b3440adcbd404e79d1262ecb96c0b26e1efdb9 Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 00:50:46 +0300 Subject: [PATCH 07/15] fixing some dest/source mismatches --- .../internal/keeper/secret_contracts_test.go | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 93a9410b7..ea0000b31 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3722,8 +3722,8 @@ func TestSendFunds(t *testing.T) { description: "one, has all", coinsToSend: `20one`, isSuccess: true, - balancesBefore: "5000one,200000denom", - balancesAfter: "4980one,200000denom", + balancesBefore: "200000denom,5000one", + balancesAfter: "200000denom,4980one", destinationBalancesAfter: "20one", }, { @@ -3789,10 +3789,9 @@ func TestSendFunds(t *testing.T) { }, } { t.Run(test.description, func(t *testing.T) { - ctx, keeper, helperWallet, privKeyA, _, _ := setupBasicTest(t, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) + ctx, keeper, helperWallet, helperPrivKey, _, _ := setupBasicTest(t, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) fundingWallet, fundingWalletPrivKey := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, stringToCoins(test.balancesBefore)) - receivingWallet, _ := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, sdk.NewCoins()) // todo remove: this is only to verify that the account was funded correctly @@ -3810,10 +3809,10 @@ func TestSendFunds(t *testing.T) { // prepare receiving contract if destinationType != "user" { - destinationCodeId, destinationHash = uploadCode(ctx, t, keeper, originVersion.WasmFilePath, helperWallet) + destinationCodeId, destinationHash = uploadCode(ctx, t, keeper, destinationVersion.WasmFilePath, helperWallet) if destinationType == "exec" { - _, _, destinationAddr, _, _ = initHelperImpl(t, keeper, ctx, destinationCodeId, helperWallet, privKeyA, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) + _, _, destinationAddr, _, _ = initHelperImpl(t, keeper, ctx, destinationCodeId, helperWallet, helperPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, sdk.NewCoins()) } } @@ -3841,17 +3840,17 @@ func TestSendFunds(t *testing.T) { if originType == "init" { // todo maybe extract data or wasmEvents, to know the receiving contract's address - _, _, _, _, _ = initHelperImpl(t, keeper, ctx, originCodeId, helperWallet, privKeyA, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) + _, _, _, _, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) // verify that no coins where left in the intermediate contract // todo this is incorrect since keeper does not revert first tx //sendingContractCoins := keeper.bankKeeper.GetAllBalances(ctx, originAddress) //require.Equal(t, sendingContractCoins.String(), "") } else if originType == "exec" { - _, _, _, _, _ = initHelperImpl(t, keeper, ctx, originCodeId, helperWallet, privKeyA, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) + _, _, _, _, _ = initHelper(t, keeper, ctx, originCodeId, helperWallet, helperPrivKey, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests) // todo maybe extract data or wasmEvents, to know the receiving contract's address - _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, helperWallet, privKeyA, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) + _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, helperWallet, helperPrivKey, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) // verify that no coins where left in the intermediate contract // todo this is incorrect since keeper does not revert first tx @@ -3860,11 +3859,11 @@ func TestSendFunds(t *testing.T) { if destinationType == "exec" { _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, "{no_logs:{}}", false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) } else { - _, _, destinationAddr, _, _ = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.coinsToSend)) + _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.coinsToSend)) } } - if destinationType == "init" || originType == "exec" { + if destinationType == "init" && originType == "exec" { // todo somehow retrieve destination address, which was not known in advance destinationAddr = helperWallet } @@ -3880,7 +3879,12 @@ func TestSendFunds(t *testing.T) { destinationCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, destinationAddr) require.Equal(t, originCoinsAfter.String(), test.balancesAfter) - require.Equal(t, destinationCoinsAfter.String(), test.destinationBalancesAfter) + + if !(destinationType == "init" && originType == "exec") { + // todo somehow retrieve destination address, which was not known in advance + destinationAddr = helperWallet + require.Equal(t, destinationCoinsAfter.String(), test.destinationBalancesAfter) + } }) } }) From 886534363b9ffd015993d50a6fd06e4f40c1a7f7 Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 01:19:10 +0300 Subject: [PATCH 08/15] adding init/exec messages to contracts that forward all funds to another contract's init/exec --- .../internal/keeper/secret_contracts_test.go | 2 +- .../testdata/test-contract/src/contract.rs | 60 +++++++++++++++++++ .../v1-sanity-contract/src/contract.rs | 34 +++++++++++ .../testdata/v1-sanity-contract/src/msg.rs | 20 +++++++ 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index ea0000b31..3f59ebe21 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3857,7 +3857,7 @@ func TestSendFunds(t *testing.T) { } else { // user sends directly to contract if destinationType == "exec" { - _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, "{no_logs:{}}", false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) + _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, "{no_data:{}}", false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) } else { _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.coinsToSend)) } diff --git a/x/compute/internal/keeper/testdata/test-contract/src/contract.rs b/x/compute/internal/keeper/testdata/test-contract/src/contract.rs index 05fe3f751..a0e8342d3 100644 --- a/x/compute/internal/keeper/testdata/test-contract/src/contract.rs +++ b/x/compute/internal/keeper/testdata/test-contract/src/contract.rs @@ -93,6 +93,16 @@ pub enum InitMsg { from: Option, }, CosmosMsgCustom {}, + SendMultipleFundsToInitCallback { + coins: Vec, + code_id: u64, + code_hash: String, + }, + SendMultipleFundsToExecCallback { + coins: Vec, + to: HumanAddr, + code_hash: String, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -198,12 +208,22 @@ pub enum HandleMsg { code_id: u64, code_hash: String, }, + SendMultipleFundsToInitCallback { + coins: Vec, + code_id: u64, + code_hash: String, + }, SendFundsToExecCallback { amount: u32, denom: String, to: HumanAddr, code_hash: String, }, + SendMultipleFundsToExecCallback { + coins: Vec, + to: HumanAddr, + code_hash: String, + }, Sleep { ms: u64, }, @@ -526,6 +546,25 @@ pub fn init( messages: vec![CosmosMsg::Custom(Empty {})], log: vec![], }), + InitMsg::SendMultipleFundsToExecCallback { coins, to, code_hash } => Ok(InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to, + msg: Binary::from("{\"no_data\":{}}".as_bytes().to_vec()), + callback_code_hash: code_hash, + send: coins, + })], + log: vec![], + }), + InitMsg::SendMultipleFundsToInitCallback { coins, code_id, code_hash } => Ok(InitResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), + callback_code_hash: code_hash, + send: coins, + label: "test".to_string() + })], + log: vec![], + }) } } @@ -1204,6 +1243,27 @@ pub fn handle( log: vec![], data: None, }), + HandleMsg::SendMultipleFundsToExecCallback { coins, to, code_hash } => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to, + msg: Binary::from("{\"no_data\":{}}".as_bytes().to_vec()), + callback_code_hash: code_hash, + send: coins, + })], + log: vec![], + data: None, + }), + HandleMsg::SendMultipleFundsToInitCallback { coins, code_id, code_hash } => Ok(HandleResponse { + messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), + callback_code_hash: code_hash, + send: coins, + label: "test".to_string() + })], + log: vec![], + data: None, + }) } } diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs index eef939f30..e76f05b68 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs @@ -296,6 +296,23 @@ pub fn instantiate( InstantiateMsg::CosmosMsgCustom {} => { Ok(Response::new().add_message(CosmosMsg::Custom(Empty {}))) } + InstantiateMsg::SendMultipleFundsToInitCallback { coins, code_id, code_hash } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + funds: coins, + label: "init test".to_string() + })) + ), + InstantiateMsg::SendMultipleFundsToExecCallback { coins, to, code_hash } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to, + code_hash, + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + funds: coins, + })) + ) } } @@ -1106,6 +1123,23 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S ExecuteMsg::CosmosMsgCustom {} => { Ok(Response::new().add_message(CosmosMsg::Custom(Empty {}))) } + ExecuteMsg::SendMultipleFundsToInitCallback { coins, code_id, code_hash } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Instantiate { + code_id, + code_hash, + msg: Binary("{\"nop\":{}}".as_bytes().to_vec()), + funds: coins, + label: "test".to_string() + })) + ), + ExecuteMsg::SendMultipleFundsToExecCallback { coins, to, code_hash } => Ok( + Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: to, + code_hash, + msg: Binary("{\"no_data\":{}}".as_bytes().to_vec()), + funds: coins, + })) + ), } } diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs index 929213d67..ff1480e28 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs @@ -88,6 +88,16 @@ pub enum InstantiateMsg { amount: Vec, }, CosmosMsgCustom {}, + SendMultipleFundsToInitCallback { + coins: Vec, + code_id: u64, + code_hash: String, + }, + SendMultipleFundsToExecCallback { + coins: Vec, + to: String, + code_hash: String, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -284,12 +294,22 @@ pub enum ExecuteMsg { code_id: u64, code_hash: String, }, + SendMultipleFundsToInitCallback { + coins: Vec, + code_id: u64, + code_hash: String, + }, SendFundsToExecCallback { amount: u32, denom: String, to: String, code_hash: String, }, + SendMultipleFundsToExecCallback { + coins: Vec, + to: String, + code_hash: String, + }, Sleep { ms: u64, }, From a090d1f607e1f37518d5c4af4a0f8cde28344f6c Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 01:25:02 +0300 Subject: [PATCH 09/15] using contract's newly defined functions from test --- x/compute/internal/keeper/secret_contracts_test.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 3f59ebe21..b45a4f574 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3818,20 +3818,18 @@ func TestSendFunds(t *testing.T) { var err cosmwasm.StdError var originAddress sdk.AccAddress - var msg string + + inputCoins := CoinsToInput(stringToCoins(test.coinsToSend)) if destinationType == "user" { - // todo replace sending from bank to simply sending if there's such a thing - msg = fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, receivingWallet.String(), test.coinsToSend) + // todo replace sending from bank to simply sending if there's such a thing. update: probably isn't + msg = fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, receivingWallet.String(), inputCoins) destinationAddr = receivingWallet } else if destinationType == "init" { - // todo add 'send_multiple_funds_to_init_callback' to contract - msg = fmt.Sprintf(`{"send_funds_to_init_callback":{"code_id":%d,"denom":"%s","amount":%d,"code_hash":"%s"}}`, destinationCodeId, "denom", 18, destinationHash) + msg = fmt.Sprintf(`{"send_multiple_funds_to_init_callback":{"code_id":%d,"coins":"%s","code_hash":"%s"}}`, destinationCodeId, inputCoins, destinationHash) // destination address will only be known after the contract is init } else { - // todo add 'send_multiple_funds_to_exec_callback' to contract - - msg = fmt.Sprintf(`{"send_funds_to_exec_callback":{"to":"%s","denom":"%s","amount":%d,"code_hash":"%s"}}`, destinationAddr, "denom", 18, destinationHash) + msg = fmt.Sprintf(`{"send_multiple_funds_to_exec_callback":{"to":"%s","coins":"%s",code_hash":"%s"}}`, destinationAddr, inputCoins, destinationHash) } // todo remove one or both of these, if unnecessary (probably needed for extraction of destination address on init) From 00bbe7cd3c9826af90b9a36feeabe7c0c6228963 Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 01:39:52 +0300 Subject: [PATCH 10/15] fixing redundant quotes in message bug, changed order of expectation vs reality in require equals --- x/compute/internal/keeper/secret_contracts_test.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index b45a4f574..673c03237 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3826,10 +3826,11 @@ func TestSendFunds(t *testing.T) { msg = fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, receivingWallet.String(), inputCoins) destinationAddr = receivingWallet } else if destinationType == "init" { - msg = fmt.Sprintf(`{"send_multiple_funds_to_init_callback":{"code_id":%d,"coins":"%s","code_hash":"%s"}}`, destinationCodeId, inputCoins, destinationHash) + fmt.Println("THE INPUT COINS ARE", inputCoins) + msg = fmt.Sprintf(`{"send_multiple_funds_to_init_callback":{"code_id":%d,"coins":%s,"code_hash":"%s"}}`, destinationCodeId, inputCoins, destinationHash) // destination address will only be known after the contract is init } else { - msg = fmt.Sprintf(`{"send_multiple_funds_to_exec_callback":{"to":"%s","coins":"%s",code_hash":"%s"}}`, destinationAddr, inputCoins, destinationHash) + msg = fmt.Sprintf(`{"send_multiple_funds_to_exec_callback":{"to":"%s","coins":%s,code_hash":"%s"}}`, destinationAddr, inputCoins, destinationHash) } // todo remove one or both of these, if unnecessary (probably needed for extraction of destination address on init) @@ -3843,7 +3844,7 @@ func TestSendFunds(t *testing.T) { // verify that no coins where left in the intermediate contract // todo this is incorrect since keeper does not revert first tx //sendingContractCoins := keeper.bankKeeper.GetAllBalances(ctx, originAddress) - //require.Equal(t, sendingContractCoins.String(), "") + //require.Equal(t, "", sendingContractCoins.String()) } else if originType == "exec" { _, _, _, _, _ = initHelper(t, keeper, ctx, originCodeId, helperWallet, helperPrivKey, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests) @@ -3870,18 +3871,18 @@ func TestSendFunds(t *testing.T) { require.Empty(t, err) } else { require.NotEmpty(t, err) - require.Equal(t, err.Error(), test.errorMsg) + require.Equal(t, test.errorMsg, err.Error()) } originCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, originAddress) destinationCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, destinationAddr) - require.Equal(t, originCoinsAfter.String(), test.balancesAfter) + require.Equal(t, test.balancesAfter, originCoinsAfter.String()) if !(destinationType == "init" && originType == "exec") { // todo somehow retrieve destination address, which was not known in advance destinationAddr = helperWallet - require.Equal(t, destinationCoinsAfter.String(), test.destinationBalancesAfter) + require.Equal(t, test.destinationBalancesAfter, destinationCoinsAfter.String()) } }) } From 476ada5fd432f7854974abecbcf88ac2c19e53e5 Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 02:05:11 +0300 Subject: [PATCH 11/15] extractin destination address when the destination is an init call, where we didn't know the address in advance --- .../internal/keeper/secret_contracts_test.go | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 673c03237..759f7fb81 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3792,11 +3792,16 @@ func TestSendFunds(t *testing.T) { ctx, keeper, helperWallet, helperPrivKey, _, _ := setupBasicTest(t, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) fundingWallet, fundingWalletPrivKey := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, stringToCoins(test.balancesBefore)) + + fmt.Println("THE FUNDING WALLET IS", fundingWallet.String()) receivingWallet, _ := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, sdk.NewCoins()) + fmt.Println("THE RECEIVING WALLET IS", receivingWallet.String()) + // todo remove: this is only to verify that the account was funded correctly fundingWalletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, fundingWallet) require.Equal(t, test.balancesBefore, fundingWalletCoinsBefore.String()) + fmt.Println("PASSING INITIAL TEST", receivingWallet.String()) var originCodeId uint64 if originType != "user" { @@ -3826,7 +3831,6 @@ func TestSendFunds(t *testing.T) { msg = fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, receivingWallet.String(), inputCoins) destinationAddr = receivingWallet } else if destinationType == "init" { - fmt.Println("THE INPUT COINS ARE", inputCoins) msg = fmt.Sprintf(`{"send_multiple_funds_to_init_callback":{"code_id":%d,"coins":%s,"code_hash":"%s"}}`, destinationCodeId, inputCoins, destinationHash) // destination address will only be known after the contract is init } else { @@ -3835,21 +3839,23 @@ func TestSendFunds(t *testing.T) { // todo remove one or both of these, if unnecessary (probably needed for extraction of destination address on init) //var data []byte - //var wasmEvents []ContractEvent + var wasmEvents []ContractEvent + fmt.Println("THE BALANCES BEFORE ARE", test.balancesBefore) if originType == "init" { // todo maybe extract data or wasmEvents, to know the receiving contract's address - _, _, _, _, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) + fmt.Println("THE SENDING", test.balancesBefore, "COINS ON INIT") + _, _, originAddress, wasmEvents, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) // verify that no coins where left in the intermediate contract // todo this is incorrect since keeper does not revert first tx //sendingContractCoins := keeper.bankKeeper.GetAllBalances(ctx, originAddress) //require.Equal(t, "", sendingContractCoins.String()) } else if originType == "exec" { - _, _, _, _, _ = initHelper(t, keeper, ctx, originCodeId, helperWallet, helperPrivKey, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests) + _, _, originAddress, _, _ = initHelper(t, keeper, ctx, originCodeId, helperWallet, helperPrivKey, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests) // todo maybe extract data or wasmEvents, to know the receiving contract's address - _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, helperWallet, helperPrivKey, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) + _, _, _, wasmEvents, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, helperWallet, helperPrivKey, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) // verify that no coins where left in the intermediate contract // todo this is incorrect since keeper does not revert first tx @@ -3862,9 +3868,13 @@ func TestSendFunds(t *testing.T) { } } - if destinationType == "init" && originType == "exec" { + if destinationType == "init" { // todo somehow retrieve destination address, which was not known in advance - destinationAddr = helperWallet + fmt.Println("THE WASM EVENTS WERE:", wasmEvents) + fmt.Println("THE RELEVANT WASM EVENT IS:", wasmEvents[1]) + fmt.Println("THE RELEVANT PAIR ON THE WASM EVENT IS:", wasmEvents[1][0]) + fmt.Println("THE RELEVANT VALUE ON THE WASM EVENT IS:", wasmEvents[1][0].Value) + destinationAddr, _ = sdk.AccAddressFromBech32(wasmEvents[1][0].Value) } if test.isSuccess { @@ -3877,11 +3887,12 @@ func TestSendFunds(t *testing.T) { originCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, originAddress) destinationCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, destinationAddr) + fmt.Println("THE ORIGIN WALLET BALANCE AFTER IS", originCoinsAfter.String()) require.Equal(t, test.balancesAfter, originCoinsAfter.String()) if !(destinationType == "init" && originType == "exec") { // todo somehow retrieve destination address, which was not known in advance - destinationAddr = helperWallet + destinationAddr = receivingWallet require.Equal(t, test.destinationBalancesAfter, destinationCoinsAfter.String()) } }) From 23952841138732fbb9a1adde19fcbcb5b9c4d6b6 Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 13:41:27 +0300 Subject: [PATCH 12/15] checking destination balances only when there was no error --- .../internal/keeper/secret_contracts_test.go | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 759f7fb81..ab862533a 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3868,31 +3868,26 @@ func TestSendFunds(t *testing.T) { } } - if destinationType == "init" { - // todo somehow retrieve destination address, which was not known in advance - fmt.Println("THE WASM EVENTS WERE:", wasmEvents) - fmt.Println("THE RELEVANT WASM EVENT IS:", wasmEvents[1]) - fmt.Println("THE RELEVANT PAIR ON THE WASM EVENT IS:", wasmEvents[1][0]) - fmt.Println("THE RELEVANT VALUE ON THE WASM EVENT IS:", wasmEvents[1][0].Value) - destinationAddr, _ = sdk.AccAddressFromBech32(wasmEvents[1][0].Value) - } - - if test.isSuccess { - require.Empty(t, err) - } else { + if !test.isSuccess { require.NotEmpty(t, err) require.Equal(t, test.errorMsg, err.Error()) - } - - originCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, originAddress) - destinationCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, destinationAddr) + } else { + require.Empty(t, err) - fmt.Println("THE ORIGIN WALLET BALANCE AFTER IS", originCoinsAfter.String()) - require.Equal(t, test.balancesAfter, originCoinsAfter.String()) + originCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, originAddress) + fmt.Println("THE ORIGIN WALLET BALANCE AFTER IS", originCoinsAfter.String()) //todo remove + require.Equal(t, test.balancesAfter, originCoinsAfter.String()) + + if destinationType == "init" && originType != "user" { + // todo remove debugs + fmt.Println("THE WASM EVENTS WERE:", wasmEvents) + fmt.Println("THE RELEVANT WASM EVENT IS:", wasmEvents[1]) + fmt.Println("THE RELEVANT PAIR ON THE WASM EVENT IS:", wasmEvents[1][0]) + fmt.Println("THE RELEVANT VALUE ON THE WASM EVENT IS:", wasmEvents[1][0].Value) + destinationAddr, _ = sdk.AccAddressFromBech32(wasmEvents[1][0].Value) + } - if !(destinationType == "init" && originType == "exec") { - // todo somehow retrieve destination address, which was not known in advance - destinationAddr = receivingWallet + destinationCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, destinationAddr) require.Equal(t, test.destinationBalancesAfter, destinationCoinsAfter.String()) } }) From db54c2dade7266dc3f11f6849306a7db7eb1b919 Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 17:39:53 +0300 Subject: [PATCH 13/15] tweaking send funds test's expectations and fixing bugs --- .../internal/keeper/secret_contracts_test.go | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index ab862533a..c964fce33 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -336,12 +336,16 @@ func stringToCoins(balance string) sdk.Coins { individualCoins := strings.Split(balance, ",") for _, coin := range individualCoins { + if coin == "" { + continue + } var amount int64 var denom string fmt.Sscanf(coin, "%d%s", &amount, &denom) result = result.Add(sdk.NewInt64Coin(denom, amount)) } + fmt.Println("THE RESULT OF COINS IS:", result) return result } @@ -359,6 +363,7 @@ func CoinsToInput(coins sdk.Coins) string { } result += "]" + fmt.Println("THE RESULT OF INPUT IS:", result) return result } @@ -3730,7 +3735,7 @@ func TestSendFunds(t *testing.T) { description: "one, missing", coinsToSend: `20one`, isSuccess: false, - errorMsg: "todo define error", + errorMsg: "encrypted: dispatch: submessages: 0one is smaller than 20one: insufficient funds", balancesBefore: "5000another", balancesAfter: "5000another", destinationBalancesAfter: "", @@ -3739,7 +3744,7 @@ func TestSendFunds(t *testing.T) { description: "one, not enough", coinsToSend: `20one`, isSuccess: false, - errorMsg: "todo define error", + errorMsg: "encrypted: dispatch: submessages: 19one is smaller than 20one: insufficient funds", balancesBefore: "5000another,19one", balancesAfter: "5000another,19one", destinationBalancesAfter: "", @@ -3764,7 +3769,7 @@ func TestSendFunds(t *testing.T) { description: "multi-coin, missing one", coinsToSend: `130assaf,15denom`, isSuccess: false, - errorMsg: "todo define error", + errorMsg: "encrypted: dispatch: submessages: 0assaf is smaller than 130assaf: insufficient funds", balancesBefore: "200000denom", balancesAfter: "200000denom", destinationBalancesAfter: "", @@ -3773,7 +3778,7 @@ func TestSendFunds(t *testing.T) { description: "multi-coin, not enough of one of them", coinsToSend: `130assaf,15denom`, isSuccess: false, - errorMsg: "todo define error", + errorMsg: "encrypted: dispatch: submessages: 10denom is smaller than 15denom: insufficient funds", balancesBefore: "5000assaf,10denom", balancesAfter: "5000assaf,10denom", destinationBalancesAfter: "", @@ -3782,7 +3787,7 @@ func TestSendFunds(t *testing.T) { description: "multi-coin, not enough of all of them", coinsToSend: `130assaf,15denom`, isSuccess: false, - errorMsg: "todo define error", + errorMsg: "encrypted: dispatch: submessages: 12assaf is smaller than 130assaf: insufficient funds", balancesBefore: "12assaf,10denom", balancesAfter: "12assaf,10denom", destinationBalancesAfter: "", @@ -3791,6 +3796,7 @@ func TestSendFunds(t *testing.T) { t.Run(test.description, func(t *testing.T) { ctx, keeper, helperWallet, helperPrivKey, _, _ := setupBasicTest(t, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) + fmt.Println("THE FUNDING COINS ARE", stringToCoins(test.balancesBefore)) fundingWallet, fundingWalletPrivKey := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, stringToCoins(test.balancesBefore)) fmt.Println("THE FUNDING WALLET IS", fundingWallet.String()) @@ -3825,7 +3831,11 @@ func TestSendFunds(t *testing.T) { var originAddress sdk.AccAddress var msg string - inputCoins := CoinsToInput(stringToCoins(test.coinsToSend)) + fmt.Println("THE PREPARING COINS TO SEND", test.coinsToSend) + s := stringToCoins(test.coinsToSend) + fmt.Println("THE COINS TO SEND STR ARE", s) + inputCoins := CoinsToInput(s) + fmt.Println("THE COINS TO SEND ARE", inputCoins) if destinationType == "user" { // todo replace sending from bank to simply sending if there's such a thing. update: probably isn't msg = fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, receivingWallet.String(), inputCoins) @@ -3834,44 +3844,34 @@ func TestSendFunds(t *testing.T) { msg = fmt.Sprintf(`{"send_multiple_funds_to_init_callback":{"code_id":%d,"coins":%s,"code_hash":"%s"}}`, destinationCodeId, inputCoins, destinationHash) // destination address will only be known after the contract is init } else { - msg = fmt.Sprintf(`{"send_multiple_funds_to_exec_callback":{"to":"%s","coins":%s,code_hash":"%s"}}`, destinationAddr, inputCoins, destinationHash) + msg = fmt.Sprintf(`{"send_multiple_funds_to_exec_callback":{"to":"%s","coins":%s,"code_hash":"%s"}}`, destinationAddr, inputCoins, destinationHash) } - // todo remove one or both of these, if unnecessary (probably needed for extraction of destination address on init) - //var data []byte - var wasmEvents []ContractEvent - fmt.Println("THE BALANCES BEFORE ARE", test.balancesBefore) + var wasmEvents []ContractEvent if originType == "init" { - // todo maybe extract data or wasmEvents, to know the receiving contract's address - fmt.Println("THE SENDING", test.balancesBefore, "COINS ON INIT") _, _, originAddress, wasmEvents, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) - - // verify that no coins where left in the intermediate contract - // todo this is incorrect since keeper does not revert first tx - //sendingContractCoins := keeper.bankKeeper.GetAllBalances(ctx, originAddress) - //require.Equal(t, "", sendingContractCoins.String()) } else if originType == "exec" { _, _, originAddress, _, _ = initHelper(t, keeper, ctx, originCodeId, helperWallet, helperPrivKey, `{"nop":{}}`, false, originVersion.IsCosmWasmV1, defaultGasForTests) - // todo maybe extract data or wasmEvents, to know the receiving contract's address - _, _, _, wasmEvents, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, helperWallet, helperPrivKey, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) - - // verify that no coins where left in the intermediate contract - // todo this is incorrect since keeper does not revert first tx + _, _, _, wasmEvents, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.balancesBefore)) } else { // user sends directly to contract if destinationType == "exec" { _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, "{no_data:{}}", false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) } else { + fmt.Println("SENDING user->init") _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.coinsToSend)) } } if !test.isSuccess { + fmt.Println("SHOULD NOT BE SUCCESS NOW") require.NotEmpty(t, err) require.Equal(t, test.errorMsg, err.Error()) + // todo maybe check balances here too } else { + fmt.Println("SHOULD be SUCCESS NOW") require.Empty(t, err) originCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, originAddress) From c041e6cad7d534831b2be780a7a4452153e40d13 Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 18:34:42 +0300 Subject: [PATCH 14/15] since user/contract error messages differ, build on-demand. also fix wasmcount bug. ALL TESTS PASS --- .../internal/keeper/secret_contracts_test.go | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index c964fce33..2f67f6d04 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -345,7 +345,6 @@ func stringToCoins(balance string) sdk.Coins { result = result.Add(sdk.NewInt64Coin(denom, amount)) } - fmt.Println("THE RESULT OF COINS IS:", result) return result } @@ -363,7 +362,6 @@ func CoinsToInput(coins sdk.Coins) string { } result += "]" - fmt.Println("THE RESULT OF INPUT IS:", result) return result } @@ -3735,7 +3733,7 @@ func TestSendFunds(t *testing.T) { description: "one, missing", coinsToSend: `20one`, isSuccess: false, - errorMsg: "encrypted: dispatch: submessages: 0one is smaller than 20one: insufficient funds", + errorMsg: "0one is smaller than 20one: insufficient funds", balancesBefore: "5000another", balancesAfter: "5000another", destinationBalancesAfter: "", @@ -3744,7 +3742,7 @@ func TestSendFunds(t *testing.T) { description: "one, not enough", coinsToSend: `20one`, isSuccess: false, - errorMsg: "encrypted: dispatch: submessages: 19one is smaller than 20one: insufficient funds", + errorMsg: "19one is smaller than 20one: insufficient funds", balancesBefore: "5000another,19one", balancesAfter: "5000another,19one", destinationBalancesAfter: "", @@ -3769,7 +3767,7 @@ func TestSendFunds(t *testing.T) { description: "multi-coin, missing one", coinsToSend: `130assaf,15denom`, isSuccess: false, - errorMsg: "encrypted: dispatch: submessages: 0assaf is smaller than 130assaf: insufficient funds", + errorMsg: "0assaf is smaller than 130assaf: insufficient funds", balancesBefore: "200000denom", balancesAfter: "200000denom", destinationBalancesAfter: "", @@ -3778,7 +3776,7 @@ func TestSendFunds(t *testing.T) { description: "multi-coin, not enough of one of them", coinsToSend: `130assaf,15denom`, isSuccess: false, - errorMsg: "encrypted: dispatch: submessages: 10denom is smaller than 15denom: insufficient funds", + errorMsg: "10denom is smaller than 15denom: insufficient funds", balancesBefore: "5000assaf,10denom", balancesAfter: "5000assaf,10denom", destinationBalancesAfter: "", @@ -3787,7 +3785,7 @@ func TestSendFunds(t *testing.T) { description: "multi-coin, not enough of all of them", coinsToSend: `130assaf,15denom`, isSuccess: false, - errorMsg: "encrypted: dispatch: submessages: 12assaf is smaller than 130assaf: insufficient funds", + errorMsg: "12assaf is smaller than 130assaf: insufficient funds", balancesBefore: "12assaf,10denom", balancesAfter: "12assaf,10denom", destinationBalancesAfter: "", @@ -3857,18 +3855,32 @@ func TestSendFunds(t *testing.T) { _, _, _, wasmEvents, _, err = execHelperMultipleCoins(t, keeper, ctx, originAddress, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.balancesBefore)) } else { // user sends directly to contract + originAddress = fundingWallet + wasmCount := int64(-1) + if !test.isSuccess { + wasmCount = 0 + } if destinationType == "exec" { - _, _, _, _, _, err = execHelperMultipleCoins(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, "{no_data:{}}", false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend)) + fmt.Println("SENDING user->exec") + _, _, _, _, _, err = execHelperMultipleCoinsImpl(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, `{"no_data":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend), wasmCount) + fmt.Println("SENT user->exec") } else { fmt.Println("SENDING user->init") - _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.coinsToSend)) + _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, destinationCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, wasmCount, stringToCoins(test.coinsToSend)) + fmt.Println("SENT user->init") } } if !test.isSuccess { fmt.Println("SHOULD NOT BE SUCCESS NOW") require.NotEmpty(t, err) - require.Equal(t, test.errorMsg, err.Error()) + + expectedErrorMsg := test.errorMsg + if originType != "user" { + expectedErrorMsg = "dispatch: submessages: " + expectedErrorMsg + } + expectedErrorMsg = "encrypted: " + expectedErrorMsg + require.Equal(t, expectedErrorMsg, err.Error()) // todo maybe check balances here too } else { fmt.Println("SHOULD be SUCCESS NOW") From eafcea5cf48bf1211238c0a0505813e26fba7e3d Mon Sep 17 00:00:00 2001 From: Eshel Date: Thu, 11 Aug 2022 18:58:01 +0300 Subject: [PATCH 15/15] cleaning debug logs --- .../internal/keeper/secret_contracts_test.go | 31 ++----------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 2f67f6d04..10503f766 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3688,14 +3688,12 @@ func TestBankMsgSend(t *testing.T) { func TestSendFunds(t *testing.T) { for _, callTypes := range multisetsFrom([]string{"init", "exec", "user"}, 2) { originType, destinationType := callTypes[0], callTypes[1] - fmt.Println("origin calltype:", originType, "destination calltype:", destinationType) t.Run(originType+"->"+destinationType, func(t *testing.T) { alreadyTested := make(map[string]bool) alreadyTested["useruser->useruser"] = true // we are only testing contracts here for _, currentSubjects := range multisetsFrom(testContracts, 2) { - // [0] is source of transaction, [1] is destination todo remove comment if unnecessary originVersion, destinationVersion := currentSubjects[0], currentSubjects[1] // users don't have versions, so skip the repeating tests (user v1 = user v10) @@ -3794,18 +3792,12 @@ func TestSendFunds(t *testing.T) { t.Run(test.description, func(t *testing.T) { ctx, keeper, helperWallet, helperPrivKey, _, _ := setupBasicTest(t, sdk.NewCoins(sdk.NewInt64Coin("assaf", 5000))) - fmt.Println("THE FUNDING COINS ARE", stringToCoins(test.balancesBefore)) fundingWallet, fundingWalletPrivKey := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, stringToCoins(test.balancesBefore)) - - fmt.Println("THE FUNDING WALLET IS", fundingWallet.String()) receivingWallet, _ := CreateFakeFundedAccount(ctx, keeper.accountKeeper, keeper.bankKeeper, sdk.NewCoins()) - fmt.Println("THE RECEIVING WALLET IS", receivingWallet.String()) - - // todo remove: this is only to verify that the account was funded correctly + // verify that the account was funded correctly fundingWalletCoinsBefore := keeper.bankKeeper.GetAllBalances(ctx, fundingWallet) require.Equal(t, test.balancesBefore, fundingWalletCoinsBefore.String()) - fmt.Println("PASSING INITIAL TEST", receivingWallet.String()) var originCodeId uint64 if originType != "user" { @@ -3829,13 +3821,8 @@ func TestSendFunds(t *testing.T) { var originAddress sdk.AccAddress var msg string - fmt.Println("THE PREPARING COINS TO SEND", test.coinsToSend) - s := stringToCoins(test.coinsToSend) - fmt.Println("THE COINS TO SEND STR ARE", s) - inputCoins := CoinsToInput(s) - fmt.Println("THE COINS TO SEND ARE", inputCoins) + inputCoins := CoinsToInput(stringToCoins(test.coinsToSend)) if destinationType == "user" { - // todo replace sending from bank to simply sending if there's such a thing. update: probably isn't msg = fmt.Sprintf(`{"bank_msg_send":{"to":"%s","amount":%s}}`, receivingWallet.String(), inputCoins) destinationAddr = receivingWallet } else if destinationType == "init" { @@ -3845,7 +3832,6 @@ func TestSendFunds(t *testing.T) { msg = fmt.Sprintf(`{"send_multiple_funds_to_exec_callback":{"to":"%s","coins":%s,"code_hash":"%s"}}`, destinationAddr, inputCoins, destinationHash) } - fmt.Println("THE BALANCES BEFORE ARE", test.balancesBefore) var wasmEvents []ContractEvent if originType == "init" { _, _, originAddress, wasmEvents, err = initHelperImpl(t, keeper, ctx, originCodeId, fundingWallet, fundingWalletPrivKey, msg, false, originVersion.IsCosmWasmV1, defaultGasForTests, -1, stringToCoins(test.balancesBefore)) @@ -3861,18 +3847,13 @@ func TestSendFunds(t *testing.T) { wasmCount = 0 } if destinationType == "exec" { - fmt.Println("SENDING user->exec") _, _, _, _, _, err = execHelperMultipleCoinsImpl(t, keeper, ctx, destinationAddr, fundingWallet, fundingWalletPrivKey, `{"no_data":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, stringToCoins(test.coinsToSend), wasmCount) - fmt.Println("SENT user->exec") } else { - fmt.Println("SENDING user->init") _, _, destinationAddr, _, err = initHelperImpl(t, keeper, ctx, destinationCodeId, fundingWallet, fundingWalletPrivKey, `{"nop":{}}`, false, destinationVersion.IsCosmWasmV1, math.MaxUint64, wasmCount, stringToCoins(test.coinsToSend)) - fmt.Println("SENT user->init") } } if !test.isSuccess { - fmt.Println("SHOULD NOT BE SUCCESS NOW") require.NotEmpty(t, err) expectedErrorMsg := test.errorMsg @@ -3881,21 +3862,13 @@ func TestSendFunds(t *testing.T) { } expectedErrorMsg = "encrypted: " + expectedErrorMsg require.Equal(t, expectedErrorMsg, err.Error()) - // todo maybe check balances here too } else { - fmt.Println("SHOULD be SUCCESS NOW") require.Empty(t, err) originCoinsAfter := keeper.bankKeeper.GetAllBalances(ctx, originAddress) - fmt.Println("THE ORIGIN WALLET BALANCE AFTER IS", originCoinsAfter.String()) //todo remove require.Equal(t, test.balancesAfter, originCoinsAfter.String()) if destinationType == "init" && originType != "user" { - // todo remove debugs - fmt.Println("THE WASM EVENTS WERE:", wasmEvents) - fmt.Println("THE RELEVANT WASM EVENT IS:", wasmEvents[1]) - fmt.Println("THE RELEVANT PAIR ON THE WASM EVENT IS:", wasmEvents[1][0]) - fmt.Println("THE RELEVANT VALUE ON THE WASM EVENT IS:", wasmEvents[1][0].Value) destinationAddr, _ = sdk.AccAddressFromBech32(wasmEvents[1][0].Value) }