Merge PR #5795: Proto Transaction Migration

This commit is contained in:
Alexander Bezobchuk 2020-03-17 18:59:34 -04:00 committed by GitHub
commit f31b625bca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 3877 additions and 332 deletions

View File

@ -14,6 +14,7 @@ import (
rpcclient "github.com/tendermint/tendermint/rpc/client"
"github.com/cosmos/cosmos-sdk/client/flags"
clientx "github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -25,6 +26,8 @@ type CLIContext struct {
FromAddress sdk.AccAddress
Client rpcclient.Client
ChainID string
TxGenerator clientx.Generator
Marshaler codec.Marshaler
Keybase keys.Keybase
Input io.Reader
Output io.Writer
@ -36,13 +39,15 @@ type CLIContext struct {
BroadcastMode string
Verifier tmlite.Verifier
FromName string
Codec *codec.Codec
TrustNode bool
UseLedger bool
Simulate bool
GenerateOnly bool
Indent bool
SkipConfirm bool
// TODO: Deprecated (remove).
Codec *codec.Codec
}
// NewCLIContextWithInputAndFrom returns a new initialized CLIContext with parameters from the
@ -130,7 +135,20 @@ func (ctx CLIContext) WithInput(r io.Reader) CLIContext {
return ctx
}
// WithTxGenerator returns a copy of the CLIContext with an updated TxGenerator.
func (ctx CLIContext) WithTxGenerator(txg clientx.Generator) CLIContext {
ctx.TxGenerator = txg
return ctx
}
// WithMarshaler returns a copy of the CLIContext with an updated Marshaler.
func (ctx CLIContext) WithMarshaler(m codec.Marshaler) CLIContext {
ctx.Marshaler = m
return ctx
}
// WithCodec returns a copy of the context with an updated codec.
// TODO: Deprecated (remove).
func (ctx CLIContext) WithCodec(cdc *codec.Codec) CLIContext {
ctx.Codec = cdc
return ctx

38
client/tx/tx.go Normal file
View File

@ -0,0 +1,38 @@
package tx
import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type (
// Generator defines an interface a client can utilize to generate an
// application-defined concrete transaction type. The type returned must
// implement ClientTx.
Generator interface {
NewTx() ClientTx
}
// ClientTx defines an interface which an application-defined concrete transaction
// type must implement. Namely, it must be able to set messages, generate
// signatures, and provide canonical bytes to sign over. The transaction must
// also know how to encode itself.
ClientTx interface {
sdk.Tx
codec.ProtoMarshaler
SetMsgs(...sdk.Msg) error
GetSignatures() []sdk.Signature
SetSignatures(...sdk.Signature)
GetFee() sdk.Fee
SetFee(sdk.Fee)
GetMemo() string
SetMemo(string)
// CanonicalSignBytes returns the canonical JSON bytes to sign over, given a
// chain ID, along with an account and sequence number. The JSON encoding
// ensures all field names adhere to their proto definition, default values
// are omitted, and follows the JSON Canonical Form.
CanonicalSignBytes(cid string, num, seq uint64) ([]byte, error)
}
)

File diff suppressed because it is too large Load Diff

View File

@ -5,12 +5,16 @@ import "third_party/proto/cosmos-proto/cosmos.proto";
import "third_party/proto/gogoproto/gogo.proto";
import "x/auth/types/types.proto";
import "x/auth/vesting/types/types.proto";
import "x/bank/types/types.proto";
import "x/crisis/types/types.proto";
import "x/distribution/types/types.proto";
import "x/supply/types/types.proto";
import "x/evidence/types/types.proto";
import "x/gov/types/types.proto";
import "x/slashing/types/types.proto";
import "x/staking/types/types.proto";
import "x/params/types/proposal/types.proto";
import "x/upgrade/types/types.proto";
import "x/distribution/types/types.proto";
option go_package = "github.com/cosmos/cosmos-sdk/codec/std";
@ -57,8 +61,8 @@ message MsgSubmitEvidence {
option (gogoproto.equal) = true;
option (gogoproto.goproto_getters) = false;
Evidence evidence = 1;
cosmos_sdk.x.evidence.v1.MsgSubmitEvidenceBase base = 2 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
cosmos_sdk.x.evidence.v1.MsgSubmitEvidenceBase base = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
Evidence evidence = 2;
}
// MsgSubmitProposal defines the application-level message type for handling
@ -95,3 +99,49 @@ message Content {
cosmos_sdk.x.distribution.v1.CommunityPoolSpendProposal community_pool_spend = 5;
}
}
// Transaction defines the application-level transaction that can be signed and
// processed by the state-machine. It contains a base of common fields and
// repeated set of Message types.
message Transaction {
option (gogoproto.goproto_getters) = false;
cosmos_sdk.x.auth.v1.StdTxBase base = 1
[(gogoproto.jsontag) = "", (gogoproto.embed) = true, (gogoproto.nullable) = false];
repeated Message msgs = 2 [(gogoproto.nullable) = false];
}
// Message defines the set of valid concrete message types that can be used to
// construct a transaction.
message Message {
option (cosmos_proto.interface_type) = "github.com/cosmos/cosmos-sdk/types.Msg";
// sum defines the set of all allowed valid messages defined in modules.
oneof sum {
cosmos_sdk.x.bank.v1.MsgSend msg_send = 1;
cosmos_sdk.x.bank.v1.MsgMultiSend msg_multi_send = 2;
cosmos_sdk.x.crisis.v1.MsgVerifyInvariant msg_verify_invariant = 3;
cosmos_sdk.x.distribution.v1.MsgSetWithdrawAddress msg_set_withdraw_address = 4;
cosmos_sdk.x.distribution.v1.MsgWithdrawDelegatorReward msg_withdraw_delegator_reward = 5;
cosmos_sdk.x.distribution.v1.MsgWithdrawValidatorCommission msg_withdraw_validator_commission = 6;
cosmos_sdk.x.distribution.v1.MsgFundCommunityPool msg_fund_community_pool = 7;
MsgSubmitEvidence msg_submit_evidence = 8;
MsgSubmitProposal msg_submit_proposal = 9;
cosmos_sdk.x.gov.v1.MsgVote msg_vote = 10;
cosmos_sdk.x.gov.v1.MsgDeposit msg_deposit = 11;
cosmos_sdk.x.slashing.v1.MsgUnjail msg_unjail = 12;
cosmos_sdk.x.staking.v1.MsgCreateValidator msg_create_validator = 13;
cosmos_sdk.x.staking.v1.MsgEditValidator msg_edit_validator = 14;
cosmos_sdk.x.staking.v1.MsgDelegate msg_delegate = 15;
cosmos_sdk.x.staking.v1.MsgBeginRedelegate msg_begin_redelegate = 16;
cosmos_sdk.x.staking.v1.MsgUndelegate msg_undelegate = 17;
}
}
// SignDoc defines a standard application-level signing document to compose
// signatures for a Transaction.
message SignDoc {
cosmos_sdk.x.auth.v1.StdSignDocBase base = 1
[(gogoproto.jsontag) = "", (gogoproto.embed) = true, (gogoproto.nullable) = false];
repeated Message msgs = 2 [(gogoproto.nullable) = false];
}

42
codec/std/msgs_test.go Normal file
View File

@ -0,0 +1,42 @@
package std_test
import (
"testing"
"time"
"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/evidence"
"github.com/cosmos/cosmos-sdk/x/gov"
)
func TestNewMsgSubmitEvidence(t *testing.T) {
s := sdk.AccAddress("foo")
e := evidence.Equivocation{
Height: 100,
Time: time.Now().UTC(),
Power: 40000000000,
ConsensusAddress: sdk.ConsAddress("test"),
}
msg, err := std.NewMsgSubmitEvidence(e, s)
require.NoError(t, err)
require.Equal(t, msg.GetEvidence(), &e)
require.Equal(t, msg.GetSubmitter(), s)
require.NoError(t, msg.ValidateBasic())
}
func TestNewNewMsgSubmitProposal(t *testing.T) {
p := sdk.AccAddress("foo")
d := sdk.NewCoins(sdk.NewInt64Coin("stake", 1000))
c := gov.TextProposal{Title: "title", Description: "description"}
msg, err := std.NewMsgSubmitProposal(c, d, p)
require.NoError(t, err)
require.Equal(t, msg.GetContent(), &c)
require.Equal(t, msg.GetProposer(), p)
require.Equal(t, msg.GetInitialDeposit(), d)
require.NoError(t, msg.ValidateBasic())
}

174
codec/std/tx.go Normal file
View File

@ -0,0 +1,174 @@
package std
import (
clientx "github.com/cosmos/cosmos-sdk/client/tx"
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)(nil)
_ clientx.ClientTx = (*Transaction)(nil)
_ clientx.Generator = TxGenerator{}
)
// TxGenerator defines a transaction generator that allows clients to construct
// transactions.
type TxGenerator struct{}
// NewTx returns a reference to an empty Transaction type.
func (TxGenerator) NewTx() clientx.ClientTx {
return &Transaction{}
}
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 {
msgs := make([]sdk.Msg, len(tx.Msgs))
for i, m := range tx.Msgs {
msgs[i] = m.GetMsg()
}
return msgs
}
// GetSigners returns the addresses that must sign the transaction. Addresses are
// returned in a deterministic order. They are accumulated from the GetSigners
// method for each Msg in the order they appear in tx.GetMsgs(). Duplicate addresses
// will be omitted.
func (tx Transaction) GetSigners() []sdk.AccAddress {
var signers []sdk.AccAddress
seen := map[string]bool{}
for _, msg := range tx.GetMsgs() {
for _, addr := range msg.GetSigners() {
if !seen[addr.String()] {
signers = append(signers, addr)
seen[addr.String()] = true
}
}
}
return signers
}
// ValidateBasic does a simple and lightweight validation check that doesn't
// require access to any other information.
func (tx Transaction) ValidateBasic() error {
stdSigs := tx.GetSignatures()
if tx.Fee.Gas > auth.MaxGasWanted {
return sdkerrors.Wrapf(
sdkerrors.ErrInvalidRequest, "invalid gas supplied; %d > %d", tx.Fee.Gas, auth.MaxGasWanted,
)
}
if tx.Fee.Amount.IsAnyNegative() {
return sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFee, "invalid fee provided: %s", tx.Fee.Amount,
)
}
if len(stdSigs) == 0 {
return sdkerrors.ErrNoSignatures
}
if len(stdSigs) != len(tx.GetSigners()) {
return sdkerrors.Wrapf(
sdkerrors.ErrUnauthorized, "wrong number of signers; expected %d, got %d", tx.GetSigners(), len(stdSigs),
)
}
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, num, seq uint64) ([]byte, error) {
return NewSignDoc(num, seq, cid, tx.Memo, tx.Fee, tx.Msgs...).CanonicalSignBytes()
}
func NewSignDoc(num, seq uint64, cid, memo string, fee auth.StdFee, msgs ...Message) *SignDoc {
return &SignDoc{
StdSignDocBase: auth.NewStdSignDocBase(num, seq, cid, memo, fee),
Msgs: msgs,
}
}
// CanonicalSignBytes returns the canonical JSON bytes to sign over, where the
// SignDoc is derived from a Transaction. The JSON encoding ensures all field
// names adhere to their proto definition, default values are omitted, and follows
// the JSON Canonical Form.
func (sd *SignDoc) CanonicalSignBytes() ([]byte, error) {
return sdk.CanonicalSignBytes(sd)
}

