Merge PR #2959: Add TxEncoder to client TxBuilder

This commit is contained in:
Artur Albov 2018-12-13 00:29:42 +03:00 committed by Christopher Goes
parent 582ca8e8b9
commit 0c6d53dc07
21 changed files with 145 additions and 36 deletions

View File

@ -25,6 +25,7 @@ FEATURES
* Gaia
* SDK
- [\#2926](https://github.com/cosmos/cosmos-sdk/issues/2926) Add TxEncoder to client TxBuilder.
* Tendermint

View File

@ -78,14 +78,14 @@ func ParseFloat64OrReturnBadRequest(w http.ResponseWriter, s string, defaultIfEm
}
// WriteGenerateStdTxResponse writes response for the generate_only mode.
func WriteGenerateStdTxResponse(w http.ResponseWriter, txBldr authtxb.TxBuilder, msgs []sdk.Msg) {
func WriteGenerateStdTxResponse(w http.ResponseWriter, cdc *codec.Codec, txBldr authtxb.TxBuilder, msgs []sdk.Msg) {
stdMsg, err := txBldr.Build(msgs)
if err != nil {
WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
output, err := txBldr.Codec.MarshalJSON(auth.NewStdTx(stdMsg.Msgs, stdMsg.Fee, nil, stdMsg.Memo))
output, err := cdc.MarshalJSON(auth.NewStdTx(stdMsg.Msgs, stdMsg.Fee, nil, stdMsg.Memo))
if err != nil {
WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
@ -198,7 +198,7 @@ func CompleteAndBroadcastTxREST(w http.ResponseWriter, r *http.Request, cliCtx c
}
txBldr := authtxb.TxBuilder{
Codec: cdc,
TxEncoder: GetTxEncoder(cdc),
Gas: gas,
GasAdjustment: adjustment,
SimulateGas: simulateGas,
@ -223,7 +223,7 @@ func CompleteAndBroadcastTxREST(w http.ResponseWriter, r *http.Request, cliCtx c
}
if baseReq.GenerateOnly {
WriteGenerateStdTxResponse(w, txBldr, msgs)
WriteGenerateStdTxResponse(w, cdc, txBldr, msgs)
return
}

View File

@ -3,6 +3,7 @@ package utils
import (
"bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"io"
"os"
@ -99,7 +100,7 @@ func PrintUnsignedStdTx(w io.Writer, txBldr authtxb.TxBuilder, cliCtx context.CL
if err != nil {
return
}
json, err := txBldr.Codec.MarshalJSON(stdTx)
json, err := cliCtx.Codec.MarshalJSON(stdTx)
if err == nil {
fmt.Fprintf(w, "%s\n", json)
}
@ -154,6 +155,16 @@ func SignStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name string,
return txBldr.SignStdTx(name, passphrase, stdTx, appendSig)
}
// GetTxEncoder return tx encoder from global sdk configuration if ones is defined.
// Otherwise returns encoder with default logic.
func GetTxEncoder(cdc *codec.Codec) (encoder sdk.TxEncoder) {
encoder = sdk.GetConfig().GetTxEncoder()
if encoder == nil {
encoder = auth.DefaultTxEncoder(cdc)
}
return
}
// nolint
// SimulateMsgs simulates the transaction and returns the gas estimate and the adjusted value.
func simulateMsgs(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name string, msgs []sdk.Msg) (estimated, adjusted uint64, err error) {

View File

@ -1,7 +1,12 @@
package utils
import (
"encoding/json"
"errors"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
"testing"
"github.com/stretchr/testify/assert"
@ -11,6 +16,11 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
var (
priv = ed25519.GenPrivKey()
addr = sdk.AccAddress(priv.PubKey().Address())
)
func TestParseQueryResponse(t *testing.T) {
cdc := app.MakeCodec()
sdkResBytes := cdc.MustMarshalBinaryLengthPrefixed(sdk.Result{GasUsed: 10})
@ -57,3 +67,44 @@ func TestCalculateGas(t *testing.T) {
})
}
}
func TestDefaultTxEncoder(t *testing.T) {
cdc := makeCodec()
defaultEncoder := auth.DefaultTxEncoder(cdc)
encoder := GetTxEncoder(cdc)
compareEncoders(t, defaultEncoder, encoder)
}
func TestConfiguredTxEncoder(t *testing.T) {
cdc := makeCodec()
customEncoder := func(tx sdk.Tx) ([]byte, error) {
return json.Marshal(tx)
}
config := sdk.GetConfig()
config.SetTxEncoder(customEncoder)
encoder := GetTxEncoder(cdc)
compareEncoders(t, customEncoder, encoder)
}
func compareEncoders(t *testing.T, expected sdk.TxEncoder, actual sdk.TxEncoder) {
msgs := []sdk.Msg{sdk.NewTestMsg(addr)}
tx := auth.NewStdTx(msgs, auth.StdFee{}, []auth.StdSignature{}, "")
defaultEncoderBytes, err := expected(tx)
require.NoError(t, err)
encoderBytes, err := actual(tx)
require.NoError(t, err)
require.Equal(t, defaultEncoderBytes, encoderBytes)
}
func makeCodec() *codec.Codec {
cdc := app.MakeCodec()
cdc.RegisterConcrete(sdk.TestMsg{}, "cosmos-sdk/Test", nil)
return cdc
}

View File

@ -111,7 +111,7 @@ following delegation and commission default parameters:
}
// Run gaiad tx create-validator
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().WithCodec(cdc)
cliCtx, txBldr, msg, err := cli.BuildCreateValidatorMsg(cliCtx, txBldr)
if err != nil {

View File

@ -18,7 +18,7 @@ func QuizTxCmd(cdc *codec.Codec) *cobra.Command {
Short: "What's cooler than being cool?",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -42,7 +42,7 @@ func SetTrendTxCmd(cdc *codec.Codec) *cobra.Command {
Short: "You're so cool, tell us what is cool!",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)

View File

@ -20,7 +20,7 @@ func MineCmd(cdc *codec.Codec) *cobra.Command {
Short: "Mine some coins with proof-of-work!",
Args: cobra.ExactArgs(4),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)

View File

@ -3,7 +3,6 @@ package cli
import (
"encoding/hex"
"fmt"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/utils"
"github.com/cosmos/cosmos-sdk/codec"
@ -28,7 +27,7 @@ func BondTxCmd(cdc *codec.Codec) *cobra.Command {
Use: "bond",
Short: "Bond to a validator",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -81,7 +80,7 @@ func UnbondTxCmd(cdc *codec.Codec) *cobra.Command {
Use: "unbond",
Short: "Unbond from a validator",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc)

View File

@ -10,6 +10,7 @@ type Config struct {
mtx sync.RWMutex
sealed bool
bech32AddressPrefix map[string]string
txEncoder TxEncoder
}
var (
@ -24,6 +25,7 @@ var (
"validator_pub": Bech32PrefixValPub,
"consensus_pub": Bech32PrefixConsPub,
},
txEncoder: nil,
}
)
@ -65,6 +67,12 @@ func (config *Config) SetBech32PrefixForConsensusNode(addressPrefix, pubKeyPrefi
config.bech32AddressPrefix["consensus_pub"] = pubKeyPrefix
}
// SetTxEncoder builds the Config with TxEncoder used to marshal StdTx to bytes
func (config *Config) SetTxEncoder(encoder TxEncoder) {
config.assertNotSealed()
config.txEncoder = encoder
}
// Seal seals the config such that the config state could not be modified further
func (config *Config) Seal() *Config {
config.mtx.Lock()
@ -103,3 +111,8 @@ func (config *Config) GetBech32ValidatorPubPrefix() string {
func (config *Config) GetBech32ConsensusPubPrefix() string {
return config.bech32AddressPrefix["consensus_pub"]
}
// GetTxEncoder return function to encode transactions
func (config *Config) GetTxEncoder() TxEncoder {
return config.txEncoder
}

View File

@ -45,6 +45,9 @@ type Tx interface {
// TxDecoder unmarshals transaction bytes
type TxDecoder func(txBytes []byte) (Tx, Error)
// TxEncoder marshals transaction to bytes
type TxEncoder func(tx Tx) ([]byte, error)
//__________________________________________________________
var _ Msg = (*TestMsg)(nil)

View File

@ -3,7 +3,6 @@ package context
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
@ -13,7 +12,7 @@ import (
// TxBuilder implements a transaction context created in SDK modules.
type TxBuilder struct {
Codec *codec.Codec
TxEncoder sdk.TxEncoder
AccountNumber uint64
Sequence uint64
Gas uint64
@ -49,8 +48,8 @@ func NewTxBuilderFromCLI() TxBuilder {
}
// WithCodec returns a copy of the context with an updated codec.
func (bldr TxBuilder) WithCodec(cdc *codec.Codec) TxBuilder {
bldr.Codec = cdc
func (bldr TxBuilder) WithTxEncoder(txEncoder sdk.TxEncoder) TxBuilder {
bldr.TxEncoder = txEncoder
return bldr
}
@ -126,7 +125,7 @@ func (bldr TxBuilder) Sign(name, passphrase string, msg StdSignMsg) ([]byte, err
return nil, err
}
return bldr.Codec.MarshalBinaryLengthPrefixed(auth.NewStdTx(msg.Msgs, msg.Fee, []auth.StdSignature{sig}, msg.Memo))
return bldr.TxEncoder(auth.NewStdTx(msg.Msgs, msg.Fee, []auth.StdSignature{sig}, msg.Memo))
}
// BuildAndSign builds a single message to be signed, and signs a transaction
@ -165,7 +164,7 @@ func (bldr TxBuilder) BuildWithPubKey(name string, msgs []sdk.Msg) ([]byte, erro
PubKey: info.GetPubKey(),
}}
return bldr.Codec.MarshalBinaryLengthPrefixed(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
return bldr.TxEncoder(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
}
// SignStdTx appends a signature to a StdTx and returns a copy of a it. If append

View File

@ -21,7 +21,7 @@ var (
func TestTxBuilderBuild(t *testing.T) {
type fields struct {
Codec *codec.Codec
TxEncoder sdk.TxEncoder
AccountNumber uint64
Sequence uint64
Gas uint64
@ -40,7 +40,7 @@ func TestTxBuilderBuild(t *testing.T) {
}{
{
fields{
Codec: codec.New(),
TxEncoder: auth.DefaultTxEncoder(codec.New()),
AccountNumber: 1,
Sequence: 1,
Gas: 100,
@ -64,7 +64,7 @@ func TestTxBuilderBuild(t *testing.T) {
}
for i, tc := range tests {
bldr := TxBuilder{
Codec: tc.fields.Codec,
TxEncoder: tc.fields.TxEncoder,
AccountNumber: tc.fields.AccountNumber,
Sequence: tc.fields.Sequence,
Gas: tc.fields.Gas,

View File

@ -217,3 +217,10 @@ func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder {
return tx, nil
}
}
// logic for standard transaction encoding
func DefaultTxEncoder(cdc *codec.Codec) sdk.TxEncoder {
return func(tx sdk.Tx) ([]byte, error) {
return cdc.MarshalBinaryLengthPrefixed(tx)
}
}

View File

@ -2,6 +2,7 @@ package auth
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"strings"
"testing"
@ -137,3 +138,25 @@ func TestTxValidateBasic(t *testing.T) {
err = tx.ValidateBasic()
require.NoError(t, err)
}
func TestDefaultTxEncoder(t *testing.T) {
cdc := codec.New()
sdk.RegisterCodec(cdc)
RegisterCodec(cdc)
cdc.RegisterConcrete(sdk.TestMsg{}, "cosmos-sdk/Test", nil)
encoder := DefaultTxEncoder(cdc)
msgs := []sdk.Msg{sdk.NewTestMsg(addr)}
fee := newStdFee()
sigs := []StdSignature{}
tx := NewStdTx(msgs, fee, sigs, "")
cdcBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
require.NoError(t, err)
encoderBytes, err := encoder(tx)
require.NoError(t, err)
require.Equal(t, cdcBytes, encoderBytes)
}

View File

@ -27,7 +27,7 @@ func SendTxCmd(cdc *codec.Codec) *cobra.Command {
Use: "send",
Short: "Create and sign a send tx",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)

View File

@ -55,7 +55,7 @@ func GetCmdWithdrawRewards(cdc *codec.Codec) *cobra.Command {
flagOnlyFromValidator, flagIsValidator)
}
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -110,7 +110,7 @@ func GetCmdSetWithdrawAddr(cdc *codec.Codec) *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)

View File

@ -80,7 +80,7 @@ $ gaiacli gov submit-proposal --title="Test Proposal" --description="My awesome
return err
}
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -182,7 +182,7 @@ Submit a deposit for an acive proposal. You can find the proposal-id by running
$ gaiacli tx gov deposit 1 10STAKE --from mykey
`),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -252,7 +252,7 @@ Submit a vote for an acive proposal. You can find the proposal-id by running gai
$ gaiacli tx gov vote 1 yes --from mykey
`),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)

View File

@ -7,7 +7,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/utils"
codec "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
"github.com/cosmos/cosmos-sdk/x/ibc"
@ -27,7 +27,7 @@ func IBCTransferCmd(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "transfer",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)

View File

@ -1,6 +1,7 @@
package cli
import (
"github.com/cosmos/cosmos-sdk/client/utils"
"os"
"time"
@ -201,7 +202,7 @@ func (c relayCommander) refine(bz []byte, ibcSeq, accSeq uint64, passphrase stri
Sequence: ibcSeq,
}
txBldr := authtxb.NewTxBuilderFromCLI().WithSequence(accSeq).WithCodec(c.cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithSequence(accSeq).WithTxEncoder(utils.GetTxEncoder(c.cdc))
cliCtx := context.NewCLIContext()
name, err := cliCtx.GetFromName()

View File

@ -20,7 +20,7 @@ func GetCmdUnjail(cdc *codec.Codec) *cobra.Command {
Args: cobra.NoArgs,
Short: "unjail validator previously jailed for downtime",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)

View File

@ -2,6 +2,7 @@ package cli
import (
"fmt"
"github.com/cosmos/cosmos-sdk/x/auth"
"os"
"github.com/cosmos/cosmos-sdk/client"
@ -22,7 +23,7 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command {
Use: "create-validator",
Short: "create new validator initialized with a self-delegation to it",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -63,7 +64,7 @@ func GetCmdEditValidator(cdc *codec.Codec) *cobra.Command {
Use: "edit-validator",
Short: "edit and existing validator account",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -115,7 +116,7 @@ func GetCmdDelegate(cdc *codec.Codec) *cobra.Command {
Use: "delegate",
Short: "delegate liquid tokens to an validator",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -157,7 +158,7 @@ func GetCmdRedelegate(storeName string, cdc *codec.Codec) *cobra.Command {
Use: "redelegate",
Short: "redelegate illiquid tokens from one validator to another",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
@ -212,7 +213,7 @@ func GetCmdUnbond(storeName string, cdc *codec.Codec) *cobra.Command {
Use: "unbond",
Short: "unbond shares from a validator",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)