diff --git a/x/auth/client/rest.go b/x/auth/client/rest.go deleted file mode 100644 index a3e15d4bdeac..000000000000 --- a/x/auth/client/rest.go +++ /dev/null @@ -1,65 +0,0 @@ -package client - -import ( - "log" - "net/http" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/cosmos/cosmos-sdk/x/auth/types" -) - -// WriteGenerateStdTxResponse writes response for the generate only mode. -func WriteGenerateStdTxResponse(w http.ResponseWriter, clientCtx client.Context, br rest.BaseReq, msgs []sdk.Msg) { - gasAdj, ok := rest.ParseFloat64OrReturnBadRequest(w, br.GasAdjustment, flags.DefaultGasAdjustment) - if !ok { - return - } - - gasSetting, err := flags.ParseGasSetting(br.Gas) - if rest.CheckBadRequestError(w, err) { - return - } - - txBldr := types.NewTxBuilder( - GetTxEncoder(clientCtx.Codec), br.AccountNumber, br.Sequence, gasSetting.Gas, gasAdj, - br.Simulate, br.ChainID, br.Memo, br.Fees, br.GasPrices, - ) - - if br.Simulate || gasSetting.Simulate { - if gasAdj < 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errors.ErrorInvalidGasAdjustment.Error()) - return - } - - txBldr, err = EnrichWithGas(txBldr, clientCtx, msgs) - if rest.CheckInternalServerError(w, err) { - return - } - - if br.Simulate { - rest.WriteSimulationResponse(w, clientCtx.Codec, txBldr.Gas()) - return - } - } - - stdMsg, err := txBldr.BuildSignMsg(msgs) - if rest.CheckBadRequestError(w, err) { - return - } - - // NOTE: amino is used intentionally here, don't migrate it - output, err := clientCtx.Codec.MarshalJSON(types.NewStdTx(stdMsg.Msgs, stdMsg.Fee, nil, stdMsg.Memo)) - if rest.CheckInternalServerError(w, err) { - return - } - - w.Header().Set("Content-Type", "application/json") - if _, err := w.Write(output); err != nil { - log.Printf("could not write response: %v", err) - } - -} diff --git a/x/auth/client/tx.go b/x/auth/client/tx.go index 280ed358f9b7..7f7fde8526e0 100644 --- a/x/auth/client/tx.go +++ b/x/auth/client/tx.go @@ -37,40 +37,6 @@ func (gr GasEstimateResponse) String() string { return fmt.Sprintf("gas estimate: %d", gr.GasEstimate) } -// EnrichWithGas calculates the gas estimate that would be consumed by the -// transaction and set the transaction's respective value accordingly. -func EnrichWithGas(txBldr authtypes.TxBuilder, clientCtx client.Context, msgs []sdk.Msg) (authtypes.TxBuilder, error) { - _, adjusted, err := simulateMsgs(txBldr, clientCtx, msgs) - if err != nil { - return txBldr, err - } - - return txBldr.WithGas(adjusted), nil -} - -// CalculateGas simulates the execution of a transaction and returns -// the simulation response obtained by the query and the adjusted gas amount. -func CalculateGas( - queryFunc func(string, []byte) ([]byte, int64, error), cdc *codec.Codec, - txBytes []byte, adjustment float64, -) (sdk.SimulationResponse, uint64, error) { - - // run a simulation (via /app/simulate query) to - // estimate gas and update TxBuilder accordingly - rawRes, _, err := queryFunc("/app/simulate", txBytes) - if err != nil { - return sdk.SimulationResponse{}, 0, err - } - - simRes, err := ParseQueryResponse(rawRes) - if err != nil { - return sdk.SimulationResponse{}, 0, err - } - - adjusted := adjustGasEstimate(simRes.GasUsed, adjustment) - return simRes, adjusted, nil -} - // PrintUnsignedStdTx builds an unsigned StdTx and prints it to os.Stdout. func PrintUnsignedStdTx(txBldr tx.Factory, clientCtx client.Context, msgs []sdk.Msg) error { err := tx.GenerateTx(clientCtx, txBldr, msgs...) @@ -196,21 +162,6 @@ func GetTxEncoder(cdc *codec.Codec) (encoder sdk.TxEncoder) { return encoder } -// simulateMsgs simulates the transaction and returns the simulation response and -// the adjusted gas value. -func simulateMsgs(txBldr authtypes.TxBuilder, clientCtx client.Context, msgs []sdk.Msg) (sdk.SimulationResponse, uint64, error) { - txBytes, err := txBldr.BuildTxForSim(msgs) - if err != nil { - return sdk.SimulationResponse{}, 0, err - } - - return CalculateGas(clientCtx.QueryWithData, clientCtx.Codec, txBytes, txBldr.GasAdjustment()) -} - -func adjustGasEstimate(estimate uint64, adjustment float64) uint64 { - return uint64(adjustment * float64(estimate)) -} - func ParseQueryResponse(bz []byte) (sdk.SimulationResponse, error) { var simRes sdk.SimulationResponse if err := jsonpb.Unmarshal(strings.NewReader(string(bz)), &simRes); err != nil { diff --git a/x/auth/client/tx_test.go b/x/auth/client/tx_test.go index 49d7b696c72b..13b5743cf2c7 100644 --- a/x/auth/client/tx_test.go +++ b/x/auth/client/tx_test.go @@ -1,7 +1,6 @@ package client_test import ( - "errors" "fmt" "strings" "testing" @@ -45,58 +44,6 @@ func TestParseQueryResponse(t *testing.T) { require.Error(t, err) } -func TestCalculateGas(t *testing.T) { - cdc := makeCodec() - makeQueryFunc := func(gasUsed uint64, wantErr bool) func(string, []byte) ([]byte, int64, error) { - return func(string, []byte) ([]byte, int64, error) { - if wantErr { - return nil, 0, errors.New("query failed") - } - simRes := &sdk.SimulationResponse{ - GasInfo: sdk.GasInfo{GasUsed: gasUsed, GasWanted: gasUsed}, - Result: &sdk.Result{Data: []byte("tx data"), Log: "log"}, - } - - bz, _ := codec.ProtoMarshalJSON(simRes) - return bz, 0, nil - } - } - - type args struct { - queryFuncGasUsed uint64 - queryFuncWantErr bool - adjustment float64 - } - - tests := []struct { - name string - args args - wantEstimate uint64 - wantAdjusted uint64 - expPass bool - }{ - {"error", args{0, true, 1.2}, 0, 0, false}, - {"adjusted gas", args{10, false, 1.2}, 10, 12, true}, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - queryFunc := makeQueryFunc(tt.args.queryFuncGasUsed, tt.args.queryFuncWantErr) - simRes, gotAdjusted, err := authclient.CalculateGas(queryFunc, cdc, []byte(""), tt.args.adjustment) - if tt.expPass { - require.NoError(t, err) - require.Equal(t, simRes.GasInfo.GasUsed, tt.wantEstimate) - require.Equal(t, gotAdjusted, tt.wantAdjusted) - require.NotNil(t, simRes.Result) - } else { - require.Error(t, err) - require.Nil(t, simRes.Result) - } - }) - } -} - // TODO: remove this and authclient.GetTxEncoder after the proto tx migration is complete func TestDefaultTxEncoder(t *testing.T) { cdc := makeCodec() diff --git a/x/auth/types/txbuilder.go b/x/auth/types/txbuilder.go deleted file mode 100644 index 9ba806aa55e4..000000000000 --- a/x/auth/types/txbuilder.go +++ /dev/null @@ -1,306 +0,0 @@ -package types - -import ( - "errors" - "fmt" - "io" - "os" - "strings" - - "github.com/spf13/pflag" - - "github.com/spf13/viper" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// TxBuilder implements a transaction context created in SDK modules. -type TxBuilder struct { - txEncoder sdk.TxEncoder - keybase keyring.Keyring - accountNumber uint64 - sequence uint64 - gas uint64 - gasAdjustment float64 - simulateAndExecute bool - chainID string - memo string - fees sdk.Coins - gasPrices sdk.DecCoins -} - -// NewTxBuilder returns a new initialized TxBuilder. -func NewTxBuilder( - txEncoder sdk.TxEncoder, accNumber, seq, gas uint64, gasAdj float64, - simulateAndExecute bool, chainID, memo string, fees sdk.Coins, gasPrices sdk.DecCoins, -) TxBuilder { - - return TxBuilder{ - txEncoder: txEncoder, - keybase: nil, - accountNumber: accNumber, - sequence: seq, - gas: gas, - gasAdjustment: gasAdj, - simulateAndExecute: simulateAndExecute, - chainID: chainID, - memo: memo, - fees: fees, - gasPrices: gasPrices, - } -} - -// NewTxBuilderFromFlags returns a new initialized TxBuilder with parameters extracted from -// FlagSet. -func NewTxBuilderFromFlags(input io.Reader, fs *pflag.FlagSet, keyringPath string) (TxBuilder, error) { - backend, _ := fs.GetString(flags.FlagKeyringBackend) - kb, _ := keyring.New(sdk.KeyringServiceName(), backend, keyringPath, input) - accNum, _ := fs.GetUint64(flags.FlagAccountNumber) - seq, _ := fs.GetUint64(flags.FlagSequence) - gasAdjustment, _ := fs.GetFloat64(flags.FlagGasAdjustment) - chainID, _ := fs.GetString(flags.FlagChainID) - memo, _ := fs.GetString(flags.FlagMemo) - fees, _ := fs.GetString(flags.FlagFees) - gasPrices, _ := fs.GetString(flags.FlagGasPrices) - - gasStr, _ := fs.GetString(flags.FlagGas) - gasSetting, err := flags.ParseGasSetting(gasStr) - if err != nil { - return TxBuilder{}, err - } - - txbldr := TxBuilder{ - keybase: kb, - accountNumber: accNum, - sequence: seq, - gas: gasSetting.Gas, - simulateAndExecute: gasSetting.Simulate, - gasAdjustment: gasAdjustment, - chainID: chainID, - memo: memo, - } - - txbldr = txbldr.WithFees(fees) - txbldr = txbldr.WithGasPrices(gasPrices) - - return txbldr, nil -} - -// TxEncoder returns the transaction encoder -func (bldr TxBuilder) TxEncoder() sdk.TxEncoder { return bldr.txEncoder } - -// AccountNumber returns the account number -func (bldr TxBuilder) AccountNumber() uint64 { return bldr.accountNumber } - -// Sequence returns the transaction sequence -func (bldr TxBuilder) Sequence() uint64 { return bldr.sequence } - -// Gas returns the gas for the transaction -func (bldr TxBuilder) Gas() uint64 { return bldr.gas } - -// GasAdjustment returns the gas adjustment -func (bldr TxBuilder) GasAdjustment() float64 { return bldr.gasAdjustment } - -// Keybase returns the keybase -func (bldr TxBuilder) Keybase() keyring.Keyring { return bldr.keybase } - -// SimulateAndExecute returns the option to simulate and then execute the transaction -// using the gas from the simulation results -func (bldr TxBuilder) SimulateAndExecute() bool { return bldr.simulateAndExecute } - -// ChainID returns the chain id -func (bldr TxBuilder) ChainID() string { return bldr.chainID } - -// Memo returns the memo message -func (bldr TxBuilder) Memo() string { return bldr.memo } - -// Fees returns the fees for the transaction -func (bldr TxBuilder) Fees() sdk.Coins { return bldr.fees } - -// GasPrices returns the gas prices set for the transaction, if any. -func (bldr TxBuilder) GasPrices() sdk.DecCoins { return bldr.gasPrices } - -// WithTxEncoder returns a copy of the context with an updated codec. -func (bldr TxBuilder) WithTxEncoder(txEncoder sdk.TxEncoder) TxBuilder { - bldr.txEncoder = txEncoder - return bldr -} - -// WithChainID returns a copy of the context with an updated chainID. -func (bldr TxBuilder) WithChainID(chainID string) TxBuilder { - bldr.chainID = chainID - return bldr -} - -// WithGas returns a copy of the context with an updated gas. -func (bldr TxBuilder) WithGas(gas uint64) TxBuilder { - bldr.gas = gas - return bldr -} - -// WithFees returns a copy of the context with an updated fee. -func (bldr TxBuilder) WithFees(fees string) TxBuilder { - parsedFees, err := sdk.ParseCoins(fees) - if err != nil { - panic(err) - } - - bldr.fees = parsedFees - return bldr -} - -// WithGasPrices returns a copy of the context with updated gas prices. -func (bldr TxBuilder) WithGasPrices(gasPrices string) TxBuilder { - parsedGasPrices, err := sdk.ParseDecCoins(gasPrices) - if err != nil { - panic(err) - } - - bldr.gasPrices = parsedGasPrices - return bldr -} - -// WithKeybase returns a copy of the context with updated keybase. -func (bldr TxBuilder) WithKeybase(keybase keyring.Keyring) TxBuilder { - bldr.keybase = keybase - return bldr -} - -// WithSequence returns a copy of the context with an updated sequence number. -func (bldr TxBuilder) WithSequence(sequence uint64) TxBuilder { - bldr.sequence = sequence - return bldr -} - -// WithMemo returns a copy of the context with an updated memo. -func (bldr TxBuilder) WithMemo(memo string) TxBuilder { - bldr.memo = strings.TrimSpace(memo) - return bldr -} - -// WithAccountNumber returns a copy of the context with an account number. -func (bldr TxBuilder) WithAccountNumber(accnum uint64) TxBuilder { - bldr.accountNumber = accnum - return bldr -} - -// BuildSignMsg builds a single message to be signed from a TxBuilder given a -// set of messages. It returns an error if a fee is supplied but cannot be -// parsed. -func (bldr TxBuilder) BuildSignMsg(msgs []sdk.Msg) (StdSignMsg, error) { - if bldr.chainID == "" { - return StdSignMsg{}, fmt.Errorf("chain ID required but not specified") - } - - fees := bldr.fees - if !bldr.gasPrices.IsZero() { - if !fees.IsZero() { - return StdSignMsg{}, errors.New("cannot provide both fees and gas prices") - } - - glDec := sdk.NewDec(int64(bldr.gas)) - - // Derive the fees based on the provided gas prices, where - // fee = ceil(gasPrice * gasLimit). - fees = make(sdk.Coins, len(bldr.gasPrices)) - for i, gp := range bldr.gasPrices { - fee := gp.Amount.Mul(glDec) - fees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) - } - } - - return StdSignMsg{ - ChainID: bldr.chainID, - AccountNumber: bldr.accountNumber, - Sequence: bldr.sequence, - Memo: bldr.memo, - Msgs: msgs, - Fee: NewStdFee(bldr.gas, fees), - }, nil -} - -// Sign signs a transaction given a name and a single message to be signed. -// Returns error if signing fails. -func (bldr TxBuilder) Sign(name string, msg StdSignMsg) ([]byte, error) { - sig, err := MakeSignature(bldr.keybase, name, msg) - if err != nil { - return nil, err - } - - return bldr.txEncoder(NewStdTx(msg.Msgs, msg.Fee, []StdSignature{sig}, msg.Memo)) -} - -// BuildAndSign builds a single message to be signed, and signs a transaction -// with the built message given a name and a set of messages. -func (bldr TxBuilder) BuildAndSign(name string, msgs []sdk.Msg) ([]byte, error) { - msg, err := bldr.BuildSignMsg(msgs) - if err != nil { - return nil, err - } - - return bldr.Sign(name, msg) -} - -// BuildTxForSim creates a StdSignMsg and encodes a transaction with the -// StdSignMsg with a single empty StdSignature for tx simulation. -func (bldr TxBuilder) BuildTxForSim(msgs []sdk.Msg) ([]byte, error) { - signMsg, err := bldr.BuildSignMsg(msgs) - if err != nil { - return nil, err - } - - // the ante handler will populate with a sentinel pubkey - sigs := []StdSignature{{}} - return bldr.txEncoder(NewStdTx(signMsg.Msgs, signMsg.Fee, sigs, signMsg.Memo)) -} - -// SignStdTx appends a signature to a StdTx and returns a copy of it. If append -// is false, it replaces the signatures already attached with the new signature. -func (bldr TxBuilder) SignStdTx(name string, stdTx StdTx, appendSig bool) (signedStdTx StdTx, err error) { - if bldr.chainID == "" { - return StdTx{}, fmt.Errorf("chain ID required but not specified") - } - - stdSignature, err := MakeSignature(bldr.keybase, name, StdSignMsg{ - ChainID: bldr.chainID, - AccountNumber: bldr.accountNumber, - Sequence: bldr.sequence, - Fee: stdTx.Fee, - Msgs: stdTx.GetMsgs(), - Memo: stdTx.GetMemo(), - }) - if err != nil { - return - } - - sigs := stdTx.Signatures - if len(sigs) == 0 || !appendSig { - sigs = []StdSignature{stdSignature} - } else { - sigs = append(sigs, stdSignature) - } - signedStdTx = NewStdTx(stdTx.GetMsgs(), stdTx.Fee, sigs, stdTx.GetMemo()) - return -} - -// MakeSignature builds a StdSignature given a keyring, key name, and a StdSignMsg. -func MakeSignature(kr keyring.Keyring, name string, msg StdSignMsg) (sig StdSignature, err error) { - if kr == nil { - kr, err = keyring.New(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), os.Stdin) - if err != nil { - return - } - } - - sigBytes, pubkey, err := kr.Sign(name, msg.Bytes()) - if err != nil { - return - } - - return StdSignature{ - PubKey: pubkey, - Signature: sigBytes, - }, nil -} diff --git a/x/auth/types/txbuilder_test.go b/x/auth/types/txbuilder_test.go deleted file mode 100644 index fc007eb679b5..000000000000 --- a/x/auth/types/txbuilder_test.go +++ /dev/null @@ -1,150 +0,0 @@ -package types - -import ( - "reflect" - "testing" - - "github.com/cosmos/cosmos-sdk/testutil/testdata" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func TestTxBuilderBuild(t *testing.T) { - type fields struct { - TxEncoder sdk.TxEncoder - AccountNumber uint64 - Sequence uint64 - Gas uint64 - GasAdjustment float64 - SimulateGas bool - ChainID string - Memo string - Fees sdk.Coins - GasPrices sdk.DecCoins - } - defaultMsg := []sdk.Msg{testdata.NewTestMsg(addr)} - tests := []struct { - name string - fields fields - msgs []sdk.Msg - want StdSignMsg - wantErr bool - }{ - { - "builder with fees", - fields{ - TxEncoder: DefaultTxEncoder(codec.New()), - AccountNumber: 1, - Sequence: 1, - Gas: 200000, - GasAdjustment: 1.1, - SimulateGas: false, - ChainID: "test-chain", - Memo: "hello from Voyager 1!", - Fees: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))), - }, - defaultMsg, - StdSignMsg{ - ChainID: "test-chain", - AccountNumber: 1, - Sequence: 1, - Memo: "hello from Voyager 1!", - Msgs: defaultMsg, - Fee: NewStdFee(200000, sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))}), - }, - false, - }, - { - "builder with gas prices", - fields{ - TxEncoder: DefaultTxEncoder(codec.New()), - AccountNumber: 1, - Sequence: 1, - Gas: 200000, - GasAdjustment: 1.1, - SimulateGas: false, - ChainID: "test-chain", - Memo: "hello from Voyager 2!", - GasPrices: sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(10000, sdk.Precision))}, - }, - defaultMsg, - StdSignMsg{ - ChainID: "test-chain", - AccountNumber: 1, - Sequence: 1, - Memo: "hello from Voyager 2!", - Msgs: defaultMsg, - Fee: NewStdFee(200000, sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))}), - }, - false, - }, - { - "no chain-id supplied", - fields{ - TxEncoder: DefaultTxEncoder(codec.New()), - AccountNumber: 1, - Sequence: 1, - Gas: 200000, - GasAdjustment: 1.1, - SimulateGas: false, - ChainID: "", - Memo: "hello from Voyager 1!", - Fees: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))), - }, - defaultMsg, - StdSignMsg{ - ChainID: "test-chain", - AccountNumber: 1, - Sequence: 1, - Memo: "hello from Voyager 1!", - Msgs: defaultMsg, - Fee: NewStdFee(200000, sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))}), - }, - true, - }, - { - "builder w/ fees and gas prices", - fields{ - TxEncoder: DefaultTxEncoder(codec.New()), - AccountNumber: 1, - Sequence: 1, - Gas: 200000, - GasAdjustment: 1.1, - SimulateGas: false, - ChainID: "test-chain", - Memo: "hello from Voyager 1!", - Fees: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))), - GasPrices: sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(10000, sdk.Precision))}, - }, - defaultMsg, - StdSignMsg{ - ChainID: "test-chain", - AccountNumber: 1, - Sequence: 1, - Memo: "hello from Voyager 1!", - Msgs: defaultMsg, - Fee: NewStdFee(200000, sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))}), - }, - true, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - bldr := NewTxBuilder( - tt.fields.TxEncoder, tt.fields.AccountNumber, tt.fields.Sequence, - tt.fields.Gas, tt.fields.GasAdjustment, tt.fields.SimulateGas, - tt.fields.ChainID, tt.fields.Memo, tt.fields.Fees, tt.fields.GasPrices, - ) - got, err := bldr.BuildSignMsg(tt.msgs) - require.Equal(t, tt.wantErr, (err != nil)) - if err == nil { - require.True(t, reflect.DeepEqual(tt.want, got)) - } - }) - } -}