Skip to content

Commit

Permalink
copied /tx POST from terra-money/core/pull/551
Browse files Browse the repository at this point in the history
  • Loading branch information
reuvenpo authored and Cashmaney committed Mar 16, 2022
1 parent 1c6a301 commit 99c75cc
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
119 changes: 119 additions & 0 deletions x/auth/client/rest/broadcast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package rest

import (
"errors"
"fmt"
"io/ioutil"
"net/http"

"github.com/cosmos/cosmos-sdk/client"
clientrest "github.com/cosmos/cosmos-sdk/client/rest"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)

// BroadcastReq defines a tx broadcasting request.
type BroadcastReq struct {
Tx legacytx.StdTx `json:"tx" yaml:"tx"`
Mode string `json:"mode" yaml:"mode"`
Sequences []uint64 `json:"sequences" yaml:"sequences"`
FeeGranter string `json:"fee_granter" yaml:"fee_granter"`
}

var _ codectypes.UnpackInterfacesMessage = BroadcastReq{}

// UnpackInterfaces implements the UnpackInterfacesMessage interface.
func (m BroadcastReq) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
return m.Tx.UnpackInterfaces(unpacker)
}

// BroadcastTxRequest implements a tx broadcasting handler that is responsible
// for broadcasting a valid and signed tx to a full node. The tx can be
// broadcasted via a sync|async|block mechanism.
func BroadcastTxRequest(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req BroadcastReq

body, err := ioutil.ReadAll(r.Body)
if rest.CheckBadRequestError(w, err) {
return
}

// NOTE: amino is used intentionally here, don't migrate it!
err = clientCtx.LegacyAmino.UnmarshalJSON(body, &req)
if err != nil {
err := fmt.Errorf("this transaction cannot be broadcasted via legacy REST endpoints, because it does not support"+
" Amino serialization. Please either use CLI, gRPC, gRPC-gateway, or directly query the Tendermint RPC"+
" endpoint to broadcast this transaction. The new REST endpoint (via gRPC-gateway) is POST /cosmos/tx/v1beta1/txs."+
" Please also see the REST endpoints migration guide at %s for more info", clientrest.DeprecationURL)
if rest.CheckBadRequestError(w, err) {
return
}
}

txBuilder := clientCtx.TxConfig.NewTxBuilder()
txBuilder.SetFeeAmount(req.Tx.GetFee())
txBuilder.SetGasLimit(req.Tx.GetGas())
txBuilder.SetMemo(req.Tx.GetMemo())
if err := txBuilder.SetMsgs(req.Tx.GetMsgs()...); rest.CheckBadRequestError(w, err) {
return
}

txBuilder.SetTimeoutHeight(req.Tx.GetTimeoutHeight())
if req.FeeGranter != "" {
addr, err := sdk.AccAddressFromBech32(req.FeeGranter)
if rest.CheckBadRequestError(w, err) {
return
}

txBuilder.SetFeeGranter(addr)
}

signatures, err := req.Tx.GetSignaturesV2()
if rest.CheckBadRequestError(w, err) {
return
}

// if sequence is not given, try fetch from the chain
if len(req.Sequences) == 0 {
for _, sig := range signatures {
_, seq, err := clientCtx.AccountRetriever.GetAccountNumberSequence(clientCtx, sdk.AccAddress(sig.PubKey.Address().Bytes()))
if rest.CheckBadRequestError(w, err) {
return
}
req.Sequences = append(req.Sequences, seq)
}
}

// check the sequence nubmer is equal with the signature nubmer
if len(signatures) != len(req.Sequences) {
rest.CheckBadRequestError(w, errors.New("Must provide each signers's sequence number"))
return
}

// fill sequence number to new signature
for i, seq := range req.Sequences {
signatures[i].Sequence = seq
}

if err := txBuilder.SetSignatures(signatures...); rest.CheckBadRequestError(w, err) {
return
}

// compute signature bytes
txBytes, err := clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
if rest.CheckInternalServerError(w, err) {
return
}

clientCtx = clientCtx.WithBroadcastMode(req.Mode)
res, err := clientCtx.BroadcastTx(txBytes)
if rest.CheckInternalServerError(w, err) {
return
}

rest.PostProcessResponseBare(w, clientCtx, res)
}
}
1 change: 1 addition & 0 deletions x/auth/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func RegisterTxRoutes(clientCtx client.Context, rtr *mux.Router) {
r := rest.WithHTTPDeprecationHeaders(rtr)
r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(clientCtx)).Methods("GET")
r.HandleFunc("/txs", QueryTxsRequestHandlerFn(clientCtx)).Methods("GET")
r.HandleFunc("/txs", BroadcastTxRequest(clientCtx)).Methods("POST")
r.HandleFunc("/txs/encode", EncodeTxRequest(clientCtx)).Methods("POST")
r.HandleFunc("/txs/decode", DecodeTxRequestHandlerFn(clientCtx)).Methods("POST")
}

0 comments on commit 99c75cc

Please sign in to comment.