diff --git a/baseapp/abci.go b/baseapp/abci.go index b3569ff8f53c..398673bd1662 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -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 diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 2dee74b67e82..338c7c4d0cb3 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -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, diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 07713ef4fe24..0f1a1263f5c2 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -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, } diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 46051b38237b..285f09df6a4b 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -90,7 +90,7 @@ 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) { @@ -245,7 +245,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 +272,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 +280,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 +359,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 +381,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 +401,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 +416,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 +438,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 +476,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 +494,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 +504,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 +572,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 +627,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 +651,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 +667,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{ @@ -2074,7 +2057,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, diff --git a/baseapp/grpcrouter_test.go b/baseapp/grpcrouter_test.go index e22e77a61de0..ca7a6e9b5486 100644 --- a/baseapp/grpcrouter_test.go +++ b/baseapp/grpcrouter_test.go @@ -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) diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index bc837e3cc595..6b770499c70b 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -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, diff --git a/baseapp/util_test.go b/baseapp/util_test.go index 5f7504af85ec..7244aff8307a 100644 --- a/baseapp/util_test.go +++ b/baseapp/util_test.go @@ -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. diff --git a/server/mock/app.go b/server/mock/app.go index ff4a58fa829c..9de4420531f0 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -42,7 +42,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) diff --git a/server/mock/tx.go b/server/mock/tx.go index bfa6e6ad6b4b..0bd381443a45 100644 --- a/server/mock/tx.go +++ b/server/mock/tx.go @@ -2,12 +2,10 @@ package mock import ( - "bytes" "fmt" "math" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/middleware" ) @@ -70,22 +68,3 @@ func (tx kvstoreTx) GetSigners() []sdk.AccAddress { func (tx kvstoreTx) GetGas() uint64 { return math.MaxUint64 } - -// takes raw transaction bytes and decodes them into an sdk.Tx. An sdk.Tx has -// all the signatures and can be used to authenticate. -func decodeTx(txBytes []byte) (sdk.Tx, error) { - var tx sdk.Tx - - split := bytes.Split(txBytes, []byte("=")) - if len(split) == 1 { - k := split[0] - tx = &kvstoreTx{k, k, txBytes} - } else if len(split) == 2 { - k, v := split[0], split[1] - tx = &kvstoreTx{k, v, txBytes} - } else { - return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "too many '='") - } - - return tx, nil -} diff --git a/simapp/app.go b/simapp/app.go index 3598f9de1f52..51306e498bd4 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -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) diff --git a/simapp/app_test.go b/simapp/app_test.go index 7b51b0d835bd..fa8881f93d29 100644 --- a/simapp/app_test.go +++ b/simapp/app_test.go @@ -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) diff --git a/x/auth/middleware/middleware.go b/x/auth/middleware/middleware.go index a17cdd291ed7..53d16938e219 100644 --- a/x/auth/middleware/middleware.go +++ b/x/auth/middleware/middleware.go @@ -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 diff --git a/x/auth/middleware/run_msgs_test.go b/x/auth/middleware/run_msgs_test.go index 6278d5c023d2..8d3fe1e6845b 100644 --- a/x/auth/middleware/run_msgs_test.go +++ b/x/auth/middleware/run_msgs_test.go @@ -1,10 +1,6 @@ package middleware_test import ( - "fmt" - - "github.com/gogo/protobuf/proto" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -31,5 +27,5 @@ func (s *MWTestSuite) TestRunMsgs() { res, err := txHandler.DeliverTx(sdk.WrapSDKContext(ctx), tx.Request{Tx: testTx, TxBytes: txBytes}) s.Require().NoError(err) s.Require().Len(res.MsgResponses, 1) - s.Require().Equal(fmt.Sprintf("/%s", proto.MessageName(&testdata.MsgCreateDogResponse{})), res.MsgResponses[0].TypeUrl) + s.Require().Equal(sdk.MsgTypeURL(&testdata.MsgCreateDog{}), res.MsgResponses[0].TypeUrl) } diff --git a/x/auth/middleware/tx.go b/x/auth/middleware/tx.go new file mode 100644 index 000000000000..e198cff713f4 --- /dev/null +++ b/x/auth/middleware/tx.go @@ -0,0 +1,72 @@ +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 txDecoderTxHandler struct { + next tx.Handler + txDecoder sdk.TxDecoder +} + +// TxDecoderMiddleware +func NewTxDecoderMiddleware(txDecoder sdk.TxDecoder) tx.Middleware { + return func(txh tx.Handler) tx.Handler { + return txDecoderTxHandler{next: txh, txDecoder: txDecoder} + } +} + +var _ tx.Handler = gasTxHandler{} + +// CheckTx implements tx.Handler.CheckTx. +func (h txDecoderTxHandler) 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 txDecoderTxHandler) 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 txDecoderTxHandler) 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. +func (h txDecoderTxHandler) populateReq(req tx.Request) (tx.Request, error) { + if req.Tx != nil && req.TxBytes != nil { + return req, nil + } + + if len(req.TxBytes) == 0 { + return tx.Request{}, sdkerrors.ErrInvalidRequest.Wrap("got empty tx bytes") + } + + sdkTx, err := h.txDecoder(req.TxBytes) + if err != nil { + return tx.Request{}, err + } + + return tx.Request{Tx: sdkTx, TxBytes: req.TxBytes}, nil +} diff --git a/x/upgrade/types/storeloader_test.go b/x/upgrade/types/storeloader_test.go index 4389f3da7838..341a2ffe30da 100644 --- a/x/upgrade/types/storeloader_test.go +++ b/x/upgrade/types/storeloader_test.go @@ -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)