38
codec/std/tx_test.go Normal file
View File

@ -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))
}

View File

@ -3,6 +3,7 @@
## Changelog
- 2020 March 06: Initial Draft
- 2020 March 12: API Updates
## Status
@ -43,9 +44,9 @@ message Message {
option (cosmos_proto.interface_type) = "github.com/cosmos/cosmos-sdk/types.Msg";
oneof sum {
bank.MsgSend = 1;
staking.MsgCreateValidator = 2;
staking.MsgDelegate = 3;
cosmos_sdk.x.bank.v1.MsgSend msg_send = 1;
cosmos_sdk.x.bank.v1.MsgMultiSend msg_multi_send = 2;
cosmos_sdk.x.crisis.v1.MsgVerifyInvariant msg_verify_invariant = 3;
// ...
}
}
@ -61,10 +62,8 @@ Example:
// app/codec/codec.proto
message Transaction {
option (cosmos_proto.interface_type) = "github.com/cosmos/cosmos-sdk/types.Tx";
StdTxBase base = 1;
repeated Message msgs = 2;
cosmos_sdk.x.auth.v1.StdTxBase base = 1;
repeated Message msgs = 2;
}
```
@ -80,7 +79,8 @@ to provide canonical representation of a `Transaction` to sign over, clients mus
obey the following rules:
- Encode `SignDoc` (see below) via [Protobuf's canonical JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json).
- Default and zero values must be stripped from the output (`0`, `“”`, `null`, `false`, `[]`, and `{}`).
- Default must be stripped from the output!
- JSON keys adhere to their Proto-defined field names.
- Generate canonical JSON to sign via the [JSON Canonical Form Spec](https://gibson042.github.io/canonicaljson-spec/).
- This spec should be trivial to interpret and implement in any language.
@ -103,9 +103,8 @@ to handle all the types, but also knows how to generate transactions, signatures
and messages.
```go
type TxGenerator interface {
type Generator interface {
NewTx() ClientTx
SignBytes func(chainID string, num, seq uint64, fee StdFee, msgs []sdk.Msg, memo string) ([]byte, error)
}
type ClientTx interface {
@ -113,27 +112,22 @@ type ClientTx interface {
codec.ProtoMarshaler
SetMsgs(...sdk.Msg) error
GetSignatures() []StdSignature
SetSignatures(...StdSignature) error
GetFee() StdFee
SetFee(StdFee)
GetSignatures() []sdk.Signature
SetSignatures(...sdk.Signature)
GetFee() sdk.Fee
SetFee(sdk.Fee)
GetMemo() string
SetMemo(string)
CanonicalSignBytes(cid string, num, seq uint64) ([]byte, error)
}
```
We then extend `codec.Marshaler` to also require fulfillment of `TxGenerator`.
We then update `CLIContext` to have two new fields: `Generator` and `Marshler`.
```go
type ClientMarshaler interface {
TxGenerator
codec.Marshaler
}
```
Then, each module will at the minimum accept a `ClientMarshaler` instead of a concrete
Then, each module will at the minimum accept a `Marshaler` instead of a concrete
Amino codec. If the module needs to work with any interface types, it will use
the `Codec` interface defined by the module which also extends `ClientMarshaler`.
the `Codec` interface defined by the module which also extends `Marshaler`.
## Future Improvements

4
go.mod
View File

@ -7,9 +7,10 @@ require (
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d
github.com/cosmos/ledger-cosmos-go v0.11.1
github.com/gibson042/canonicaljson-go v1.0.3
github.com/gogo/protobuf v1.3.1
github.com/golang/mock v1.4.3
github.com/golang/protobuf v1.3.5
github.com/golang/protobuf v1.4.0-rc.4
github.com/gorilla/handlers v1.4.2
github.com/gorilla/mux v1.7.4
github.com/hashicorp/golang-lru v0.5.4
@ -30,6 +31,7 @@ require (
github.com/tendermint/iavl v0.13.1
github.com/tendermint/tendermint v0.33.2
github.com/tendermint/tm-db v0.5.0
google.golang.org/protobuf v1.20.1 // indirect
gopkg.in/yaml.v2 v2.2.8
)

19
go.sum
View File

@ -111,6 +111,8 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gibson042/canonicaljson-go v1.0.3 h1:EAyF8L74AWabkyUmrvEFHEt/AGFQeD6RfwbAuf0j1bI=
github.com/gibson042/canonicaljson-go v1.0.3/go.mod h1:DsLpJTThXyGNO+KZlI85C1/KDcImpP67k/RKVjcaEqo=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
@ -130,8 +132,6 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.4.2 h1:fXIkPzOBCwDUPvYmOPzETABgbqpYlYNigQ2o64eMr5c=
github.com/golang/mock v1.4.2/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -140,8 +140,11 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4 h1:+EOh4OY6tjM6ZueeUKinl1f0U2820HzQOuf1iqMnsks=
github.com/golang/protobuf v1.4.0-rc.4/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@ -558,6 +561,12 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.20.1 h1:ESRXHgpUBG5D2I5mmsQIyYxB/tQIZfSZ8wLyFDf/N/U=
google.golang.org/protobuf v1.20.1/go.mod h1:KqelGeouBkcbcuB3HCk4/YH2tmNLk6YSWA5LIWeI/lY=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -585,9 +594,7 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=

View File

@ -39,7 +39,7 @@ func GenTx(msgs []sdk.Msg, feeAmt sdk.Coins, gas uint64, chainID string, accnums
}
sigs[i] = auth.StdSignature{
PubKey: p.PubKey(),
PubKey: p.PubKey().Bytes(),
Signature: sig,
}
}

View File

@ -1,6 +1,11 @@
package types
import (
"bytes"
jsonc "github.com/gibson042/canonicaljson-go"
"github.com/gogo/protobuf/jsonpb"
"github.com/cosmos/cosmos-sdk/codec"
)
@ -9,3 +14,27 @@ func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterInterface((*Msg)(nil), nil)
cdc.RegisterInterface((*Tx)(nil), nil)
}
// CanonicalSignBytes returns a canonical JSON encoding of a Proto message that
// can be signed over. The JSON encoding ensures all field names adhere to their
// Proto definition, default values are omitted, and follows the JSON Canonical
// Form.
func CanonicalSignBytes(m codec.ProtoMarshaler) ([]byte, error) {
jm := &jsonpb.Marshaler{EmitDefaults: false, OrigName: false}
buf := new(bytes.Buffer)
// first, encode via canonical Protocol Buffer JSON
if err := jm.Marshal(buf, m); err != nil {
return nil, err
}
genericJSON := make(map[string]interface{})
// decode canonical proto encoding into a generic map
if err := jsonc.Unmarshal(buf.Bytes(), &genericJSON); err != nil {
return nil, err
}
// finally, return the canonical JSON encoding via JSON Canonical Form
return jsonc.Marshal(genericJSON)
}

View File

@ -2,45 +2,59 @@ package types
import (
"encoding/json"
"github.com/tendermint/tendermint/crypto"
)
// Transactions messages must fulfill the Msg
type Msg interface {
type (
// Msg defines the interface a transaction message must fulfill.
Msg interface {
// Return the message type.
// Must be alphanumeric or empty.
Route() string
// Return the message type.
// Must be alphanumeric or empty.
Route() string
// Returns a human-readable string for the message, intended for utilization
// within tags
Type() string
// Returns a human-readable string for the message, intended for utilization
// within tags
Type() string
// ValidateBasic does a simple validation check that
// doesn't require access to any other information.
ValidateBasic() error
// ValidateBasic does a simple validation check that
// doesn't require access to any other information.
ValidateBasic() error
// Get the canonical byte representation of the Msg.
GetSignBytes() []byte
// Get the canonical byte representation of the Msg.
GetSignBytes() []byte
// Signers returns the addrs of signers that must sign.
// CONTRACT: All signatures must be present to be valid.
// CONTRACT: Returns addrs in some deterministic order.
GetSigners() []AccAddress
}
// Signers returns the addrs of signers that must sign.
// CONTRACT: All signatures must be present to be valid.
// CONTRACT: Returns addrs in some deterministic order.
GetSigners() []AccAddress
}
//__________________________________________________________
// Fee defines an interface for an application application-defined concrete
// transaction type to be able to set and return the transaction fee.
Fee interface {
GetGas() uint64
GetAmount() Coins
}
// Transactions objects must fulfill the Tx
type Tx interface {
// Gets the all the transaction's messages.
GetMsgs() []Msg
// Signature defines an interface for an application application-defined
// concrete transaction type to be able to set and return transaction signatures.
Signature interface {
GetPubKey() crypto.PubKey
GetSignature() []byte
}
// ValidateBasic does a simple and lightweight validation check that doesn't
// require access to any other information.
ValidateBasic() error
}
// Tx defines the interface a transaction must fulfill.
Tx interface {
// Gets the all the transaction's messages.
GetMsgs() []Msg
//__________________________________________________________
// ValidateBasic does a simple and lightweight validation check that doesn't
// require access to any other information.
ValidateBasic() error
}
)
// TxDecoder unmarshals transaction bytes
type TxDecoder func(txBytes []byte) (Tx, error)

View File

@ -22,6 +22,7 @@ const (
DefaultSigVerifyCostSecp256k1 = types.DefaultSigVerifyCostSecp256k1
QueryAccount = types.QueryAccount
QueryParams = types.QueryParams
MaxGasWanted = types.MaxGasWanted
)
var (
@ -58,6 +59,9 @@ var (
MakeSignature = types.MakeSignature
ValidateGenAccounts = types.ValidateGenAccounts
GetGenesisStateFromAppState = types.GetGenesisStateFromAppState
NewStdSignature = types.NewStdSignature
NewStdTxBase = types.NewStdTxBase
NewStdSignDocBase = types.NewStdSignDocBase
// variable aliases
ModuleCdc = types.ModuleCdc
@ -87,4 +91,6 @@ type (
TxBuilder = types.TxBuilder
GenesisAccountIterator = types.GenesisAccountIterator
Codec = types.Codec
StdSignDocBase = types.StdSignDocBase
StdTxBase = types.StdTxBase
)

View File

@ -127,7 +127,7 @@ func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
// use stdsignature to mock the size of a full signature
simSig := types.StdSignature{
Signature: simSecp256k1Sig[:],
PubKey: pubkey,
PubKey: pubkey.Bytes(),
}
sigBz := codec.Cdc.MustMarshalBinaryBare(simSig)

View File

@ -106,15 +106,15 @@ func makeMultiSignCmd(cdc *codec.Codec) func(cmd *cobra.Command, args []string)
txBldr.ChainID(), txBldr.AccountNumber(), txBldr.Sequence(),
stdTx.Fee, stdTx.GetMsgs(), stdTx.GetMemo(),
)
if ok := stdSig.PubKey.VerifyBytes(sigBytes, stdSig.Signature); !ok {
if ok := stdSig.GetPubKey().VerifyBytes(sigBytes, stdSig.Signature); !ok {
return fmt.Errorf("couldn't verify signature")
}
if err := multisigSig.AddSignatureFromPubKey(stdSig.Signature, stdSig.PubKey, multisigPub.PubKeys); err != nil {
if err := multisigSig.AddSignatureFromPubKey(stdSig.Signature, stdSig.GetPubKey(), multisigPub.PubKeys); err != nil {
return err
}
}
newStdSig := types.StdSignature{Signature: cdc.MustMarshalBinaryBare(multisigSig), PubKey: multisigPub}
newStdSig := types.StdSignature{Signature: cdc.MustMarshalBinaryBare(multisigSig), PubKey: multisigPub.Bytes()}
newTx := types.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, []types.StdSignature{newStdSig}, stdTx.GetMemo())
sigOnly := viper.GetBool(flagSigOnly)

View File

@ -208,7 +208,7 @@ func printAndValidateSigs(
}
for i, sig := range sigs {
sigAddr := sdk.AccAddress(sig.Address())
sigAddr := sdk.AccAddress(sig.GetPubKey().Address())
sigSanity := "OK"
var (
@ -235,13 +235,13 @@ func printAndValidateSigs(
stdTx.Fee, stdTx.GetMsgs(), stdTx.GetMemo(),
)
if ok := sig.VerifyBytes(sigBytes, sig.Signature); !ok {
if ok := sig.GetPubKey().VerifyBytes(sigBytes, sig.Signature); !ok {
sigSanity = "ERROR: signature invalid"
success = false
}
}
multiPK, ok := sig.PubKey.(multisig.PubKeyMultisigThreshold)
multiPK, ok := sig.GetPubKey().(multisig.PubKeyMultisigThreshold)
if ok {
var multiSig multisig.Multisignature
cliCtx.Codec.MustUnmarshalBinaryBare(sig.Signature, &multiSig)

View File

@ -14,11 +14,137 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/exported"
)
var (
_ sdk.Tx = (*StdTx)(nil)
// MaxGasWanted defines the max gas allowed.
const MaxGasWanted = uint64((1 << 63) - 1)
maxGasWanted = uint64((1 << 63) - 1)
)
// NewStdFee returns a new instance of StdFee
func NewStdFee(gas uint64, amount sdk.Coins) StdFee {
return StdFee{
Amount: amount,
Gas: gas,
}
}
// GetGas returns the fee's (wanted) gas.
func (fee StdFee) GetGas() uint64 {
return fee.Gas
}
// GetAmount returns the fee's amount.
func (fee StdFee) GetAmount() sdk.Coins {
return fee.Amount
}
// Bytes returns the encoded bytes of a StdFee.
func (fee StdFee) Bytes() []byte {
if len(fee.Amount) == 0 {
fee.Amount = sdk.NewCoins()
}
bz, err := codec.Cdc.MarshalJSON(fee)
if err != nil {
panic(err)
}
return bz
}
// GasPrices returns the gas prices for a StdFee.
//
// NOTE: The gas prices returned are not the true gas prices that were
// originally part of the submitted transaction because the fee is computed
// as fee = ceil(gasWanted * gasPrices).
func (fee StdFee) GasPrices() sdk.DecCoins {
return sdk.NewDecCoinsFromCoins(fee.Amount...).QuoDec(sdk.NewDec(int64(fee.Gas)))
}
func NewStdSignature(pk crypto.PubKey, sig []byte) StdSignature {
return StdSignature{PubKey: pk.Bytes(), Signature: sig}
}
// GetSignature returns the raw signature bytes.
func (ss StdSignature) GetSignature() []byte {
return ss.Signature
}
// GetPubKey returns the public key of a signature as a crypto.PubKey using the
// Amino codec.
func (ss StdSignature) GetPubKey() (pk crypto.PubKey) {
if len(ss.PubKey) == 0 {
return nil
}
codec.Cdc.MustUnmarshalBinaryBare(ss.PubKey, &pk)
return pk
}
// MarshalYAML returns the YAML representation of the signature.
func (ss StdSignature) MarshalYAML() (interface{}, error) {
var (
bz []byte
pubkey string
err error
)
if ss.PubKey != nil {
pubkey, err = sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, ss.GetPubKey())
if err != nil {
return nil, err
}
}
bz, err = yaml.Marshal(struct {
PubKey string
Signature string
}{
PubKey: pubkey,
Signature: fmt.Sprintf("%X", ss.Signature),
})
if err != nil {
return nil, err
}
return string(bz), err
}
func NewStdTxBase(fee StdFee, sigs []StdSignature, memo string) StdTxBase {
return StdTxBase{
Fee: fee,
Signatures: sigs,
Memo: memo,
}
}
func NewStdSignDocBase(num, seq uint64, cid, memo string, fee StdFee) StdSignDocBase {
return StdSignDocBase{
ChainID: cid,
AccountNumber: num,
Sequence: seq,
Memo: memo,
Fee: fee,
}
}
// CountSubKeys counts the total number of keys for a multi-sig public key.
func CountSubKeys(pub crypto.PubKey) int {
v, ok := pub.(multisig.PubKeyMultisigThreshold)
if !ok {
return 1
}
numKeys := 0
for _, subkey := range v.PubKeys {
numKeys += CountSubKeys(subkey)
}
return numKeys
}
// ---------------------------------------------------------------------------
// DEPRECATED
// ---------------------------------------------------------------------------
var _ sdk.Tx = (*StdTx)(nil)
// StdTx is a standard way to wrap a Msg with Fee and Signatures.
// NOTE: the first signature is the fee payer (Signatures must not be nil).
@ -46,10 +172,10 @@ func (tx StdTx) GetMsgs() []sdk.Msg { return tx.Msgs }
func (tx StdTx) ValidateBasic() error {
stdSigs := tx.GetSignatures()
if tx.Fee.Gas > maxGasWanted {
if tx.Fee.Gas > MaxGasWanted {
return sdkerrors.Wrapf(
sdkerrors.ErrInvalidRequest,
"invalid gas supplied; %d > %d", tx.Fee.Gas, maxGasWanted,
"invalid gas supplied; %d > %d", tx.Fee.Gas, MaxGasWanted,
)
}
if tx.Fee.Amount.IsAnyNegative() {
@ -71,29 +197,15 @@ func (tx StdTx) ValidateBasic() error {
return nil
}
// CountSubKeys counts the total number of keys for a multi-sig public key.
func CountSubKeys(pub crypto.PubKey) int {
v, ok := pub.(multisig.PubKeyMultisigThreshold)
if !ok {
return 1
}
numKeys := 0
for _, subkey := range v.PubKeys {
numKeys += CountSubKeys(subkey)
}
return numKeys
}
// GetSigners returns the addresses that must sign the transaction.
// Addresses are returned in a deterministic order.
// They are accumulated from the GetSigners method for each Msg
// in the order they appear in tx.GetMsgs().
// Duplicate addresses will be omitted.
func (tx StdTx) GetSigners() []sdk.AccAddress {
seen := map[string]bool{}
var signers []sdk.AccAddress
seen := map[string]bool{}
for _, msg := range tx.GetMsgs() {
for _, addr := range msg.GetSigners() {
if !seen[addr.String()] {
@ -102,6 +214,7 @@ func (tx StdTx) GetSigners() []sdk.AccAddress {
}
}
}
return signers
}
@ -127,9 +240,11 @@ func (tx StdTx) GetSignatures() [][]byte {
// If pubkey is not included in the signature, then nil is in the slice instead
func (tx StdTx) GetPubKeys() []crypto.PubKey {
pks := make([]crypto.PubKey, len(tx.Signatures))
for i, stdSig := range tx.Signatures {
pks[i] = stdSig.PubKey
pks[i] = stdSig.GetPubKey()
}
return pks
}
@ -163,43 +278,6 @@ func (tx StdTx) FeePayer() sdk.AccAddress {
return sdk.AccAddress{}
}
// NewStdFee returns a new instance of StdFee
func NewStdFee(gas uint64, amount sdk.Coins) StdFee {
return StdFee{
Amount: amount,
Gas: gas,
}
}
// Bytes for signing later
func (fee StdFee) Bytes() []byte {
// normalize. XXX
// this is a sign of something ugly
// (in the lcd_test, client side its null,
// server side its [])
if len(fee.Amount) == 0 {
fee.Amount = sdk.NewCoins()
}
bz, err := codec.Cdc.MarshalJSON(fee) // TODO
if err != nil {
panic(err)
}
return bz
}
// GasPrices returns the gas prices for a StdFee.
//
// NOTE: The gas prices returned are not the true gas prices that were
// originally part of the submitted transaction because the fee is computed
// as fee = ceil(gasWanted * gasPrices).
func (fee StdFee) GasPrices() sdk.DecCoins {
return sdk.NewDecCoinsFromCoins(fee.Amount...).QuoDec(sdk.NewDec(int64(fee.Gas)))
}
//__________________________________________________________
// StdSignDoc is replay-prevention structure.
// It includes the result of msg.GetSignBytes(),
// as well as the ChainID (prevent cross chain replay)
@ -237,12 +315,6 @@ func StdSignBytes(chainID string, accnum uint64, sequence uint64, fee StdFee, ms
return sdk.MustSortJSON(bz)
}
// StdSignature represents a sig
type StdSignature struct {
crypto.PubKey `json:"pub_key" yaml:"pub_key"` // optional
Signature []byte `json:"signature" yaml:"signature"`
}
// DefaultTxDecoder logic for standard transaction decoding
func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) {
@ -269,32 +341,3 @@ func DefaultTxEncoder(cdc *codec.Codec) sdk.TxEncoder {
return cdc.MarshalBinaryBare(tx)
}
}
// MarshalYAML returns the YAML representation of the signature.
func (ss StdSignature) MarshalYAML() (interface{}, error) {
var (
bz []byte
pubkey string
err error
)
if ss.PubKey != nil {
pubkey, err = sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, ss.PubKey)
if err != nil {
return nil, err
}
}
bz, err = yaml.Marshal(struct {
PubKey string
Signature string
}{
PubKey: pubkey,
Signature: fmt.Sprintf("%s", ss.Signature),
})
if err != nil {
return nil, err
}
return string(bz), err
}

View File

@ -152,11 +152,11 @@ func TestStdSignatureMarshalYAML(t *testing.T) {
"|\n pubkey: \"\"\n signature: \"\"\n",
},
{
StdSignature{PubKey: pubKey, Signature: []byte("dummySig")},
fmt.Sprintf("|\n pubkey: %s\n signature: dummySig\n", sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, pubKey)),
StdSignature{PubKey: pubKey.Bytes(), Signature: []byte("dummySig")},
fmt.Sprintf("|\n pubkey: %s\n signature: 64756D6D79536967\n", sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, pubKey)),
},
{
StdSignature{PubKey: pubKey, Signature: nil},
StdSignature{PubKey: pubKey.Bytes(), Signature: nil},
fmt.Sprintf("|\n pubkey: %s\n signature: \"\"\n", sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, pubKey)),
},
}

View File

@ -42,7 +42,7 @@ func NewTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey, accNums
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
sigs[i] = StdSignature{PubKey: priv.PubKey().Bytes(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, "")
@ -59,7 +59,7 @@ func NewTestTxWithMemo(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey,
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
sigs[i] = StdSignature{PubKey: priv.PubKey().Bytes(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, memo)
@ -74,7 +74,7 @@ func NewTestTxWithSignBytes(msgs []sdk.Msg, privs []crypto.PrivKey, accNums []ui
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
sigs[i] = StdSignature{PubKey: priv.PubKey().Bytes(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, memo)

View File

@ -286,8 +286,9 @@ func MakeSignature(keybase keys.Keybase, name, passphrase string,
if err != nil {
return
}
return StdSignature{
PubKey: pubkey,
PubKey: pubkey.Bytes(),
Signature: sigBytes,
}, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -23,13 +23,23 @@ message BaseAccount {
// gas to be used by the transaction. The ratio yields an effective "gasprice",
// which must be above some miminum to be accepted into the mempool.
message StdFee {
option (gogoproto.equal) = true;
option (gogoproto.goproto_getters) = false;
option (gogoproto.equal) = true;
repeated cosmos_sdk.v1.Coin amount = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
uint64 gas = 2;
}
// StdSignature defines a signature structure that contains the signature of a
// transaction and an optional public key.
message StdSignature {
option (gogoproto.goproto_getters) = false;
bytes pub_key = 1 [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""];
bytes signature = 2;
}
// Params defines the parameters for the auth module.
message Params {
option (gogoproto.equal) = true;
@ -43,3 +53,21 @@ message Params {
uint64 sig_verify_cost_secp256k1 = 5
[(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""];
}
// StdTxBase defines a transaction base which application-level concrete transaction
// types can extend.
message StdTxBase {
StdFee fee = 1 [(gogoproto.nullable) = false];
repeated StdSignature signatures = 2 [(gogoproto.nullable) = false];
string memo = 3;
}
// StdSignDocBase defines the base structure for which applications can extend
// to define the concrete structure that signers sign over.
message StdSignDocBase {
string chain_id = 1 [(gogoproto.customname) = "ChainID", (gogoproto.moretags) = "yaml:\"chain_id\""];
uint64 account_number = 2 [(gogoproto.moretags) = "yaml:\"account_number\""];
uint64 sequence = 3;
string memo = 4;
StdFee fee = 5 [(gogoproto.nullable) = false];
}