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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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