From e904b04afa68392a2a18b83817b8cf4cad547dc8 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Mon, 10 Jul 2023 11:09:43 +0200 Subject: [PATCH 01/15] start implement rest e2e test Signed-off-by: Lorenz Herzberger --- tests/e2e/machine/rest.go | 99 +++++++++++++++++++++++++++++++++++++++ testutil/rest.go | 46 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 tests/e2e/machine/rest.go create mode 100644 testutil/rest.go diff --git a/tests/e2e/machine/rest.go b/tests/e2e/machine/rest.go new file mode 100644 index 0000000..27215ec --- /dev/null +++ b/tests/e2e/machine/rest.go @@ -0,0 +1,99 @@ +package machine + +import ( + "fmt" + "planetmint-go/testutil" + machinetypes "planetmint-go/x/machine/types" + + "github.com/cosmos/cosmos-sdk/codec/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func (s *E2ETestSuite) TestAttestMachineREST() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + // Query Sequence Number + k, err := val.ClientCtx.Keyring.Key("machine") + s.Require().NoError(err) + + addr, err := k.GetAddress() + s.Require().NoError(err) + + reqAccountInfo := fmt.Sprintf("%s/cosmos/auth/v1beta1/account_info/%s", baseURL, addr.String()) + respAccountInfo, err := testutil.GetRequest(reqAccountInfo) + s.Require().NoError(err) + + s.T().Log(string(respAccountInfo)) + + var resAccountInfo authtypes.QueryAccountInfoResponse + err = val.ClientCtx.Codec.UnmarshalJSON(respAccountInfo, &resAccountInfo) + s.Require().NoError(err) + + s.T().Log(resAccountInfo.Info.AccountNumber) + // Create Attest Machine TX + machine := machinetypes.Machine{ + Name: "machine", + Ticker: "machine_ticker", + Issued: 1, + Amount: 1000, + Precision: 8, + IssuerPlanetmint: pubKey, + IssuerLiquid: pubKey, + MachineId: pubKey, + Metadata: &machinetypes.Metadata{ + AdditionalDataCID: "CID", + Gps: "{\"Latitude\":\"-48.876667\",\"Longitude\":\"-123.393333\"}", + }, + } + // machineJSON, err := json.Marshal(&machine) + // s.Require().NoError(err) + + msg := machinetypes.MsgAttestMachine{ + Creator: string(addr), + Machine: &machine, + } + + msg.Type() + + // Encode TX + reqEncodeTx := fmt.Sprintf("%s/cosmos/tx/encode", baseURL) + + signerInfos := make([]txtypes.SignerInfo, 1) + signerInfos[1].PublicKey = &types.Any{ + TypeUrl: "/cosmos.crypto.secp256k1.PubKey", + Value: k.PubKey.Value, + } + signerInfos[1].ModeInfo = &txtypes.ModeInfo{ + Sum: &txtypes.ModeInfo_Single_{ + Single: &txtypes.ModeInfo_Single{ + Mode: signing.SignMode_SIGN_MODE_DIRECT, + }, + }, + } + signerInfos[1].Sequence = resAccountInfo.Info.Sequence + + reqEncodeTxBody := txtypes.TxEncodeRequest{ + Tx: &txtypes.Tx{ + Body: &txtypes.TxBody{ + // Messages: make([]*types.Any, 0), + }, + AuthInfo: &txtypes.AuthInfo{ + SignerInfos: signerInfos, + Tip: nil, + }, + Signatures: [][]byte{}, + }, + } + s.Require().NoError(err) + // var resEncodeTX TXEncodeRequest + respEncodeTx, err := testutil.PostRequest(reqEncodeTx, "application/json", []byte(reqEncodeTxBody)) + s.Require().NoError(err) + + s.T().Log(respEncodeTx) + // Send encoded TX to /cosmos/tx/v1beta1/txs + + // Query Machine by Pubkey +} diff --git a/testutil/rest.go b/testutil/rest.go new file mode 100644 index 0000000..180a7be --- /dev/null +++ b/testutil/rest.go @@ -0,0 +1,46 @@ +package testutil + +import ( + "bytes" + "fmt" + "io" + "net/http" +) + +// GetRequest defines a wrapper around an HTTP GET request with a provided URL. +// An error is returned if the request or reading the body fails. +func GetRequest(url string) ([]byte, error) { + res, err := http.Get(url) //nolint:gosec // only used for testing + if err != nil { + return nil, err + } + defer func() { + _ = res.Body.Close() + }() + + body, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + + return body, nil +} + +// PostRequest defines a wrapper around an HTTP POST request with a provided URL and data. +// An error is returned if the request or reading the body fails. +func PostRequest(url, contentType string, data []byte) ([]byte, error) { + res, err := http.Post(url, contentType, bytes.NewBuffer(data)) //nolint:gosec // only used for testing + if err != nil { + return nil, fmt.Errorf("error while sending post request: %w", err) + } + defer func() { + _ = res.Body.Close() + }() + + bz, err := io.ReadAll(res.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + + return bz, nil +} From ee4f2bfda00b36fbe56165cd8bf9dfbc81bc1dcf Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 12 Jul 2023 10:57:18 +0200 Subject: [PATCH 02/15] issue tx over e2e rest test Signed-off-by: Lorenz Herzberger --- tests/e2e/machine/rest.go | 101 +++++++++++++++++++++++++++++++------ tests/e2e/machine/suite.go | 3 +- 2 files changed, 88 insertions(+), 16 deletions(-) diff --git a/tests/e2e/machine/rest.go b/tests/e2e/machine/rest.go index 27215ec..9c4a557 100644 --- a/tests/e2e/machine/rest.go +++ b/tests/e2e/machine/rest.go @@ -5,9 +5,16 @@ import ( "planetmint-go/testutil" machinetypes "planetmint-go/x/machine/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/cosmos-sdk/client/tx" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/codec/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -26,13 +33,10 @@ func (s *E2ETestSuite) TestAttestMachineREST() { respAccountInfo, err := testutil.GetRequest(reqAccountInfo) s.Require().NoError(err) - s.T().Log(string(respAccountInfo)) - var resAccountInfo authtypes.QueryAccountInfoResponse err = val.ClientCtx.Codec.UnmarshalJSON(respAccountInfo, &resAccountInfo) s.Require().NoError(err) - s.T().Log(resAccountInfo.Info.AccountNumber) // Create Attest Machine TX machine := machinetypes.Machine{ Name: "machine", @@ -48,37 +52,103 @@ func (s *E2ETestSuite) TestAttestMachineREST() { Gps: "{\"Latitude\":\"-48.876667\",\"Longitude\":\"-123.393333\"}", }, } - // machineJSON, err := json.Marshal(&machine) - // s.Require().NoError(err) + + txBuilder := val.ClientCtx.TxConfig.NewTxBuilder() msg := machinetypes.MsgAttestMachine{ - Creator: string(addr), + Creator: addr.String(), Machine: &machine, } + err = txBuilder.SetMsgs(&msg) + s.Require().NoError(err) - msg.Type() + txBuilder.SetGasLimit(200000) + txBuilder.SetFeeAmount(sdk.Coins{sdk.NewInt64Coin("stake", 2)}) + txBuilder.SetTimeoutHeight(0) + + pk, err := k.GetPubKey() + s.Require().NoError(err) + sk := k.GetLocal().PrivKey + + var priv cryptotypes.PrivKey + err = val.ClientCtx.Codec.UnpackAny(sk, &priv) + s.Require().NoError(err) + + sigV2 := signing.SignatureV2{ + PubKey: pk, + Data: &signing.SingleSignatureData{ + SignMode: val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: resAccountInfo.Info.Sequence, + } + + err = txBuilder.SetSignatures(sigV2) + s.Require().NoError(err) + + signerData := xauthsigning.SignerData{ + ChainID: val.ClientCtx.ChainID, + AccountNumber: resAccountInfo.Info.AccountNumber, + Sequence: resAccountInfo.Info.Sequence, + } + sigV2, err = tx.SignWithPrivKey( + val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, + txBuilder, priv, val.ClientCtx.TxConfig, resAccountInfo.Info.Sequence, + ) + s.Require().NoError(err) + + err = txBuilder.SetSignatures(sigV2) + s.Require().NoError(err) + + txBytes, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) + s.Require().NoError(err) + + broadcastTxUrl := fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", baseURL) + req := txtypes.BroadcastTxRequest{ + TxBytes: txBytes, + Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC, + } + + marshalledReq, err := val.ClientCtx.Codec.MarshalJSON(&req) + s.Require().NoError(err) + + s.Require().NoError(err) + r, err := testutil.PostRequest(broadcastTxUrl, "application/json", marshalledReq) + s.Require().NoError(err) + + s.T().Log("RESULT:") + s.T().Log(string(r)) // Encode TX - reqEncodeTx := fmt.Sprintf("%s/cosmos/tx/encode", baseURL) + reqEncodeTx := fmt.Sprintf("%s/cosmos/tx/v1beta1/encode", baseURL) - signerInfos := make([]txtypes.SignerInfo, 1) - signerInfos[1].PublicKey = &types.Any{ + msgs := make([]*types.Any, 1) + msgs[0], err = cdctypes.NewAnyWithValue(&msg) + s.Require().NoError(err) + + signerInfos := make([]*txtypes.SignerInfo, 1) + signerInfos[0] = &txtypes.SignerInfo{} + signerInfos[0].PublicKey = &types.Any{ TypeUrl: "/cosmos.crypto.secp256k1.PubKey", Value: k.PubKey.Value, } - signerInfos[1].ModeInfo = &txtypes.ModeInfo{ + signerInfos[0].ModeInfo = &txtypes.ModeInfo{ Sum: &txtypes.ModeInfo_Single_{ Single: &txtypes.ModeInfo_Single{ Mode: signing.SignMode_SIGN_MODE_DIRECT, }, }, } - signerInfos[1].Sequence = resAccountInfo.Info.Sequence + signerInfos[0].Sequence = resAccountInfo.Info.Sequence reqEncodeTxBody := txtypes.TxEncodeRequest{ Tx: &txtypes.Tx{ Body: &txtypes.TxBody{ - // Messages: make([]*types.Any, 0), + Messages: msgs, + Memo: "", + TimeoutHeight: 0, + ExtensionOptions: []*types.Any{}, + NonCriticalExtensionOptions: []*types.Any{}, }, AuthInfo: &txtypes.AuthInfo{ SignerInfos: signerInfos, @@ -87,12 +157,13 @@ func (s *E2ETestSuite) TestAttestMachineREST() { Signatures: [][]byte{}, }, } + reqEncodeTxBodyBytes, err := reqEncodeTxBody.Marshal() s.Require().NoError(err) // var resEncodeTX TXEncodeRequest - respEncodeTx, err := testutil.PostRequest(reqEncodeTx, "application/json", []byte(reqEncodeTxBody)) + respEncodeTx, err := testutil.PostRequest(reqEncodeTx, "application/json", reqEncodeTxBodyBytes) s.Require().NoError(err) - s.T().Log(respEncodeTx) + s.T().Log(string(respEncodeTx)) // Send encoded TX to /cosmos/tx/v1beta1/txs // Query Machine by Pubkey diff --git a/tests/e2e/machine/suite.go b/tests/e2e/machine/suite.go index c8cfd05..6991cbc 100644 --- a/tests/e2e/machine/suite.go +++ b/tests/e2e/machine/suite.go @@ -20,6 +20,7 @@ import ( // Queryable pubkey for TestAttestMachine const pubKey = "A/ZrbETECRq5DNGJZ0aH0DjlV4Y1opMlRfGoEJH454eB" +const mnemonic = "science humor project sword foil amazing exhibit afford kangaroo child pulse adapt camera trigger isolate pull approve october dragon critic vendor panic business valve" // Struct definition of machine E2ETestSuite type E2ETestSuite struct { @@ -42,7 +43,7 @@ func (s *E2ETestSuite) SetupSuite() { val := s.network.Validators[0] kb := val.ClientCtx.Keyring - account, _, err := kb.NewMnemonic("machine", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) + account, err := kb.NewAccount("machine", mnemonic, keyring.DefaultBIP39Passphrase, sdk.FullFundraiserPath, hd.Secp256k1) s.Require().NoError(err) addr, _ := account.GetAddress() From 24511388d25a3a2750ea8ec3a7f66f53e4df1b10 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 12 Jul 2023 13:30:58 +0200 Subject: [PATCH 03/15] query machine in test Signed-off-by: Lorenz Herzberger --- tests/e2e/machine/rest.go | 11 +++++++++++ tests/e2e/machine/suite.go | 6 ++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/e2e/machine/rest.go b/tests/e2e/machine/rest.go index 9c4a557..75a60fb 100644 --- a/tests/e2e/machine/rest.go +++ b/tests/e2e/machine/rest.go @@ -2,6 +2,7 @@ package machine import ( "fmt" + "net/url" "planetmint-go/testutil" machinetypes "planetmint-go/x/machine/types" @@ -119,6 +120,16 @@ func (s *E2ETestSuite) TestAttestMachineREST() { s.T().Log("RESULT:") s.T().Log(string(r)) + s.T().Log(string(pubKey)) + urlPubKey := url.QueryEscape(pubKey) + s.T().Log(string(urlPubKey)) + + queryMachineUrl := fmt.Sprintf("%s/planetmint-go/machine/get_machine_by_public_key/%s", baseURL, urlPubKey) + s.T().Log(string(queryMachineUrl)) + queryMachineRes, err := testutil.GetRequest(queryMachineUrl) + s.Require().NoError(err) + s.T().Log(string(queryMachineRes)) + // Encode TX reqEncodeTx := fmt.Sprintf("%s/cosmos/tx/v1beta1/encode", baseURL) diff --git a/tests/e2e/machine/suite.go b/tests/e2e/machine/suite.go index 6991cbc..fd1c686 100644 --- a/tests/e2e/machine/suite.go +++ b/tests/e2e/machine/suite.go @@ -19,8 +19,10 @@ import ( ) // Queryable pubkey for TestAttestMachine -const pubKey = "A/ZrbETECRq5DNGJZ0aH0DjlV4Y1opMlRfGoEJH454eB" -const mnemonic = "science humor project sword foil amazing exhibit afford kangaroo child pulse adapt camera trigger isolate pull approve october dragon critic vendor panic business valve" +// const pubKey = "A/ZrbETECRq5DNGJZ0aH0DjlV4Y1opMlRfGoEJH454eB" +// const mnemonic = "science humor project sword foil amazing exhibit afford kangaroo child pulse adapt camera trigger isolate pull approve october dragon critic vendor panic business valve" +const pubKey = "AjKN6HiWucu1EBwzX0ACnkvomJiLRwq79oPxoLMY1zRw" +const mnemonic = "helmet hedgehog lab actor weekend elbow pelican valid obtain hungry rocket decade tower gallery fit practice cart cherry giggle hair snack glance bulb farm" // Struct definition of machine E2ETestSuite type E2ETestSuite struct { From c1389ea9318a1f88eaa32ec9cd446adb1e198f70 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 12 Jul 2023 15:24:33 +0200 Subject: [PATCH 04/15] implement TestAttestMachineREST Signed-off-by: Lorenz Herzberger --- tests/e2e/machine/rest.go | 67 +++++--------------------------------- tests/e2e/machine/suite.go | 2 -- 2 files changed, 9 insertions(+), 60 deletions(-) diff --git a/tests/e2e/machine/rest.go b/tests/e2e/machine/rest.go index 75a60fb..e310604 100644 --- a/tests/e2e/machine/rest.go +++ b/tests/e2e/machine/rest.go @@ -9,9 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/client/tx" - cdctypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -110,72 +108,25 @@ func (s *E2ETestSuite) TestAttestMachineREST() { Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC, } - marshalledReq, err := val.ClientCtx.Codec.MarshalJSON(&req) + broadCastTxBody, err := val.ClientCtx.Codec.MarshalJSON(&req) s.Require().NoError(err) s.Require().NoError(err) - r, err := testutil.PostRequest(broadcastTxUrl, "application/json", marshalledReq) + broadCastTxResponse, err := testutil.PostRequest(broadcastTxUrl, "application/json", broadCastTxBody) s.Require().NoError(err) - s.T().Log("RESULT:") - s.T().Log(string(r)) + var bctRes txtypes.BroadcastTxResponse + err = val.ClientCtx.Codec.UnmarshalJSON(broadCastTxResponse, &bctRes) + s.Require().NoError(err) + s.Require().Equal(uint32(0), bctRes.TxResponse.Code) - s.T().Log(string(pubKey)) urlPubKey := url.QueryEscape(pubKey) - s.T().Log(string(urlPubKey)) - queryMachineUrl := fmt.Sprintf("%s/planetmint-go/machine/get_machine_by_public_key/%s", baseURL, urlPubKey) - s.T().Log(string(queryMachineUrl)) queryMachineRes, err := testutil.GetRequest(queryMachineUrl) s.Require().NoError(err) - s.T().Log(string(queryMachineRes)) - // Encode TX - reqEncodeTx := fmt.Sprintf("%s/cosmos/tx/v1beta1/encode", baseURL) - - msgs := make([]*types.Any, 1) - msgs[0], err = cdctypes.NewAnyWithValue(&msg) + var qmRes machinetypes.QueryGetMachineByPublicKeyResponse + err = val.ClientCtx.Codec.UnmarshalJSON(queryMachineRes, &qmRes) s.Require().NoError(err) - - signerInfos := make([]*txtypes.SignerInfo, 1) - signerInfos[0] = &txtypes.SignerInfo{} - signerInfos[0].PublicKey = &types.Any{ - TypeUrl: "/cosmos.crypto.secp256k1.PubKey", - Value: k.PubKey.Value, - } - signerInfos[0].ModeInfo = &txtypes.ModeInfo{ - Sum: &txtypes.ModeInfo_Single_{ - Single: &txtypes.ModeInfo_Single{ - Mode: signing.SignMode_SIGN_MODE_DIRECT, - }, - }, - } - signerInfos[0].Sequence = resAccountInfo.Info.Sequence - - reqEncodeTxBody := txtypes.TxEncodeRequest{ - Tx: &txtypes.Tx{ - Body: &txtypes.TxBody{ - Messages: msgs, - Memo: "", - TimeoutHeight: 0, - ExtensionOptions: []*types.Any{}, - NonCriticalExtensionOptions: []*types.Any{}, - }, - AuthInfo: &txtypes.AuthInfo{ - SignerInfos: signerInfos, - Tip: nil, - }, - Signatures: [][]byte{}, - }, - } - reqEncodeTxBodyBytes, err := reqEncodeTxBody.Marshal() - s.Require().NoError(err) - // var resEncodeTX TXEncodeRequest - respEncodeTx, err := testutil.PostRequest(reqEncodeTx, "application/json", reqEncodeTxBodyBytes) - s.Require().NoError(err) - - s.T().Log(string(respEncodeTx)) - // Send encoded TX to /cosmos/tx/v1beta1/txs - - // Query Machine by Pubkey + s.Require().Equal(&machine, qmRes.Machine) } diff --git a/tests/e2e/machine/suite.go b/tests/e2e/machine/suite.go index fd1c686..8863ffa 100644 --- a/tests/e2e/machine/suite.go +++ b/tests/e2e/machine/suite.go @@ -19,8 +19,6 @@ import ( ) // Queryable pubkey for TestAttestMachine -// const pubKey = "A/ZrbETECRq5DNGJZ0aH0DjlV4Y1opMlRfGoEJH454eB" -// const mnemonic = "science humor project sword foil amazing exhibit afford kangaroo child pulse adapt camera trigger isolate pull approve october dragon critic vendor panic business valve" const pubKey = "AjKN6HiWucu1EBwzX0ACnkvomJiLRwq79oPxoLMY1zRw" const mnemonic = "helmet hedgehog lab actor weekend elbow pelican valid obtain hungry rocket decade tower gallery fit practice cart cherry giggle hair snack glance bulb farm" From 3ed94b62f02027cf8e52fd68ac965dfe439f4916 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 12 Jul 2023 16:53:01 +0200 Subject: [PATCH 05/15] add asset e2e test suite Signed-off-by: Lorenz Herzberger --- tests/e2e/asset/cli_test.go | 14 +++++ tests/e2e/asset/suite.go | 100 ++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 tests/e2e/asset/cli_test.go create mode 100644 tests/e2e/asset/suite.go diff --git a/tests/e2e/asset/cli_test.go b/tests/e2e/asset/cli_test.go new file mode 100644 index 0000000..950d764 --- /dev/null +++ b/tests/e2e/asset/cli_test.go @@ -0,0 +1,14 @@ +package asset + +import ( + "planetmint-go/testutil/network" + "testing" + + "github.com/stretchr/testify/suite" +) + +func TestE2ETestSuite(t *testing.T) { + cfg := network.DefaultConfig() + cfg.NumValidators = 1 + suite.Run(t, NewE2ETestSuite(cfg)) +} diff --git a/tests/e2e/asset/suite.go b/tests/e2e/asset/suite.go new file mode 100644 index 0000000..1aeb88a --- /dev/null +++ b/tests/e2e/asset/suite.go @@ -0,0 +1,100 @@ +package asset + +import ( + "encoding/json" + "fmt" + "planetmint-go/testutil/network" + + clitestutil "planetmint-go/testutil/cli" + machinecli "planetmint-go/x/machine/client/cli" + + machinetypes "planetmint-go/x/machine/types" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" + bank "github.com/cosmos/cosmos-sdk/x/bank/client/cli" + "github.com/stretchr/testify/suite" +) + +// Queryable pubkey for TestNotarizeAsset +const pubKey = "AjKN6HiWucu1EBwzX0ACnkvomJiLRwq79oPxoLMY1zRw" +const mnemonic = "helmet hedgehog lab actor weekend elbow pelican valid obtain hungry rocket decade tower gallery fit practice cart cherry giggle hair snack glance bulb farm" + +// Struct definition of machine E2ETestSuite +type E2ETestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network +} + +// Returns new machine E2ETestSuite +func NewE2ETestSuite(cfg network.Config) *E2ETestSuite { + return &E2ETestSuite{cfg: cfg} +} + +// Sets up new machine E2ETestSuite +func (s *E2ETestSuite) SetupSuite() { + s.T().Log("setting up e2e test suite") + + s.network = network.New(s.T()) + val := s.network.Validators[0] + + kb := val.ClientCtx.Keyring + account, err := kb.NewAccount("machine", mnemonic, keyring.DefaultBIP39Passphrase, sdk.FullFundraiserPath, hd.Secp256k1) + s.Require().NoError(err) + + addr, _ := account.GetAddress() + + // sending funds to machine to initialize account on chain + args := []string{ + "node0", + addr.String(), + "1000stake", + "--yes", + fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), + } + _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.NewSendTxCmd(), args) + s.Require().NoError(err) + + s.Require().NoError(s.network.WaitForNextBlock()) +} + +// Tear down machine E2ETestSuite +func (s *E2ETestSuite) TearDownSuite() { + s.T().Log("tearing down e2e test suite") +} + +func (s *E2ETestSuite) TestNotarizeAsset() { + val := s.network.Validators[0] + + machine := machinetypes.Machine{ + Name: "machine", + Ticker: "machine_ticker", + Issued: 1, + Amount: 1000, + Precision: 8, + IssuerPlanetmint: pubKey, + IssuerLiquid: pubKey, + MachineId: pubKey, + Metadata: &machinetypes.Metadata{ + AdditionalDataCID: "CID", + Gps: "{\"Latitude\":\"-48.876667\",\"Longitude\":\"-123.393333\"}", + }, + } + machineJSON, err := json.Marshal(&machine) + s.Require().NoError(err) + + args := []string{ + fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID), + fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), + fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), + "--yes", + string(machineJSON), + } + + _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, machinecli.CmdAttestMachine(), args) + s.Require().NoError(err) +} From 8d0b0e6b8b03e5980ad931c6a828183a287005e2 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 12 Jul 2023 17:03:03 +0200 Subject: [PATCH 06/15] start implement TestNotarizeAsset Signed-off-by: Lorenz Herzberger --- tests/e2e/asset/suite.go | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tests/e2e/asset/suite.go b/tests/e2e/asset/suite.go index 1aeb88a..625207a 100644 --- a/tests/e2e/asset/suite.go +++ b/tests/e2e/asset/suite.go @@ -6,6 +6,7 @@ import ( "planetmint-go/testutil/network" clitestutil "planetmint-go/testutil/cli" + assetcli "planetmint-go/x/asset/client/cli" machinecli "planetmint-go/x/machine/client/cli" machinetypes "planetmint-go/x/machine/types" @@ -60,15 +61,6 @@ func (s *E2ETestSuite) SetupSuite() { s.Require().NoError(err) s.Require().NoError(s.network.WaitForNextBlock()) -} - -// Tear down machine E2ETestSuite -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") -} - -func (s *E2ETestSuite) TestNotarizeAsset() { - val := s.network.Validators[0] machine := machinetypes.Machine{ Name: "machine", @@ -87,7 +79,7 @@ func (s *E2ETestSuite) TestNotarizeAsset() { machineJSON, err := json.Marshal(&machine) s.Require().NoError(err) - args := []string{ + args = []string{ fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID), fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), @@ -98,3 +90,24 @@ func (s *E2ETestSuite) TestNotarizeAsset() { _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, machinecli.CmdAttestMachine(), args) s.Require().NoError(err) } + +// Tear down machine E2ETestSuite +func (s *E2ETestSuite) TearDownSuite() { + s.T().Log("tearing down e2e test suite") +} + +func (s *E2ETestSuite) TestNotarizeAsset() { + val := s.network.Validators[0] + + args := []string{ + // TODO: add cid-hash and signature + pubKey, + fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID), + fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), + fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), + "--yes", + } + + _, err := clitestutil.ExecTestCLICmd(val.ClientCtx, assetcli.CmdNotarizeAsset(), args) + s.Require().NoError(err) +} From 5c82451c093d9ededa88deb8e375a7136bd68752 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 12 Jul 2023 17:11:12 +0200 Subject: [PATCH 07/15] move sample asset to sample.go Signed-off-by: Lorenz Herzberger --- testutil/sample/sample.go | 17 +++++++++++++++++ x/asset/keeper/msg_server_test.go | 21 +-------------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/testutil/sample/sample.go b/testutil/sample/sample.go index 0cfe279..c77954c 100644 --- a/testutil/sample/sample.go +++ b/testutil/sample/sample.go @@ -1,6 +1,7 @@ package sample import ( + "crypto/sha256" "encoding/hex" machinetypes "planetmint-go/x/machine/types" @@ -55,3 +56,19 @@ func Metadata() machinetypes.Metadata { AdditionalDataCID: "CID", } } + +func Asset(sk string, pk string) (string, string) { + cid := "cid" + + skBytes, _ := hex.DecodeString(sk) + privKey := &secp256k1.PrivKey{Key: skBytes} + + cidBytes, _ := hex.DecodeString(cid) + hash := sha256.Sum256(cidBytes) + + sign, _ := privKey.Sign(hash[:]) + + signatureHex := hex.EncodeToString(sign) + + return cid, signatureHex +} diff --git a/x/asset/keeper/msg_server_test.go b/x/asset/keeper/msg_server_test.go index 07493c6..59afb87 100644 --- a/x/asset/keeper/msg_server_test.go +++ b/x/asset/keeper/msg_server_test.go @@ -2,8 +2,6 @@ package keeper_test import ( "context" - "crypto/sha256" - "encoding/hex" "testing" keepertest "planetmint-go/testutil/keeper" @@ -11,7 +9,6 @@ import ( "planetmint-go/x/asset/keeper" "planetmint-go/x/asset/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -30,23 +27,7 @@ func TestMsgServer(t *testing.T) { func TestMsgServerNotarizeAsset(t *testing.T) { sk, pk := sample.KeyPair() - cid := "cid" - - skBytes, err := hex.DecodeString(sk) - if err != nil { - assert.Equal(t, true, false) - } - privKey := &secp256k1.PrivKey{Key: skBytes} - - cidBytes, _ := hex.DecodeString(cid) - hash := sha256.Sum256(cidBytes) - - sign, err := privKey.Sign(hash[:]) - if err != nil { - assert.Equal(t, true, false) - } - - signatureHex := hex.EncodeToString(sign) + cid, signatureHex := sample.Asset(sk, pk) msg := types.NewMsgNotarizeAsset(pk, cid, signatureHex, pk) msgServer, ctx := setupMsgServer(t) From b7c177aa46e0f06cfb451b05fc19f8fda9e651df Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Thu, 13 Jul 2023 14:33:25 +0200 Subject: [PATCH 08/15] add to asset e2e test suite Signed-off-by: Lorenz Herzberger --- go.mod | 2 +- tests/e2e/asset/suite.go | 71 +++++++++++++++++++++++++++++++++------ tests/e2e/machine/rest.go | 3 +- 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 4eac684..94bb462 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( cosmossdk.io/api v0.3.1 + cosmossdk.io/errors v1.0.0-beta.7 github.com/cometbft/cometbft v0.37.1 github.com/cometbft/cometbft-db v0.7.0 github.com/cosmos/cosmos-sdk v0.47.3 @@ -31,7 +32,6 @@ require ( cloud.google.com/go/storage v1.29.0 // indirect cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect - cosmossdk.io/errors v1.0.0-beta.7 // indirect cosmossdk.io/log v1.1.0 // indirect cosmossdk.io/math v1.0.1 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect diff --git a/tests/e2e/asset/suite.go b/tests/e2e/asset/suite.go index 625207a..a7db06b 100644 --- a/tests/e2e/asset/suite.go +++ b/tests/e2e/asset/suite.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "planetmint-go/testutil/network" + "planetmint-go/testutil/sample" clitestutil "planetmint-go/testutil/cli" assetcli "planetmint-go/x/asset/client/cli" @@ -80,7 +81,6 @@ func (s *E2ETestSuite) SetupSuite() { s.Require().NoError(err) args = []string{ - fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID), fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), "--yes", @@ -89,6 +89,7 @@ func (s *E2ETestSuite) SetupSuite() { _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, machinecli.CmdAttestMachine(), args) s.Require().NoError(err) + s.Require().NoError(s.network.WaitForNextBlock()) } // Tear down machine E2ETestSuite @@ -99,15 +100,65 @@ func (s *E2ETestSuite) TearDownSuite() { func (s *E2ETestSuite) TestNotarizeAsset() { val := s.network.Validators[0] - args := []string{ - // TODO: add cid-hash and signature - pubKey, - fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID), - fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), - fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), - "--yes", + sk, pk := sample.KeyPair() + cid, signature := sample.Asset(sk, pk) + + testCases := []struct { + name string + args []string + expErr bool + errMsg string + }{ + { + "machine not found", + []string{ + cid, + signature, + pk, + fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), + fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), + "--yes", + }, + true, + "machine not found", + }, + { + "invalid signature", + []string{ + "cid", + "signature", + pubKey, + fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), + fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), + "--yes", + }, + true, + "invalid signature", + }, + { + "valid notarization", + []string{ + // TODO: Create Valid Inputs + cid, + signature, + pubKey, + fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), + fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), + "--yes", + }, + false, + "", + }, } - _, err := clitestutil.ExecTestCLICmd(val.ClientCtx, assetcli.CmdNotarizeAsset(), args) - s.Require().NoError(err) + for _, tc := range testCases { + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, assetcli.CmdNotarizeAsset(), tc.args) + if tc.expErr { + s.Require().Error(err) + s.Require().Contains(err.Error(), tc.errMsg) + } else { + s.Require().NoError(err) + s.T().Log(out) + } + } } diff --git a/tests/e2e/machine/rest.go b/tests/e2e/machine/rest.go index e310604..af99cdd 100644 --- a/tests/e2e/machine/rest.go +++ b/tests/e2e/machine/rest.go @@ -6,9 +6,8 @@ import ( "planetmint-go/testutil" machinetypes "planetmint-go/x/machine/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" From cb96fe967973cf394001335c099c711df1747e57 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Tue, 18 Jul 2023 16:15:59 +0200 Subject: [PATCH 09/15] asset e2e tests for raw log Signed-off-by: Lorenz Herzberger --- tests/e2e/asset/suite.go | 78 +++++++++++++++------ testutil/sample/sample.go | 2 +- x/asset/keeper/msg_server_notarize_asset.go | 4 +- x/asset/keeper/msg_server_test.go | 2 +- 4 files changed, 59 insertions(+), 27 deletions(-) diff --git a/tests/e2e/asset/suite.go b/tests/e2e/asset/suite.go index a7db06b..8ffeca9 100644 --- a/tests/e2e/asset/suite.go +++ b/tests/e2e/asset/suite.go @@ -1,23 +1,30 @@ package asset import ( + "encoding/hex" "encoding/json" "fmt" "planetmint-go/testutil/network" "planetmint-go/testutil/sample" + "regexp" clitestutil "planetmint-go/testutil/cli" assetcli "planetmint-go/x/asset/client/cli" machinecli "planetmint-go/x/machine/client/cli" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + machinetypes "planetmint-go/x/machine/types" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" bank "github.com/cosmos/cosmos-sdk/x/bank/client/cli" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + "sigs.k8s.io/yaml" ) // Queryable pubkey for TestNotarizeAsset @@ -47,6 +54,9 @@ func (s *E2ETestSuite) SetupSuite() { kb := val.ClientCtx.Keyring account, err := kb.NewAccount("machine", mnemonic, keyring.DefaultBIP39Passphrase, sdk.FullFundraiserPath, hd.Secp256k1) s.Require().NoError(err) + pk, err := account.GetPubKey() + pkHex := hex.EncodeToString(pk.Bytes()) + s.Require().NoError(err) addr, _ := account.GetAddress() @@ -69,9 +79,9 @@ func (s *E2ETestSuite) SetupSuite() { Issued: 1, Amount: 1000, Precision: 8, - IssuerPlanetmint: pubKey, - IssuerLiquid: pubKey, - MachineId: pubKey, + IssuerPlanetmint: pkHex, + IssuerLiquid: pkHex, + MachineId: pkHex, Metadata: &machinetypes.Metadata{ AdditionalDataCID: "CID", Gps: "{\"Latitude\":\"-48.876667\",\"Longitude\":\"-123.393333\"}", @@ -97,29 +107,36 @@ func (s *E2ETestSuite) TearDownSuite() { s.T().Log("tearing down e2e test suite") } +// Needed to export private key from Keyring +type unsafeExporter interface { + ExportPrivateKeyObject(uid string) (types.PrivKey, error) +} + func (s *E2ETestSuite) TestNotarizeAsset() { val := s.network.Validators[0] - sk, pk := sample.KeyPair() - cid, signature := sample.Asset(sk, pk) + privKey, err := val.ClientCtx.Keyring.(unsafeExporter).ExportPrivateKeyObject("machine") + s.Require().NoError(err) + + sk := hex.EncodeToString(privKey.Bytes()) + + cidHash, signature := sample.Asset(sk) testCases := []struct { name string args []string - expErr bool - errMsg string + rawLog string }{ { "machine not found", []string{ - cid, + cidHash, signature, - pk, + "pubkey", fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), "--yes", }, - true, "machine not found", }, { @@ -127,38 +144,53 @@ func (s *E2ETestSuite) TestNotarizeAsset() { []string{ "cid", "signature", - pubKey, + hex.EncodeToString(privKey.PubKey().Bytes()), fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), "--yes", }, - true, "invalid signature", }, { "valid notarization", []string{ - // TODO: Create Valid Inputs - cid, + cidHash, signature, - pubKey, + hex.EncodeToString(privKey.PubKey().Bytes()), fmt.Sprintf("--%s=%s", flags.FlagFrom, "machine"), fmt.Sprintf("--%s=%s", flags.FlagFees, "2stake"), "--yes", }, - false, - "", + "planetmintgo.asset.MsgNotarizeAsset", }, } for _, tc := range testCases { out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, assetcli.CmdNotarizeAsset(), tc.args) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - s.Require().NoError(err) - s.T().Log(out) + s.Require().NoError(err) + // Hack: numbers come back as strings and cannot be unmarshalled into TxResponse struct + m := regexp.MustCompile(`"([0-9]+?)"`) + str := m.ReplaceAllString(out.String(), "${1}") + + var txResponse sdk.TxResponse + err = json.Unmarshal([]byte(str), &txResponse) + s.Require().NoError(err) + + s.Require().NoError(s.network.WaitForNextBlock()) + args := []string{ + txResponse.TxHash, } + out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, authcmd.QueryTxCmd(), args) + s.Require().NoError(err) + + str = m.ReplaceAllString(out.String(), "${1}") + // Need to convert to JSON first, because TxResponse struct lacks `yaml:"height,omitempty"`, etc. + j, err := yaml.YAMLToJSON([]byte(str)) + s.Require().NoError(err) + + err = json.Unmarshal(j, &txResponse) + s.Require().NoError(err) + + assert.Contains(s.T(), txResponse.RawLog, tc.rawLog) } } diff --git a/testutil/sample/sample.go b/testutil/sample/sample.go index c77954c..0c09db7 100644 --- a/testutil/sample/sample.go +++ b/testutil/sample/sample.go @@ -57,7 +57,7 @@ func Metadata() machinetypes.Metadata { } } -func Asset(sk string, pk string) (string, string) { +func Asset(sk string) (string, string) { cid := "cid" skBytes, _ := hex.DecodeString(sk) diff --git a/x/asset/keeper/msg_server_notarize_asset.go b/x/asset/keeper/msg_server_notarize_asset.go index 6e96f71..d3d5711 100644 --- a/x/asset/keeper/msg_server_notarize_asset.go +++ b/x/asset/keeper/msg_server_notarize_asset.go @@ -18,12 +18,12 @@ func (k msgServer) NotarizeAsset(goCtx context.Context, msg *types.MsgNotarizeAs _, found := k.machineKeeper.GetMachineIndex(ctx, msg.PubKey) if !found { - return &types.MsgNotarizeAssetResponse{}, errors.New("machine not found") + return nil, errors.New("machine not found") } valid := ValidateSignature(msg.Hash, msg.Signature, msg.PubKey) if !valid { - return &types.MsgNotarizeAssetResponse{}, errors.New("invalid signature") + return nil, errors.New("invalid signature") } var asset = types.Asset{ diff --git a/x/asset/keeper/msg_server_test.go b/x/asset/keeper/msg_server_test.go index 59afb87..8f72e79 100644 --- a/x/asset/keeper/msg_server_test.go +++ b/x/asset/keeper/msg_server_test.go @@ -27,7 +27,7 @@ func TestMsgServer(t *testing.T) { func TestMsgServerNotarizeAsset(t *testing.T) { sk, pk := sample.KeyPair() - cid, signatureHex := sample.Asset(sk, pk) + cid, signatureHex := sample.Asset(sk) msg := types.NewMsgNotarizeAsset(pk, cid, signatureHex, pk) msgServer, ctx := setupMsgServer(t) From 9e42d74bc3f4137ed80909dc7b71113084f8f2c7 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 19 Jul 2023 09:58:19 +0200 Subject: [PATCH 10/15] add basic notarize asset rest test Signed-off-by: Lorenz Herzberger --- tests/e2e/asset/rest.go | 115 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 tests/e2e/asset/rest.go diff --git a/tests/e2e/asset/rest.go b/tests/e2e/asset/rest.go new file mode 100644 index 0000000..2eff4b9 --- /dev/null +++ b/tests/e2e/asset/rest.go @@ -0,0 +1,115 @@ +package asset + +import ( + "encoding/hex" + "fmt" + "planetmint-go/testutil" + "planetmint-go/testutil/sample" + + assettypes "planetmint-go/x/asset/types" + + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func (s *E2ETestSuite) TestNotarizeAssetREST() { + val := s.network.Validators[0] + baseURL := val.APIAddress + + // Query Sequence Number + k, err := val.ClientCtx.Keyring.Key("machine") + s.Require().NoError(err) + + addr, err := k.GetAddress() + s.Require().NoError(err) + + reqAccountInfo := fmt.Sprintf("%s/cosmos/auth/v1beta1/account_info/%s", baseURL, addr.String()) + respAccountInfo, err := testutil.GetRequest(reqAccountInfo) + s.Require().NoError(err) + + var resAccountInfo authtypes.QueryAccountInfoResponse + err = val.ClientCtx.Codec.UnmarshalJSON(respAccountInfo, &resAccountInfo) + s.Require().NoError(err) + + privKey, err := val.ClientCtx.Keyring.(unsafeExporter).ExportPrivateKeyObject("machine") + s.Require().NoError(err) + + sk := hex.EncodeToString(privKey.Bytes()) + + cidHash, signature := sample.Asset(sk) + + msg := assettypes.MsgNotarizeAsset{ + Creator: addr.String(), + Hash: cidHash, + Signature: signature, + PubKey: hex.EncodeToString(privKey.PubKey().Bytes()), + } + + txBuilder := val.ClientCtx.TxConfig.NewTxBuilder() + err = txBuilder.SetMsgs(&msg) + + txBuilder.SetGasLimit(200000) + txBuilder.SetFeeAmount(sdk.Coins{sdk.NewInt64Coin("stake", 2)}) + txBuilder.SetTimeoutHeight(0) + + pk, err := k.GetPubKey() + s.Require().NoError(err) + secretk := k.GetLocal().PrivKey + + var priv cryptotypes.PrivKey + err = val.ClientCtx.Codec.UnpackAny(secretk, &priv) + s.Require().NoError(err) + + sigV2 := signing.SignatureV2{ + PubKey: pk, + Data: &signing.SingleSignatureData{ + SignMode: val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: resAccountInfo.Info.Sequence, + } + + err = txBuilder.SetSignatures(sigV2) + s.Require().NoError(err) + + signerData := xauthsigning.SignerData{ + ChainID: val.ClientCtx.ChainID, + AccountNumber: resAccountInfo.Info.AccountNumber, + Sequence: resAccountInfo.Info.Sequence, + } + sigV2, err = tx.SignWithPrivKey( + val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, + txBuilder, priv, val.ClientCtx.TxConfig, resAccountInfo.Info.Sequence, + ) + s.Require().NoError(err) + + err = txBuilder.SetSignatures(sigV2) + s.Require().NoError(err) + + txBytes, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) + s.Require().NoError(err) + + broadcastTxUrl := fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", baseURL) + req := txtypes.BroadcastTxRequest{ + TxBytes: txBytes, + Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC, + } + + broadCastTxBody, err := val.ClientCtx.Codec.MarshalJSON(&req) + s.Require().NoError(err) + + s.Require().NoError(err) + broadCastTxResponse, err := testutil.PostRequest(broadcastTxUrl, "application/json", broadCastTxBody) + s.Require().NoError(err) + + var bctRes txtypes.BroadcastTxResponse + err = val.ClientCtx.Codec.UnmarshalJSON(broadCastTxResponse, &bctRes) + s.Require().NoError(err) + s.Require().Equal(uint32(0), bctRes.TxResponse.Code) +} From 5fb957b02fbef15eea3f435293fc97d1df668f02 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 19 Jul 2023 11:15:22 +0200 Subject: [PATCH 11/15] move tx prep and broadcast to testutils Signed-off-by: Lorenz Herzberger --- tests/e2e/asset/rest.go | 85 ++--------------------------- testutil/rest.go | 118 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 79 deletions(-) diff --git a/tests/e2e/asset/rest.go b/tests/e2e/asset/rest.go index 2eff4b9..80280a5 100644 --- a/tests/e2e/asset/rest.go +++ b/tests/e2e/asset/rest.go @@ -2,46 +2,26 @@ package asset import ( "encoding/hex" - "fmt" "planetmint-go/testutil" "planetmint-go/testutil/sample" assettypes "planetmint-go/x/asset/types" - - "github.com/cosmos/cosmos-sdk/client/tx" - sdk "github.com/cosmos/cosmos-sdk/types" - txtypes "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" - - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func (s *E2ETestSuite) TestNotarizeAssetREST() { val := s.network.Validators[0] - baseURL := val.APIAddress - // Query Sequence Number + // Create Msg k, err := val.ClientCtx.Keyring.Key("machine") s.Require().NoError(err) addr, err := k.GetAddress() s.Require().NoError(err) - reqAccountInfo := fmt.Sprintf("%s/cosmos/auth/v1beta1/account_info/%s", baseURL, addr.String()) - respAccountInfo, err := testutil.GetRequest(reqAccountInfo) - s.Require().NoError(err) - - var resAccountInfo authtypes.QueryAccountInfoResponse - err = val.ClientCtx.Codec.UnmarshalJSON(respAccountInfo, &resAccountInfo) - s.Require().NoError(err) - privKey, err := val.ClientCtx.Keyring.(unsafeExporter).ExportPrivateKeyObject("machine") s.Require().NoError(err) sk := hex.EncodeToString(privKey.Bytes()) - cidHash, signature := sample.Asset(sk) msg := assettypes.MsgNotarizeAsset{ @@ -51,65 +31,12 @@ func (s *E2ETestSuite) TestNotarizeAssetREST() { PubKey: hex.EncodeToString(privKey.PubKey().Bytes()), } - txBuilder := val.ClientCtx.TxConfig.NewTxBuilder() - err = txBuilder.SetMsgs(&msg) - - txBuilder.SetGasLimit(200000) - txBuilder.SetFeeAmount(sdk.Coins{sdk.NewInt64Coin("stake", 2)}) - txBuilder.SetTimeoutHeight(0) - - pk, err := k.GetPubKey() - s.Require().NoError(err) - secretk := k.GetLocal().PrivKey - - var priv cryptotypes.PrivKey - err = val.ClientCtx.Codec.UnpackAny(secretk, &priv) + // Prepare Tx + txBytes, err := testutil.PrepareTx(val, &msg, "machine") s.Require().NoError(err) - sigV2 := signing.SignatureV2{ - PubKey: pk, - Data: &signing.SingleSignatureData{ - SignMode: val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), - Signature: nil, - }, - Sequence: resAccountInfo.Info.Sequence, - } - - err = txBuilder.SetSignatures(sigV2) + // Broadcast Tx + broadcastTxResponse, err := testutil.BroadcastTx(val, txBytes) s.Require().NoError(err) - - signerData := xauthsigning.SignerData{ - ChainID: val.ClientCtx.ChainID, - AccountNumber: resAccountInfo.Info.AccountNumber, - Sequence: resAccountInfo.Info.Sequence, - } - sigV2, err = tx.SignWithPrivKey( - val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, - txBuilder, priv, val.ClientCtx.TxConfig, resAccountInfo.Info.Sequence, - ) - s.Require().NoError(err) - - err = txBuilder.SetSignatures(sigV2) - s.Require().NoError(err) - - txBytes, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - - broadcastTxUrl := fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", baseURL) - req := txtypes.BroadcastTxRequest{ - TxBytes: txBytes, - Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC, - } - - broadCastTxBody, err := val.ClientCtx.Codec.MarshalJSON(&req) - s.Require().NoError(err) - - s.Require().NoError(err) - broadCastTxResponse, err := testutil.PostRequest(broadcastTxUrl, "application/json", broadCastTxBody) - s.Require().NoError(err) - - var bctRes txtypes.BroadcastTxResponse - err = val.ClientCtx.Codec.UnmarshalJSON(broadCastTxResponse, &bctRes) - s.Require().NoError(err) - s.Require().Equal(uint32(0), bctRes.TxResponse.Code) + s.Require().Equal(uint32(0), broadcastTxResponse.TxResponse.Code) } diff --git a/testutil/rest.go b/testutil/rest.go index 180a7be..31bdd65 100644 --- a/testutil/rest.go +++ b/testutil/rest.go @@ -5,6 +5,17 @@ import ( "fmt" "io" "net/http" + + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/testutil/network" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" ) // GetRequest defines a wrapper around an HTTP GET request with a provided URL. @@ -44,3 +55,110 @@ func PostRequest(url, contentType string, data []byte) ([]byte, error) { return bz, nil } + +func PrepareTx(val *network.Validator, msg sdk.Msg, signer string) ([]byte, error) { + k, err := val.ClientCtx.Keyring.Key(signer) + if err != nil { + return nil, err + } + + addr, err := k.GetAddress() + if err != nil { + return nil, err + } + + reqAccountInfo := fmt.Sprintf("%s/cosmos/auth/v1beta1/account_info/%s", val.APIAddress, addr.String()) + respAccountInfo, err := GetRequest(reqAccountInfo) + if err != nil { + return nil, err + } + + var resAccountInfo authtypes.QueryAccountInfoResponse + err = val.ClientCtx.Codec.UnmarshalJSON(respAccountInfo, &resAccountInfo) + if err != nil { + return nil, err + } + + txBuilder := val.ClientCtx.TxConfig.NewTxBuilder() + txBuilder.SetMsgs(msg) + txBuilder.SetGasLimit(200000) + txBuilder.SetFeeAmount(sdk.Coins{sdk.NewInt64Coin("stake", 2)}) + txBuilder.SetTimeoutHeight(0) + + pk, err := k.GetPubKey() + if err != nil { + return nil, err + } + + sk := k.GetLocal().PrivKey + + var priv cryptotypes.PrivKey + err = val.ClientCtx.Codec.UnpackAny(sk, &priv) + if err != nil { + return nil, err + } + + sigV2 := signing.SignatureV2{ + PubKey: pk, + Data: &signing.SingleSignatureData{ + SignMode: val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: resAccountInfo.Info.Sequence, + } + + err = txBuilder.SetSignatures(sigV2) + if err != nil { + return nil, err + } + + signerData := xauthsigning.SignerData{ + ChainID: val.ClientCtx.ChainID, + AccountNumber: resAccountInfo.Info.AccountNumber, + Sequence: resAccountInfo.Info.Sequence, + } + sigV2, err = tx.SignWithPrivKey( + val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, + txBuilder, priv, val.ClientCtx.TxConfig, resAccountInfo.Info.Sequence, + ) + if err != nil { + return nil, err + } + + err = txBuilder.SetSignatures(sigV2) + if err != nil { + return nil, err + } + + txBytes, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) + if err != nil { + return nil, err + } + + return txBytes, nil +} + +func BroadcastTx(val *network.Validator, txBytes []byte) (*txtypes.BroadcastTxResponse, error) { + broadcastTxUrl := fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", val.APIAddress) + req := txtypes.BroadcastTxRequest{ + TxBytes: txBytes, + Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC, + } + + broadCastTxBody, err := val.ClientCtx.Codec.MarshalJSON(&req) + if err != nil { + return nil, err + } + broadCastTxResponse, err := PostRequest(broadcastTxUrl, "application/json", broadCastTxBody) + if err != nil { + return nil, err + } + + var bctRes txtypes.BroadcastTxResponse + err = val.ClientCtx.Codec.UnmarshalJSON(broadCastTxResponse, &bctRes) + if err != nil { + return nil, err + } + + return &bctRes, nil +} From 2874e577b06095469c82bd3f13b2af633b7ce77f Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 19 Jul 2023 13:06:50 +0200 Subject: [PATCH 12/15] refactor asset rest test Signed-off-by: Lorenz Herzberger --- tests/e2e/asset/rest.go | 68 +++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/tests/e2e/asset/rest.go b/tests/e2e/asset/rest.go index 80280a5..f4668a5 100644 --- a/tests/e2e/asset/rest.go +++ b/tests/e2e/asset/rest.go @@ -2,10 +2,13 @@ package asset import ( "encoding/hex" + "fmt" "planetmint-go/testutil" "planetmint-go/testutil/sample" assettypes "planetmint-go/x/asset/types" + + txtypes "github.com/cosmos/cosmos-sdk/types/tx" ) func (s *E2ETestSuite) TestNotarizeAssetREST() { @@ -24,19 +27,60 @@ func (s *E2ETestSuite) TestNotarizeAssetREST() { sk := hex.EncodeToString(privKey.Bytes()) cidHash, signature := sample.Asset(sk) - msg := assettypes.MsgNotarizeAsset{ - Creator: addr.String(), - Hash: cidHash, - Signature: signature, - PubKey: hex.EncodeToString(privKey.PubKey().Bytes()), + testCases := []struct { + name string + msg assettypes.MsgNotarizeAsset + rawLog string + }{ + { + "machine not found", + assettypes.MsgNotarizeAsset{ + Creator: addr.String(), + Hash: cidHash, + Signature: signature, + PubKey: "human pubkey", + }, + "machine not found", + }, + { + "invalid signature", + assettypes.MsgNotarizeAsset{ + Creator: addr.String(), + Hash: cidHash, + Signature: "invalid signature", + PubKey: hex.EncodeToString(privKey.PubKey().Bytes()), + }, + "invalid signature", + }, + { + "valid notarization", + assettypes.MsgNotarizeAsset{ + Creator: addr.String(), + Hash: cidHash, + Signature: signature, + PubKey: hex.EncodeToString(privKey.PubKey().Bytes()), + }, + "planetmintgo.asset.MsgNotarizeAsset", + }, } - // Prepare Tx - txBytes, err := testutil.PrepareTx(val, &msg, "machine") - s.Require().NoError(err) + for _, tc := range testCases { + // Prepare Tx + txBytes, err := testutil.PrepareTx(val, &tc.msg, "machine") + s.Require().NoError(err) - // Broadcast Tx - broadcastTxResponse, err := testutil.BroadcastTx(val, txBytes) - s.Require().NoError(err) - s.Require().Equal(uint32(0), broadcastTxResponse.TxResponse.Code) + // Broadcast Tx + broadcastTxResponse, err := testutil.BroadcastTx(val, txBytes) + s.Require().NoError(err) + + s.network.WaitForNextBlock() + + tx, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", val.APIAddress, broadcastTxResponse.TxResponse.TxHash)) + s.Require().NoError(err) + + var txRes txtypes.GetTxResponse + err = val.ClientCtx.Codec.UnmarshalJSON(tx, &txRes) + s.Require().NoError(err) + s.Require().Contains(txRes.TxResponse.RawLog, tc.rawLog) + } } From 9210301c88eb8cf682242ba839e50da80f3dd370 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 19 Jul 2023 13:16:02 +0200 Subject: [PATCH 13/15] refactor machine rest test Signed-off-by: Lorenz Herzberger --- tests/e2e/machine/rest.go | 83 +++++---------------------------------- 1 file changed, 9 insertions(+), 74 deletions(-) diff --git a/tests/e2e/machine/rest.go b/tests/e2e/machine/rest.go index af99cdd..c52b6d8 100644 --- a/tests/e2e/machine/rest.go +++ b/tests/e2e/machine/rest.go @@ -2,18 +2,10 @@ package machine import ( "fmt" - "net/url" "planetmint-go/testutil" machinetypes "planetmint-go/x/machine/types" - "github.com/cosmos/cosmos-sdk/client/tx" - sdk "github.com/cosmos/cosmos-sdk/types" - - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func (s *E2ETestSuite) TestAttestMachineREST() { @@ -27,14 +19,6 @@ func (s *E2ETestSuite) TestAttestMachineREST() { addr, err := k.GetAddress() s.Require().NoError(err) - reqAccountInfo := fmt.Sprintf("%s/cosmos/auth/v1beta1/account_info/%s", baseURL, addr.String()) - respAccountInfo, err := testutil.GetRequest(reqAccountInfo) - s.Require().NoError(err) - - var resAccountInfo authtypes.QueryAccountInfoResponse - err = val.ClientCtx.Codec.UnmarshalJSON(respAccountInfo, &resAccountInfo) - s.Require().NoError(err) - // Create Attest Machine TX machine := machinetypes.Machine{ Name: "machine", @@ -51,76 +35,27 @@ func (s *E2ETestSuite) TestAttestMachineREST() { }, } - txBuilder := val.ClientCtx.TxConfig.NewTxBuilder() - msg := machinetypes.MsgAttestMachine{ Creator: addr.String(), Machine: &machine, } - err = txBuilder.SetMsgs(&msg) + + txBytes, err := testutil.PrepareTx(val, &msg, "machine") s.Require().NoError(err) - txBuilder.SetGasLimit(200000) - txBuilder.SetFeeAmount(sdk.Coins{sdk.NewInt64Coin("stake", 2)}) - txBuilder.SetTimeoutHeight(0) - - pk, err := k.GetPubKey() - s.Require().NoError(err) - sk := k.GetLocal().PrivKey - - var priv cryptotypes.PrivKey - err = val.ClientCtx.Codec.UnpackAny(sk, &priv) + broadcastTxResponse, err := testutil.BroadcastTx(val, txBytes) s.Require().NoError(err) - sigV2 := signing.SignatureV2{ - PubKey: pk, - Data: &signing.SingleSignatureData{ - SignMode: val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), - Signature: nil, - }, - Sequence: resAccountInfo.Info.Sequence, - } - - err = txBuilder.SetSignatures(sigV2) + s.network.WaitForNextBlock() + tx, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", val.APIAddress, broadcastTxResponse.TxResponse.TxHash)) s.Require().NoError(err) - signerData := xauthsigning.SignerData{ - ChainID: val.ClientCtx.ChainID, - AccountNumber: resAccountInfo.Info.AccountNumber, - Sequence: resAccountInfo.Info.Sequence, - } - sigV2, err = tx.SignWithPrivKey( - val.ClientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, - txBuilder, priv, val.ClientCtx.TxConfig, resAccountInfo.Info.Sequence, - ) + var txRes txtypes.GetTxResponse + err = val.ClientCtx.Codec.UnmarshalJSON(tx, &txRes) s.Require().NoError(err) + s.Require().Equal(uint32(0), txRes.TxResponse.Code) - err = txBuilder.SetSignatures(sigV2) - s.Require().NoError(err) - - txBytes, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - - broadcastTxUrl := fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", baseURL) - req := txtypes.BroadcastTxRequest{ - TxBytes: txBytes, - Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC, - } - - broadCastTxBody, err := val.ClientCtx.Codec.MarshalJSON(&req) - s.Require().NoError(err) - - s.Require().NoError(err) - broadCastTxResponse, err := testutil.PostRequest(broadcastTxUrl, "application/json", broadCastTxBody) - s.Require().NoError(err) - - var bctRes txtypes.BroadcastTxResponse - err = val.ClientCtx.Codec.UnmarshalJSON(broadCastTxResponse, &bctRes) - s.Require().NoError(err) - s.Require().Equal(uint32(0), bctRes.TxResponse.Code) - - urlPubKey := url.QueryEscape(pubKey) - queryMachineUrl := fmt.Sprintf("%s/planetmint-go/machine/get_machine_by_public_key/%s", baseURL, urlPubKey) + queryMachineUrl := fmt.Sprintf("%s/planetmint-go/machine/get_machine_by_public_key/%s", baseURL, pubKey) queryMachineRes, err := testutil.GetRequest(queryMachineUrl) s.Require().NoError(err) From 02f2140df43050018716d42b5478172c4f8bdbcb Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 19 Jul 2023 13:19:05 +0200 Subject: [PATCH 14/15] removed unused constant Signed-off-by: Lorenz Herzberger --- tests/e2e/asset/suite.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e/asset/suite.go b/tests/e2e/asset/suite.go index 8ffeca9..6de70b5 100644 --- a/tests/e2e/asset/suite.go +++ b/tests/e2e/asset/suite.go @@ -28,7 +28,6 @@ import ( ) // Queryable pubkey for TestNotarizeAsset -const pubKey = "AjKN6HiWucu1EBwzX0ACnkvomJiLRwq79oPxoLMY1zRw" const mnemonic = "helmet hedgehog lab actor weekend elbow pelican valid obtain hungry rocket decade tower gallery fit practice cart cherry giggle hair snack glance bulb farm" // Struct definition of machine E2ETestSuite From d43b61b9aa3569ca335df9fb4a6923b0e72b2b77 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 19 Jul 2023 14:13:08 +0200 Subject: [PATCH 15/15] fix linter errors Signed-off-by: Lorenz Herzberger --- tests/e2e/asset/rest.go | 1 + tests/e2e/asset/suite.go | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/e2e/asset/rest.go b/tests/e2e/asset/rest.go index f4668a5..b1f6231 100644 --- a/tests/e2e/asset/rest.go +++ b/tests/e2e/asset/rest.go @@ -11,6 +11,7 @@ import ( txtypes "github.com/cosmos/cosmos-sdk/types/tx" ) +// TestNotarizeAssetREST notarizes asset over REST endpoint func (s *E2ETestSuite) TestNotarizeAssetREST() { val := s.network.Validators[0] diff --git a/tests/e2e/asset/suite.go b/tests/e2e/asset/suite.go index 6de70b5..661fabe 100644 --- a/tests/e2e/asset/suite.go +++ b/tests/e2e/asset/suite.go @@ -30,7 +30,7 @@ import ( // Queryable pubkey for TestNotarizeAsset const mnemonic = "helmet hedgehog lab actor weekend elbow pelican valid obtain hungry rocket decade tower gallery fit practice cart cherry giggle hair snack glance bulb farm" -// Struct definition of machine E2ETestSuite +// E2ETestSuite struct definition of asset suite type E2ETestSuite struct { suite.Suite @@ -38,12 +38,12 @@ type E2ETestSuite struct { network *network.Network } -// Returns new machine E2ETestSuite +// NewE2ETestSuite returns configured asset E2ETestSuite func NewE2ETestSuite(cfg network.Config) *E2ETestSuite { return &E2ETestSuite{cfg: cfg} } -// Sets up new machine E2ETestSuite +// SetupSuite initializes asset E2ETestSuite func (s *E2ETestSuite) SetupSuite() { s.T().Log("setting up e2e test suite") @@ -101,7 +101,7 @@ func (s *E2ETestSuite) SetupSuite() { s.Require().NoError(s.network.WaitForNextBlock()) } -// Tear down machine E2ETestSuite +// TearDownSuite clean up after testing func (s *E2ETestSuite) TearDownSuite() { s.T().Log("tearing down e2e test suite") } @@ -111,6 +111,7 @@ type unsafeExporter interface { ExportPrivateKeyObject(uid string) (types.PrivKey, error) } +// TestNotarizeAsset notarizes asset over cli func (s *E2ETestSuite) TestNotarizeAsset() { val := s.network.Validators[0]