Incorporating @ValarDragon's comments
This commit is contained in:
parent
fb5fe9914d
commit
f36f749818
|
@ -9,6 +9,7 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||||
amino "github.com/tendermint/go-amino"
|
amino "github.com/tendermint/go-amino"
|
||||||
|
"github.com/tendermint/tendermint/libs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultGasAdjustment is applied to gas estimates to avoid tx
|
// DefaultGasAdjustment is applied to gas estimates to avoid tx
|
||||||
|
@ -58,7 +59,7 @@ func SendTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
txCtx, err = enrichCtxWithGasIfGasAuto(txCtx, cliCtx, cliCtx.FromAddressName, passphrase, msgs)
|
txCtx, err = enrichCtxWithGasIfGasAuto(txCtx, cliCtx, passphrase, msgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -72,35 +73,43 @@ func SendTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg)
|
||||||
return cliCtx.EnsureBroadcastTx(txBytes)
|
return cliCtx.EnsureBroadcastTx(txBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func enrichCtxWithGasIfGasAuto(txCtx authctx.TxContext, cliCtx context.CLIContext, name, passphrase string, msgs []sdk.Msg) (authctx.TxContext, error) {
|
func enrichCtxWithGasIfGasAuto(txCtx authctx.TxContext, cliCtx context.CLIContext, passphrase string, msgs []sdk.Msg) (authctx.TxContext, error) {
|
||||||
if cliCtx.Gas == 0 {
|
if cliCtx.Gas == 0 {
|
||||||
return EnrichTxContextWithGas(txCtx, cliCtx, name, passphrase, msgs)
|
txBytes, err := BuildAndSignTxWithZeroGas(txCtx, cliCtx.FromAddressName, passphrase, msgs)
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, err
|
||||||
|
}
|
||||||
|
estimate, adjusted, err := CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, cliCtx.GasAdjustment)
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, err
|
||||||
|
}
|
||||||
|
fmt.Fprintf(os.Stderr, "gas: [estimated = %v] [adjusted = %v]\n", estimate, adjusted)
|
||||||
|
return txCtx.WithGas(adjusted), nil
|
||||||
}
|
}
|
||||||
return txCtx, nil
|
return txCtx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnrichTxContextWithGas simulates the execution of a transaction to
|
// BuildAndSignTxWithZeroGas builds transactions with GasWanted set to 0.
|
||||||
// then populate the relevant TxContext.Gas field with the estimate
|
func BuildAndSignTxWithZeroGas(txCtx authctx.TxContext, name, passphrase string, msgs []sdk.Msg) ([]byte, error) {
|
||||||
// obtained by the query.
|
return txCtx.WithGas(0).BuildAndSign(name, passphrase, msgs)
|
||||||
func EnrichTxContextWithGas(txCtx authctx.TxContext, cliCtx context.CLIContext, name, passphrase string, msgs []sdk.Msg) (authctx.TxContext, error) {
|
}
|
||||||
txCtxSimulation := txCtx.WithGas(0)
|
|
||||||
txBytes, err := txCtxSimulation.BuildAndSign(name, passphrase, msgs)
|
// CalculateGas simulates the execution of a transaction and returns
|
||||||
if err != nil {
|
// both the estimate obtained by the query and the adjusted amount.
|
||||||
return txCtx, err
|
func CalculateGas(queryFunc func(string, common.HexBytes) ([]byte, error), cdc *amino.Codec, txBytes []byte, adjustment float64) (estimate, adjusted int64, err error) {
|
||||||
}
|
|
||||||
// run a simulation (via /app/simulate query) to
|
// run a simulation (via /app/simulate query) to
|
||||||
// estimate gas and update TxContext accordingly
|
// estimate gas and update TxContext accordingly
|
||||||
rawRes, err := cliCtx.Query("/app/simulate", txBytes)
|
rawRes, err := queryFunc("/app/simulate", txBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return txCtx, err
|
return
|
||||||
}
|
}
|
||||||
estimate, err := parseQueryResponse(cliCtx.Codec, rawRes)
|
estimate, err = parseQueryResponse(cdc, rawRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return txCtx, err
|
return
|
||||||
}
|
}
|
||||||
adjusted := adjustGasEstimate(estimate, cliCtx.GasAdjustment)
|
adjusted = adjustGasEstimate(estimate, adjustment)
|
||||||
fmt.Fprintf(os.Stderr, "gas: [estimated = %v] [adjusted = %v]\n", estimate, adjusted)
|
fmt.Fprintf(os.Stderr, "gas: [estimated = %v] [adjusted = %v]\n", estimate, adjusted)
|
||||||
return txCtx.WithGas(adjusted), nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func adjustGasEstimate(estimate int64, adjustment float64) int64 {
|
func adjustGasEstimate(estimate int64, adjustment float64) int64 {
|
||||||
|
|
|
@ -86,11 +86,12 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLICo
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.Gas == 0 {
|
if m.Gas == 0 {
|
||||||
txCtx, err = utils.EnrichTxContextWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
newCtx, httperr, err := enrichContextWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
utils.WriteErrorResponse(&w, httperr, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
txCtx = newCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||||
|
@ -114,3 +115,15 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLICo
|
||||||
w.Write(output)
|
w.Write(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enrichContextWithGas(txCtx authctx.TxContext, cliCtx context.CLIContext, name, password string, msg sdk.Msg) (authctx.TxContext, int, error) {
|
||||||
|
txBytes, err := utils.BuildAndSignTxWithZeroGas(txCtx, name, password, []sdk.Msg{msg})
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
_, adjusted, err := utils.CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, cliCtx.GasAdjustment)
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusUnauthorized, err
|
||||||
|
}
|
||||||
|
return txCtx.WithGas(adjusted), http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
|
@ -77,11 +77,12 @@ func signAndBuild(w http.ResponseWriter, cliCtx context.CLIContext, baseReq base
|
||||||
}
|
}
|
||||||
|
|
||||||
if baseReq.Gas == 0 {
|
if baseReq.Gas == 0 {
|
||||||
txCtx, err = utils.EnrichTxContextWithGas(txCtx, cliCtx, baseReq.Name, baseReq.Password, []sdk.Msg{msg})
|
newCtx, httperr, err := enrichContextWithGas(txCtx, cliCtx, baseReq.Name, baseReq.Password, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
utils.WriteErrorResponse(&w, httperr, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
txCtx = newCtx
|
||||||
}
|
}
|
||||||
txBytes, err := txCtx.BuildAndSign(baseReq.Name, baseReq.Password, []sdk.Msg{msg})
|
txBytes, err := txCtx.BuildAndSign(baseReq.Name, baseReq.Password, []sdk.Msg{msg})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -115,3 +116,15 @@ func parseInt64OrReturnBadRequest(s string, w http.ResponseWriter) (n int64, ok
|
||||||
}
|
}
|
||||||
return n, true
|
return n, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enrichContextWithGas(txCtx authctx.TxContext, cliCtx context.CLIContext, name, password string, msg sdk.Msg) (authctx.TxContext, int, error) {
|
||||||
|
txBytes, err := utils.BuildAndSignTxWithZeroGas(txCtx, name, password, []sdk.Msg{msg})
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
_, adjusted, err := utils.CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, cliCtx.GasAdjustment)
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusUnauthorized, err
|
||||||
|
}
|
||||||
|
return txCtx.WithGas(adjusted), http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
|
@ -77,12 +77,12 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.Gas == 0 {
|
if m.Gas == 0 {
|
||||||
txCtx, err = utils.EnrichTxContextWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
newCtx, httperr, err := enrichContextWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
utils.WriteErrorResponse(&w, httperr, err.Error())
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
txCtx = newCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||||
|
@ -106,3 +106,15 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
|
||||||
w.Write(output)
|
w.Write(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enrichContextWithGas(txCtx authctx.TxContext, cliCtx context.CLIContext, name, password string, msg sdk.Msg) (authctx.TxContext, int, error) {
|
||||||
|
txBytes, err := utils.BuildAndSignTxWithZeroGas(txCtx, name, password, []sdk.Msg{msg})
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
_, adjusted, err := utils.CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, cliCtx.GasAdjustment)
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusUnauthorized, err
|
||||||
|
}
|
||||||
|
return txCtx.WithGas(adjusted), http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
|
@ -78,11 +78,12 @@ func unjailRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLI
|
||||||
msg := slashing.NewMsgUnjail(validatorAddr)
|
msg := slashing.NewMsgUnjail(validatorAddr)
|
||||||
|
|
||||||
if m.Gas == 0 {
|
if m.Gas == 0 {
|
||||||
txCtx, err = utils.EnrichTxContextWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
newCtx, httperr, err := enrichContextWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
utils.WriteErrorResponse(&w, httperr, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
txCtx = newCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||||
|
@ -106,3 +107,15 @@ func unjailRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLI
|
||||||
w.Write(output)
|
w.Write(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enrichContextWithGas(txCtx authctx.TxContext, cliCtx context.CLIContext, name, password string, msg sdk.Msg) (authctx.TxContext, int, error) {
|
||||||
|
txBytes, err := utils.BuildAndSignTxWithZeroGas(txCtx, name, password, []sdk.Msg{msg})
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
_, adjusted, err := utils.CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, cliCtx.GasAdjustment)
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusUnauthorized, err
|
||||||
|
}
|
||||||
|
return txCtx.WithGas(adjusted), http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
|
@ -276,11 +276,12 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
||||||
m.Sequence++
|
m.Sequence++
|
||||||
|
|
||||||
if m.Gas == 0 {
|
if m.Gas == 0 {
|
||||||
txCtx, err = utils.EnrichTxContextWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
newCtx, httperr, err := enrichContextWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
utils.WriteErrorResponse(&w, httperr, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
txCtx = newCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||||
|
@ -315,3 +316,15 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
||||||
w.Write(output)
|
w.Write(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enrichContextWithGas(txCtx authcliCtx.TxContext, cliCtx context.CLIContext, name, password string, msg sdk.Msg) (authcliCtx.TxContext, int, error) {
|
||||||
|
txBytes, err := utils.BuildAndSignTxWithZeroGas(txCtx, name, password, []sdk.Msg{msg})
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
_, adjusted, err := utils.CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, cliCtx.GasAdjustment)
|
||||||
|
if err != nil {
|
||||||
|
return txCtx, http.StatusUnauthorized, err
|
||||||
|
}
|
||||||
|
return txCtx.WithGas(adjusted), http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue