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>
This commit is contained in:
parent
9566c99185
commit
b3e922d08b
|
@ -112,6 +112,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
* (x/gov) [\#10373](https://github.com/cosmos/cosmos-sdk/pull/10373) Removed gov `keeper.{MustMarshal, MustUnmarshal}`.
|
||||
* [\#10348](https://github.com/cosmos/cosmos-sdk/pull/10348) StdSignBytes takes a new argument of type `*tx.Tip` for signing over tips using LEGACY_AMINO_JSON.
|
||||
* [\#10208](https://github.com/cosmos/cosmos-sdk/pull/10208) The `x/auth/signing.Tx` interface now also includes a new `GetTip() *tx.Tip` method for verifying tipped transactions. The `x/auth/types` expected BankKeeper interface now expects the `SendCoins` method too.
|
||||
* [\#10612](https://github.com/cosmos/cosmos-sdk/pull/10612) `baseapp.NewBaseApp` constructor function doesn't take the `sdk.TxDecoder` anymore. This logic has been moved into the TxDecoderMiddleware.
|
||||
|
||||
### Client Breaking Changes
|
||||
|
||||
|
|
|
@ -250,13 +250,8 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
|||
panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type))
|
||||
}
|
||||
|
||||
reqTx, err := app.txDecoder(req.Tx)
|
||||
if err != nil {
|
||||
return sdkerrors.ResponseCheckTx(err, 0, 0, app.trace)
|
||||
}
|
||||
|
||||
ctx := app.getContextForTx(mode, req.Tx)
|
||||
res, checkRes, err := app.txHandler.CheckTx(ctx, tx.Request{Tx: reqTx, TxBytes: req.Tx}, tx.RequestCheckTx{Type: req.Type})
|
||||
res, checkRes, err := app.txHandler.CheckTx(ctx, tx.Request{TxBytes: req.Tx}, tx.RequestCheckTx{Type: req.Type})
|
||||
if err != nil {
|
||||
return sdkerrors.ResponseCheckTx(err, uint64(res.GasUsed), uint64(res.GasWanted), app.trace)
|
||||
}
|
||||
|
@ -285,14 +280,9 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx
|
|||
}
|
||||
}
|
||||
}()
|
||||
reqTx, err := app.txDecoder(req.Tx)
|
||||
if err != nil {
|
||||
abciRes = sdkerrors.ResponseDeliverTx(err, 0, 0, app.trace)
|
||||
return abciRes
|
||||
}
|
||||
|
||||
ctx := app.getContextForTx(runTxModeDeliver, req.Tx)
|
||||
res, err := app.txHandler.DeliverTx(ctx, tx.Request{Tx: reqTx, TxBytes: req.Tx})
|
||||
res, err := app.txHandler.DeliverTx(ctx, tx.Request{TxBytes: req.Tx})
|
||||
if err != nil {
|
||||
abciRes = sdkerrors.ResponseDeliverTx(err, uint64(res.GasUsed), uint64(res.GasWanted), app.trace)
|
||||
return abciRes
|
||||
|
|
|
@ -25,20 +25,20 @@ func TestGetBlockRentionHeight(t *testing.T) {
|
|||
expected int64
|
||||
}{
|
||||
"defaults": {
|
||||
bapp: baseapp.NewBaseApp(name, logger, db, nil),
|
||||
bapp: baseapp.NewBaseApp(name, logger, db),
|
||||
maxAgeBlocks: 0,
|
||||
commitHeight: 499000,
|
||||
expected: 0,
|
||||
},
|
||||
"pruning unbonding time only": {
|
||||
bapp: baseapp.NewBaseApp(name, logger, db, nil, baseapp.SetMinRetainBlocks(1)),
|
||||
bapp: baseapp.NewBaseApp(name, logger, db, baseapp.SetMinRetainBlocks(1)),
|
||||
maxAgeBlocks: 362880,
|
||||
commitHeight: 499000,
|
||||
expected: 136120,
|
||||
},
|
||||
"pruning iavl snapshot only": {
|
||||
bapp: baseapp.NewBaseApp(
|
||||
name, logger, db, nil,
|
||||
name, logger, db,
|
||||
baseapp.SetPruning(sdk.PruningOptions{KeepEvery: 10000}),
|
||||
baseapp.SetMinRetainBlocks(1),
|
||||
),
|
||||
|
@ -48,7 +48,7 @@ func TestGetBlockRentionHeight(t *testing.T) {
|
|||
},
|
||||
"pruning state sync snapshot only": {
|
||||
bapp: baseapp.NewBaseApp(
|
||||
name, logger, db, nil,
|
||||
name, logger, db,
|
||||
baseapp.SetSnapshotInterval(50000),
|
||||
baseapp.SetSnapshotKeepRecent(3),
|
||||
baseapp.SetMinRetainBlocks(1),
|
||||
|
@ -59,7 +59,7 @@ func TestGetBlockRentionHeight(t *testing.T) {
|
|||
},
|
||||
"pruning min retention only": {
|
||||
bapp: baseapp.NewBaseApp(
|
||||
name, logger, db, nil,
|
||||
name, logger, db,
|
||||
baseapp.SetMinRetainBlocks(400000),
|
||||
),
|
||||
maxAgeBlocks: 0,
|
||||
|
@ -68,7 +68,7 @@ func TestGetBlockRentionHeight(t *testing.T) {
|
|||
},
|
||||
"pruning all conditions": {
|
||||
bapp: baseapp.NewBaseApp(
|
||||
name, logger, db, nil,
|
||||
name, logger, db,
|
||||
baseapp.SetPruning(sdk.PruningOptions{KeepEvery: 10000}),
|
||||
baseapp.SetMinRetainBlocks(400000),
|
||||
baseapp.SetSnapshotInterval(50000), baseapp.SetSnapshotKeepRecent(3),
|
||||
|
@ -79,7 +79,7 @@ func TestGetBlockRentionHeight(t *testing.T) {
|
|||
},
|
||||
"no pruning due to no persisted state": {
|
||||
bapp: baseapp.NewBaseApp(
|
||||
name, logger, db, nil,
|
||||
name, logger, db,
|
||||
baseapp.SetPruning(sdk.PruningOptions{KeepEvery: 10000}),
|
||||
baseapp.SetMinRetainBlocks(400000),
|
||||
baseapp.SetSnapshotInterval(50000), baseapp.SetSnapshotKeepRecent(3),
|
||||
|
@ -90,7 +90,7 @@ func TestGetBlockRentionHeight(t *testing.T) {
|
|||
},
|
||||
"disable pruning": {
|
||||
bapp: baseapp.NewBaseApp(
|
||||
name, logger, db, nil,
|
||||
name, logger, db,
|
||||
baseapp.SetPruning(sdk.PruningOptions{KeepEvery: 10000}),
|
||||
baseapp.SetMinRetainBlocks(0),
|
||||
baseapp.SetSnapshotInterval(50000), baseapp.SetSnapshotKeepRecent(3),
|
||||
|
@ -127,7 +127,7 @@ func TestBaseAppCreateQueryContextRejectsNegativeHeights(t *testing.T) {
|
|||
logger := defaultLogger()
|
||||
db := dbm.NewMemDB()
|
||||
name := t.Name()
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil)
|
||||
app := baseapp.NewBaseApp(name, logger, db)
|
||||
|
||||
proves := []bool{
|
||||
false, true,
|
||||
|
|
|
@ -52,7 +52,6 @@ type BaseApp struct { // nolint: maligned
|
|||
queryRouter sdk.QueryRouter // router for redirecting query calls
|
||||
grpcQueryRouter *GRPCQueryRouter // router for redirecting gRPC query calls
|
||||
interfaceRegistry types.InterfaceRegistry
|
||||
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
|
||||
|
||||
txHandler tx.Handler // txHandler for {Deliver,Check}Tx and simulations
|
||||
initChainer sdk.InitChainer // initialize state with validators and state blob
|
||||
|
@ -137,7 +136,7 @@ type BaseApp struct { // nolint: maligned
|
|||
//
|
||||
// NOTE: The db is used to store the version number for now.
|
||||
func NewBaseApp(
|
||||
name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),
|
||||
name string, logger log.Logger, db dbm.DB, options ...func(*BaseApp),
|
||||
) *BaseApp {
|
||||
app := &BaseApp{
|
||||
logger: logger,
|
||||
|
@ -147,7 +146,6 @@ func NewBaseApp(
|
|||
storeLoader: DefaultStoreLoader,
|
||||
queryRouter: NewQueryRouter(),
|
||||
grpcQueryRouter: NewGRPCQueryRouter(),
|
||||
txDecoder: txDecoder,
|
||||
fauxMerkleMode: false,
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/snapshots"
|
||||
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
|
||||
"github.com/cosmos/cosmos-sdk/store/rootmulti"
|
||||
|
@ -40,9 +41,13 @@ var (
|
|||
capKey1 = sdk.NewKVStoreKey("key1")
|
||||
capKey2 = sdk.NewKVStoreKey("key2")
|
||||
|
||||
interfaceRegistry = testdata.NewTestInterfaceRegistry()
|
||||
encCfg = simapp.MakeTestEncodingConfig()
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerTestCodec(encCfg.Amino)
|
||||
}
|
||||
|
||||
type paramStore struct {
|
||||
db *dbm.MemDB
|
||||
}
|
||||
|
@ -90,13 +95,10 @@ func newBaseApp(name string, options ...func(*baseapp.BaseApp)) *baseapp.BaseApp
|
|||
db := dbm.NewMemDB()
|
||||
codec := codec.NewLegacyAmino()
|
||||
registerTestCodec(codec)
|
||||
return baseapp.NewBaseApp(name, logger, db, testTxDecoder(codec), options...)
|
||||
return baseapp.NewBaseApp(name, logger, db, options...)
|
||||
}
|
||||
|
||||
func registerTestCodec(cdc *codec.LegacyAmino) {
|
||||
// register Tx, Msg
|
||||
sdk.RegisterLegacyAminoCodec(cdc)
|
||||
|
||||
// register test types
|
||||
cdc.RegisterConcrete(&txTest{}, "cosmos-sdk/baseapp/txTest", nil)
|
||||
cdc.RegisterConcrete(&msgCounter{}, "cosmos-sdk/baseapp/msgCounter", nil)
|
||||
|
@ -106,10 +108,7 @@ func registerTestCodec(cdc *codec.LegacyAmino) {
|
|||
}
|
||||
|
||||
// aminoTxEncoder creates a amino TxEncoder for testing purposes.
|
||||
func aminoTxEncoder() sdk.TxEncoder {
|
||||
cdc := codec.NewLegacyAmino()
|
||||
registerTestCodec(cdc)
|
||||
|
||||
func aminoTxEncoder(cdc *codec.LegacyAmino) sdk.TxEncoder {
|
||||
return legacytx.StdTxConfig{Cdc: cdc}.TxEncoder()
|
||||
}
|
||||
|
||||
|
@ -132,6 +131,7 @@ func setupBaseApp(t *testing.T, options ...func(*baseapp.BaseApp)) *baseapp.Base
|
|||
func testTxHandler(options middleware.TxHandlerOptions, customTxHandlerMiddleware handlerFun) tx.Handler {
|
||||
return middleware.ComposeMiddlewares(
|
||||
middleware.NewRunMsgsTxHandler(options.MsgServiceRouter, options.LegacyRouter),
|
||||
middleware.NewTxDecoderMiddleware(options.TxDecoder),
|
||||
middleware.GasTxMiddleware,
|
||||
middleware.RecoveryTxMiddleware,
|
||||
middleware.NewIndexEventsTxMiddleware(options.IndexEvents),
|
||||
|
@ -161,7 +161,8 @@ func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) { return ctx, nil },
|
||||
)
|
||||
|
@ -200,7 +201,7 @@ func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options
|
|||
tx.Msgs = append(tx.Msgs, msgKeyValue{Key: key, Value: value})
|
||||
keyCounter++
|
||||
}
|
||||
txBytes, err := codec.Marshal(tx)
|
||||
txBytes, err := encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
resp := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.True(t, resp.IsOK(), "%v", resp.String())
|
||||
|
@ -245,7 +246,7 @@ func TestLoadVersion(t *testing.T) {
|
|||
pruningOpt := baseapp.SetPruning(storetypes.PruneNothing)
|
||||
db := dbm.NewMemDB()
|
||||
name := t.Name()
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil, pruningOpt)
|
||||
app := baseapp.NewBaseApp(name, logger, db, pruningOpt)
|
||||
|
||||
// make a cap key and mount the store
|
||||
err := app.LoadLatestVersion() // needed to make stores non-nil
|
||||
|
@ -272,7 +273,7 @@ func TestLoadVersion(t *testing.T) {
|
|||
commitID2 := storetypes.CommitID{Version: 2, Hash: res.Data}
|
||||
|
||||
// reload with LoadLatestVersion
|
||||
app = baseapp.NewBaseApp(name, logger, db, nil, pruningOpt)
|
||||
app = baseapp.NewBaseApp(name, logger, db, pruningOpt)
|
||||
app.MountStores()
|
||||
err = app.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
|
@ -280,7 +281,7 @@ func TestLoadVersion(t *testing.T) {
|
|||
|
||||
// reload with LoadVersion, see if you can commit the same block and get
|
||||
// the same result
|
||||
app = baseapp.NewBaseApp(name, logger, db, nil, pruningOpt)
|
||||
app = baseapp.NewBaseApp(name, logger, db, pruningOpt)
|
||||
err = app.LoadVersion(1)
|
||||
require.Nil(t, err)
|
||||
testLoadVersionHelper(t, app, int64(1), commitID1)
|
||||
|
@ -359,7 +360,7 @@ func TestSetLoader(t *testing.T) {
|
|||
if tc.setLoader != nil {
|
||||
opts = append(opts, tc.setLoader)
|
||||
}
|
||||
app := baseapp.NewBaseApp(t.Name(), defaultLogger(), db, nil, opts...)
|
||||
app := baseapp.NewBaseApp(t.Name(), defaultLogger(), db, opts...)
|
||||
app.MountStores(sdk.NewKVStoreKey(tc.loadStoreKey))
|
||||
err := app.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
|
@ -381,7 +382,7 @@ func TestVersionSetterGetter(t *testing.T) {
|
|||
pruningOpt := baseapp.SetPruning(storetypes.PruneDefault)
|
||||
db := dbm.NewMemDB()
|
||||
name := t.Name()
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil, pruningOpt)
|
||||
app := baseapp.NewBaseApp(name, logger, db, pruningOpt)
|
||||
|
||||
require.Equal(t, "", app.Version())
|
||||
res := app.Query(abci.RequestQuery{Path: "app/version"})
|
||||
|
@ -401,7 +402,7 @@ func TestLoadVersionInvalid(t *testing.T) {
|
|||
pruningOpt := baseapp.SetPruning(storetypes.PruneNothing)
|
||||
db := dbm.NewMemDB()
|
||||
name := t.Name()
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil, pruningOpt)
|
||||
app := baseapp.NewBaseApp(name, logger, db, pruningOpt)
|
||||
|
||||
err := app.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
|
@ -416,7 +417,7 @@ func TestLoadVersionInvalid(t *testing.T) {
|
|||
commitID1 := storetypes.CommitID{Version: 1, Hash: res.Data}
|
||||
|
||||
// create a new app with the stores mounted under the same cap key
|
||||
app = baseapp.NewBaseApp(name, logger, db, nil, pruningOpt)
|
||||
app = baseapp.NewBaseApp(name, logger, db, pruningOpt)
|
||||
|
||||
// require we can load the latest version
|
||||
err = app.LoadVersion(1)
|
||||
|
@ -438,7 +439,7 @@ func TestLoadVersionPruning(t *testing.T) {
|
|||
pruningOpt := baseapp.SetPruning(pruningOptions)
|
||||
db := dbm.NewMemDB()
|
||||
name := t.Name()
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil, pruningOpt)
|
||||
app := baseapp.NewBaseApp(name, logger, db, pruningOpt)
|
||||
|
||||
// make a cap key and mount the store
|
||||
capKey := sdk.NewKVStoreKey("key1")
|
||||
|
@ -476,7 +477,7 @@ func TestLoadVersionPruning(t *testing.T) {
|
|||
}
|
||||
|
||||
// reload with LoadLatestVersion, check it loads last version
|
||||
app = baseapp.NewBaseApp(name, logger, db, nil, pruningOpt)
|
||||
app = baseapp.NewBaseApp(name, logger, db, pruningOpt)
|
||||
app.MountStores(capKey)
|
||||
|
||||
err = app.LoadLatestVersion()
|
||||
|
@ -494,7 +495,7 @@ func testLoadVersionHelper(t *testing.T, app *baseapp.BaseApp, expectedHeight in
|
|||
func TestOptionFunction(t *testing.T) {
|
||||
logger := defaultLogger()
|
||||
db := dbm.NewMemDB()
|
||||
bap := baseapp.NewBaseApp("starting name", logger, db, nil, testChangeNameHelper("new name"))
|
||||
bap := baseapp.NewBaseApp("starting name", logger, db, testChangeNameHelper("new name"))
|
||||
require.Equal(t, bap.GetName(), "new name", "BaseApp should have had name changed via option function")
|
||||
}
|
||||
|
||||
|
@ -504,23 +505,6 @@ func testChangeNameHelper(name string) func(*baseapp.BaseApp) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test that txs can be unmarshalled and read and that
|
||||
// correct error codes are returned when not
|
||||
func TestTxDecoder(t *testing.T) {
|
||||
codec := codec.NewLegacyAmino()
|
||||
registerTestCodec(codec)
|
||||
|
||||
app := newBaseApp(t.Name())
|
||||
tx := newTxCounter(1, 0)
|
||||
txBytes := codec.MustMarshal(tx)
|
||||
|
||||
dTx, err := app.TxDecoder(txBytes)
|
||||
require.NoError(t, err)
|
||||
|
||||
cTx := dTx.(txTest)
|
||||
require.Equal(t, tx.Counter, cTx.Counter)
|
||||
}
|
||||
|
||||
// Test that Info returns the latest committed state.
|
||||
func TestInfo(t *testing.T) {
|
||||
app := newBaseApp(t.Name())
|
||||
|
@ -589,7 +573,7 @@ func TestInitChainer(t *testing.T) {
|
|||
// we can reload the same app later
|
||||
db := dbm.NewMemDB()
|
||||
logger := defaultLogger()
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil)
|
||||
app := baseapp.NewBaseApp(name, logger, db)
|
||||
capKey := sdk.NewKVStoreKey("main")
|
||||
capKey2 := sdk.NewKVStoreKey("key2")
|
||||
app.MountStores(capKey, capKey2)
|
||||
|
@ -644,7 +628,7 @@ func TestInitChainer(t *testing.T) {
|
|||
require.Equal(t, value, res.Value)
|
||||
|
||||
// reload app
|
||||
app = baseapp.NewBaseApp(name, logger, db, nil)
|
||||
app = baseapp.NewBaseApp(name, logger, db)
|
||||
app.SetInitChainer(initChainer)
|
||||
app.MountStores(capKey, capKey2)
|
||||
err = app.LoadLatestVersion() // needed to make stores non-nil
|
||||
|
@ -668,7 +652,7 @@ func TestInitChain_WithInitialHeight(t *testing.T) {
|
|||
name := t.Name()
|
||||
db := dbm.NewMemDB()
|
||||
logger := defaultLogger()
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil)
|
||||
app := baseapp.NewBaseApp(name, logger, db)
|
||||
|
||||
app.InitChain(
|
||||
abci.RequestInitChain{
|
||||
|
@ -684,7 +668,7 @@ func TestBeginBlock_WithInitialHeight(t *testing.T) {
|
|||
name := t.Name()
|
||||
db := dbm.NewMemDB()
|
||||
logger := defaultLogger()
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil)
|
||||
app := baseapp.NewBaseApp(name, logger, db)
|
||||
|
||||
app.InitChain(
|
||||
abci.RequestInitChain{
|
||||
|
@ -973,7 +957,8 @@ func TestCheckTx(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
customHandlerTxTest(t, capKey1, counterKey),
|
||||
)
|
||||
|
@ -985,17 +970,13 @@ func TestCheckTx(t *testing.T) {
|
|||
nTxs := int64(5)
|
||||
app.InitChain(abci.RequestInitChain{})
|
||||
|
||||
// Create same codec used in txDecoder
|
||||
codec := codec.NewLegacyAmino()
|
||||
registerTestCodec(codec)
|
||||
|
||||
for i := int64(0); i < nTxs; i++ {
|
||||
tx := newTxCounter(i, 0) // no messages
|
||||
txBytes, err := codec.Marshal(tx)
|
||||
txBytes, err := encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
r := app.CheckTx(abci.RequestCheckTx{Tx: txBytes})
|
||||
require.Empty(t, r.GetEvents())
|
||||
require.True(t, r.IsOK(), fmt.Sprintf("%v", r))
|
||||
require.True(t, r.IsOK(), fmt.Sprintf("%+v", r))
|
||||
}
|
||||
|
||||
checkStateStore := app.CheckState().Context().KVStore(capKey1)
|
||||
|
@ -1026,6 +1007,7 @@ func TestDeliverTx(t *testing.T) {
|
|||
anteKey := []byte("ante-key")
|
||||
// test increments in the handler
|
||||
deliverKey := []byte("deliver-key")
|
||||
|
||||
txHandlerOpt := func(bapp *baseapp.BaseApp) {
|
||||
legacyRouter := middleware.NewLegacyRouter()
|
||||
r := sdk.NewRoute(routeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
|
||||
|
@ -1033,7 +1015,8 @@ func TestDeliverTx(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
customHandlerTxTest(t, capKey1, anteKey),
|
||||
)
|
||||
|
@ -1042,10 +1025,6 @@ func TestDeliverTx(t *testing.T) {
|
|||
app := setupBaseApp(t, txHandlerOpt)
|
||||
app.InitChain(abci.RequestInitChain{})
|
||||
|
||||
// Create same codec used in txDecoder
|
||||
codec := codec.NewLegacyAmino()
|
||||
registerTestCodec(codec)
|
||||
|
||||
nBlocks := 3
|
||||
txPerHeight := 5
|
||||
|
||||
|
@ -1057,7 +1036,7 @@ func TestDeliverTx(t *testing.T) {
|
|||
counter := int64(blockN*txPerHeight + i)
|
||||
tx := newTxCounter(counter, counter)
|
||||
|
||||
txBytes, err := codec.Marshal(tx)
|
||||
txBytes, err := encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
|
@ -1086,6 +1065,7 @@ func TestMultiMsgDeliverTx(t *testing.T) {
|
|||
// increment the msg counter
|
||||
deliverKey := []byte("deliver-key")
|
||||
deliverKey2 := []byte("deliver-key2")
|
||||
|
||||
txHandlerOpt := func(bapp *baseapp.BaseApp) {
|
||||
legacyRouter := middleware.NewLegacyRouter()
|
||||
r1 := sdk.NewRoute(routeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
|
||||
|
@ -1095,7 +1075,8 @@ func TestMultiMsgDeliverTx(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
customHandlerTxTest(t, capKey1, anteKey),
|
||||
)
|
||||
|
@ -1103,17 +1084,13 @@ func TestMultiMsgDeliverTx(t *testing.T) {
|
|||
}
|
||||
app := setupBaseApp(t, txHandlerOpt)
|
||||
|
||||
// Create same codec used in txDecoder
|
||||
codec := codec.NewLegacyAmino()
|
||||
registerTestCodec(codec)
|
||||
|
||||
// run a multi-msg tx
|
||||
// with all msgs the same route
|
||||
|
||||
header := tmproto.Header{Height: 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
tx := newTxCounter(0, 0, 1, 2)
|
||||
txBytes, err := codec.Marshal(tx)
|
||||
txBytes, err := encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
|
@ -1133,7 +1110,7 @@ func TestMultiMsgDeliverTx(t *testing.T) {
|
|||
tx = newTxCounter(1, 3)
|
||||
tx.Msgs = append(tx.Msgs, msgCounter2{0})
|
||||
tx.Msgs = append(tx.Msgs, msgCounter2{1})
|
||||
txBytes, err = codec.Marshal(tx)
|
||||
txBytes, err = encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
|
@ -1183,7 +1160,8 @@ func TestSimulateTx(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) { return ctx, nil },
|
||||
)
|
||||
|
@ -1193,10 +1171,6 @@ func TestSimulateTx(t *testing.T) {
|
|||
|
||||
app.InitChain(abci.RequestInitChain{})
|
||||
|
||||
// Create same codec used in txDecoder
|
||||
cdc := codec.NewLegacyAmino()
|
||||
registerTestCodec(cdc)
|
||||
|
||||
nBlocks := 3
|
||||
for blockN := 0; blockN < nBlocks; blockN++ {
|
||||
count := int64(blockN + 1)
|
||||
|
@ -1205,7 +1179,7 @@ func TestSimulateTx(t *testing.T) {
|
|||
|
||||
tx := newTxCounter(count, count)
|
||||
tx.GasLimit = gasConsumed
|
||||
txBytes, err := cdc.Marshal(tx)
|
||||
txBytes, err := encCfg.Amino.Marshal(tx)
|
||||
require.Nil(t, err)
|
||||
|
||||
// simulate a message, check gas reported
|
||||
|
@ -1258,7 +1232,8 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
|
||||
return
|
||||
|
@ -1274,7 +1249,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
// transaction with no messages
|
||||
{
|
||||
emptyTx := &txTest{}
|
||||
_, result, err := app.SimDeliver(aminoTxEncoder(), emptyTx)
|
||||
_, result, err := app.SimDeliver(aminoTxEncoder(encCfg.Amino), emptyTx)
|
||||
require.Nil(t, result)
|
||||
|
||||
space, code, _ := sdkerrors.ABCIInfo(err, false)
|
||||
|
@ -1300,7 +1275,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
|
||||
for _, testCase := range testCases {
|
||||
tx := testCase.tx
|
||||
_, _, err := app.SimDeliver(aminoTxEncoder(), tx)
|
||||
_, _, err := app.SimDeliver(aminoTxEncoder(encCfg.Amino), tx)
|
||||
|
||||
if testCase.fail {
|
||||
require.Error(t, err)
|
||||
|
@ -1317,7 +1292,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
// transaction with no known route
|
||||
{
|
||||
unknownRouteTx := txTest{[]sdk.Msg{&msgNoRoute{}}, 0, false, math.MaxUint64}
|
||||
_, result, err := app.SimDeliver(aminoTxEncoder(), unknownRouteTx)
|
||||
_, result, err := app.SimDeliver(aminoTxEncoder(encCfg.Amino), unknownRouteTx)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, result)
|
||||
|
||||
|
@ -1326,7 +1301,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), code, err)
|
||||
|
||||
unknownRouteTx = txTest{[]sdk.Msg{&msgCounter{}, &msgNoRoute{}}, 0, false, math.MaxUint64}
|
||||
_, result, err = app.SimDeliver(aminoTxEncoder(), unknownRouteTx)
|
||||
_, result, err = app.SimDeliver(aminoTxEncoder(encCfg.Amino), unknownRouteTx)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, result)
|
||||
|
||||
|
@ -1340,8 +1315,10 @@ func TestRunInvalidTransaction(t *testing.T) {
|
|||
tx := newTxCounter(0, 0)
|
||||
tx.Msgs = append(tx.Msgs, &msgNoDecode{})
|
||||
|
||||
// new codec so we can encode the tx, but we shouldn't be able to decode
|
||||
// new codec so we can encode the tx, but we shouldn't be able to decode,
|
||||
// because baseapp's codec is not aware of msgNoDecode.
|
||||
newCdc := codec.NewLegacyAmino()
|
||||
sdk.RegisterLegacyAminoCodec(newCdc) // register Tx, Msg
|
||||
registerTestCodec(newCdc)
|
||||
newCdc.RegisterConcrete(&msgNoDecode{}, "cosmos-sdk/baseapp/msgNoDecode", nil)
|
||||
|
||||
|
@ -1382,7 +1359,8 @@ func TestTxGasLimits(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
ante,
|
||||
)
|
||||
|
@ -1421,7 +1399,7 @@ func TestTxGasLimits(t *testing.T) {
|
|||
for i, tc := range testCases {
|
||||
tx := tc.tx
|
||||
tx.GasLimit = gasGranted
|
||||
gInfo, result, err := app.SimDeliver(aminoTxEncoder(), tx)
|
||||
gInfo, result, err := app.SimDeliver(aminoTxEncoder(encCfg.Amino), tx)
|
||||
|
||||
// check gas used and wanted
|
||||
require.Equal(t, tc.gasUsed, gInfo.GasUsed, fmt.Sprintf("tc #%d; gas: %v, result: %v, err: %s", i, gInfo, result, err))
|
||||
|
@ -1469,7 +1447,8 @@ func TestMaxBlockGasLimits(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
ante,
|
||||
)
|
||||
|
@ -1514,7 +1493,7 @@ func TestMaxBlockGasLimits(t *testing.T) {
|
|||
|
||||
// execute the transaction multiple times
|
||||
for j := 0; j < tc.numDelivers; j++ {
|
||||
_, result, err := app.SimDeliver(aminoTxEncoder(), tx)
|
||||
_, result, err := app.SimDeliver(aminoTxEncoder(encCfg.Amino), tx)
|
||||
|
||||
ctx := app.DeliverState().Context()
|
||||
|
||||
|
@ -1546,7 +1525,6 @@ func TestMaxBlockGasLimits(t *testing.T) {
|
|||
func TestBaseAppMiddleware(t *testing.T) {
|
||||
anteKey := []byte("ante-key")
|
||||
deliverKey := []byte("deliver-key")
|
||||
cdc := codec.NewLegacyAmino()
|
||||
|
||||
txHandlerOpt := func(bapp *baseapp.BaseApp) {
|
||||
legacyRouter := middleware.NewLegacyRouter()
|
||||
|
@ -1555,7 +1533,8 @@ func TestBaseAppMiddleware(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
customHandlerTxTest(t, capKey1, anteKey),
|
||||
)
|
||||
|
@ -1564,7 +1543,6 @@ func TestBaseAppMiddleware(t *testing.T) {
|
|||
app := setupBaseApp(t, txHandlerOpt)
|
||||
|
||||
app.InitChain(abci.RequestInitChain{})
|
||||
registerTestCodec(cdc)
|
||||
|
||||
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
@ -1575,7 +1553,7 @@ func TestBaseAppMiddleware(t *testing.T) {
|
|||
// the next txs ante handler execution (customHandlerTxTest).
|
||||
tx := newTxCounter(0, 0)
|
||||
tx.setFailOnAnte(true)
|
||||
txBytes, err := cdc.Marshal(tx)
|
||||
txBytes, err := encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.Empty(t, res.Events)
|
||||
|
@ -1590,7 +1568,7 @@ func TestBaseAppMiddleware(t *testing.T) {
|
|||
tx = newTxCounter(0, 0)
|
||||
tx.setFailOnHandler(true)
|
||||
|
||||
txBytes, err = cdc.Marshal(tx)
|
||||
txBytes, err = encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
|
@ -1606,7 +1584,7 @@ func TestBaseAppMiddleware(t *testing.T) {
|
|||
// implicitly checked by previous tx executions
|
||||
tx = newTxCounter(1, 0)
|
||||
|
||||
txBytes, err = cdc.Marshal(tx)
|
||||
txBytes, err = encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
|
@ -1635,9 +1613,6 @@ func TestGasConsumptionBadTx(t *testing.T) {
|
|||
return ctx, nil
|
||||
}
|
||||
|
||||
cdc := codec.NewLegacyAmino()
|
||||
registerTestCodec(cdc)
|
||||
|
||||
txHandlerOpt := func(bapp *baseapp.BaseApp) {
|
||||
legacyRouter := middleware.NewLegacyRouter()
|
||||
r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
||||
|
@ -1649,7 +1624,8 @@ func TestGasConsumptionBadTx(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
ante,
|
||||
)
|
||||
|
@ -1673,7 +1649,7 @@ func TestGasConsumptionBadTx(t *testing.T) {
|
|||
tx := newTxCounter(5, 0)
|
||||
tx.GasLimit = gasWanted
|
||||
tx.setFailOnAnte(true)
|
||||
txBytes, err := cdc.Marshal(tx)
|
||||
txBytes, err := encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
|
@ -1681,7 +1657,7 @@ func TestGasConsumptionBadTx(t *testing.T) {
|
|||
|
||||
// require next tx to fail due to black gas limit
|
||||
tx = newTxCounter(5, 0)
|
||||
txBytes, err = cdc.Marshal(tx)
|
||||
txBytes, err = encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
|
@ -1710,7 +1686,8 @@ func TestQuery(t *testing.T) {
|
|||
txHandler := testTxHandler(
|
||||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(interfaceRegistry),
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: testTxDecoder(encCfg.Amino),
|
||||
},
|
||||
func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
|
||||
store := ctx.KVStore(capKey1)
|
||||
|
@ -1738,7 +1715,7 @@ func TestQuery(t *testing.T) {
|
|||
require.Equal(t, 0, len(res.Value))
|
||||
|
||||
// query is still empty after a CheckTx
|
||||
_, resTx, err := app.SimCheck(aminoTxEncoder(), tx)
|
||||
_, resTx, err := app.SimCheck(aminoTxEncoder(encCfg.Amino), tx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resTx)
|
||||
res = app.Query(query)
|
||||
|
@ -1748,7 +1725,7 @@ func TestQuery(t *testing.T) {
|
|||
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
|
||||
_, resTx, err = app.SimDeliver(aminoTxEncoder(), tx)
|
||||
_, resTx, err = app.SimDeliver(aminoTxEncoder(encCfg.Amino), tx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resTx)
|
||||
res = app.Query(query)
|
||||
|
@ -2030,16 +2007,15 @@ func TestWithRouter(t *testing.T) {
|
|||
customRouter := &testCustomRouter{routes: sync.Map{}}
|
||||
r := sdk.NewRoute(routeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
|
||||
customRouter.AddRoute(r)
|
||||
txHandler := middleware.NewRunMsgsTxHandler(middleware.NewMsgServiceRouter(interfaceRegistry), customRouter)
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
middleware.NewRunMsgsTxHandler(middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry), customRouter),
|
||||
middleware.NewTxDecoderMiddleware(testTxDecoder(encCfg.Amino)),
|
||||
)
|
||||
bapp.SetTxHandler(txHandler)
|
||||
}
|
||||
app := setupBaseApp(t, txHandlerOpt)
|
||||
app.InitChain(abci.RequestInitChain{})
|
||||
|
||||
// Create same codec used in txDecoder
|
||||
codec := codec.NewLegacyAmino()
|
||||
registerTestCodec(codec)
|
||||
|
||||
nBlocks := 3
|
||||
txPerHeight := 5
|
||||
|
||||
|
@ -2051,7 +2027,7 @@ func TestWithRouter(t *testing.T) {
|
|||
counter := int64(blockN*txPerHeight + i)
|
||||
tx := newTxCounter(counter, counter)
|
||||
|
||||
txBytes, err := codec.Marshal(tx)
|
||||
txBytes, err := encCfg.Amino.Marshal(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
|
@ -2074,7 +2050,7 @@ func TestBaseApp_EndBlock(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
app := baseapp.NewBaseApp(name, logger, db, nil)
|
||||
app := baseapp.NewBaseApp(name, logger, db)
|
||||
app.SetParamStore(¶mStore{db: dbm.NewMemDB()})
|
||||
app.InitChain(abci.RequestInitChain{
|
||||
ConsensusParams: cp,
|
||||
|
|
|
@ -55,7 +55,7 @@ func TestRegisterQueryServiceTwice(t *testing.T) {
|
|||
db := dbm.NewMemDB()
|
||||
encCfg := simapp.MakeTestEncodingConfig()
|
||||
logger, _ := log.NewDefaultLogger("plain", "info", false)
|
||||
app := baseapp.NewBaseApp("test", logger, db, encCfg.TxConfig.TxDecoder())
|
||||
app := baseapp.NewBaseApp("test", logger, db)
|
||||
app.SetInterfaceRegistry(encCfg.InterfaceRegistry)
|
||||
testdata.RegisterInterfaces(encCfg.InterfaceRegistry)
|
||||
|
||||
|
|
|
@ -36,13 +36,8 @@ func (app *BaseApp) SimCheck(txEncoder sdk.TxEncoder, sdkTx sdk.Tx) (sdk.GasInfo
|
|||
|
||||
// Simulate executes a tx in simulate mode to get result and gas info.
|
||||
func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) {
|
||||
sdkTx, err := app.txDecoder(txBytes)
|
||||
if err != nil {
|
||||
return sdk.GasInfo{}, nil, err
|
||||
}
|
||||
|
||||
ctx := app.getContextForTx(runTxModeSimulate, txBytes)
|
||||
res, err := app.txHandler.SimulateTx(ctx, tx.Request{Tx: sdkTx, TxBytes: txBytes})
|
||||
res, err := app.txHandler.SimulateTx(ctx, tx.Request{TxBytes: txBytes})
|
||||
gasInfo := sdk.GasInfo{
|
||||
GasWanted: res.GasWanted,
|
||||
GasUsed: res.GasUsed,
|
||||
|
|
|
@ -45,13 +45,6 @@ func (app *BaseApp) GetName() string {
|
|||
return app.name
|
||||
}
|
||||
|
||||
// GetName return name.
|
||||
//
|
||||
// This method is only accessible in baseapp tests.
|
||||
func (app *BaseApp) TxDecoder(txBytes []byte) (sdk.Tx, error) {
|
||||
return app.txDecoder(txBytes)
|
||||
}
|
||||
|
||||
// CreateQueryContext calls app's createQueryContext.
|
||||
//
|
||||
// This method is only accessible in baseapp tests.
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
func testTxHandler(options middleware.TxHandlerOptions) tx.Handler {
|
||||
return middleware.ComposeMiddlewares(
|
||||
middleware.NewRunMsgsTxHandler(options.MsgServiceRouter, options.LegacyRouter),
|
||||
middleware.NewTxDecoderMiddleware(options.TxDecoder),
|
||||
middleware.GasTxMiddleware,
|
||||
middleware.RecoveryTxMiddleware,
|
||||
middleware.NewIndexEventsTxMiddleware(options.IndexEvents),
|
||||
|
@ -42,7 +43,7 @@ func NewApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
|||
capKeyMainStore := sdk.NewKVStoreKey("main")
|
||||
|
||||
// Create BaseApp.
|
||||
baseApp := bam.NewBaseApp("kvstore", logger, db, decodeTx)
|
||||
baseApp := bam.NewBaseApp("kvstore", logger, db)
|
||||
|
||||
// Set mounts for BaseApp's MultiStore.
|
||||
baseApp.MountStores(capKeyMainStore)
|
||||
|
@ -59,6 +60,7 @@ func NewApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
|||
middleware.TxHandlerOptions{
|
||||
LegacyRouter: legacyRouter,
|
||||
MsgServiceRouter: middleware.NewMsgServiceRouter(encCfg.InterfaceRegistry),
|
||||
TxDecoder: decodeTx,
|
||||
},
|
||||
)
|
||||
baseApp.SetTxHandler(txHandler)
|
||||
|
|
|
@ -205,7 +205,7 @@ func NewSimApp(
|
|||
legacyAmino := encodingConfig.Amino
|
||||
interfaceRegistry := encodingConfig.InterfaceRegistry
|
||||
|
||||
bApp := baseapp.NewBaseApp(appName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...)
|
||||
bApp := baseapp.NewBaseApp(appName, logger, db, baseAppOptions...)
|
||||
bApp.SetCommitMultiStoreTracer(traceStore)
|
||||
bApp.SetVersion(version.Version)
|
||||
bApp.SetInterfaceRegistry(interfaceRegistry)
|
||||
|
@ -431,6 +431,7 @@ func (app *SimApp) setTxHandler(txConfig client.TxConfig, indexEventsStr []strin
|
|||
FeegrantKeeper: app.FeeGrantKeeper,
|
||||
SignModeHandler: txConfig.SignModeHandler(),
|
||||
SigGasConsumer: authmiddleware.DefaultSigVerificationGasConsumer,
|
||||
TxDecoder: txConfig.TxDecoder(),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
|
@ -78,7 +78,7 @@ func TestRunMigrations(t *testing.T) {
|
|||
app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{})
|
||||
|
||||
// Create a new baseapp and configurator for the purpose of this test.
|
||||
bApp := baseapp.NewBaseApp(appName, logger, db, encCfg.TxConfig.TxDecoder())
|
||||
bApp := baseapp.NewBaseApp(appName, logger, db)
|
||||
bApp.SetCommitMultiStoreTracer(nil)
|
||||
bApp.SetInterfaceRegistry(encCfg.InterfaceRegistry)
|
||||
msr := authmiddleware.NewMsgServiceRouter(encCfg.InterfaceRegistry)
|
||||
|
|
|
@ -22,6 +22,19 @@ type ResponseSimulateTx struct {
|
|||
Result *sdk.Result
|
||||
}
|
||||
|
||||
// Request is the tx request type used in middlewares.
|
||||
// At least one of Tx or TxBytes must be set. If only TxBytes is set, then
|
||||
// Tx will be populated by the TxDecoderMiddleware. If only Tx is set, then
|
||||
// some middlewares (such as signature verification) will fail.
|
||||
//
|
||||
// In practice, the middleware stack is called from {Check,Deliver}Tx, which
|
||||
// only passes the TxBytes. Then, the TxDecoderMiddleware decodes the bytes
|
||||
// into the Tx field.
|
||||
type Request struct {
|
||||
Tx sdk.Tx
|
||||
TxBytes []byte
|
||||
}
|
||||
|
||||
// Response is the tx response type used in middlewares.
|
||||
type Response struct {
|
||||
GasWanted uint64
|
||||
|
@ -34,12 +47,6 @@ type Response struct {
|
|||
Events []abci.Event
|
||||
}
|
||||
|
||||
// Request is the tx request type used in middlewares.
|
||||
type Request struct {
|
||||
Tx sdk.Tx
|
||||
TxBytes []byte
|
||||
}
|
||||
|
||||
// RequestCheckTx is the additional request type used in middlewares CheckTx
|
||||
// method.
|
||||
type RequestCheckTx struct {
|
||||
|
|
|
@ -16,7 +16,7 @@ func (s *MWTestSuite) TestValidateBasic() {
|
|||
ctx := s.SetupTest(true) // setup
|
||||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.ValidateBasicMiddleware)
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler, middleware.ValidateBasicMiddleware)
|
||||
|
||||
// keys and addresses
|
||||
priv1, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
@ -54,7 +54,7 @@ func (s *MWTestSuite) TestValidateBasic() {
|
|||
func (s *MWTestSuite) TestValidateMemo() {
|
||||
ctx := s.SetupTest(true) // setup
|
||||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.ValidateMemoMiddleware(s.app.AccountKeeper))
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler, middleware.ValidateMemoMiddleware(s.app.AccountKeeper))
|
||||
|
||||
// keys and addresses
|
||||
priv1, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
@ -90,7 +90,7 @@ func (s *MWTestSuite) TestConsumeGasForTxSize() {
|
|||
ctx := s.SetupTest(true) // setup
|
||||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.ConsumeTxSizeGasMiddleware(s.app.AccountKeeper))
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler, middleware.ConsumeTxSizeGasMiddleware(s.app.AccountKeeper))
|
||||
|
||||
// keys and addresses
|
||||
priv1, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
@ -174,7 +174,7 @@ func (s *MWTestSuite) TestConsumeGasForTxSize() {
|
|||
func (s *MWTestSuite) TestTxHeightTimeoutMiddleware() {
|
||||
ctx := s.SetupTest(true)
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.TxTimeoutHeightMiddleware)
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler, middleware.TxTimeoutHeightMiddleware)
|
||||
|
||||
// keys and addresses
|
||||
priv1, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
|
|
@ -13,7 +13,7 @@ func (s *MWTestSuite) TestRejectExtensionOptionsMiddleware() {
|
|||
ctx := s.SetupTest(true) // setup
|
||||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.RejectExtensionOptionsMiddleware)
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler, middleware.RejectExtensionOptionsMiddleware)
|
||||
|
||||
// no extension options should not trigger an error
|
||||
theTx := txBuilder.GetTx()
|
||||
|
|
|
@ -13,7 +13,7 @@ func (s *MWTestSuite) TestEnsureMempoolFees() {
|
|||
ctx := s.SetupTest(true) // setup
|
||||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.MempoolFeeMiddleware)
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler, middleware.MempoolFeeMiddleware)
|
||||
|
||||
// keys and addresses
|
||||
priv1, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
@ -55,7 +55,7 @@ func (s *MWTestSuite) TestDeductFees() {
|
|||
ctx := s.SetupTest(false) // setup
|
||||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
noopTxHandler{},
|
||||
noopTxHandler,
|
||||
middleware.DeductFeeMiddleware(
|
||||
s.app.AccountKeeper,
|
||||
s.app.BankKeeper,
|
||||
|
|
|
@ -31,7 +31,7 @@ func (s *MWTestSuite) TestDeductFeesNoDelegation() {
|
|||
protoTxCfg := tx.NewTxConfig(codec.NewProtoCodec(app.InterfaceRegistry()), tx.DefaultSignModes)
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
noopTxHandler{},
|
||||
noopTxHandler,
|
||||
middleware.DeductFeeMiddleware(
|
||||
s.app.AccountKeeper,
|
||||
s.app.BankKeeper,
|
||||
|
|
|
@ -50,7 +50,7 @@ func (s *MWTestSuite) setupGasTx() (signing.Tx, []byte, sdk.Context, uint64) {
|
|||
|
||||
func (s *MWTestSuite) TestSetup() {
|
||||
testTx, _, ctx, gasLimit := s.setupGasTx()
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.GasTxMiddleware)
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler, middleware.GasTxMiddleware)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
|
@ -77,62 +77,48 @@ func (s *MWTestSuite) TestSetup() {
|
|||
|
||||
func (s *MWTestSuite) TestRecoverPanic() {
|
||||
testTx, txBytes, ctx, gasLimit := s.setupGasTx()
|
||||
txHandler := middleware.ComposeMiddlewares(outOfGasTxHandler{}, middleware.GasTxMiddleware, middleware.RecoveryTxMiddleware)
|
||||
txHandler := middleware.ComposeMiddlewares(outOfGasTxHandler, middleware.GasTxMiddleware, middleware.RecoveryTxMiddleware)
|
||||
res, _, err := txHandler.CheckTx(sdk.WrapSDKContext(ctx), tx.Request{Tx: testTx, TxBytes: txBytes}, tx.RequestCheckTx{})
|
||||
s.Require().Error(err, "Did not return error on OutOfGas panic")
|
||||
s.Require().True(errors.Is(sdkerrors.ErrOutOfGas, err), "Returned error is not an out of gas error")
|
||||
s.Require().Equal(gasLimit, uint64(res.GasWanted))
|
||||
|
||||
txHandler = middleware.ComposeMiddlewares(outOfGasTxHandler{}, middleware.GasTxMiddleware)
|
||||
txHandler = middleware.ComposeMiddlewares(outOfGasTxHandler, middleware.GasTxMiddleware)
|
||||
s.Require().Panics(func() {
|
||||
txHandler.CheckTx(sdk.WrapSDKContext(ctx), tx.Request{Tx: testTx, TxBytes: txBytes}, tx.RequestCheckTx{})
|
||||
}, "Recovered from non-Out-of-Gas panic")
|
||||
}
|
||||
|
||||
// outOfGasTxHandler is a test middleware that will throw OutOfGas panic.
|
||||
type outOfGasTxHandler struct{}
|
||||
|
||||
var _ tx.Handler = outOfGasTxHandler{}
|
||||
|
||||
func (txh outOfGasTxHandler) DeliverTx(ctx context.Context, _ tx.Request) (tx.Response, error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
overLimit := sdkCtx.GasMeter().Limit() + 1
|
||||
|
||||
// Should panic with outofgas error
|
||||
sdkCtx.GasMeter().ConsumeGas(overLimit, "test panic")
|
||||
|
||||
panic("not reached")
|
||||
}
|
||||
func (txh outOfGasTxHandler) CheckTx(ctx context.Context, _ tx.Request, _ tx.RequestCheckTx) (tx.Response, tx.ResponseCheckTx, error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
overLimit := sdkCtx.GasMeter().Limit() + 1
|
||||
|
||||
// Should panic with outofgas error
|
||||
sdkCtx.GasMeter().ConsumeGas(overLimit, "test panic")
|
||||
|
||||
panic("not reached")
|
||||
}
|
||||
func (txh outOfGasTxHandler) SimulateTx(ctx context.Context, _ tx.Request) (tx.Response, error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
overLimit := sdkCtx.GasMeter().Limit() + 1
|
||||
|
||||
// Should panic with outofgas error
|
||||
sdkCtx.GasMeter().ConsumeGas(overLimit, "test panic")
|
||||
|
||||
panic("not reached")
|
||||
// customTxHandler is a test middleware that will run a custom function.
|
||||
type customTxHandler struct {
|
||||
fn func(context.Context, tx.Request) (tx.Response, error)
|
||||
}
|
||||
|
||||
// noopTxHandler is a test middleware that does nothing.
|
||||
type noopTxHandler struct{}
|
||||
var _ tx.Handler = customTxHandler{}
|
||||
|
||||
var _ tx.Handler = noopTxHandler{}
|
||||
|
||||
func (txh noopTxHandler) CheckTx(_ context.Context, _ tx.Request, _ tx.RequestCheckTx) (tx.Response, tx.ResponseCheckTx, error) {
|
||||
return tx.Response{}, tx.ResponseCheckTx{}, nil
|
||||
func (h customTxHandler) DeliverTx(ctx context.Context, req tx.Request) (tx.Response, error) {
|
||||
return h.fn(ctx, req)
|
||||
}
|
||||
func (txh noopTxHandler) SimulateTx(_ context.Context, _ tx.Request) (tx.Response, error) {
|
||||
func (h customTxHandler) CheckTx(ctx context.Context, req tx.Request, _ tx.RequestCheckTx) (tx.Response, tx.ResponseCheckTx, error) {
|
||||
res, err := h.fn(ctx, req)
|
||||
return res, tx.ResponseCheckTx{}, err
|
||||
}
|
||||
func (h customTxHandler) SimulateTx(ctx context.Context, req tx.Request) (tx.Response, error) {
|
||||
return h.fn(ctx, req)
|
||||
}
|
||||
|
||||
// noopTxHandler is a test middleware that returns an empty response.
|
||||
var noopTxHandler = customTxHandler{func(_ context.Context, _ tx.Request) (tx.Response, error) {
|
||||
return tx.Response{}, nil
|
||||
}
|
||||
func (txh noopTxHandler) DeliverTx(ctx context.Context, _ tx.Request) (tx.Response, error) {
|
||||
return tx.Response{}, nil
|
||||
}
|
||||
}}
|
||||
|
||||
// outOfGasTxHandler is a test middleware that panics with an outOfGas error.
|
||||
var outOfGasTxHandler = customTxHandler{func(ctx context.Context, _ tx.Request) (tx.Response, error) {
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
overLimit := sdkCtx.GasMeter().Limit() + 1
|
||||
|
||||
// Should panic with outofgas error
|
||||
sdkCtx.GasMeter().ConsumeGas(overLimit, "test panic")
|
||||
|
||||
panic("not reached")
|
||||
}}
|
||||
|
|
|
@ -32,6 +32,10 @@ func ComposeMiddlewares(txHandler tx.Handler, middlewares ...tx.Middleware) tx.H
|
|||
|
||||
type TxHandlerOptions struct {
|
||||
Debug bool
|
||||
|
||||
// TxDecoder is used to decode the raw tx bytes into a sdk.Tx.
|
||||
TxDecoder sdk.TxDecoder
|
||||
|
||||
// IndexEvents defines the set of events in the form {eventType}.{attributeKey},
|
||||
// which informs Tendermint what to index. If empty, all events will be indexed.
|
||||
IndexEvents map[string]struct{}
|
||||
|
@ -49,6 +53,10 @@ type TxHandlerOptions struct {
|
|||
// NewDefaultTxHandler defines a TxHandler middleware stacks that should work
|
||||
// for most applications.
|
||||
func NewDefaultTxHandler(options TxHandlerOptions) (tx.Handler, error) {
|
||||
if options.TxDecoder == nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "txDecoder is required for middlewares")
|
||||
}
|
||||
|
||||
if options.AccountKeeper == nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for middlewares")
|
||||
}
|
||||
|
@ -68,6 +76,7 @@ func NewDefaultTxHandler(options TxHandlerOptions) (tx.Handler, error) {
|
|||
|
||||
return ComposeMiddlewares(
|
||||
NewRunMsgsTxHandler(options.MsgServiceRouter, options.LegacyRouter),
|
||||
NewTxDecoderMiddleware(options.TxDecoder),
|
||||
// Set a new GasMeter on sdk.Context.
|
||||
//
|
||||
// Make sure the Gas middleware is outside of all other middlewares
|
||||
|
|
|
@ -1025,6 +1025,7 @@ func (s *MWTestSuite) TestCustomSignatureVerificationGasConsumer() {
|
|||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "unrecognized public key type: %T", pubkey)
|
||||
}
|
||||
},
|
||||
TxDecoder: s.clientCtx.TxConfig.TxDecoder(),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
|
|
@ -12,7 +12,7 @@ func (s *MWTestSuite) TestPriority() {
|
|||
ctx := s.SetupTest(true) // setup
|
||||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler{}, middleware.TxPriorityMiddleware)
|
||||
txHandler := middleware.ComposeMiddlewares(noopTxHandler, middleware.TxPriorityMiddleware)
|
||||
|
||||
// keys and addresses
|
||||
priv1, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
|
|
@ -27,7 +27,7 @@ func (s *MWTestSuite) TestSetPubKey() {
|
|||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
require := s.Require()
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
noopTxHandler{},
|
||||
noopTxHandler,
|
||||
middleware.SetPubKeyMiddleware(s.app.AccountKeeper),
|
||||
)
|
||||
|
||||
|
@ -127,7 +127,7 @@ func (s *MWTestSuite) TestSigVerification() {
|
|||
// make block height non-zero to ensure account numbers part of signBytes
|
||||
ctx = ctx.WithBlockHeight(1)
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
noopTxHandler{},
|
||||
noopTxHandler,
|
||||
middleware.SetPubKeyMiddleware(s.app.AccountKeeper),
|
||||
middleware.SigVerificationMiddleware(
|
||||
s.app.AccountKeeper,
|
||||
|
@ -239,7 +239,7 @@ func (s *MWTestSuite) TestSigVerification_ExplicitAmino() {
|
|||
gasLimit := testdata.NewTestGasLimit()
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
noopTxHandler{},
|
||||
noopTxHandler,
|
||||
middleware.SetPubKeyMiddleware(s.app.AccountKeeper),
|
||||
middleware.SigVerificationMiddleware(
|
||||
s.app.AccountKeeper,
|
||||
|
@ -342,7 +342,7 @@ func (s *MWTestSuite) runSigMiddlewares(params types.Params, _ bool, privs ...cr
|
|||
s.Require().NoError(err)
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
noopTxHandler{},
|
||||
noopTxHandler,
|
||||
middleware.SetPubKeyMiddleware(s.app.AccountKeeper),
|
||||
middleware.SigGasConsumeMiddleware(s.app.AccountKeeper, middleware.DefaultSigVerificationGasConsumer),
|
||||
middleware.SigVerificationMiddleware(
|
||||
|
@ -382,7 +382,7 @@ func (s *MWTestSuite) TestIncrementSequenceMiddleware() {
|
|||
s.Require().NoError(err)
|
||||
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
noopTxHandler{},
|
||||
noopTxHandler,
|
||||
middleware.IncrementSequenceMiddleware(s.app.AccountKeeper),
|
||||
)
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ func (s *MWTestSuite) SetupTest(isCheckTx bool) sdk.Context {
|
|||
FeegrantKeeper: s.app.FeeGrantKeeper,
|
||||
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
|
||||
SigGasConsumer: middleware.DefaultSigVerificationGasConsumer,
|
||||
TxDecoder: s.clientCtx.TxConfig.TxDecoder(),
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.txHandler = txHandler
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package middleware_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/middleware"
|
||||
)
|
||||
|
||||
func (s *MWTestSuite) TestTxDecoderMiddleware() {
|
||||
ctx := s.SetupTest(true) // setup
|
||||
require := s.Require()
|
||||
|
||||
// Create a tx.
|
||||
priv1, _, addr1 := testdata.KeyTestPubAddr()
|
||||
txBuilder := s.clientCtx.TxConfig.NewTxBuilder()
|
||||
err := txBuilder.SetMsgs(testdata.NewTestMsg(addr1))
|
||||
require.NoError(err)
|
||||
sdkTx, txBz, err := s.createTestTx(txBuilder, []cryptotypes.PrivKey{priv1}, []uint64{1}, []uint64{0}, ctx.ChainID())
|
||||
require.NoError(err)
|
||||
|
||||
// Create a custom tx.Handler that checks that the req.Tx field is
|
||||
// correctly populated.
|
||||
txReqChecker := customTxHandler{func(c context.Context, r tx.Request) (tx.Response, error) {
|
||||
require.NotNil(r.Tx)
|
||||
require.Equal(sdkTx.GetMsgs()[0], r.Tx.GetMsgs()[0])
|
||||
return tx.Response{}, nil
|
||||
}}
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
req tx.Request
|
||||
expErr bool
|
||||
}{
|
||||
{"empty tx bz", tx.Request{}, true},
|
||||
{"tx bz and tx both given as inputs", tx.Request{Tx: sdkTx, TxBytes: txBz}, false},
|
||||
{"tx bz only given as input", tx.Request{TxBytes: txBz}, false},
|
||||
{"tx only given as input", tx.Request{Tx: sdkTx}, false},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
s.Run(tc.name, func() {
|
||||
txHandler := middleware.ComposeMiddlewares(
|
||||
txReqChecker,
|
||||
middleware.NewTxDecoderMiddleware(s.clientCtx.TxConfig.TxDecoder()),
|
||||
)
|
||||
_, err := txHandler.DeliverTx(sdk.WrapSDKContext(ctx), tc.req)
|
||||
if tc.expErr {
|
||||
require.Error(err)
|
||||
} else {
|
||||
require.NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -124,7 +124,7 @@ func TestSetLoader(t *testing.T) {
|
|||
// load the app with the existing db
|
||||
opts := []func(*baseapp.BaseApp){baseapp.SetPruning(storetypes.PruneNothing)}
|
||||
|
||||
origapp := baseapp.NewBaseApp(t.Name(), defaultLogger(), db, nil, opts...)
|
||||
origapp := baseapp.NewBaseApp(t.Name(), defaultLogger(), db, opts...)
|
||||
origapp.MountStores(sdk.NewKVStoreKey(tc.origStoreKey))
|
||||
err := origapp.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
|
@ -140,7 +140,7 @@ func TestSetLoader(t *testing.T) {
|
|||
}
|
||||
|
||||
// load the new app with the original app db
|
||||
app := baseapp.NewBaseApp(t.Name(), defaultLogger(), db, nil, opts...)
|
||||
app := baseapp.NewBaseApp(t.Name(), defaultLogger(), db, opts...)
|
||||
app.MountStores(sdk.NewKVStoreKey(tc.loadStoreKey))
|
||||
err = app.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
|
|
Loading…
Reference in New Issue