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" rpcclient "github.com/tendermint/tendermint/rpc/client"
"github.com/cosmos/cosmos-sdk/client/flags" "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/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/crypto/keys"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
@ -25,6 +26,8 @@ type CLIContext struct {
FromAddress sdk.AccAddress FromAddress sdk.AccAddress
Client rpcclient.Client Client rpcclient.Client
ChainID string ChainID string
TxGenerator clientx.Generator
Marshaler codec.Marshaler
Keybase keys.Keybase Keybase keys.Keybase
Input io.Reader Input io.Reader
Output io.Writer Output io.Writer
@ -36,13 +39,15 @@ type CLIContext struct {
BroadcastMode string BroadcastMode string
Verifier tmlite.Verifier Verifier tmlite.Verifier
FromName string FromName string
Codec *codec.Codec
TrustNode bool TrustNode bool
UseLedger bool UseLedger bool
Simulate bool Simulate bool
GenerateOnly bool GenerateOnly bool
Indent bool Indent bool
SkipConfirm bool SkipConfirm bool
// TODO: Deprecated (remove).
Codec *codec.Codec
} }
// NewCLIContextWithInputAndFrom returns a new initialized CLIContext with parameters from the // NewCLIContextWithInputAndFrom returns a new initialized CLIContext with parameters from the
@ -130,7 +135,20 @@ func (ctx CLIContext) WithInput(r io.Reader) CLIContext {
return ctx 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. // WithCodec returns a copy of the context with an updated codec.
// TODO: Deprecated (remove).
func (ctx CLIContext) WithCodec(cdc *codec.Codec) CLIContext { func (ctx CLIContext) WithCodec(cdc *codec.Codec) CLIContext {
ctx.Codec = cdc ctx.Codec = cdc
return ctx 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 "third_party/proto/gogoproto/gogo.proto";
import "x/auth/types/types.proto"; import "x/auth/types/types.proto";
import "x/auth/vesting/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/supply/types/types.proto";
import "x/evidence/types/types.proto"; import "x/evidence/types/types.proto";
import "x/gov/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/params/types/proposal/types.proto";
import "x/upgrade/types/types.proto"; import "x/upgrade/types/types.proto";
import "x/distribution/types/types.proto";
option go_package = "github.com/cosmos/cosmos-sdk/codec/std"; option go_package = "github.com/cosmos/cosmos-sdk/codec/std";
@ -57,8 +61,8 @@ message MsgSubmitEvidence {
option (gogoproto.equal) = true; option (gogoproto.equal) = true;
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
Evidence evidence = 1; cosmos_sdk.x.evidence.v1.MsgSubmitEvidenceBase base = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
cosmos_sdk.x.evidence.v1.MsgSubmitEvidenceBase base = 2 [(gogoproto.nullable) = false, (gogoproto.embed) = true]; Evidence evidence = 2;
} }
// MsgSubmitProposal defines the application-level message type for handling // 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; 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 ## Changelog
- 2020 March 06: Initial Draft - 2020 March 06: Initial Draft
- 2020 March 12: API Updates
## Status ## Status
@ -43,9 +44,9 @@ message Message {
option (cosmos_proto.interface_type) = "github.com/cosmos/cosmos-sdk/types.Msg"; option (cosmos_proto.interface_type) = "github.com/cosmos/cosmos-sdk/types.Msg";
oneof sum { oneof sum {
bank.MsgSend = 1; cosmos_sdk.x.bank.v1.MsgSend msg_send = 1;
staking.MsgCreateValidator = 2; cosmos_sdk.x.bank.v1.MsgMultiSend msg_multi_send = 2;
staking.MsgDelegate = 3; cosmos_sdk.x.crisis.v1.MsgVerifyInvariant msg_verify_invariant = 3;
// ... // ...
} }
} }
@ -61,10 +62,8 @@ Example:
// app/codec/codec.proto // app/codec/codec.proto
message Transaction { message Transaction {
option (cosmos_proto.interface_type) = "github.com/cosmos/cosmos-sdk/types.Tx"; cosmos_sdk.x.auth.v1.StdTxBase base = 1;
repeated Message msgs = 2;
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: obey the following rules:
- Encode `SignDoc` (see below) via [Protobuf's canonical JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json). - 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/). - 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. - 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. and messages.
```go ```go
type TxGenerator interface { type Generator interface {
NewTx() ClientTx NewTx() ClientTx
SignBytes func(chainID string, num, seq uint64, fee StdFee, msgs []sdk.Msg, memo string) ([]byte, error)
} }
type ClientTx interface { type ClientTx interface {
@ -113,27 +112,22 @@ type ClientTx interface {
codec.ProtoMarshaler codec.ProtoMarshaler
SetMsgs(...sdk.Msg) error SetMsgs(...sdk.Msg) error
GetSignatures() []StdSignature GetSignatures() []sdk.Signature
SetSignatures(...StdSignature) error SetSignatures(...sdk.Signature)
GetFee() StdFee GetFee() sdk.Fee
SetFee(StdFee) SetFee(sdk.Fee)
GetMemo() string GetMemo() string
SetMemo(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 Then, each module will at the minimum accept a `Marshaler` instead of a concrete
type ClientMarshaler interface {
TxGenerator
codec.Marshaler
}
```
Then, each module will at the minimum accept a `ClientMarshaler` instead of a concrete
Amino codec. If the module needs to work with any interface types, it will use 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 ## Future Improvements

4
go.mod
View File

@ -7,9 +7,10 @@ require (
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d
github.com/cosmos/ledger-cosmos-go v0.11.1 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/gogo/protobuf v1.3.1
github.com/golang/mock v1.4.3 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/handlers v1.4.2
github.com/gorilla/mux v1.7.4 github.com/gorilla/mux v1.7.4
github.com/hashicorp/golang-lru v0.5.4 github.com/hashicorp/golang-lru v0.5.4
@ -30,6 +31,7 @@ require (
github.com/tendermint/iavl v0.13.1 github.com/tendermint/iavl v0.13.1
github.com/tendermint/tendermint v0.33.2 github.com/tendermint/tendermint v0.33.2
github.com/tendermint/tm-db v0.5.0 github.com/tendermint/tm-db v0.5.0
google.golang.org/protobuf v1.20.1 // indirect
gopkg.in/yaml.v2 v2.2.8 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 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 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/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.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.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= 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-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/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.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 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 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= 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.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.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.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 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.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= 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/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/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 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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-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.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 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/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= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= 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= 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{ sigs[i] = auth.StdSignature{
PubKey: p.PubKey(), PubKey: p.PubKey().Bytes(),
Signature: sig, Signature: sig,
} }
} }

View File

@ -1,6 +1,11 @@
package types package types
import ( import (
"bytes"
jsonc "github.com/gibson042/canonicaljson-go"
"github.com/gogo/protobuf/jsonpb"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
) )
@ -9,3 +14,27 @@ func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterInterface((*Msg)(nil), nil) cdc.RegisterInterface((*Msg)(nil), nil)
cdc.RegisterInterface((*Tx)(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 ( import (
"encoding/json" "encoding/json"
"github.com/tendermint/tendermint/crypto"
) )
// Transactions messages must fulfill the Msg type (
type Msg interface { // Msg defines the interface a transaction message must fulfill.
Msg interface {
// Return the message type. // Return the message type.
// Must be alphanumeric or empty. // Must be alphanumeric or empty.
Route() string Route() string
// Returns a human-readable string for the message, intended for utilization // Returns a human-readable string for the message, intended for utilization
// within tags // within tags
Type() string Type() string
// ValidateBasic does a simple validation check that // ValidateBasic does a simple validation check that
// doesn't require access to any other information. // doesn't require access to any other information.
ValidateBasic() error ValidateBasic() error
// Get the canonical byte representation of the Msg. // Get the canonical byte representation of the Msg.
GetSignBytes() []byte GetSignBytes() []byte
// Signers returns the addrs of signers that must sign. // Signers returns the addrs of signers that must sign.
// CONTRACT: All signatures must be present to be valid. // CONTRACT: All signatures must be present to be valid.
// CONTRACT: Returns addrs in some deterministic order. // CONTRACT: Returns addrs in some deterministic order.
GetSigners() []AccAddress 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 // Signature defines an interface for an application application-defined
type Tx interface { // concrete transaction type to be able to set and return transaction signatures.
// Gets the all the transaction's messages. Signature interface {
GetMsgs() []Msg GetPubKey() crypto.PubKey
GetSignature() []byte
}
// ValidateBasic does a simple and lightweight validation check that doesn't // Tx defines the interface a transaction must fulfill.
// require access to any other information. Tx interface {
ValidateBasic() error // 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 // TxDecoder unmarshals transaction bytes
type TxDecoder func(txBytes []byte) (Tx, error) type TxDecoder func(txBytes []byte) (Tx, error)

View File

@ -22,6 +22,7 @@ const (
DefaultSigVerifyCostSecp256k1 = types.DefaultSigVerifyCostSecp256k1 DefaultSigVerifyCostSecp256k1 = types.DefaultSigVerifyCostSecp256k1
QueryAccount = types.QueryAccount QueryAccount = types.QueryAccount
QueryParams = types.QueryParams QueryParams = types.QueryParams
MaxGasWanted = types.MaxGasWanted
) )
var ( var (
@ -58,6 +59,9 @@ var (
MakeSignature = types.MakeSignature MakeSignature = types.MakeSignature
ValidateGenAccounts = types.ValidateGenAccounts ValidateGenAccounts = types.ValidateGenAccounts
GetGenesisStateFromAppState = types.GetGenesisStateFromAppState GetGenesisStateFromAppState = types.GetGenesisStateFromAppState
NewStdSignature = types.NewStdSignature
NewStdTxBase = types.NewStdTxBase
NewStdSignDocBase = types.NewStdSignDocBase
// variable aliases // variable aliases
ModuleCdc = types.ModuleCdc ModuleCdc = types.ModuleCdc
@ -87,4 +91,6 @@ type (
TxBuilder = types.TxBuilder TxBuilder = types.TxBuilder
GenesisAccountIterator = types.GenesisAccountIterator GenesisAccountIterator = types.GenesisAccountIterator
Codec = types.Codec 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 // use stdsignature to mock the size of a full signature
simSig := types.StdSignature{ simSig := types.StdSignature{
Signature: simSecp256k1Sig[:], Signature: simSecp256k1Sig[:],
PubKey: pubkey, PubKey: pubkey.Bytes(),
} }
sigBz := codec.Cdc.MustMarshalBinaryBare(simSig) 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(), txBldr.ChainID(), txBldr.AccountNumber(), txBldr.Sequence(),
stdTx.Fee, stdTx.GetMsgs(), stdTx.GetMemo(), 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") 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 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()) newTx := types.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, []types.StdSignature{newStdSig}, stdTx.GetMemo())
sigOnly := viper.GetBool(flagSigOnly) sigOnly := viper.GetBool(flagSigOnly)

View File

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

View File

@ -14,11 +14,137 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/auth/exported"
) )
var ( // MaxGasWanted defines the max gas allowed.
_ sdk.Tx = (*StdTx)(nil) 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. // 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). // 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 { func (tx StdTx) ValidateBasic() error {
stdSigs := tx.GetSignatures() stdSigs := tx.GetSignatures()
if tx.Fee.Gas > maxGasWanted { if tx.Fee.Gas > MaxGasWanted {
return sdkerrors.Wrapf( return sdkerrors.Wrapf(
sdkerrors.ErrInvalidRequest, 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() { if tx.Fee.Amount.IsAnyNegative() {
@ -71,29 +197,15 @@ func (tx StdTx) ValidateBasic() error {
return nil 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. // GetSigners returns the addresses that must sign the transaction.
// Addresses are returned in a deterministic order. // Addresses are returned in a deterministic order.
// They are accumulated from the GetSigners method for each Msg // They are accumulated from the GetSigners method for each Msg
// in the order they appear in tx.GetMsgs(). // in the order they appear in tx.GetMsgs().
// Duplicate addresses will be omitted. // Duplicate addresses will be omitted.
func (tx StdTx) GetSigners() []sdk.AccAddress { func (tx StdTx) GetSigners() []sdk.AccAddress {
seen := map[string]bool{}
var signers []sdk.AccAddress var signers []sdk.AccAddress
seen := map[string]bool{}
for _, msg := range tx.GetMsgs() { for _, msg := range tx.GetMsgs() {
for _, addr := range msg.GetSigners() { for _, addr := range msg.GetSigners() {
if !seen[addr.String()] { if !seen[addr.String()] {
@ -102,6 +214,7 @@ func (tx StdTx) GetSigners() []sdk.AccAddress {
} }
} }
} }
return signers 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 // If pubkey is not included in the signature, then nil is in the slice instead
func (tx StdTx) GetPubKeys() []crypto.PubKey { func (tx StdTx) GetPubKeys() []crypto.PubKey {
pks := make([]crypto.PubKey, len(tx.Signatures)) pks := make([]crypto.PubKey, len(tx.Signatures))
for i, stdSig := range tx.Signatures { for i, stdSig := range tx.Signatures {
pks[i] = stdSig.PubKey pks[i] = stdSig.GetPubKey()
} }
return pks return pks
} }
@ -163,43 +278,6 @@ func (tx StdTx) FeePayer() sdk.AccAddress {
return 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. // StdSignDoc is replay-prevention structure.
// It includes the result of msg.GetSignBytes(), // It includes the result of msg.GetSignBytes(),
// as well as the ChainID (prevent cross chain replay) // 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) 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 // DefaultTxDecoder logic for standard transaction decoding
func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder { func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) { return func(txBytes []byte) (sdk.Tx, error) {
@ -269,32 +341,3 @@ func DefaultTxEncoder(cdc *codec.Codec) sdk.TxEncoder {
return cdc.MarshalBinaryBare(tx) 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", "|\n pubkey: \"\"\n signature: \"\"\n",
}, },
{ {
StdSignature{PubKey: pubKey, Signature: []byte("dummySig")}, StdSignature{PubKey: pubKey.Bytes(), Signature: []byte("dummySig")},
fmt.Sprintf("|\n pubkey: %s\n signature: dummySig\n", sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, pubKey)), 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)), 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) panic(err)
} }
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig} sigs[i] = StdSignature{PubKey: priv.PubKey().Bytes(), Signature: sig}
} }
tx := NewStdTx(msgs, fee, sigs, "") tx := NewStdTx(msgs, fee, sigs, "")
@ -59,7 +59,7 @@ func NewTestTxWithMemo(ctx sdk.Context, msgs []sdk.Msg, privs []crypto.PrivKey,
panic(err) 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) tx := NewStdTx(msgs, fee, sigs, memo)
@ -74,7 +74,7 @@ func NewTestTxWithSignBytes(msgs []sdk.Msg, privs []crypto.PrivKey, accNums []ui
panic(err) 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) tx := NewStdTx(msgs, fee, sigs, memo)

View File

@ -286,8 +286,9 @@ func MakeSignature(keybase keys.Keybase, name, passphrase string,
if err != nil { if err != nil {
return return
} }
return StdSignature{ return StdSignature{
PubKey: pubkey, PubKey: pubkey.Bytes(),
Signature: sigBytes, Signature: sigBytes,
}, nil }, 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", // 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. // which must be above some miminum to be accepted into the mempool.
message StdFee { message StdFee {
option (gogoproto.equal) = true; option (gogoproto.goproto_getters) = false;
option (gogoproto.equal) = true;
repeated cosmos_sdk.v1.Coin amount = 1 repeated cosmos_sdk.v1.Coin amount = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
uint64 gas = 2; 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. // Params defines the parameters for the auth module.
message Params { message Params {
option (gogoproto.equal) = true; option (gogoproto.equal) = true;
@ -43,3 +53,21 @@ message Params {
uint64 sig_verify_cost_secp256k1 = 5 uint64 sig_verify_cost_secp256k1 = 5
[(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""]; [(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];
}