Merge pull request #6085: Move codec/std to std

This commit is contained in:
Aaron Craelius
2020-04-27 15:40:50 -04:00
committed by GitHub
parent 9b51908597
commit cc90f2e002
39 changed files with 233 additions and 234 deletions
-198
View File
@@ -1,198 +0,0 @@
package std
import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/bank"
bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported"
"github.com/cosmos/cosmos-sdk/x/evidence"
eviexported "github.com/cosmos/cosmos-sdk/x/evidence/exported"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"
)
var (
_ auth.Codec = (*Codec)(nil)
_ bank.Codec = (*Codec)(nil)
_ evidence.Codec = (*Codec)(nil)
_ gov.Codec = (*Codec)(nil)
)
// Codec defines the application-level codec. This codec contains all the
// required module-specific codecs that are to be provided upon initialization.
type Codec struct {
codec.Marshaler
// Keep reference to the amino codec to allow backwards compatibility along
// with type, and interface registration.
amino *codec.Codec
}
func NewAppCodec(amino *codec.Codec) *Codec {
return &Codec{Marshaler: codec.NewHybridCodec(amino), amino: amino}
}
// MarshalAccount marshals an Account interface. If the given type implements
// the Marshaler interface, it is treated as a Proto-defined message and
// serialized that way. Otherwise, it falls back on the internal Amino codec.
func (c *Codec) MarshalAccount(accI authexported.Account) ([]byte, error) {
acc := &Account{}
if err := acc.SetAccount(accI); err != nil {
return nil, err
}
return c.Marshaler.MarshalBinaryBare(acc)
}
// UnmarshalAccount returns an Account interface from raw encoded account bytes
// of a Proto-based Account type. An error is returned upon decoding failure.
func (c *Codec) UnmarshalAccount(bz []byte) (authexported.Account, error) {
acc := &Account{}
if err := c.Marshaler.UnmarshalBinaryBare(bz, acc); err != nil {
return nil, err
}
return acc.GetAccount(), nil
}
// MarshalAccountJSON JSON encodes an account object implementing the Account
// interface.
func (c *Codec) MarshalAccountJSON(acc authexported.Account) ([]byte, error) {
return c.Marshaler.MarshalJSON(acc)
}
// UnmarshalAccountJSON returns an Account from JSON encoded bytes.
func (c *Codec) UnmarshalAccountJSON(bz []byte) (authexported.Account, error) {
acc := &Account{}
if err := c.Marshaler.UnmarshalJSON(bz, acc); err != nil {
return nil, err
}
return acc.GetAccount(), nil
}
// MarshalSupply marshals a SupplyI interface. If the given type implements
// the Marshaler interface, it is treated as a Proto-defined message and
// serialized that way. Otherwise, it falls back on the internal Amino codec.
func (c *Codec) MarshalSupply(supplyI bankexported.SupplyI) ([]byte, error) {
supply := &Supply{}
if err := supply.SetSupplyI(supplyI); err != nil {
return nil, err
}
return c.Marshaler.MarshalBinaryBare(supply)
}
// UnmarshalSupply returns a SupplyI interface from raw encoded account bytes
// of a Proto-based SupplyI type. An error is returned upon decoding failure.
func (c *Codec) UnmarshalSupply(bz []byte) (bankexported.SupplyI, error) {
supply := &Supply{}
if err := c.Marshaler.UnmarshalBinaryBare(bz, supply); err != nil {
return nil, err
}
return supply.GetSupplyI(), nil
}
// MarshalSupplyJSON JSON encodes a supply object implementing the SupplyI
// interface.
func (c *Codec) MarshalSupplyJSON(supply bankexported.SupplyI) ([]byte, error) {
return c.Marshaler.MarshalJSON(supply)
}
// UnmarshalSupplyJSON returns a SupplyI from JSON encoded bytes.
func (c *Codec) UnmarshalSupplyJSON(bz []byte) (bankexported.SupplyI, error) {
supply := &Supply{}
if err := c.Marshaler.UnmarshalJSON(bz, supply); err != nil {
return nil, err
}
return supply.GetSupplyI(), nil
}
// MarshalEvidence marshals an Evidence interface. If the given type implements
// the Marshaler interface, it is treated as a Proto-defined message and
// serialized that way. Otherwise, it falls back on the internal Amino codec.
func (c *Codec) MarshalEvidence(evidenceI eviexported.Evidence) ([]byte, error) {
evidence := &Evidence{}
if err := evidence.SetEvidence(evidenceI); err != nil {
return nil, err
}
return c.Marshaler.MarshalBinaryBare(evidence)
}
// UnmarshalEvidence returns an Evidence interface from raw encoded evidence
// bytes of a Proto-based Evidence type. An error is returned upon decoding
// failure.
func (c *Codec) UnmarshalEvidence(bz []byte) (eviexported.Evidence, error) {
evidence := &Evidence{}
if err := c.Marshaler.UnmarshalBinaryBare(bz, evidence); err != nil {
return nil, err
}
return evidence.GetEvidence(), nil
}
// MarshalEvidenceJSON JSON encodes an evidence object implementing the Evidence
// interface.
func (c *Codec) MarshalEvidenceJSON(evidence eviexported.Evidence) ([]byte, error) {
return c.Marshaler.MarshalJSON(evidence)
}
// UnmarshalEvidenceJSON returns an Evidence from JSON encoded bytes
func (c *Codec) UnmarshalEvidenceJSON(bz []byte) (eviexported.Evidence, error) {
evidence := &Evidence{}
if err := c.Marshaler.UnmarshalJSON(bz, evidence); err != nil {
return nil, err
}
return evidence.GetEvidence(), nil
}
// MarshalProposal marshals a Proposal. It accepts a Proposal defined by the x/gov
// module and uses the application-level Proposal type which has the concrete
// Content implementation to serialize.
func (c *Codec) MarshalProposal(p gov.Proposal) ([]byte, error) {
proposal := &Proposal{ProposalBase: p.ProposalBase}
if err := proposal.Content.SetContent(p.Content); err != nil {
return nil, err
}
return c.Marshaler.MarshalBinaryBare(proposal)
}
// UnmarshalProposal decodes a Proposal defined by the x/gov module and uses the
// application-level Proposal type which has the concrete Content implementation
// to deserialize.
func (c *Codec) UnmarshalProposal(bz []byte) (gov.Proposal, error) {
proposal := &Proposal{}
if err := c.Marshaler.UnmarshalBinaryBare(bz, proposal); err != nil {
return gov.Proposal{}, err
}
return gov.Proposal{
Content: proposal.Content.GetContent(),
ProposalBase: proposal.ProposalBase,
}, nil
}
// ----------------------------------------------------------------------------
// necessary types and interfaces registered. This codec is provided to all the
// modules the application depends on.
//
// NOTE: This codec will be deprecated in favor of AppCodec once all modules are
// migrated.
func MakeCodec(bm module.BasicManager) *codec.Codec {
cdc := codec.New()
bm.RegisterCodec(cdc)
vesting.RegisterCodec(cdc)
sdk.RegisterCodec(cdc)
codec.RegisterCrypto(cdc)
return cdc
}
File diff suppressed because it is too large Load Diff
-184
View File
@@ -1,184 +0,0 @@
syntax = "proto3";
package cosmos_sdk.codec.std.v1;
import "third_party/proto/cosmos-proto/cosmos.proto";
import "third_party/proto/gogoproto/gogo.proto";
import "types/types.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/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";
option go_package = "github.com/cosmos/cosmos-sdk/codec/std";
// Account defines the application-level Account type.
message Account {
option (cosmos_proto.interface_type) = "*github.com/cosmos/cosmos-sdk/x/auth/exported.Account";
// sum defines a list of all acceptable concrete Account implementations.
oneof sum {
cosmos_sdk.x.auth.v1.BaseAccount base_account = 1;
cosmos_sdk.x.auth.vesting.v1.ContinuousVestingAccount continuous_vesting_account = 2;
cosmos_sdk.x.auth.vesting.v1.DelayedVestingAccount delayed_vesting_account = 3;
cosmos_sdk.x.auth.vesting.v1.PeriodicVestingAccount periodic_vesting_account = 4;
cosmos_sdk.x.auth.v1.ModuleAccount module_account = 5;
}
}
// Supply defines the application-level Supply type.
message Supply {
option (gogoproto.equal) = true;
option (cosmos_proto.interface_type) = "*github.com/cosmos/cosmos-sdk/x/bank/exported.SupplyI";
// sum defines a set of all acceptable concrete Supply implementations.
oneof sum {
cosmos_sdk.x.bank.v1.Supply supply = 1;
}
}
// Evidence defines the application-level allowed Evidence to be submitted via a
// MsgSubmitEvidence message.
message Evidence {
option (gogoproto.equal) = true;
option (cosmos_proto.interface_type) = "github.com/cosmos/cosmos-sdk/x/evidence/exported.Evidence";
// sum defines a set of all acceptable concrete Evidence implementations.
oneof sum {
cosmos_sdk.x.evidence.v1.Equivocation equivocation = 1;
}
}
// MsgSubmitEvidence defines the application-level message type for handling
// evidence submission.
message MsgSubmitEvidence {
option (gogoproto.equal) = true;
option (gogoproto.goproto_getters) = false;
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
// governance proposals.
message MsgSubmitProposal {
option (gogoproto.equal) = true;
option (gogoproto.goproto_getters) = false;
cosmos_sdk.x.gov.v1.MsgSubmitProposalBase base = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
Content content = 2;
}
// Proposal defines the application-level concrete proposal type used in governance
// proposals.
message Proposal {
option (gogoproto.equal) = true;
cosmos_sdk.x.gov.v1.ProposalBase base = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
Content content = 2 [(gogoproto.nullable) = false];
}
// Content defines the application-level allowed Content to be included in a
// governance proposal.
message Content {
option (gogoproto.equal) = true;
option (cosmos_proto.interface_type) = "*github.com/cosmos/cosmos-sdk/x/gov/types.Content";
// sum defines a set of all acceptable concrete governance proposal Content types.
oneof sum {
cosmos_sdk.x.gov.v1.TextProposal text = 1;
cosmos_sdk.x.params.v1.ParameterChangeProposal parameter_change = 2;
cosmos_sdk.x.upgrade.v1.SoftwareUpgradeProposal software_upgrade = 3;
cosmos_sdk.x.upgrade.v1.CancelSoftwareUpgradeProposal cancel_software_upgrade = 4;
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;
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 {
StdSignDocBase base = 1 [(gogoproto.jsontag) = "", (gogoproto.embed) = true, (gogoproto.nullable) = false];
repeated Message msgs = 2 [(gogoproto.nullable) = false];
}
// StdFee includes the amount of coins paid in fees and the maximum
// 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.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;
}
// 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];
}
-10
View File
@@ -1,10 +0,0 @@
/*
Package std defines all the common and standard Cosmos SDK Protocol Buffer
message definitions and type implementations. The std package defines and exposes
a single concrete Codec type that implements all the necessary module codec
interfaces along with all the types necessary to use those modules.
Applications can choose to either use the codec directly or even extend it without
having the need to redefine all the message and type implementations.
*/
package std
-91
View File
@@ -1,91 +0,0 @@
package std
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/evidence"
eviexported "github.com/cosmos/cosmos-sdk/x/evidence/exported"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"
)
var (
_ eviexported.MsgSubmitEvidence = MsgSubmitEvidence{}
_ gov.MsgSubmitProposalI = &MsgSubmitProposal{}
)
// NewMsgSubmitEvidence returns a new MsgSubmitEvidence.
func NewMsgSubmitEvidence(evidenceI eviexported.Evidence, s sdk.AccAddress) (MsgSubmitEvidence, error) {
e := &Evidence{}
if err := e.SetEvidence(evidenceI); err != nil {
return MsgSubmitEvidence{}, err
}
return MsgSubmitEvidence{
Evidence: e,
MsgSubmitEvidenceBase: evidence.NewMsgSubmitEvidenceBase(s),
}, nil
}
// ValidateBasic performs basic (non-state-dependant) validation on a
// MsgSubmitEvidence.
func (msg MsgSubmitEvidence) ValidateBasic() error {
if err := msg.MsgSubmitEvidenceBase.ValidateBasic(); err != nil {
return nil
}
if msg.Evidence == nil {
return sdkerrors.Wrap(evidence.ErrInvalidEvidence, "missing evidence")
}
if err := msg.Evidence.GetEvidence().ValidateBasic(); err != nil {
return err
}
return nil
}
// nolint
func (msg MsgSubmitEvidence) GetEvidence() eviexported.Evidence { return msg.Evidence.GetEvidence() }
func (msg MsgSubmitEvidence) GetSubmitter() sdk.AccAddress { return msg.Submitter }
// NewMsgSubmitProposal returns a new MsgSubmitProposal.
func NewMsgSubmitProposal(c gov.Content, d sdk.Coins, p sdk.AccAddress) (gov.MsgSubmitProposalI, error) {
content := &Content{}
if err := content.SetContent(c); err != nil {
return nil, err
}
return &MsgSubmitProposal{
Content: content,
MsgSubmitProposalBase: gov.NewMsgSubmitProposalBase(d, p),
}, nil
}
// ValidateBasic performs basic (non-state-dependant) validation on a
// MsgSubmitProposal.
func (msg MsgSubmitProposal) ValidateBasic() error {
if err := msg.MsgSubmitProposalBase.ValidateBasic(); err != nil {
return nil
}
if msg.Content == nil {
return sdkerrors.Wrap(gov.ErrInvalidProposalContent, "missing content")
}
if !gov.IsValidProposalType(msg.Content.GetContent().ProposalType()) {
return sdkerrors.Wrap(gov.ErrInvalidProposalType, msg.Content.GetContent().ProposalType())
}
if err := msg.Content.GetContent().ValidateBasic(); err != nil {
return err
}
return nil
}
// nolint
func (msg *MsgSubmitProposal) GetContent() gov.Content { return msg.Content.GetContent() }
func (msg *MsgSubmitProposal) SetContent(content gov.Content) error {
stdContent := &Content{}
err := stdContent.SetContent(content)
if err != nil {
return err
}
msg.Content = stdContent
return nil
}
-73
View File
@@ -1,73 +0,0 @@
package std_test
import (
"testing"
"time"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"
"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"
)
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())
}
type invalidProposal struct {
*gov.TextProposal
}
func TestMsgSubmitProposal(t *testing.T) {
p := sdk.AccAddress("foo")
d := sdk.NewCoins(sdk.NewInt64Coin("stake", 1000))
c := gov.NewTextProposal("title", "description")
//
// test constructor
//
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())
_, err = std.NewMsgSubmitProposal(invalidProposal{}, d, p)
require.Error(t, err)
//
// test setter methods
//
msg = &std.MsgSubmitProposal{}
msg.SetProposer(p)
msg.SetInitialDeposit(d)
err = msg.SetContent(c)
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())
msg = &std.MsgSubmitProposal{}
err = msg.SetContent(invalidProposal{})
require.Error(t, err)
}
-265
View File
@@ -1,265 +0,0 @@
package std
import (
"github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/crypto"
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{}
_ clientx.ClientFee = &StdFee{}
_ clientx.ClientSignature = &StdSignature{}
)
// TxGenerator defines a transaction generator that allows clients to construct
// transactions.
type TxGenerator struct{}
func (g TxGenerator) NewFee() clientx.ClientFee {
return &StdFee{}
}
func (g TxGenerator) NewSignature() clientx.ClientSignature {
return &StdSignature{}
}
// NewTx returns a reference to an empty Transaction type.
func (TxGenerator) NewTx() clientx.ClientTx {
return &Transaction{}
}
func NewTransaction(fee StdFee, memo string, sdkMsgs []sdk.Msg) (*Transaction, error) {
tx := &Transaction{
StdTxBase: 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 ...clientx.ClientSignature) error {
sigs := make([]StdSignature, len(sdkSigs))
for i, sig := range sdkSigs {
if sig != nil {
sigs[i] = NewStdSignature(sig.GetPubKey(), sig.GetSignature())
}
}
tx.Signatures = sigs
return nil
}
// 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 clientx.ClientFee) error {
tx.Fee = NewStdFee(fee.GetGas(), fee.GetAmount())
return nil
}
// 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 StdFee, msgs ...Message) *SignDoc {
return &SignDoc{
StdSignDocBase: 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)
}
// NewStdFee returns a new instance of StdFee
func NewStdFee(gas uint64, amount sdk.Coins) StdFee {
return StdFee{
Amount: amount,
Gas: gas,
}
}
func NewStdSignature(pk crypto.PubKey, sig []byte) StdSignature {
var pkBz []byte
if pk != nil {
pkBz = pk.Bytes()
}
return StdSignature{PubKey: pkBz, Signature: sig}
}
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,
}
}
func (m StdFee) GetGas() uint64 {
return m.Gas
}
func (m StdFee) GetAmount() sdk.Coins {
return m.Amount
}
func (m *StdFee) SetGas(gas uint64) {
m.Gas = gas
}
func (m *StdFee) SetAmount(amount sdk.Coins) {
m.Amount = amount
}
func (m StdSignature) GetPubKey() crypto.PubKey {
var pk crypto.PubKey
if len(m.PubKey) == 0 {
return nil
}
amino.MustUnmarshalBinaryBare(m.PubKey, &pk)
return pk
}
func (m StdSignature) GetSignature() []byte {
return m.Signature
}
func (m *StdSignature) SetPubKey(pk crypto.PubKey) error {
m.PubKey = pk.Bytes()
return nil
}
func (m *StdSignature) SetSignature(signature []byte) {
m.Signature = signature
}
-37
View File
@@ -1,37 +0,0 @@
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/bank"
)
func TestTransaction(t *testing.T) {
f := std.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))
}