From 76624e7eb27f7bdf6cb0d070c895715c550db3f8 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:07:33 +0700 Subject: [PATCH 01/16] coding --- tests/systemtests/cometbft_client_test.go | 2 +- tests/systemtests/genesis_io.go | 15 +++++++++ tests/systemtests/gov_test.go | 2 +- tests/systemtests/tx | 1 + tests/systemtests/tx_test.go | 37 +++++++++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 tests/systemtests/tx create mode 100644 tests/systemtests/tx_test.go diff --git a/tests/systemtests/cometbft_client_test.go b/tests/systemtests/cometbft_client_test.go index e031ae0c8f55..3c79adfe846c 100644 --- a/tests/systemtests/cometbft_client_test.go +++ b/tests/systemtests/cometbft_client_test.go @@ -1,4 +1,4 @@ -//go:build system_test +//go:build !system_test package systemtests diff --git a/tests/systemtests/genesis_io.go b/tests/systemtests/genesis_io.go index df2081ba0924..782f9efbbeee 100644 --- a/tests/systemtests/genesis_io.go +++ b/tests/systemtests/genesis_io.go @@ -1,7 +1,10 @@ package systemtests import ( + "bytes" "fmt" + "io" + "os" "testing" "time" @@ -44,3 +47,15 @@ func GetGenesisBalance(rawGenesis []byte, addr string) sdk.Coins { } return r } + +// StoreTempFile creates a temporary file in the test's temporary directory with the provided content. +// It returns a pointer to the created file. Errors during the process are handled with test assertions. +func StoreTempFile(t *testing.T, content []byte) *os.File { + t.Helper() + out, err := os.CreateTemp(t.TempDir(), "") + require.NoError(t, err) + _, err = io.Copy(out, bytes.NewReader(content)) + require.NoError(t, err) + require.NoError(t, out.Close()) + return out +} diff --git a/tests/systemtests/gov_test.go b/tests/systemtests/gov_test.go index 73bc7fd96efc..86aa61a7075e 100644 --- a/tests/systemtests/gov_test.go +++ b/tests/systemtests/gov_test.go @@ -1,4 +1,4 @@ -//go:build system_test +//go:build !system_test package systemtests diff --git a/tests/systemtests/tx b/tests/systemtests/tx new file mode 100644 index 000000000000..51ae02b210e6 --- /dev/null +++ b/tests/systemtests/tx @@ -0,0 +1 @@ +{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1psqxug2jg5w2xsyn4vmnvtm545x57crh0zr85d","to_address":"cosmos1azqhsyjw3qvv99eggyuzp4vg7fnh5jr433nnz0","amount":[{"denom":"stake","amount":"1000"}]}],"memo":"","timeout_height":"0","unordered":false,"timeout_timestamp":"1970-01-01T00:00:00Z","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[{"denom":"stake","amount":"10"}],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":[]} diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go new file mode 100644 index 000000000000..d7099bdb2d3a --- /dev/null +++ b/tests/systemtests/tx_test.go @@ -0,0 +1,37 @@ +//go:build system_test + +package systemtests + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestQueryBySig(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + // qc := tx.NewServiceClient(sut.RPCClient(t)) + + // create unsign tx + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + res := cli.RunCommandWithArgs(bankSendCmdArgs...) + txFile := StoreTempFile(t, []byte(res)) + fmt.Println("txFile", txFile) + + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s",sut.chainID), fmt.Sprintf("--output-document=%s", txFile.Name())) + fmt.Println("res", res) +} From 5d2292f1b07329ec3e4611fb8f2c1f53015f8c61 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Mon, 7 Oct 2024 19:32:44 +0700 Subject: [PATCH 02/16] test grpc --- tests/systemtests/tx_test.go | 434 ++++++++++++++++++++++++++++++++++- 1 file changed, 432 insertions(+), 2 deletions(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index d7099bdb2d3a..01a315b538ef 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -3,12 +3,24 @@ package systemtests import ( + "context" + "encoding/base64" + "fmt" + "testing" + "github.com/cosmos/cosmos-sdk/types/tx" "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" ) +var bankMsgSendEventAction = "message.action='/cosmos.bank.v1beta1.MsgSend'" + func TestQueryBySig(t *testing.T) { sut.ResetChain(t) @@ -24,7 +36,7 @@ func TestQueryBySig(t *testing.T) { sut.StartChain(t) - // qc := tx.NewServiceClient(sut.RPCClient(t)) + qc := tx.NewServiceClient(sut.RPCClient(t)) // create unsign tx bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} @@ -32,6 +44,424 @@ func TestQueryBySig(t *testing.T) { txFile := StoreTempFile(t, []byte(res)) fmt.Println("txFile", txFile) - res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s",sut.chainID), fmt.Sprintf("--output-document=%s", txFile.Name())) + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") fmt.Println("res", res) + sig := gjson.Get(res, "signatures.0").String() + fmt.Println("sig", sig) + signedTxFile := StoreTempFile(t, []byte(res)) + + res = cli.Run("tx", "broadcast", signedTxFile.Name()) + fmt.Println("res", res) + RequireTxSuccess(t, res) + + sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig) + resp, err := qc.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{ + Query: sigFormatted, + OrderBy: 0, + Page: 0, + Limit: 10, + }) + require.NoError(t, err) + require.Len(t, resp.Txs, 1) + require.Len(t, resp.Txs[0].Signatures, 1) +} + +func TestSimulateTx_GRPC(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + qc := tx.NewServiceClient(sut.RPCClient(t)) + + // create unsign tx + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + res := cli.RunCommandWithArgs(bankSendCmdArgs...) + txFile := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") + signedTxFile := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name()) + txBz, err := base64.StdEncoding.DecodeString(res) + require.NoError(t, err) + + testCases := []struct { + name string + req *tx.SimulateRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "request cannot be nil"}, + {"empty request", &tx.SimulateRequest{}, true, "empty txBytes is not allowed"}, + {"valid request with tx_bytes", &tx.SimulateRequest{TxBytes: txBz}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Broadcast the tx via gRPC via the validator's clientCtx (which goes + // through Tendermint). + res, err := qc.Simulate(context.Background(), tc.req) + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + // Check the result and gas used are correct. + // + // The 12 events are: + // - Sending Fee to the pool: coin_spent, coin_received and transfer + // - tx.* events: tx.fee, tx.acc_seq, tx.signature + // - Sending Amount to recipient: coin_spent, coin_received and transfer + // - Msg events: message.module=bank, message.action=/cosmos.bank.v1beta1.MsgSend and message.sender= (in one message) + require.Equal(t, 10, len(res.GetResult().GetEvents())) + require.True(t, res.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty. + } + }) + } + + +} + +func TestGetTxEvents_GRPC(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + qc := tx.NewServiceClient(sut.RPCClient(t)) + rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--note=foobar", "--fees=1stake") + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + rsp = cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake") + txResult, found = cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + testCases := []struct { + name string + req *tx.GetTxsEventRequest + expErr bool + expErrMsg string + expLen int + }{ + { + "nil request", + nil, + true, + "request cannot be nil", + 0, + }, + { + "empty request", + &tx.GetTxsEventRequest{}, + true, + "query cannot be empty", + 0, + }, + { + "request with dummy event", + &tx.GetTxsEventRequest{Query: "foobar"}, + true, + "failed to search for txs", + 0, + }, + { + "request with order-by", + &tx.GetTxsEventRequest{ + Query: bankMsgSendEventAction, + OrderBy: tx.OrderBy_ORDER_BY_ASC, + }, + false, + "", + 2, + }, + { + "without pagination", + &tx.GetTxsEventRequest{ + Query: bankMsgSendEventAction, + }, + false, + "", + 2, + }, + { + "with pagination", + &tx.GetTxsEventRequest{ + Query: bankMsgSendEventAction, + Page: 1, + Limit: 1, + }, + false, + "", + 1, + }, + { + "with multi events", + &tx.GetTxsEventRequest{ + Query: fmt.Sprintf("%s AND message.module='bank'", bankMsgSendEventAction), + }, + false, + "", + 2, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Query the tx via gRPC. + grpcRes, err := qc.GetTxsEvent(context.Background(), tc.req) + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + require.GreaterOrEqual(t, len(grpcRes.Txs), 1) + require.Equal(t, "foobar", grpcRes.Txs[0].Body.Memo) + require.Equal(t, tc.expLen, len(grpcRes.Txs)) + + // Make sure fields are populated. + // ref: https://github.com/cosmos/cosmos-sdk/issues/8680 + // ref: https://github.com/cosmos/cosmos-sdk/issues/8681 + require.NotEmpty(t, grpcRes.TxResponses[0].Timestamp) + require.Empty(t, grpcRes.TxResponses[0].RawLog) // logs are empty if the transactions are successful + } + }) + } + + + +} + +func TestGetTx_GRPC(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + qc := tx.NewServiceClient(sut.RPCClient(t)) + + rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar") + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + txHash := gjson.Get(txResult, "txhash").String() + + testCases := []struct { + name string + req *tx.GetTxRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "request cannot be nil"}, + {"empty request", &tx.GetTxRequest{}, true, "tx hash cannot be empty"}, + {"request with dummy hash", &tx.GetTxRequest{Hash: "deadbeef"}, true, "code = NotFound desc = tx not found: deadbeef"}, + {"good request", &tx.GetTxRequest{Hash: txHash}, false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Query the tx via gRPC. + grpcRes, err := qc.GetTx(context.Background(), tc.req) + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + require.Equal(t, "foobar", grpcRes.Tx.Body.Memo) + } + }) + } +} + +func TestGetBlockWithTxs_GRPC(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + qc := tx.NewServiceClient(sut.RPCClient(t)) + + rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar") + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + height := gjson.Get(txResult, "height").Int() + + testCases := []struct { + name string + req *tx.GetBlockWithTxsRequest + expErr bool + expErrMsg string + expTxsLen int + }{ + {"nil request", nil, true, "request cannot be nil", 0}, + {"empty request", &tx.GetBlockWithTxsRequest{}, true, "height must not be less than 1 or greater than the current height", 0}, + {"bad height", &tx.GetBlockWithTxsRequest{Height: 99999999}, true, "height must not be less than 1 or greater than the current height", 0}, + {"bad pagination", &tx.GetBlockWithTxsRequest{Height: height, Pagination: &query.PageRequest{Offset: 1000, Limit: 100}}, true, "out of range", 0}, + {"good request", &tx.GetBlockWithTxsRequest{Height: height}, false, "", 1}, + {"with pagination request", &tx.GetBlockWithTxsRequest{Height: height, Pagination: &query.PageRequest{Offset: 0, Limit: 1}}, false, "", 1}, + {"page all request", &tx.GetBlockWithTxsRequest{Height: height, Pagination: &query.PageRequest{Offset: 0, Limit: 100}}, false, "", 1}, + {"block with 0 tx", &tx.GetBlockWithTxsRequest{Height: height - 1, Pagination: &query.PageRequest{Offset: 0, Limit: 100}}, false, "", 0}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t * testing.T) { + // Query the tx via gRPC. + grpcRes, err := qc.GetBlockWithTxs(context.Background(), tc.req) + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + } else { + require.NoError(t, err) + if tc.expTxsLen > 0 { + require.Equal(t, "foobar", grpcRes.Txs[0].Body.Memo) + } + require.Equal(t, grpcRes.Block.Header.Height, tc.req.Height) + if tc.req.Pagination != nil { + require.LessOrEqual(t, len(grpcRes.Txs), int(tc.req.Pagination.Limit)) + } + } + }) + } +} + +func TestTxEncode_GRPC(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + qc := tx.NewServiceClient(sut.RPCClient(t)) + + protoTx := &tx.Tx{ + Body: &tx.TxBody{ + Messages: []*codectypes.Any{}, + }, + AuthInfo: &tx.AuthInfo{}, + Signatures: [][]byte{}, + } + + testCases := []struct { + name string + req *tx.TxEncodeRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "request cannot be nil"}, + {"empty request", &tx.TxEncodeRequest{}, true, "invalid empty tx"}, + {"valid tx request", &tx.TxEncodeRequest{Tx: protoTx}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.TxEncode(context.Background(), tc.req) + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + require.Empty(t, res) + } else { + require.NoError(t, err) + } + }) + } } + +func TestTxDecode_GRPC(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + qc := tx.NewServiceClient(sut.RPCClient(t)) + + // create unsign tx + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + res := cli.RunCommandWithArgs(bankSendCmdArgs...) + txFile := StoreTempFile(t, []byte(res)) + fmt.Println("txFile", txFile) + + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") + signedTxFile := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name()) + fmt.Println("res", res) + txBz, err := base64.StdEncoding.DecodeString(res) + fmt.Println("txBz", txBz, err) + invalidTxBytes := append(txBz, byte(0o00)) + + testCases := []struct { + name string + req *tx.TxDecodeRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "request cannot be nil"}, + {"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"}, + {"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"}, + {"valid request with tx bytes", &tx.TxDecodeRequest{TxBytes: txBz}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.TxDecode(context.Background(), tc.req) + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + require.Empty(t, res) + } else { + require.NoError(t, err) + require.NotEmpty(t, res.GetTx()) + } + }) + } +} \ No newline at end of file From 5d6d1e21201bc64e64450dd34e5b20053ea0710f Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Mon, 7 Oct 2024 19:37:20 +0700 Subject: [PATCH 03/16] clean up --- tests/systemtests/cometbft_client_test.go | 2 +- tests/systemtests/gov_test.go | 2 +- tests/systemtests/tx | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 tests/systemtests/tx diff --git a/tests/systemtests/cometbft_client_test.go b/tests/systemtests/cometbft_client_test.go index 3c79adfe846c..e031ae0c8f55 100644 --- a/tests/systemtests/cometbft_client_test.go +++ b/tests/systemtests/cometbft_client_test.go @@ -1,4 +1,4 @@ -//go:build !system_test +//go:build system_test package systemtests diff --git a/tests/systemtests/gov_test.go b/tests/systemtests/gov_test.go index 86aa61a7075e..73bc7fd96efc 100644 --- a/tests/systemtests/gov_test.go +++ b/tests/systemtests/gov_test.go @@ -1,4 +1,4 @@ -//go:build !system_test +//go:build system_test package systemtests diff --git a/tests/systemtests/tx b/tests/systemtests/tx deleted file mode 100644 index 51ae02b210e6..000000000000 --- a/tests/systemtests/tx +++ /dev/null @@ -1 +0,0 @@ -{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1psqxug2jg5w2xsyn4vmnvtm545x57crh0zr85d","to_address":"cosmos1azqhsyjw3qvv99eggyuzp4vg7fnh5jr433nnz0","amount":[{"denom":"stake","amount":"1000"}]}],"memo":"","timeout_height":"0","unordered":false,"timeout_timestamp":"1970-01-01T00:00:00Z","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[{"denom":"stake","amount":"10"}],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":[]} From cb168488ef5214f5a144ecb4826d3e5220c652d8 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:32:23 +0700 Subject: [PATCH 04/16] multisig test ok --- tests/systemtests/tx_test.go | 60 +++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index 01a315b538ef..cb0dbcd1a34a 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -42,16 +42,12 @@ func TestQueryBySig(t *testing.T) { bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} res := cli.RunCommandWithArgs(bankSendCmdArgs...) txFile := StoreTempFile(t, []byte(res)) - fmt.Println("txFile", txFile) res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") - fmt.Println("res", res) sig := gjson.Get(res, "signatures.0").String() - fmt.Println("sig", sig) signedTxFile := StoreTempFile(t, []byte(res)) res = cli.Run("tx", "broadcast", signedTxFile.Name()) - fmt.Println("res", res) RequireTxSuccess(t, res) sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig) @@ -428,15 +424,12 @@ func TestTxDecode_GRPC(t *testing.T) { bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} res := cli.RunCommandWithArgs(bankSendCmdArgs...) txFile := StoreTempFile(t, []byte(res)) - fmt.Println("txFile", txFile) res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") signedTxFile := StoreTempFile(t, []byte(res)) res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name()) - fmt.Println("res", res) txBz, err := base64.StdEncoding.DecodeString(res) - fmt.Println("txBz", txBz, err) invalidTxBytes := append(txBz, byte(0o00)) testCases := []struct { @@ -464,4 +457,57 @@ func TestTxDecode_GRPC(t *testing.T) { } }) } +} + +func TestSimMultiSigTx(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + _ = cli.AddKey("account1") + _ = cli.AddKey("account2") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + multiSigName := "multisig" + res := cli.RunCommandWithArgs("keys", "add", multiSigName, "--multisig=account1,account2", "--multisig-threshold=2", "--keyring-backend=test", "--home=./testnet") + multiSigAddr := cli.GetKeyAddr(multiSigName) + + // Send from validator to multisig addr + rsp := cli.Run("tx", "bank", "send", valAddr, multiSigAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake") + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + multiSigBalance := cli.QueryBalance(multiSigAddr, denom) + require.Equal(t, multiSigBalance, transferAmount) + + // Send from multisig to validator + // create unsign tx + var newTransferAmount int64 = 100 + bankSendCmdArgs := []string{"tx", "bank", "send", multiSigAddr, valAddr, fmt.Sprintf("%d%s", newTransferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + res = cli.RunCommandWithArgs(bankSendCmdArgs...) + txFile := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account1"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet") + account1Signed := StoreTempFile(t, []byte(res)) + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account2"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet") + account2Signed := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "multisign-batch", txFile.Name(), multiSigName, account1Signed.Name(), account2Signed.Name(), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet") + txSignedFile := StoreTempFile(t, []byte(res)) + + res = cli.Run("tx", "broadcast", txSignedFile.Name()) + RequireTxSuccess(t, res) + + multiSigBalance = cli.QueryBalance(multiSigAddr, denom) + require.Equal(t, multiSigBalance, transferAmount - newTransferAmount - 10) + + } \ No newline at end of file From 65a87ef0f757dfead3dc7bb109ad983a4c437678 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Sun, 13 Oct 2024 22:11:01 +0700 Subject: [PATCH 05/16] add grpc gateway tests --- tests/systemtests/tx_test.go | 403 ++++++++++++++++++++++++++++++++++- 1 file changed, 395 insertions(+), 8 deletions(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index cb0dbcd1a34a..630f444dd2fd 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -5,18 +5,20 @@ package systemtests import ( "context" "encoding/base64" + "encoding/json" "fmt" "testing" + "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/types/tx" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" ) var bankMsgSendEventAction = "message.action='/cosmos.bank.v1beta1.MsgSend'" @@ -124,8 +126,68 @@ func TestSimulateTx_GRPC(t *testing.T) { } }) } +} + +func TestSimulateTx_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + // qc := tx.NewServiceClient(sut.RPCClient(t)) + baseURL := sut.APIAddress() + + // create unsign tx + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + res := cli.RunCommandWithArgs(bankSendCmdArgs...) + txFile := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") + signedTxFile := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name()) + txBz, err := base64.StdEncoding.DecodeString(res) + require.NoError(t, err) + + testCases := []struct { + name string + req *tx.SimulateRequest + expErr bool + expErrMsg string + }{ + {"empty request", &tx.SimulateRequest{}, true, "empty txBytes is not allowed"}, + {"valid request with tx_bytes", &tx.SimulateRequest{TxBytes: txBz}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + reqBz, err := json.Marshal(tc.req) + res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/simulate", baseURL), "application/json", reqBz) + require.NoError(t, err) + if tc.expErr { + require.Contains(t, string(res), tc.expErrMsg) + } else { + require.NoError(t, err) + msgResponses := gjson.Get(string(res), "result.msg_responses").Array() + require.Equal(t, len(msgResponses), 1) + + events := gjson.Get(string(res), "result.events").Array() + require.Equal(t, len(events), 10) + + gasUsed := gjson.Get(string(res), "gas_info.gas_used").Int() + require.True(t, gasUsed > 0) + } + }) + } } func TestGetTxEvents_GRPC(t *testing.T) { @@ -244,8 +306,105 @@ func TestGetTxEvents_GRPC(t *testing.T) { } }) } - +} + +func TestGetTxEvents_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + // qc := tx.NewServiceClient(sut.RPCClient(t)) + baseURL := sut.APIAddress() + rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--note=foobar", "--fees=1stake") + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + rsp = cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake") + txResult, found = cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + testCases := []struct { + name string + url string + expErr bool + expErrMsg string + expLen int + }{ + { + "empty params", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", baseURL), + true, + "query cannot be empty", 0, + }, + { + "without pagination", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s", baseURL, bankMsgSendEventAction), + false, + "", 2, + }, + { + "with pagination", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&page=%d&limit=%d", baseURL, bankMsgSendEventAction, 1, 1), + false, + "", 1, + }, + { + "valid request: order by asc", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=ORDER_BY_ASC", baseURL, bankMsgSendEventAction, "message.module='bank'"), + false, + "", 2, + }, + { + "valid request: order by desc", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=ORDER_BY_DESC", baseURL, bankMsgSendEventAction, "message.module='bank'"), + false, + "", 2, + }, + { + "invalid request: invalid order by", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=invalid_order", baseURL, bankMsgSendEventAction, "message.module='bank'"), + true, + "is not a valid tx.OrderBy", 0, + }, + { + "expect pass with multiple-events", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s", baseURL, bankMsgSendEventAction, "message.module='bank'"), + false, + "", 2, + }, + { + "expect pass with escape event", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s", baseURL, "message.action%3D'/cosmos.bank.v1beta1.MsgSend'"), + false, + "", 2, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := testutil.GetRequest(tc.url) + require.NoError(t, err) + if tc.expErr { + require.Contains(t, string(res), tc.expErrMsg) + } else { + require.NoError(t, err) + txs := gjson.Get(string(res), "txs").Array() + require.Equal(t, len(txs), tc.expLen) + } + }) + } } @@ -298,6 +457,71 @@ func TestGetTx_GRPC(t *testing.T) { } } +func TestGetTx_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + baseURL := sut.APIAddress() + + rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar") + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + txHash := gjson.Get(txResult, "txhash").String() + + testCases := []struct { + name string + url string + expErr bool + expErrMsg string + }{ + { + "empty params", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/", baseURL), + true, "tx hash cannot be empty", + }, + { + "dummy hash", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", baseURL, "deadbeef"), + true, "tx not found", + }, + { + "good hash", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", baseURL, txHash), + false, "", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := testutil.GetRequest(tc.url) + require.NoError(t, err) + if tc.expErr { + require.Contains(t, string(res), tc.expErrMsg) + } else { + timestamp := gjson.Get(string(res), "tx_response.timestamp").String() + require.NotEmpty(t, timestamp) + + height := gjson.Get(string(res), "tx_response.height").Int() + require.NotZero(t, height) + + rawLog := gjson.Get(string(res), "tx_response.raw_log").String() + require.Empty(t, rawLog) + } + }) + } +} + func TestGetBlockWithTxs_GRPC(t *testing.T) { sut.ResetChain(t) @@ -338,7 +562,7 @@ func TestGetBlockWithTxs_GRPC(t *testing.T) { {"block with 0 tx", &tx.GetBlockWithTxsRequest{Height: height - 1, Pagination: &query.PageRequest{Offset: 0, Limit: 100}}, false, "", 0}, } for _, tc := range testCases { - t.Run(tc.name, func(t * testing.T) { + t.Run(tc.name, func(t *testing.T) { // Query the tx via gRPC. grpcRes, err := qc.GetBlockWithTxs(context.Background(), tc.req) if tc.expErr { @@ -358,6 +582,68 @@ func TestGetBlockWithTxs_GRPC(t *testing.T) { } } +func TestGetBlockWithTxs_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + baseUrl := sut.APIAddress() + + rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar") + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + height := gjson.Get(txResult, "height").Int() + + testCases := []struct { + name string + url string + expErr bool + expErrMsg string + }{ + { + "empty params", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/block/0", baseUrl), + true, "height must not be less than 1 or greater than the current height", + }, + { + "bad height", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/block/%d", baseUrl, 9999999), + true, "height must not be less than 1 or greater than the current height", + }, + { + "good request", + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/block/%d", baseUrl, height), + false, "", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := testutil.GetRequest(tc.url) + require.NoError(t, err) + if tc.expErr { + require.Contains(t, string(res), tc.expErrMsg) + } else { + memo := gjson.Get(string(res), "txs.0.body.memo").String() + require.Equal(t, memo, "foobar") + + respHeight := gjson.Get(string(res), "block.header.height").Int() + require.Equal(t, respHeight, height) + } + }) + } +} + func TestTxEncode_GRPC(t *testing.T) { sut.ResetChain(t) @@ -374,7 +660,7 @@ func TestTxEncode_GRPC(t *testing.T) { Body: &tx.TxBody{ Messages: []*codectypes.Any{}, }, - AuthInfo: &tx.AuthInfo{}, + AuthInfo: &tx.AuthInfo{}, Signatures: [][]byte{}, } @@ -403,6 +689,49 @@ func TestTxEncode_GRPC(t *testing.T) { } } +func TestTxEncode_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + baseUrl := sut.APIAddress() + + protoTx := &tx.Tx{ + Body: &tx.TxBody{ + Messages: []*codectypes.Any{}, + }, + AuthInfo: &tx.AuthInfo{}, + Signatures: [][]byte{}, + } + + testCases := []struct { + name string + req *tx.TxEncodeRequest + expErr bool + expErrMsg string + }{ + {"empty request", &tx.TxEncodeRequest{}, true, "invalid empty tx"}, + {"valid tx request", &tx.TxEncodeRequest{Tx: protoTx}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + reqBz, err := json.Marshal(tc.req) + + res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/encode", baseUrl), "application/json", reqBz) + require.NoError(t, err) + if tc.expErr { + require.Contains(t, string(res), tc.expErrMsg) + } + }) + } +} + func TestTxDecode_GRPC(t *testing.T) { sut.ResetChain(t) @@ -430,6 +759,7 @@ func TestTxDecode_GRPC(t *testing.T) { res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name()) txBz, err := base64.StdEncoding.DecodeString(res) + require.NoError(t, err) invalidTxBytes := append(txBz, byte(0o00)) testCases := []struct { @@ -459,6 +789,64 @@ func TestTxDecode_GRPC(t *testing.T) { } } +func TestTxDecode_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + + cli := NewCLIWrapper(t, sut, verbose) + // get validator address + valAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, valAddr) + + // add new key + receiverAddr := cli.AddKey("account1") + denom := "stake" + var transferAmount int64 = 1000 + + sut.StartChain(t) + + basrUrl := sut.APIAddress() + + // create unsign tx + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + res := cli.RunCommandWithArgs(bankSendCmdArgs...) + txFile := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") + signedTxFile := StoreTempFile(t, []byte(res)) + + res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name()) + txBz, err := base64.StdEncoding.DecodeString(res) + require.NoError(t, err) + invalidTxBytes := append(txBz, byte(0o00)) + + testCases := []struct { + name string + req *tx.TxDecodeRequest + expErr bool + expErrMsg string + }{ + {"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"}, + {"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"}, + {"valid request with tx_bytes", &tx.TxDecodeRequest{TxBytes: txBz}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + reqBz, err := json.Marshal(tc.req) + require.NoError(t, err) + + res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/decode", basrUrl), "application/json", reqBz) + require.NoError(t, err) + if tc.expErr { + require.Contains(t, string(res), tc.expErrMsg) + } else { + signatures := gjson.Get(string(res), "tx.signatures").Array() + require.Equal(t, len(signatures), 1) + } + }) + } +} + func TestSimMultiSigTx(t *testing.T) { sut.ResetChain(t) @@ -505,9 +893,8 @@ func TestSimMultiSigTx(t *testing.T) { res = cli.Run("tx", "broadcast", txSignedFile.Name()) RequireTxSuccess(t, res) - + multiSigBalance = cli.QueryBalance(multiSigAddr, denom) - require.Equal(t, multiSigBalance, transferAmount - newTransferAmount - 10) + require.Equal(t, multiSigBalance, transferAmount-newTransferAmount-10) - -} \ No newline at end of file +} From 4d3a46e80d2e2667642c20438a0f56915ba6669e Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:31:58 +0700 Subject: [PATCH 06/16] remove migrated test --- tests/e2e/tx/service_test.go | 866 ----------------------------------- 1 file changed, 866 deletions(-) diff --git a/tests/e2e/tx/service_test.go b/tests/e2e/tx/service_test.go index f0e4e527664c..a18568c99e28 100644 --- a/tests/e2e/tx/service_test.go +++ b/tests/e2e/tx/service_test.go @@ -2,40 +2,24 @@ package tx_test import ( "context" - "encoding/base64" "fmt" "os" - "strings" "testing" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "cosmossdk.io/math" "cosmossdk.io/simapp" banktypes "cosmossdk.io/x/bank/types" - "github.com/cosmos/cosmos-sdk/client" - clienttx "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" - "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - authclient "github.com/cosmos/cosmos-sdk/x/auth/client" - authtest "github.com/cosmos/cosmos-sdk/x/auth/client/testutil" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" ) -var bankMsgSendEventAction = fmt.Sprintf("message.action='%s'", sdk.MsgTypeURL(&banktypes.MsgSend{})) - type E2ETestSuite struct { suite.Suite @@ -119,819 +103,6 @@ func (s *E2ETestSuite) TearDownSuite() { s.network.Cleanup() } -func (s *E2ETestSuite) TestQueryBySig() { - // broadcast tx - txb := s.mkTxBuilder() - txbz, err := s.cfg.TxConfig.TxEncoder()(txb.GetTx()) - s.Require().NoError(err) - resp, err := s.queryClient.BroadcastTx(context.Background(), &tx.BroadcastTxRequest{TxBytes: txbz, Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC}) - s.Require().NoError(err) - s.Require().NotEmpty(resp.TxResponse.TxHash) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // get the signature out of the builder - sigs, err := txb.GetTx().GetSignaturesV2() - s.Require().NoError(err) - s.Require().Len(sigs, 1) - sig, ok := sigs[0].Data.(*signing.SingleSignatureData) - s.Require().True(ok) - - // encode, format, query - b64Sig := base64.StdEncoding.EncodeToString(sig.Signature) - sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, b64Sig) - res, err := s.queryClient.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{ - Query: sigFormatted, - OrderBy: 0, - Page: 0, - Limit: 10, - }) - s.Require().NoError(err) - s.Require().Len(res.Txs, 1) - s.Require().Len(res.Txs[0].Signatures, 1) - s.Require().Equal(res.Txs[0].Signatures[0], sig.Signature) -} - -func (s *E2ETestSuite) TestSimulateTx_GRPC() { - val := s.network.GetValidators()[0] - txBuilder := s.mkTxBuilder() - // Convert the txBuilder to a tx.Tx. - protoTx, err := txBuilder.GetTx().(interface{ AsTx() (*tx.Tx, error) }).AsTx() - s.Require().NoError(err) - // Encode the txBuilder to txBytes. - txBytes, err := val.GetClientCtx().TxConfig.TxEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - - testCases := []struct { - name string - req *tx.SimulateRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &tx.SimulateRequest{}, true, "empty txBytes is not allowed"}, - {"valid request with proto tx (deprecated)", &tx.SimulateRequest{Tx: protoTx}, false, ""}, - {"valid request with tx_bytes", &tx.SimulateRequest{TxBytes: txBytes}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - // Broadcast the tx via gRPC via the validator's clientCtx (which goes - // through Tendermint). - res, err := s.queryClient.Simulate(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - // Check the result and gas used are correct. - // - // The 12 events are: - // - Sending Fee to the pool: coin_spent, coin_received and transfer - // - tx.* events: tx.fee, tx.acc_seq, tx.signature - // - Sending Amount to recipient: coin_spent, coin_received and transfer - // - Msg events: message.module=bank, message.action=/cosmos.bank.v1beta1.MsgSend and message.sender= (in one message) - s.Require().Equal(10, len(res.GetResult().GetEvents())) - s.Require().True(res.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty. - } - }) - } -} - -func (s *E2ETestSuite) TestSimulateTx_GRPCGateway() { - val := s.network.GetValidators()[0] - txBuilder := s.mkTxBuilder() - // Convert the txBuilder to a tx.Tx. - protoTx, err := txBuilder.GetTx().(interface{ AsTx() (*tx.Tx, error) }).AsTx() - s.Require().NoError(err) - // Encode the txBuilder to txBytes. - txBytes, err := val.GetClientCtx().TxConfig.TxEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - - testCases := []struct { - name string - req *tx.SimulateRequest - expErr bool - expErrMsg string - }{ - {"empty request", &tx.SimulateRequest{}, true, "empty txBytes is not allowed"}, - {"valid request with proto tx (deprecated)", &tx.SimulateRequest{Tx: protoTx}, false, ""}, - {"valid request with tx_bytes", &tx.SimulateRequest{TxBytes: txBytes}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - req, err := val.GetClientCtx().Codec.MarshalJSON(tc.req) - s.Require().NoError(err) - res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/simulate", val.GetAPIAddress()), "application/json", req) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.SimulateResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - // Check the result and gas used are correct. - s.Require().Len(result.GetResult().MsgResponses, 1) - s.Require().Equal(10, len(result.GetResult().GetEvents())) // See TestSimulateTx_GRPC for the 10 events. - s.Require().True(result.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty. - } - }) - } -} - -func (s *E2ETestSuite) TestGetTxEvents_GRPC() { - testCases := []struct { - name string - req *tx.GetTxsEventRequest - expErr bool - expErrMsg string - expLen int - }{ - { - "nil request", - nil, - true, - "request cannot be nil", - 0, - }, - { - "empty request", - &tx.GetTxsEventRequest{}, - true, - "query cannot be empty", - 0, - }, - { - "request with dummy event", - &tx.GetTxsEventRequest{Query: "foobar"}, - true, - "failed to search for txs", - 0, - }, - { - "request with order-by", - &tx.GetTxsEventRequest{ - Query: bankMsgSendEventAction, - OrderBy: tx.OrderBy_ORDER_BY_ASC, - }, - false, - "", - 3, - }, - { - "without pagination", - &tx.GetTxsEventRequest{ - Query: bankMsgSendEventAction, - }, - false, - "", - 3, - }, - { - "with pagination", - &tx.GetTxsEventRequest{ - Query: bankMsgSendEventAction, - Page: 1, - Limit: 2, - }, - false, - "", - 2, - }, - { - "with multi events", - &tx.GetTxsEventRequest{ - Query: fmt.Sprintf("%s AND message.module='bank'", bankMsgSendEventAction), - }, - false, - "", - 3, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - // Query the tx via gRPC. - grpcRes, err := s.queryClient.GetTxsEvent(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - s.Require().GreaterOrEqual(len(grpcRes.Txs), 1) - s.Require().Equal("foobar", grpcRes.Txs[0].Body.Memo) - s.Require().Equal(tc.expLen, len(grpcRes.Txs)) - - // Make sure fields are populated. - // ref: https://github.com/cosmos/cosmos-sdk/issues/8680 - // ref: https://github.com/cosmos/cosmos-sdk/issues/8681 - s.Require().NotEmpty(grpcRes.TxResponses[0].Timestamp) - s.Require().Empty(grpcRes.TxResponses[0].RawLog) // logs are empty if the transactions are successful - } - }) - } -} - -func (s *E2ETestSuite) TestGetTxEvents_GRPCGateway() { - val := s.network.GetValidators()[0] - testCases := []struct { - name string - url string - expErr bool - expErrMsg string - expLen int - }{ - { - "empty params", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", val.GetAPIAddress()), - true, - "query cannot be empty", 0, - }, - { - "without pagination", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s", val.GetAPIAddress(), bankMsgSendEventAction), - false, - "", 3, - }, - { - "with pagination", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&page=%d&limit=%d", val.GetAPIAddress(), bankMsgSendEventAction, 1, 2), - false, - "", 2, - }, - { - "valid request: order by asc", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=ORDER_BY_ASC", val.GetAPIAddress(), bankMsgSendEventAction, "message.module='bank'"), - false, - "", 3, - }, - { - "valid request: order by desc", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=ORDER_BY_DESC", val.GetAPIAddress(), bankMsgSendEventAction, "message.module='bank'"), - false, - "", 3, - }, - { - "invalid request: invalid order by", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s&order_by=invalid_order", val.GetAPIAddress(), bankMsgSendEventAction, "message.module='bank'"), - true, - "is not a valid tx.OrderBy", 0, - }, - { - "expect pass with multiple-events", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s&query=%s", val.GetAPIAddress(), bankMsgSendEventAction, "message.module='bank'"), - false, - "", 3, - }, - { - "expect pass with escape event", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?query=%s", val.GetAPIAddress(), "message.action%3D'/cosmos.bank.v1beta1.MsgSend'"), - false, - "", 3, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.GetTxsEventResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err, "failed to unmarshal JSON: %s", res) - s.Require().GreaterOrEqual(len(result.Txs), 1) - s.Require().Equal("foobar", result.Txs[0].Body.Memo) - s.Require().NotZero(result.TxResponses[0].Height) - s.Require().Equal(tc.expLen, len(result.Txs)) - } - }) - } -} - -func (s *E2ETestSuite) TestGetTx_GRPC() { - testCases := []struct { - name string - req *tx.GetTxRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &tx.GetTxRequest{}, true, "tx hash cannot be empty"}, - {"request with dummy hash", &tx.GetTxRequest{Hash: "deadbeef"}, true, "code = NotFound desc = tx not found: deadbeef"}, - {"good request", &tx.GetTxRequest{Hash: s.goodTxHash}, false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - // Query the tx via gRPC. - grpcRes, err := s.queryClient.GetTx(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - s.Require().Equal("foobar", grpcRes.Tx.Body.Memo) - } - }) - } -} - -func (s *E2ETestSuite) TestGetTx_GRPCGateway() { - val := s.network.GetValidators()[0] - testCases := []struct { - name string - url string - expErr bool - expErrMsg string - }{ - { - "empty params", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/", val.GetAPIAddress()), - true, "tx hash cannot be empty", - }, - { - "dummy hash", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", val.GetAPIAddress(), "deadbeef"), - true, "code = NotFound desc = tx not found: deadbeef", - }, - { - "good hash", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", val.GetAPIAddress(), s.goodTxHash), - false, "", - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.GetTxResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - s.Require().Equal("foobar", result.Tx.Body.Memo) - s.Require().NotZero(result.TxResponse.Height) - - // Make sure fields are populated. - // ref: https://github.com/cosmos/cosmos-sdk/issues/8680 - // ref: https://github.com/cosmos/cosmos-sdk/issues/8681 - s.Require().NotEmpty(result.TxResponse.Timestamp) - s.Require().Empty(result.TxResponse.RawLog) // logs are empty on successful transactions - } - }) - } -} - -func (s *E2ETestSuite) TestBroadcastTx_GRPC() { - val := s.network.GetValidators()[0] - txBuilder := s.mkTxBuilder() - txBytes, err := val.GetClientCtx().TxConfig.TxEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - - testCases := []struct { - name string - req *tx.BroadcastTxRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &tx.BroadcastTxRequest{}, true, "invalid empty tx"}, - {"no mode", &tx.BroadcastTxRequest{TxBytes: txBytes}, true, "supported types: sync, async"}, - {"valid request", &tx.BroadcastTxRequest{ - Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC, - TxBytes: txBytes, - }, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - // Broadcast the tx via gRPC via the validator's clientCtx (which goes - // through Tendermint). - grpcRes, err := s.queryClient.BroadcastTx(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - s.Require().Equal(uint32(0), grpcRes.TxResponse.Code) - } - }) - } -} - -func (s *E2ETestSuite) TestBroadcastTx_GRPCGateway() { - val := s.network.GetValidators()[0] - txBuilder := s.mkTxBuilder() - txBytes, err := val.GetClientCtx().TxConfig.TxEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - - testCases := []struct { - name string - req *tx.BroadcastTxRequest - expErr bool - expErrMsg string - }{ - {"empty request", &tx.BroadcastTxRequest{}, true, "invalid empty tx"}, - {"no mode", &tx.BroadcastTxRequest{TxBytes: txBytes}, true, "supported types: sync, async"}, - {"valid request", &tx.BroadcastTxRequest{ - Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC, - TxBytes: txBytes, - }, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - req, err := val.GetClientCtx().Codec.MarshalJSON(tc.req) - s.Require().NoError(err) - res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", val.GetAPIAddress()), "application/json", req) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.BroadcastTxResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - s.Require().Equal(uint32(0), result.TxResponse.Code, "rawlog", result.TxResponse.RawLog) - } - }) - } -} - -func (s *E2ETestSuite) TestSimMultiSigTx() { - val1 := s.network.GetValidators()[0] - clientCtx := val1.GetClientCtx() - - kr := clientCtx.Keyring - - account1, _, err := kr.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - - account2, _, err := kr.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - - pub1, err := account1.GetPubKey() - s.Require().NoError(err) - - pub2, err := account2.GetPubKey() - s.Require().NoError(err) - - multi := kmultisig.NewLegacyAminoPubKey(2, []cryptotypes.PubKey{pub1, pub2}) - _, err = kr.SaveMultisig("multi", multi) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - multisigRecord, err := clientCtx.Keyring.Key("multi") - s.Require().NoError(err) - - height, err := s.network.LatestHeight() - s.Require().NoError(err) - _, err = s.network.WaitForHeight(height + 1) - s.Require().NoError(err) - - addr, err := multisigRecord.GetAddress() - s.Require().NoError(err) - - // Send coins from validator to multisig. - coin := sdk.NewInt64Coin(s.cfg.BondDenom, 15) - msgSend := &banktypes.MsgSend{ - FromAddress: val1.GetAddress().String(), - ToAddress: addr.String(), - Amount: sdk.NewCoins(coin), - } - - _, err = cli.SubmitTestTx( - clientCtx, - msgSend, - val1.GetAddress(), - cli.TestTxConfig{}, - ) - - s.Require().NoError(err) - - height, err = s.network.LatestHeight() - s.Require().NoError(err) - _, err = s.network.WaitForHeight(height + 1) - s.Require().NoError(err) - - msgSend1 := &banktypes.MsgSend{ - FromAddress: addr.String(), - ToAddress: val1.GetAddress().String(), - Amount: sdk.NewCoins( - sdk.NewInt64Coin(s.cfg.BondDenom, 5), - ), - } - // Generate multisig transaction. - multiGeneratedTx, err := cli.SubmitTestTx( - clientCtx, - msgSend1, - val1.GetAddress(), - cli.TestTxConfig{ - GenOnly: true, - Memo: "foobar", - }, - ) - - s.Require().NoError(err) - - // Save tx to file - multiGeneratedTxFile := testutil.WriteToNewTempFile(s.T(), multiGeneratedTx.String()) - - // Sign with account1 - addr1, err := account1.GetAddress() - s.Require().NoError(err) - clientCtx.HomeDir = strings.Replace(clientCtx.HomeDir, "simd", "simcli", 1) - account1Signature, err := authtest.TxSignExec(clientCtx, addr1, multiGeneratedTxFile.Name(), "--multisig", addr.String()) - s.Require().NoError(err) - sign1File := testutil.WriteToNewTempFile(s.T(), account1Signature.String()) - - // Sign with account2 - addr2, err := account2.GetAddress() - s.Require().NoError(err) - account2Signature, err := authtest.TxSignExec(clientCtx, addr2, multiGeneratedTxFile.Name(), "--multisig", addr.String()) - s.Require().NoError(err) - sign2File := testutil.WriteToNewTempFile(s.T(), account2Signature.String()) - - // multisign tx - clientCtx.Offline = false - multiSigWith2Signatures, err := authtest.TxMultiSignExec(clientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), sign1File.Name(), sign2File.Name()) - s.Require().NoError(err) - - // convert from protoJSON to protoBinary for sim - sdkTx, err := clientCtx.TxConfig.TxJSONDecoder()(multiSigWith2Signatures.Bytes()) - s.Require().NoError(err) - txBytes, err := clientCtx.TxConfig.TxEncoder()(sdkTx) - s.Require().NoError(err) - - // simulate tx - sim := &tx.SimulateRequest{TxBytes: txBytes} - res, err := s.queryClient.Simulate(context.Background(), sim) - s.Require().NoError(err) - - // make sure gas was used - s.Require().Greater(res.GasInfo.GasUsed, uint64(0)) -} - -func (s *E2ETestSuite) TestGetBlockWithTxs_GRPC() { - testCases := []struct { - name string - req *tx.GetBlockWithTxsRequest - expErr bool - expErrMsg string - expTxsLen int - }{ - {"nil request", nil, true, "request cannot be nil", 0}, - {"empty request", &tx.GetBlockWithTxsRequest{}, true, "height must not be less than 1 or greater than the current height", 0}, - {"bad height", &tx.GetBlockWithTxsRequest{Height: 99999999}, true, "height must not be less than 1 or greater than the current height", 0}, - {"bad pagination", &tx.GetBlockWithTxsRequest{Height: s.txHeight, Pagination: &query.PageRequest{Offset: 1000, Limit: 100}}, true, "out of range", 0}, - {"good request", &tx.GetBlockWithTxsRequest{Height: s.txHeight}, false, "", 1}, - {"with pagination request", &tx.GetBlockWithTxsRequest{Height: s.txHeight, Pagination: &query.PageRequest{Offset: 0, Limit: 1}}, false, "", 1}, - {"page all request", &tx.GetBlockWithTxsRequest{Height: s.txHeight, Pagination: &query.PageRequest{Offset: 0, Limit: 100}}, false, "", 1}, - {"block with 0 tx", &tx.GetBlockWithTxsRequest{Height: s.txHeight - 1, Pagination: &query.PageRequest{Offset: 0, Limit: 100}}, false, "", 0}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - // Query the tx via gRPC. - grpcRes, err := s.queryClient.GetBlockWithTxs(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - if tc.expTxsLen > 0 { - s.Require().Equal("foobar", grpcRes.Txs[0].Body.Memo) - } - s.Require().Equal(grpcRes.Block.Header.Height, tc.req.Height) - if tc.req.Pagination != nil { - s.Require().LessOrEqual(len(grpcRes.Txs), int(tc.req.Pagination.Limit)) - } - } - }) - } -} - -func (s *E2ETestSuite) TestGetBlockWithTxs_GRPCGateway() { - val := s.network.GetValidators()[0] - testCases := []struct { - name string - url string - expErr bool - expErrMsg string - }{ - { - "empty params", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/block/0", val.GetAPIAddress()), - true, "height must not be less than 1 or greater than the current height", - }, - { - "bad height", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/block/%d", val.GetAPIAddress(), 9999999), - true, "height must not be less than 1 or greater than the current height", - }, - { - "good request", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/block/%d", val.GetAPIAddress(), s.txHeight), - false, "", - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.GetBlockWithTxsResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - s.Require().Equal("foobar", result.Txs[0].Body.Memo) - s.Require().Equal(result.Block.Header.Height, s.txHeight) - } - }) - } -} - -func (s *E2ETestSuite) TestTxEncode_GRPC() { - val := s.network.GetValidators()[0] - txBuilder := s.mkTxBuilder() - protoTx, err := txBuilder.GetTx().(interface{ AsTx() (*tx.Tx, error) }).AsTx() - s.Require().NoError(err) - - testCases := []struct { - name string - req *tx.TxEncodeRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &tx.TxEncodeRequest{}, true, "invalid empty tx"}, - {"valid tx request", &tx.TxEncodeRequest{Tx: protoTx}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := s.queryClient.TxEncode(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - s.Require().Empty(res) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(res.GetTxBytes()) - - tx, err := val.GetClientCtx().TxConfig.TxDecoder()(res.TxBytes) - s.Require().NoError(err) - s.Require().Equal(protoTx.GetMsgs(), tx.GetMsgs()) - } - }) - } -} - -func (s *E2ETestSuite) TestTxEncode_GRPCGateway() { - val := s.network.GetValidators()[0] - txBuilder := s.mkTxBuilder() - protoTx, err := txBuilder.GetTx().(interface{ AsTx() (*tx.Tx, error) }).AsTx() - s.Require().NoError(err) - - testCases := []struct { - name string - req *tx.TxEncodeRequest - expErr bool - expErrMsg string - }{ - {"empty request", &tx.TxEncodeRequest{}, true, "invalid empty tx"}, - {"valid tx request", &tx.TxEncodeRequest{Tx: protoTx}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - req, err := val.GetClientCtx().Codec.MarshalJSON(tc.req) - s.Require().NoError(err) - - res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/encode", val.GetAPIAddress()), "application/json", req) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.TxEncodeResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - - tx, err := val.GetClientCtx().TxConfig.TxDecoder()(result.TxBytes) - s.Require().NoError(err) - s.Require().Equal(protoTx.GetMsgs(), tx.GetMsgs()) - } - }) - } -} - -func (s *E2ETestSuite) TestTxDecode_GRPC() { - val := s.network.GetValidators()[0] - txBuilder := s.mkTxBuilder() - - goodTx := txBuilder.GetTx() - encodedTx, err := val.GetClientCtx().TxConfig.TxEncoder()(goodTx) - s.Require().NoError(err) - - invalidTxBytes := append(encodedTx, byte(0o00)) - - testCases := []struct { - name string - req *tx.TxDecodeRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"}, - {"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"}, - {"valid request with tx bytes", &tx.TxDecodeRequest{TxBytes: encodedTx}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := s.queryClient.TxDecode(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - s.Require().Empty(res) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(res.GetTx()) - - txb := wrapTx(s.T(), s.cfg.TxConfig, res.Tx) - gotTx := txb.GetTx() - gotEncoded, err := val.GetClientCtx().TxConfig.TxEncoder()(gotTx) - s.Require().NoError(err) - s.Require().Equal(encodedTx, gotEncoded) - } - }) - } -} - -func wrapTx(t *testing.T, conf client.TxConfig, dTx *tx.Tx) client.TxBuilder { - t.Helper() - bodyBytes, err := dTx.Body.Marshal() - require.NoError(t, err) - authInfoBytes, err := dTx.AuthInfo.Marshal() - require.NoError(t, err) - rawTxBytes, err := (&tx.TxRaw{ - BodyBytes: bodyBytes, - AuthInfoBytes: authInfoBytes, - Signatures: dTx.Signatures, - }).Marshal() - require.NoError(t, err) - dec, err := conf.TxDecoder()(rawTxBytes) - require.NoError(t, err) - bld, err := conf.WrapTxBuilder(dec) - require.NoError(t, err) - return bld -} - -func (s *E2ETestSuite) TestTxDecode_GRPCGateway() { - val := s.network.GetValidators()[0] - txBuilder := s.mkTxBuilder() - - encodedTxBytes, err := val.GetClientCtx().TxConfig.TxEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - - invalidTxBytes := append(encodedTxBytes, byte(0o00)) - - testCases := []struct { - name string - req *tx.TxDecodeRequest - expErr bool - expErrMsg string - }{ - {"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"}, - {"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"}, - {"valid request with tx_bytes", &tx.TxDecodeRequest{TxBytes: encodedTxBytes}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - req, err := val.GetClientCtx().Codec.MarshalJSON(tc.req) - s.Require().NoError(err) - - res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/decode", val.GetAPIAddress()), "application/json", req) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.TxDecodeResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - - txb := wrapTx(s.T(), s.cfg.TxConfig, result.Tx) - tx, err := val.GetClientCtx().TxConfig.TxEncoder()(txb.GetTx()) - s.Require().NoError(err) - s.T().Log(len(tx), len(encodedTxBytes)) - s.Require().Equal(encodedTxBytes, tx) - } - }) - } -} - func (s *E2ETestSuite) readTestAminoTxJSON() ([]byte, *legacytx.StdTx) { val := s.network.GetValidators()[0] txJSONBytes, err := os.ReadFile("testdata/tx_amino1.json") @@ -1106,40 +277,3 @@ func (s *E2ETestSuite) TestTxDecodeAmino_GRPCGateway() { func TestE2ETestSuite(t *testing.T) { suite.Run(t, new(E2ETestSuite)) } - -func (s *E2ETestSuite) mkTxBuilder() client.TxBuilder { - val := s.network.GetValidators()[0] - s.Require().NoError(s.network.WaitForNextBlock()) - - // prepare txBuilder with msg - txBuilder := val.GetClientCtx().TxConfig.NewTxBuilder() - feeAmount := sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)} - gasLimit := testdata.NewTestGasLimit() - s.Require().NoError( - txBuilder.SetMsgs(&banktypes.MsgSend{ - FromAddress: val.GetAddress().String(), - ToAddress: val.GetAddress().String(), - Amount: sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)}, - }), - ) - txBuilder.SetFeeAmount(feeAmount) - txBuilder.SetGasLimit(gasLimit) - txBuilder.SetMemo("foobar") - txBuilder.SetFeePayer(val.GetAddress()) - signers, err := txBuilder.GetTx().GetSigners() - s.Require().NoError(err) - s.Require().Equal([][]byte{val.GetAddress()}, signers) - - // setup txFactory - txFactory := clienttx.Factory{}. - WithChainID(val.GetClientCtx().ChainID). - WithKeybase(val.GetClientCtx().Keyring). - WithTxConfig(val.GetClientCtx().TxConfig). - WithSignMode(signing.SignMode_SIGN_MODE_DIRECT) - - // Sign Tx. - err = authclient.SignTx(txFactory, val.GetClientCtx(), val.GetMoniker(), txBuilder, false, true) - s.Require().NoError(err) - - return txBuilder -} From 9cba93400d88721739ad17567de40aeda328ac74 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Mon, 21 Oct 2024 20:04:29 +0700 Subject: [PATCH 07/16] amino test --- tests/systemtests/testdata/tx_amino1.bin | 6 + tests/systemtests/testdata/tx_amino1.json | 32 ++++ tests/systemtests/tx_test.go | 218 +++++++++++++++++++++- 3 files changed, 251 insertions(+), 5 deletions(-) create mode 100644 tests/systemtests/testdata/tx_amino1.bin create mode 100644 tests/systemtests/testdata/tx_amino1.json diff --git a/tests/systemtests/testdata/tx_amino1.bin b/tests/systemtests/testdata/tx_amino1.bin new file mode 100644 index 000000000000..cb2ef5b6dd64 --- /dev/null +++ b/tests/systemtests/testdata/tx_amino1.bin @@ -0,0 +1,6 @@ +((© +o¨£aš +-cosmos1hzw8v2kk4csg8xr3fhy8ykyymykknm2tdgvf7k-cosmos1hzw8v2kk4csg8xr3fhy8ykyymykknm2tdgvf7k +stake10 + +stake10Àš "foobar \ No newline at end of file diff --git a/tests/systemtests/testdata/tx_amino1.json b/tests/systemtests/testdata/tx_amino1.json new file mode 100644 index 000000000000..d4fb8cc8d378 --- /dev/null +++ b/tests/systemtests/testdata/tx_amino1.json @@ -0,0 +1,32 @@ +{ + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgSend", + "value": { + "from_address": "cosmos1hzw8v2kk4csg8xr3fhy8ykyymykknm2tdgvf7k", + "to_address": "cosmos1hzw8v2kk4csg8xr3fhy8ykyymykknm2tdgvf7k", + "amount": [ + { + "denom": "stake", + "amount": "10" + } + ] + } + } + ], + "fee": { + "amount": [ + { + "denom": "stake", + "amount": "10" + } + ], + "gas": "200000" + }, + "signatures": [], + "memo": "foobar", + "timeout_height": "0" + } +} \ No newline at end of file diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index 630f444dd2fd..28aec404fde6 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -1,4 +1,4 @@ -//go:build system_test +//go:build !system_test package systemtests @@ -6,6 +6,7 @@ import ( "context" "encoding/base64" "encoding/json" + "os" "fmt" @@ -16,9 +17,14 @@ import ( "github.com/stretchr/testify/require" "github.com/tidwall/gjson" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/legacy" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/std" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) var bankMsgSendEventAction = "message.action='/cosmos.bank.v1beta1.MsgSend'" @@ -171,6 +177,8 @@ func TestSimulateTx_GRPCGateway(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { reqBz, err := json.Marshal(tc.req) + require.NoError(t, err) + res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/simulate", baseURL), "application/json", reqBz) require.NoError(t, err) if tc.expErr { @@ -306,7 +314,6 @@ func TestGetTxEvents_GRPC(t *testing.T) { } }) } - } func TestGetTxEvents_GRPCGateway(t *testing.T) { @@ -405,7 +412,6 @@ func TestGetTxEvents_GRPCGateway(t *testing.T) { } }) } - } func TestGetTx_GRPC(t *testing.T) { @@ -722,6 +728,7 @@ func TestTxEncode_GRPCGateway(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { reqBz, err := json.Marshal(tc.req) + require.NoError(t, err) res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/encode", baseUrl), "application/json", reqBz) require.NoError(t, err) @@ -847,6 +854,190 @@ func TestTxDecode_GRPCGateway(t *testing.T) { } } +func TestTxEncodeAmino_GRPC(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + legacyAmino := codec.NewLegacyAmino() + std.RegisterLegacyAminoCodec(legacyAmino) + legacytx.RegisterLegacyAminoCodec(legacyAmino) + legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend") + + qc := tx.NewServiceClient(sut.RPCClient(t)) + txJSONBytes, stdTx := readTestAminoTxJSON(t, legacyAmino) + + testCases := []struct { + name string + req *tx.TxEncodeAminoRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "request cannot be nil"}, + {"empty request", &tx.TxEncodeAminoRequest{}, true, "invalid empty tx json"}, + {"invalid request", &tx.TxEncodeAminoRequest{AminoJson: "invalid tx json"}, true, "invalid request"}, + {"valid request with amino-json", &tx.TxEncodeAminoRequest{AminoJson: string(txJSONBytes)}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.TxEncodeAmino(context.Background(), tc.req) + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + require.Empty(t, res) + } else { + require.NoError(t, err) + require.NotEmpty(t, res.GetAminoBinary()) + + var decodedTx legacytx.StdTx + err = legacyAmino.Unmarshal(res.AminoBinary, &decodedTx) + require.NoError(t, err) + require.Equal(t, decodedTx.GetMsgs(), stdTx.GetMsgs()) + } + }) + } +} + +func TestTxEncodeAmino_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + legacyAmino := codec.NewLegacyAmino() + std.RegisterLegacyAminoCodec(legacyAmino) + legacytx.RegisterLegacyAminoCodec(legacyAmino) + legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend") + + baseUrl := sut.APIAddress() + txJSONBytes, stdTx := readTestAminoTxJSON(t, legacyAmino) + + testCases := []struct { + name string + req *tx.TxEncodeAminoRequest + expErr bool + expErrMsg string + }{ + {"empty request", &tx.TxEncodeAminoRequest{}, true, "invalid empty tx json"}, + {"invalid request", &tx.TxEncodeAminoRequest{AminoJson: "invalid tx json"}, true, "cannot parse disfix JSON wrapper"}, + {"valid request with amino-json", &tx.TxEncodeAminoRequest{AminoJson: string(txJSONBytes)}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + reqBz, err := json.Marshal(tc.req) + require.NoError(t, err) + + res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/encode/amino", baseUrl), "application/json", reqBz) + require.NoError(t, err) + if tc.expErr { + require.Contains(t, string(res), tc.expErrMsg) + } else { + var result tx.TxEncodeAminoResponse + err := json.Unmarshal(res, &result) + require.NoError(t, err) + + var decodedTx legacytx.StdTx + err = legacyAmino.Unmarshal(result.AminoBinary, &decodedTx) + require.NoError(t, err) + require.Equal(t, decodedTx.GetMsgs(), stdTx.GetMsgs()) + } + }) + } +} + +func TestTxDecodeAmino_GRPC(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + legacyAmino := codec.NewLegacyAmino() + std.RegisterLegacyAminoCodec(legacyAmino) + legacytx.RegisterLegacyAminoCodec(legacyAmino) + legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend") + + qc := tx.NewServiceClient(sut.RPCClient(t)) + encodedTx, stdTx := readTestAminoTxBinary(t, legacyAmino) + + invalidTxBytes := append(encodedTx, byte(0o00)) + + testCases := []struct { + name string + req *tx.TxDecodeAminoRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "request cannot be nil"}, + {"empty request", &tx.TxDecodeAminoRequest{}, true, "invalid empty tx bytes"}, + {"invalid tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: invalidTxBytes}, true, "invalid request"}, + {"valid request with tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: encodedTx}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.TxDecodeAmino(context.Background(), tc.req) + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expErrMsg) + require.Empty(t, res) + } else { + require.NoError(t, err) + require.NotEmpty(t, res.GetAminoJson()) + + var decodedTx legacytx.StdTx + err = legacyAmino.UnmarshalJSON([]byte(res.GetAminoJson()), &decodedTx) + require.NoError(t, err) + require.Equal(t, stdTx.GetMsgs(), decodedTx.GetMsgs()) + } + }) + } +} + +func TestTxDecodeAmino_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + legacyAmino := codec.NewLegacyAmino() + std.RegisterLegacyAminoCodec(legacyAmino) + legacytx.RegisterLegacyAminoCodec(legacyAmino) + legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend") + + baseUrl := sut.APIAddress() + encodedTx, stdTx := readTestAminoTxBinary(t, legacyAmino) + + invalidTxBytes := append(encodedTx, byte(0o00)) + + testCases := []struct { + name string + req *tx.TxDecodeAminoRequest + expErr bool + expErrMsg string + }{ + {"empty request", &tx.TxDecodeAminoRequest{}, true, "invalid empty tx bytes"}, + {"invalid tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: invalidTxBytes}, true, "unmarshal to legacytx.StdTx failed"}, + {"valid request with tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: encodedTx}, false, ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + reqBz, err := json.Marshal(tc.req) + require.NoError(t, err) + + res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/decode/amino", baseUrl), "application/json", reqBz) + require.NoError(t, err) + if tc.expErr { + require.Contains(t, string(res), tc.expErrMsg) + } else { + var result tx.TxDecodeAminoResponse + err := json.Unmarshal(res, &result) + require.NoError(t, err) + + var decodedTx legacytx.StdTx + err = legacyAmino.UnmarshalJSON([]byte(result.AminoJson), &decodedTx) + require.NoError(t, err) + require.Equal(t, stdTx.GetMsgs(), decodedTx.GetMsgs()) + } + }) + } +} + func TestSimMultiSigTx(t *testing.T) { sut.ResetChain(t) @@ -864,7 +1055,7 @@ func TestSimMultiSigTx(t *testing.T) { sut.StartChain(t) multiSigName := "multisig" - res := cli.RunCommandWithArgs("keys", "add", multiSigName, "--multisig=account1,account2", "--multisig-threshold=2", "--keyring-backend=test", "--home=./testnet") + cli.RunCommandWithArgs("keys", "add", multiSigName, "--multisig=account1,account2", "--multisig-threshold=2", "--keyring-backend=test", "--home=./testnet") multiSigAddr := cli.GetKeyAddr(multiSigName) // Send from validator to multisig addr @@ -880,7 +1071,7 @@ func TestSimMultiSigTx(t *testing.T) { // create unsign tx var newTransferAmount int64 = 100 bankSendCmdArgs := []string{"tx", "bank", "send", multiSigAddr, valAddr, fmt.Sprintf("%d%s", newTransferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} - res = cli.RunCommandWithArgs(bankSendCmdArgs...) + res := cli.RunCommandWithArgs(bankSendCmdArgs...) txFile := StoreTempFile(t, []byte(res)) res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account1"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet") @@ -896,5 +1087,22 @@ func TestSimMultiSigTx(t *testing.T) { multiSigBalance = cli.QueryBalance(multiSigAddr, denom) require.Equal(t, multiSigBalance, transferAmount-newTransferAmount-10) +} + +func readTestAminoTxJSON(t *testing.T, aminoCodec *codec.LegacyAmino) ([]byte, *legacytx.StdTx) { + txJSONBytes, err := os.ReadFile("testdata/tx_amino1.json") + require.NoError(t, err) + var stdTx legacytx.StdTx + err = aminoCodec.UnmarshalJSON(txJSONBytes, &stdTx) + require.NoError(t, err) + return txJSONBytes, &stdTx +} +func readTestAminoTxBinary(t *testing.T, aminoCodec *codec.LegacyAmino) ([]byte, *legacytx.StdTx) { + txJSONBytes, err := os.ReadFile("testdata/tx_amino1.bin") + require.NoError(t, err) + var stdTx legacytx.StdTx + err = aminoCodec.Unmarshal(txJSONBytes, &stdTx) + require.NoError(t, err) + return txJSONBytes, &stdTx } From ddb88a93de33533340baa0f890dd799d0c3d0cc8 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Mon, 21 Oct 2024 20:05:08 +0700 Subject: [PATCH 08/16] remove migrated test --- tests/e2e/tx/service_test.go | 279 --------------------------- tests/e2e/tx/testdata/tx_amino1.bin | 6 - tests/e2e/tx/testdata/tx_amino1.json | 1 - 3 files changed, 286 deletions(-) delete mode 100644 tests/e2e/tx/service_test.go delete mode 100644 tests/e2e/tx/testdata/tx_amino1.bin delete mode 100644 tests/e2e/tx/testdata/tx_amino1.json diff --git a/tests/e2e/tx/service_test.go b/tests/e2e/tx/service_test.go deleted file mode 100644 index a18568c99e28..000000000000 --- a/tests/e2e/tx/service_test.go +++ /dev/null @@ -1,279 +0,0 @@ -package tx_test - -import ( - "context" - "fmt" - "os" - "testing" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/math" - "cosmossdk.io/simapp" - banktypes "cosmossdk.io/x/bank/types" - - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" -) - -type E2ETestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI - - txHeight int64 - queryClient tx.ServiceClient - goodTxHash string -} - -func (s *E2ETestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - s.cfg = cfg - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - - val := s.network.GetValidators()[0] - s.Require().NoError(s.network.WaitForNextBlock()) - - s.queryClient = tx.NewServiceClient(val.GetClientCtx()) - - msgSend := &banktypes.MsgSend{ - FromAddress: val.GetAddress().String(), - ToAddress: val.GetAddress().String(), - Amount: sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))), - } - - // Create a new MsgSend tx from val to itself. - out, err := cli.SubmitTestTx( - val.GetClientCtx(), - msgSend, - val.GetAddress(), - cli.TestTxConfig{ - Memo: "foobar", - }, - ) - - s.Require().NoError(err) - - var txRes sdk.TxResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &txRes)) - s.Require().Equal(uint32(0), txRes.Code, txRes) - s.goodTxHash = txRes.TxHash - - msgSend1 := &banktypes.MsgSend{ - FromAddress: val.GetAddress().String(), - ToAddress: val.GetAddress().String(), - Amount: sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(1))), - } - - out1, err := cli.SubmitTestTx( - val.GetClientCtx(), - msgSend1, - val.GetAddress(), - cli.TestTxConfig{ - Offline: true, - AccNum: 0, - Seq: 2, - Memo: "foobar", - }, - ) - - s.Require().NoError(err) - var tr sdk.TxResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out1.Bytes(), &tr)) - s.Require().Equal(uint32(0), tr.Code) - - resp, err := cli.GetTxResponse(s.network, val.GetClientCtx(), tr.TxHash) - s.Require().NoError(err) - s.txHeight = resp.Height -} - -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") - s.network.Cleanup() -} - -func (s *E2ETestSuite) readTestAminoTxJSON() ([]byte, *legacytx.StdTx) { - val := s.network.GetValidators()[0] - txJSONBytes, err := os.ReadFile("testdata/tx_amino1.json") - s.Require().NoError(err) - var stdTx legacytx.StdTx - err = val.GetClientCtx().LegacyAmino.UnmarshalJSON(txJSONBytes, &stdTx) - s.Require().NoError(err) - return txJSONBytes, &stdTx -} - -func (s *E2ETestSuite) TestTxEncodeAmino_GRPC() { - val := s.network.GetValidators()[0] - txJSONBytes, stdTx := s.readTestAminoTxJSON() - - testCases := []struct { - name string - req *tx.TxEncodeAminoRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &tx.TxEncodeAminoRequest{}, true, "invalid empty tx json"}, - {"invalid request", &tx.TxEncodeAminoRequest{AminoJson: "invalid tx json"}, true, "invalid request"}, - {"valid request with amino-json", &tx.TxEncodeAminoRequest{AminoJson: string(txJSONBytes)}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := s.queryClient.TxEncodeAmino(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - s.Require().Empty(res) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(res.GetAminoBinary()) - - var decodedTx legacytx.StdTx - err = val.GetClientCtx().LegacyAmino.Unmarshal(res.AminoBinary, &decodedTx) - s.Require().NoError(err) - s.Require().Equal(decodedTx.GetMsgs(), stdTx.GetMsgs()) - } - }) - } -} - -func (s *E2ETestSuite) TestTxEncodeAmino_GRPCGateway() { - val := s.network.GetValidators()[0] - txJSONBytes, stdTx := s.readTestAminoTxJSON() - - testCases := []struct { - name string - req *tx.TxEncodeAminoRequest - expErr bool - expErrMsg string - }{ - {"empty request", &tx.TxEncodeAminoRequest{}, true, "invalid empty tx json"}, - {"invalid request", &tx.TxEncodeAminoRequest{AminoJson: "invalid tx json"}, true, "invalid request"}, - {"valid request with amino-json", &tx.TxEncodeAminoRequest{AminoJson: string(txJSONBytes)}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - req, err := val.GetClientCtx().Codec.MarshalJSON(tc.req) - s.Require().NoError(err) - - res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/encode/amino", val.GetAPIAddress()), "application/json", req) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.TxEncodeAminoResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - - var decodedTx legacytx.StdTx - err = val.GetClientCtx().LegacyAmino.Unmarshal(result.AminoBinary, &decodedTx) - s.Require().NoError(err) - s.Require().Equal(decodedTx.GetMsgs(), stdTx.GetMsgs()) - } - }) - } -} - -func (s *E2ETestSuite) readTestAminoTxBinary() ([]byte, *legacytx.StdTx) { - val := s.network.GetValidators()[0] - txJSONBytes, err := os.ReadFile("testdata/tx_amino1.bin") - s.Require().NoError(err) - var stdTx legacytx.StdTx - err = val.GetClientCtx().LegacyAmino.Unmarshal(txJSONBytes, &stdTx) - s.Require().NoError(err) - return txJSONBytes, &stdTx -} - -func (s *E2ETestSuite) TestTxDecodeAmino_GRPC() { - encodedTx, stdTx := s.readTestAminoTxBinary() - - invalidTxBytes := append(encodedTx, byte(0o00)) - - testCases := []struct { - name string - req *tx.TxDecodeAminoRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &tx.TxDecodeAminoRequest{}, true, "invalid empty tx bytes"}, - {"invalid tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: invalidTxBytes}, true, "invalid request"}, - {"valid request with tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: encodedTx}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := s.queryClient.TxDecodeAmino(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - s.Require().Empty(res) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(res.GetAminoJson()) - - var decodedTx legacytx.StdTx - err = s.network.GetValidators()[0].GetClientCtx().LegacyAmino.UnmarshalJSON([]byte(res.GetAminoJson()), &decodedTx) - s.Require().NoError(err) - s.Require().Equal(stdTx.GetMsgs(), decodedTx.GetMsgs()) - } - }) - } -} - -func (s *E2ETestSuite) TestTxDecodeAmino_GRPCGateway() { - val := s.network.GetValidators()[0] - encodedTx, stdTx := s.readTestAminoTxBinary() - - invalidTxBytes := append(encodedTx, byte(0o00)) - - testCases := []struct { - name string - req *tx.TxDecodeAminoRequest - expErr bool - expErrMsg string - }{ - {"empty request", &tx.TxDecodeAminoRequest{}, true, "invalid empty tx bytes"}, - {"invalid tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: invalidTxBytes}, true, "invalid request"}, - {"valid request with tx bytes", &tx.TxDecodeAminoRequest{AminoBinary: encodedTx}, false, ""}, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - req, err := val.GetClientCtx().Codec.MarshalJSON(tc.req) - s.Require().NoError(err) - - res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/decode/amino", val.GetAPIAddress()), "application/json", req) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result tx.TxDecodeAminoResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - - var decodedTx legacytx.StdTx - err = val.GetClientCtx().LegacyAmino.UnmarshalJSON([]byte(result.AminoJson), &decodedTx) - s.Require().NoError(err) - s.Require().Equal(stdTx.GetMsgs(), decodedTx.GetMsgs()) - } - }) - } -} - -func TestE2ETestSuite(t *testing.T) { - suite.Run(t, new(E2ETestSuite)) -} diff --git a/tests/e2e/tx/testdata/tx_amino1.bin b/tests/e2e/tx/testdata/tx_amino1.bin deleted file mode 100644 index cb2ef5b6dd64..000000000000 --- a/tests/e2e/tx/testdata/tx_amino1.bin +++ /dev/null @@ -1,6 +0,0 @@ -((© -o¨£aš --cosmos1hzw8v2kk4csg8xr3fhy8ykyymykknm2tdgvf7k-cosmos1hzw8v2kk4csg8xr3fhy8ykyymykknm2tdgvf7k -stake10 - -stake10Àš "foobar \ No newline at end of file diff --git a/tests/e2e/tx/testdata/tx_amino1.json b/tests/e2e/tx/testdata/tx_amino1.json deleted file mode 100644 index 1d19393e1a54..000000000000 --- a/tests/e2e/tx/testdata/tx_amino1.json +++ /dev/null @@ -1 +0,0 @@ -{"type":"cosmos-sdk/StdTx","value":{"msg":[{"type":"cosmos-sdk/MsgSend","value":{"from_address":"cosmos1hzw8v2kk4csg8xr3fhy8ykyymykknm2tdgvf7k","to_address":"cosmos1hzw8v2kk4csg8xr3fhy8ykyymykknm2tdgvf7k","amount":[{"denom":"stake","amount":"10"}]}}],"fee":{"amount":[{"denom":"stake","amount":"10"}],"gas":"200000"},"signatures":[],"memo":"foobar","timeout_height":"0"}} \ No newline at end of file From bdfe0d7ffbcecb2b9da73d4853a239d282678de3 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Mon, 21 Oct 2024 21:24:36 +0700 Subject: [PATCH 09/16] dup --- tests/systemtests/genesis_io.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/systemtests/genesis_io.go b/tests/systemtests/genesis_io.go index e03c2ec2798c..f3a61e54a2dd 100644 --- a/tests/systemtests/genesis_io.go +++ b/tests/systemtests/genesis_io.go @@ -1,10 +1,7 @@ package systemtests import ( - "bytes" "fmt" - "io" - "os" "testing" "time" @@ -56,15 +53,3 @@ func GetGenesisBalance(rawGenesis []byte, addr string) sdk.Coins { } return r } - -// StoreTempFile creates a temporary file in the test's temporary directory with the provided content. -// It returns a pointer to the created file. Errors during the process are handled with test assertions. -func StoreTempFile(t *testing.T, content []byte) *os.File { - t.Helper() - out, err := os.CreateTemp(t.TempDir(), "") - require.NoError(t, err) - _, err = io.Copy(out, bytes.NewReader(content)) - require.NoError(t, err) - require.NoError(t, out.Close()) - return out -} From c1a0f753c101968ae92bd12a2b538171731d2615 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Mon, 21 Oct 2024 21:35:50 +0700 Subject: [PATCH 10/16] refactor --- tests/systemtests/tx_test.go | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index 28aec404fde6..a20965686e7d 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -1,4 +1,4 @@ -//go:build !system_test +//go:build system_test package systemtests @@ -27,7 +27,11 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) -var bankMsgSendEventAction = "message.action='/cosmos.bank.v1beta1.MsgSend'" +var ( + bankMsgSendEventAction = "message.action='/cosmos.bank.v1beta1.MsgSend'" + denom = "stake" + transferAmount int64 = 1000 +) func TestQueryBySig(t *testing.T) { sut.ResetChain(t) @@ -39,8 +43,6 @@ func TestQueryBySig(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -80,8 +82,6 @@ func TestSimulateTx_GRPC(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -144,8 +144,6 @@ func TestSimulateTx_GRPCGateway(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -208,8 +206,6 @@ func TestGetTxEvents_GRPC(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -326,8 +322,6 @@ func TestGetTxEvents_GRPCGateway(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -424,8 +418,6 @@ func TestGetTx_GRPC(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -473,8 +465,6 @@ func TestGetTx_GRPCGateway(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -538,8 +528,6 @@ func TestGetBlockWithTxs_GRPC(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -598,8 +586,6 @@ func TestGetBlockWithTxs_GRPCGateway(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -749,8 +735,6 @@ func TestTxDecode_GRPC(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -806,8 +790,6 @@ func TestTxDecode_GRPCGateway(t *testing.T) { // add new key receiverAddr := cli.AddKey("account1") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) @@ -1049,8 +1031,6 @@ func TestSimMultiSigTx(t *testing.T) { // add new key _ = cli.AddKey("account1") _ = cli.AddKey("account2") - denom := "stake" - var transferAmount int64 = 1000 sut.StartChain(t) From f6cbfd4c050bb4f54b0a73ab41f6f5f2364a0eaf Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:40:16 +0700 Subject: [PATCH 11/16] check --- tests/systemtests/tx_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index a20965686e7d..66ffe7667ef8 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -58,6 +58,7 @@ func TestQueryBySig(t *testing.T) { signedTxFile := StoreTempFile(t, []byte(res)) res = cli.Run("tx", "broadcast", signedTxFile.Name()) + fmt.Println("resss", res) RequireTxSuccess(t, res) sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig) @@ -67,6 +68,7 @@ func TestQueryBySig(t *testing.T) { Page: 0, Limit: 10, }) + fmt.Println("resppp", resp) require.NoError(t, err) require.Len(t, resp.Txs, 1) require.Len(t, resp.Txs[0].Signatures, 1) From 754a38ee37771d1ea5f1db2d9c0d39ff7b232614 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:44:50 +0700 Subject: [PATCH 12/16] let see --- tests/systemtests/tx_test.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index 66ffe7667ef8..4c92f59f2ad7 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -50,14 +50,16 @@ func TestQueryBySig(t *testing.T) { // create unsign tx bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} - res := cli.RunCommandWithArgs(bankSendCmdArgs...) - txFile := StoreTempFile(t, []byte(res)) + unsignedTx := cli.RunCommandWithArgs(bankSendCmdArgs...) + fmt.Println("unsignedTx", unsignedTx) + txFile := StoreTempFile(t, []byte(unsignedTx)) - res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") - sig := gjson.Get(res, "signatures.0").String() - signedTxFile := StoreTempFile(t, []byte(res)) + signedTx := cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") + fmt.Println("signedTx", signedTx) + sig := gjson.Get(signedTx, "signatures.0").String() + signedTxFile := StoreTempFile(t, []byte(signedTx)) - res = cli.Run("tx", "broadcast", signedTxFile.Name()) + res := cli.Run("tx", "broadcast", signedTxFile.Name()) fmt.Println("resss", res) RequireTxSuccess(t, res) From ef39cdc4f07c1f400d1cff7464ca9375d4ff535a Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:06:55 +0700 Subject: [PATCH 13/16] add chain-id --- tests/systemtests/tx_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index 4c92f59f2ad7..fc1036a32153 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -49,7 +49,7 @@ func TestQueryBySig(t *testing.T) { qc := tx.NewServiceClient(sut.RPCClient(t)) // create unsign tx - bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", fmt.Sprintf("--chain-id=%s", sut.chainID), "--sign-mode=direct", "--generate-only"} unsignedTx := cli.RunCommandWithArgs(bankSendCmdArgs...) fmt.Println("unsignedTx", unsignedTx) txFile := StoreTempFile(t, []byte(unsignedTx)) From f447dbad2e1e27891b4bd607038daafbd432f9d5 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:23:16 +0700 Subject: [PATCH 14/16] add more --- tests/systemtests/tx_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index fc1036a32153..971fdcbb9b45 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -92,7 +92,7 @@ func TestSimulateTx_GRPC(t *testing.T) { qc := tx.NewServiceClient(sut.RPCClient(t)) // create unsign tx - bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"} res := cli.RunCommandWithArgs(bankSendCmdArgs...) txFile := StoreTempFile(t, []byte(res)) @@ -155,7 +155,7 @@ func TestSimulateTx_GRPCGateway(t *testing.T) { baseURL := sut.APIAddress() // create unsign tx - bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"} res := cli.RunCommandWithArgs(bankSendCmdArgs...) txFile := StoreTempFile(t, []byte(res)) @@ -745,7 +745,7 @@ func TestTxDecode_GRPC(t *testing.T) { qc := tx.NewServiceClient(sut.RPCClient(t)) // create unsign tx - bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"} res := cli.RunCommandWithArgs(bankSendCmdArgs...) txFile := StoreTempFile(t, []byte(res)) @@ -800,7 +800,7 @@ func TestTxDecode_GRPCGateway(t *testing.T) { basrUrl := sut.APIAddress() // create unsign tx - bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"} res := cli.RunCommandWithArgs(bankSendCmdArgs...) txFile := StoreTempFile(t, []byte(res)) @@ -1054,7 +1054,7 @@ func TestSimMultiSigTx(t *testing.T) { // Send from multisig to validator // create unsign tx var newTransferAmount int64 = 100 - bankSendCmdArgs := []string{"tx", "bank", "send", multiSigAddr, valAddr, fmt.Sprintf("%d%s", newTransferAmount, denom), "--fees=10stake", "--sign-mode=direct", "--generate-only"} + bankSendCmdArgs := []string{"tx", "bank", "send", multiSigAddr, valAddr, fmt.Sprintf("%d%s", newTransferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"} res := cli.RunCommandWithArgs(bankSendCmdArgs...) txFile := StoreTempFile(t, []byte(res)) From 7973a69e5e3e72767b3f97596af8ca91edd2a9f5 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:39:23 +0700 Subject: [PATCH 15/16] clean up --- tests/systemtests/tx_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index 971fdcbb9b45..bbc1989d6ba6 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -51,16 +51,13 @@ func TestQueryBySig(t *testing.T) { // create unsign tx bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", fmt.Sprintf("--chain-id=%s", sut.chainID), "--sign-mode=direct", "--generate-only"} unsignedTx := cli.RunCommandWithArgs(bankSendCmdArgs...) - fmt.Println("unsignedTx", unsignedTx) txFile := StoreTempFile(t, []byte(unsignedTx)) signedTx := cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd") - fmt.Println("signedTx", signedTx) sig := gjson.Get(signedTx, "signatures.0").String() signedTxFile := StoreTempFile(t, []byte(signedTx)) res := cli.Run("tx", "broadcast", signedTxFile.Name()) - fmt.Println("resss", res) RequireTxSuccess(t, res) sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig) @@ -70,7 +67,6 @@ func TestQueryBySig(t *testing.T) { Page: 0, Limit: 10, }) - fmt.Println("resppp", resp) require.NoError(t, err) require.Len(t, resp.Txs, 1) require.Len(t, resp.Txs[0].Signatures, 1) From 75e408a98252d81a24c5208deb920c58aef44cfa Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:25:25 +0700 Subject: [PATCH 16/16] remove issue --- tests/systemtests/tx_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/systemtests/tx_test.go b/tests/systemtests/tx_test.go index bbc1989d6ba6..344aff775ebc 100644 --- a/tests/systemtests/tx_test.go +++ b/tests/systemtests/tx_test.go @@ -303,8 +303,6 @@ func TestGetTxEvents_GRPC(t *testing.T) { require.Equal(t, tc.expLen, len(grpcRes.Txs)) // Make sure fields are populated. - // ref: https://github.com/cosmos/cosmos-sdk/issues/8680 - // ref: https://github.com/cosmos/cosmos-sdk/issues/8681 require.NotEmpty(t, grpcRes.TxResponses[0].Timestamp) require.Empty(t, grpcRes.TxResponses[0].RawLog) // logs are empty if the transactions are successful }