cosmos-sdk/x/auth/middleware/tx.go
Amaury b3e922d08b
refactor: Move TxDecoder into its own middleware (#10612)
* WIP: middleware refactor

* refactor `tx.Request`

* Add MsgResponses any in sdk.Result

* add helper functions in abci

* refactor tips

* review changes

* Fix mock tests

* Update baseapp/abci.go

* Update baseapp/abci.go

* Update types/tx/middleware.go

* Update types/tx/middleware.go

* tx.Response to abci conversion

* refactor makeABCIData

* Add comments

* Fix build

* fix build error

* fix tests

* fix test

* fix tests

* Fix TestSimulateTx

* fix tests

* fix test

* Fix build

* Simplify code

* fix test build

* Use repeated bytes in txMsgData

* Fix grpc-gateway test

* Make proto-gen

* Automagically register MsgResponse

* review changes

* Use froydi's trick

* Use Any in TxMsgData

* Finally remove API breaking change

* Revert unnecessary stuff

* refactor: Move TxDecoder into its own middleware

* Add test for txDecoderMiddleware

* Fix some baseapp tests

* Fix some more tests

* Fix mock tests

* Fix middleware tests

* Add cl

* Fix tests

* Update types/tx/middleware.go

Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com>

Co-authored-by: atheesh <atheesh@vitwit.com>
Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com>
2021-12-06 10:26:15 +01:00

78 lines
2.2 KiB
Go

package middleware
import (
"context"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx"
)
type txDecoderHandler struct {
next tx.Handler
txDecoder sdk.TxDecoder
}
// NewTxDecoderMiddleware creates a new middleware that will decode tx bytes
// into a sdk.Tx. As input request, at least one of Tx or TxBytes must be set.
// If only TxBytes is set, then TxDecoderMiddleware will populate the Tx field.
// If only Tx is set, then TxBytes will be left empty, but some middlewares
// such as signature verification might fail.
func NewTxDecoderMiddleware(txDecoder sdk.TxDecoder) tx.Middleware {
return func(txh tx.Handler) tx.Handler {
return txDecoderHandler{next: txh, txDecoder: txDecoder}
}
}
var _ tx.Handler = gasTxHandler{}
// CheckTx implements tx.Handler.CheckTx.
func (h txDecoderHandler) CheckTx(ctx context.Context, req tx.Request, checkReq tx.RequestCheckTx) (tx.Response, tx.ResponseCheckTx, error) {
newReq, err := h.populateReq(req)
if err != nil {
return tx.Response{}, tx.ResponseCheckTx{}, err
}
return h.next.CheckTx(ctx, newReq, checkReq)
}
// DeliverTx implements tx.Handler.DeliverTx.
func (h txDecoderHandler) DeliverTx(ctx context.Context, req tx.Request) (tx.Response, error) {
newReq, err := h.populateReq(req)
if err != nil {
return tx.Response{}, err
}
return h.next.DeliverTx(ctx, newReq)
}
// SimulateTx implements tx.Handler.SimulateTx method.
func (h txDecoderHandler) SimulateTx(ctx context.Context, req tx.Request) (tx.Response, error) {
newReq, err := h.populateReq(req)
if err != nil {
return tx.Response{}, err
}
return h.next.SimulateTx(ctx, newReq)
}
// populateReq takes a tx.Request, and if its Tx field is not set, then
// decodes the TxBytes and populates the decoded Tx field. It leaves
// req.TxBytes untouched.
func (h txDecoderHandler) populateReq(req tx.Request) (tx.Request, error) {
if len(req.TxBytes) == 0 && req.Tx == nil {
return tx.Request{}, sdkerrors.ErrInvalidRequest.Wrap("got empty tx request")
}
sdkTx := req.Tx
var err error
if len(req.TxBytes) != 0 {
sdkTx, err = h.txDecoder(req.TxBytes)
if err != nil {
return tx.Request{}, err
}
}
return tx.Request{Tx: sdkTx, TxBytes: req.TxBytes}, nil
}