From 0a79849d6e1ecd539c625478919bdc40bb8b0586 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 13 Mar 2020 09:51:11 -0400 Subject: [PATCH] Test tx --- codec/std/tx.go | 102 +++++++++++++++++++++++++++++++++++-------- codec/std/tx_test.go | 38 ++++++++++++++++ 2 files changed, 123 insertions(+), 17 deletions(-) create mode 100644 codec/std/tx_test.go diff --git a/codec/std/tx.go b/codec/std/tx.go index 595fbd848c..b370945232 100644 --- a/codec/std/tx.go +++ b/codec/std/tx.go @@ -6,12 +6,28 @@ import ( jsonc "github.com/gibson042/canonicaljson-go" "github.com/gogo/protobuf/jsonpb" + "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth" ) -var _ sdk.Tx = Transaction{} +var ( + _ sdk.Tx = (*Transaction)(nil) + _ client.ClientTx = (*Transaction)(nil) +) + +func NewTransaction(fee auth.StdFee, memo string, sdkMsgs []sdk.Msg) (*Transaction, error) { + tx := &Transaction{ + StdTxBase: auth.NewStdTxBase(fee, nil, memo), + } + + if err := tx.SetMsgs(sdkMsgs...); err != nil { + return nil, err + } + + return tx, nil +} // GetMsgs returns all the messages in a Transaction as a slice of sdk.Msg. func (tx Transaction) GetMsgs() []sdk.Msg { @@ -47,16 +63,16 @@ func (tx Transaction) GetSigners() []sdk.AccAddress { // ValidateBasic does a simple and lightweight validation check that doesn't // require access to any other information. func (tx Transaction) ValidateBasic() error { - stdSigs := tx.Base.GetSignatures() + stdSigs := tx.GetSignatures() - if tx.Base.Fee.Gas > auth.MaxGasWanted { + if tx.Fee.Gas > auth.MaxGasWanted { return sdkerrors.Wrapf( - sdkerrors.ErrInvalidRequest, "invalid gas supplied; %d > %d", tx.Base.Fee.Gas, auth.MaxGasWanted, + sdkerrors.ErrInvalidRequest, "invalid gas supplied; %d > %d", tx.Fee.Gas, auth.MaxGasWanted, ) } - if tx.Base.Fee.Amount.IsAnyNegative() { + if tx.Fee.Amount.IsAnyNegative() { return sdkerrors.Wrapf( - sdkerrors.ErrInsufficientFee, "invalid fee provided: %s", tx.Base.Fee.Amount, + sdkerrors.ErrInsufficientFee, "invalid fee provided: %s", tx.Fee.Amount, ) } if len(stdSigs) == 0 { @@ -71,24 +87,76 @@ func (tx Transaction) ValidateBasic() error { return nil } +// SetMsgs sets the messages for a Transaction. It will overwrite any existing +// messages set. +func (tx *Transaction) SetMsgs(sdkMsgs ...sdk.Msg) error { + msgs := make([]Message, len(sdkMsgs)) + for i, msg := range sdkMsgs { + m := &Message{} + if err := m.SetMsg(msg); err != nil { + return err + } + + msgs[i] = *m + } + + tx.Msgs = msgs + return nil +} + +// GetSignatures returns all the transaction's signatures. +func (tx Transaction) GetSignatures() []sdk.Signature { + sdkSigs := make([]sdk.Signature, len(tx.Signatures)) + for i, sig := range tx.Signatures { + sdkSigs[i] = sig + } + + return sdkSigs +} + +// SetSignatures sets the transaction's signatures. It will overwrite any +// existing signatures set. +func (tx *Transaction) SetSignatures(sdkSigs ...sdk.Signature) { + sigs := make([]auth.StdSignature, len(tx.Signatures)) + for i, sig := range sdkSigs { + sigs[i] = auth.NewStdSignature(sig.GetPubKey(), sig.GetSignature()) + } + + tx.Signatures = sigs +} + +// GetFee returns the transaction's fee. +func (tx Transaction) GetFee() sdk.Fee { + return tx.Fee +} + +// SetFee sets the transaction's fee. It will overwrite any existing fee set. +func (tx *Transaction) SetFee(fee sdk.Fee) { + tx.Fee = auth.NewStdFee(fee.GetGas(), fee.GetAmount()) +} + +// GetMemo returns the transaction's memo. +func (tx Transaction) GetMemo() string { + return tx.Memo +} + +// SetMemo sets the transaction's memo. It will overwrite any existing memo set. +func (tx *Transaction) SetMemo(memo string) { + tx.Memo = memo +} + // CanonicalSignBytes returns the canonical JSON bytes to sign over for the // Transaction given a chain ID, account sequence and account number. The JSON // encoding ensures all field names adhere to their proto definition, default // values are omitted, and follows the JSON Canonical Form. -func (tx Transaction) CanonicalSignBytes(cid string, a, s uint64) ([]byte, error) { - return NewSignDoc(a, s, cid, tx.Base.Memo, tx.Base.Fee, tx.Msgs...).CanonicalSignBytes() +func (tx Transaction) CanonicalSignBytes(cid string, num, seq uint64) ([]byte, error) { + return NewSignDoc(num, seq, cid, tx.Memo, tx.Fee, tx.Msgs...).CanonicalSignBytes() } -func NewSignDoc(a, s uint64, cid, m string, f auth.StdFee, msgs ...Message) *SignDoc { +func NewSignDoc(num, seq uint64, cid, memo string, fee auth.StdFee, msgs ...Message) *SignDoc { return &SignDoc{ - StdSignDocBase: auth.StdSignDocBase{ - ChainID: cid, - AccountNumber: a, - Sequence: s, - Memo: m, - Fee: f, - }, - Msgs: msgs, + StdSignDocBase: auth.NewStdSignDocBase(num, seq, cid, memo, fee), + Msgs: msgs, } } diff --git a/codec/std/tx_test.go b/codec/std/tx_test.go new file mode 100644 index 0000000000..5fce75a67e --- /dev/null +++ b/codec/std/tx_test.go @@ -0,0 +1,38 @@ +package std_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/codec/std" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" +) + +func TestTransaction(t *testing.T) { + f := auth.NewStdFee(100, sdk.NewCoins(sdk.NewInt64Coin("stake", 50))) + m := "hello world" + acc1 := sdk.AccAddress("from") + acc2 := sdk.AccAddress("to") + msg1 := bank.NewMsgSend(acc1, acc2, sdk.NewCoins(sdk.NewInt64Coin("stake", 100000))) + sdkMsgs := []sdk.Msg{&msg1} + + tx, err := std.NewTransaction(f, m, sdkMsgs) + require.NoError(t, err) + require.NotNil(t, tx) + require.Equal(t, tx.GetMsgs(), sdkMsgs) + require.Equal(t, tx.GetSigners(), []sdk.AccAddress{acc1}) + require.Equal(t, tx.GetFee(), f) + require.Equal(t, tx.GetMemo(), m) + + // no signatures; validation should fail + require.Empty(t, tx.GetSignatures()) + require.Error(t, tx.ValidateBasic()) + + signDocJSON := `{"base":{"accountNumber":"1","chainId":"chain-test","fee":{"amount":[{"amount":"50","denom":"stake"}],"gas":"100"},"memo":"hello world","sequence":"21"},"msgs":[{"msgSend":{"amount":[{"amount":"100000","denom":"stake"}],"fromAddress":"cosmos1veex7mgzt83cu","toAddress":"cosmos1w3hsjttrfq"}}]}` + bz, err := tx.CanonicalSignBytes("chain-test", 1, 21) + require.NoError(t, err) + require.Equal(t, signDocJSON, string(bz)) +}