Merge PR #6256: Remove oneof tx types
This commit is contained in:
parent
70767c87c4
commit
98280712ce
|
@ -28,85 +28,3 @@ message Account {
|
||||||
cosmos_sdk.x.auth.v1.ModuleAccount module_account = 5;
|
cosmos_sdk.x.auth.v1.ModuleAccount module_account = 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;
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
265
std/tx.go
265
std/tx.go
|
@ -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
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package std_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
std "github.com/cosmos/cosmos-sdk/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))
|
|
||||||
}
|
|
Loading…
Reference in New Issue