diff --git a/CHANGELOG.md b/CHANGELOG.md index 7563cf799b6e..67240c92ec9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,30 @@ Ref: https://keepachangelog.com/en/1.0.0/ # Changelog -## [Unreleased] +## [v0.53.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.53.3) - 2025-07-25 + +This patch update also includes minor dependency bumps. + +### Features + +* (abci_utils) [#25008](https://github.com/cosmos/cosmos-sdk/pull/24861) add the ability to assign a custom signer extraction adapter in `DefaultProposalHandler`. + +## [v0.53.3](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.53.3) - 2025-07-08 + +### Bug Fixes + +* [GHSA-p22h-3m2v-cmgh](https://github.com/cosmos/cosmos-sdk/security/advisories/GHSA-p22h-3m2v-cmgh) Fix x/distribution can halt when historical rewards overflow. + + +## [v0.53.2](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.53.2) - 2025-06-02 + +This patch update also includes minor dependency bumps. + +### Bug Fixes + +* (x/epochs) [#24770](https://github.com/cosmos/cosmos-sdk/pull/24770) Fix register of epoch hooks in `InvokeSetHooks`. + +## [v0.53.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.53.0) - 2025-04-29 ### Breaking Changes @@ -112,6 +135,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * The `InflationCalculationFn` argument to `mint.NewAppModule()` is now ignored and must be nil. To set a custom `InflationCalculationFn` on the default minter, use `mintkeeper.WithMintFn(mintkeeper.DefaultMintFn(customInflationFn))`. * (api) [#24428](https://github.com/cosmos/cosmos-sdk/pull/24428) Add block height to response headers * (baseapp) [#25470](https://github.com/cosmos/cosmos-sdk/pull/25470) Support mount object store in baseapp, add `ObjectStore` api in context. +* (baseapp) [#25334](https://github.com/cosmos/cosmos-sdk/pull/25334) Add `Executor` to support custom execution logic and incarnation cache for performance optimisation ### Improvements diff --git a/Makefile b/Makefile index 0e935ce2b185..59a6914743a4 100644 --- a/Makefile +++ b/Makefile @@ -531,4 +531,4 @@ build-v53: else \ echo "No changes to reapply"; \ fi -.PHONY: build-v53 \ No newline at end of file +.PHONY: build-v53 diff --git a/baseapp/abci.go b/baseapp/abci.go index 662087e58106..f7ede1c840f6 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -21,6 +21,7 @@ import ( storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/baseapp/state" + "github.com/cosmos/cosmos-sdk/baseapp/txnrunner" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" @@ -355,7 +356,7 @@ func (app *BaseApp) CheckTx(req *abci.RequestCheckTx) (*abci.ResponseCheckTx, er } if app.abciHandlers.CheckTxHandler == nil { - gasInfo, result, anteEvents, err := app.runTx(mode, req.Tx, nil) + gasInfo, result, anteEvents, err := app.RunTx(mode, req.Tx, nil, -1, nil, nil) if err != nil { return sdkerrors.ResponseCheckTxWithEvents(err, gasInfo.GasWanted, gasInfo.GasUsed, anteEvents, app.trace), nil } @@ -371,7 +372,7 @@ func (app *BaseApp) CheckTx(req *abci.RequestCheckTx) (*abci.ResponseCheckTx, er // Create wrapper to avoid users overriding the execution mode runTx := func(txBytes []byte, tx sdk.Tx) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, err error) { - return app.runTx(mode, txBytes, tx) + return app.RunTx(mode, txBytes, tx, -1, nil, nil) } return app.abciHandlers.CheckTxHandler(runTx, req) @@ -395,6 +396,14 @@ func (app *BaseApp) PrepareProposal(req *abci.RequestPrepareProposal) (resp *abc return nil, errors.New("PrepareProposal handler not set") } + // Abort any running OE so it cannot overlap with `PrepareProposal`. This could happen if optimistic + // `internalFinalizeBlock` from previous round takes a long time, but consensus has moved on to next round. + // Overlap is undesirable, since `internalFinalizeBlock` and `PrepareProoposal` could share access to + // in-memory structs depending on application implementation. + // No-op if OE is not enabled. + // Similar call to Abort() is done in `ProcessProposal`. + app.optimisticExec.Abort() + // Always reset state given that PrepareProposal can timeout and be called // again in a subsequent round. header := cmtproto.Header{ @@ -798,47 +807,45 @@ func (app *BaseApp) internalFinalizeBlock(ctx context.Context, req *abci.Request // Reset the gas meter so that the AnteHandlers aren't required to gasMeter = app.getBlockGasMeter(finalizeState.Context()) - finalizeState.SetContext(finalizeState.Context().WithBlockGasMeter(gasMeter)) + finalizeState.SetContext( + finalizeState.Context(). + WithBlockGasMeter(gasMeter). + WithTxCount(len(req.Txs))) // Iterate over all raw transactions in the proposal and attempt to execute // them, gathering the execution results. // // NOTE: Not all raw transactions may adhere to the sdk.Tx interface, e.g. // vote extensions, so skip those. - txResults := make([]*abci.ExecTxResult, 0, len(req.Txs)) - for _, rawTx := range req.Txs { - var response *abci.ExecTxResult - - if _, err := app.txDecoder(rawTx); err == nil { - response = app.deliverTx(rawTx) - } else { - // In the case where a transaction included in a block proposal is malformed, - // we still want to return a default response to comet. This is because comet - // expects a response for each transaction included in a block proposal. - response = sdkerrors.ResponseExecTxResultWithEvents( - sdkerrors.ErrTxDecode, - 0, - 0, - nil, - false, - ) - } - - // check after every tx if we should abort - select { - case <-ctx.Done(): - return nil, ctx.Err() - default: - // continue - } - - txResults = append(txResults, response) + txResults, err := app.executeTxsWithExecutor(ctx, finalizeState.MultiStore, req.Txs) + if err != nil { + // usually due to canceled + return nil, err } if finalizeState.MultiStore.TracingEnabled() { finalizeState.MultiStore = finalizeState.MultiStore.SetTracingContext(nil).(storetypes.CacheMultiStore) } + var ( + blockGasUsed uint64 + blockGasWanted uint64 + ) + for _, res := range txResults { + // GasUsed should not be -1 but just in case + if res.GasUsed > 0 { + blockGasUsed += uint64(res.GasUsed) + } + // GasWanted could be -1 if the tx is invalid + if res.GasWanted > 0 { + blockGasWanted += uint64(res.GasWanted) + } + } + finalizeState.SetContext( + finalizeState.Context(). + WithBlockGasUsed(blockGasUsed). + WithBlockGasWanted(blockGasWanted), + ) endBlock, err := app.endBlock(finalizeState.Context()) if err != nil { return nil, err @@ -863,6 +870,16 @@ func (app *BaseApp) internalFinalizeBlock(ctx context.Context, req *abci.Request }, nil } +func (app *BaseApp) executeTxsWithExecutor(ctx context.Context, ms storetypes.MultiStore, txs [][]byte) ([]*abci.ExecTxResult, error) { + if app.txRunner == nil { + app.txRunner = txnrunner.NewDefaultRunner( + app.txDecoder, + ) + } + + return app.txRunner.Run(ctx, ms, txs, app.deliverTx) +} + // FinalizeBlock will execute the block proposal provided by RequestFinalizeBlock. // Specifically, it will execute an application's BeginBlock (if defined), followed // by the transactions in the proposal, finally followed by the application's diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 2693d7c1071b..31fd20b1f7e7 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -161,6 +161,9 @@ type BaseApp struct { // // SAFETY: it's safe to do if validators validate the total gas wanted in the `ProcessProposal`, which is the case in the default handler. disableBlockGasMeter bool + + // Optional alternative tx runner, used for block-stm parallel transaction execution. If nil, default txRunner is used. + txRunner sdk.TxRunner } // NewBaseApp returns a reference to an initialized BaseApp. It accepts a @@ -602,9 +605,7 @@ func (app *BaseApp) getBlockGasMeter(ctx sdk.Context) storetypes.GasMeter { return storetypes.NewInfiniteGasMeter() } -// getContextForTx retrieves the context for the tx w/ txBytes and other memoized values. -// retrieve the context for the tx w/ txBytes and other memoized values. -func (app *BaseApp) getContextForTx(mode sdk.ExecMode, txBytes []byte) sdk.Context { +func (app *BaseApp) getContextForTx(mode sdk.ExecMode, txBytes []byte, txIndex int) sdk.Context { app.mu.Lock() defer app.mu.Unlock() @@ -614,6 +615,7 @@ func (app *BaseApp) getContextForTx(mode sdk.ExecMode, txBytes []byte) sdk.Conte } ctx := modeState.Context(). WithTxBytes(txBytes). + WithTxIndex(txIndex). WithGasMeter(storetypes.NewInfiniteGasMeter()) // WithVoteInfos(app.voteInfos) // TODO: identify if this is needed @@ -698,7 +700,7 @@ func (app *BaseApp) beginBlock(_ *abci.RequestFinalizeBlock) (sdk.BeginBlock, er return resp, nil } -func (app *BaseApp) deliverTx(tx []byte) *abci.ExecTxResult { +func (app *BaseApp) deliverTx(tx []byte, txMultiStore storetypes.MultiStore, txIndex int, incarnationCache map[string]any) *abci.ExecTxResult { gInfo := sdk.GasInfo{} resultStr := "successful" @@ -711,7 +713,7 @@ func (app *BaseApp) deliverTx(tx []byte) *abci.ExecTxResult { telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, err := app.runTx(execModeFinalize, tx, nil) + gInfo, result, anteEvents, err := app.RunTx(execModeFinalize, tx, nil, txIndex, txMultiStore, incarnationCache) if err != nil { resultStr = "failed" resp = sdkerrors.ResponseExecTxResultWithEvents( @@ -761,7 +763,7 @@ func (app *BaseApp) endBlock(_ context.Context) (sdk.EndBlock, error) { return endblock, nil } -// runTx processes a transaction within a given execution mode, encoded transaction +// RunTx processes a transaction within a given execution mode, encoded transaction // bytes, and the decoded transaction itself. All state transitions occur through // a cached Context depending on the mode provided. State only gets persisted // if all messages get executed successfully and the execution mode is DeliverTx. @@ -770,17 +772,23 @@ func (app *BaseApp) endBlock(_ context.Context) (sdk.EndBlock, error) { // and execute successfully. An error is returned otherwise. // both txbytes and the decoded tx are passed to runTx to avoid the state machine encoding the tx and decoding the transaction twice // passing the decoded tx to runTX is optional, it will be decoded if the tx is nil -func (app *BaseApp) runTx(mode sdk.ExecMode, txBytes []byte, tx sdk.Tx) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, err error) { +func (app *BaseApp) RunTx(mode sdk.ExecMode, txBytes []byte, tx sdk.Tx, txIndex int, txMultiStore storetypes.MultiStore, incarnationCache map[string]any) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, err error) { // NOTE: GasWanted should be returned by the AnteHandler. GasUsed is // determined by the GasMeter. We need access to the context to get the gas // meter, so we initialize upfront. var gasWanted uint64 - ctx := app.getContextForTx(mode, txBytes) + ctx := app.getContextForTx(mode, txBytes, txIndex) + if incarnationCache != nil { + ctx = ctx.WithIncarnationCache(incarnationCache) + } + if txMultiStore != nil { + ctx = ctx.WithMultiStore(txMultiStore) + } ms := ctx.MultiStore() // only run the tx if there is block gas remaining - if mode == execModeFinalize && ctx.BlockGasMeter().IsOutOfGas() { + if mode == sdk.ExecModeFinalize && ctx.BlockGasMeter().IsOutOfGas() { return gInfo, nil, nil, errorsmod.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") } @@ -969,6 +977,8 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, msgsV2 []protov2.Me break } + ctx = ctx.WithMsgIndex(i) + handler := app.msgServiceRouter.Handler(msg) if handler == nil { return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "no message handler found for %T", msg) @@ -1067,7 +1077,7 @@ func (app *BaseApp) PrepareProposalVerifyTx(tx sdk.Tx) ([]byte, error) { return nil, err } - _, _, _, err = app.runTx(execModePrepareProposal, bz, tx) + _, _, _, err = app.RunTx(execModePrepareProposal, bz, tx, -1, nil, nil) if err != nil { return nil, err } @@ -1086,7 +1096,7 @@ func (app *BaseApp) ProcessProposalVerifyTx(txBz []byte) (sdk.Tx, error) { return nil, err } - _, _, _, err = app.runTx(execModeProcessProposal, txBz, tx) + _, _, _, err = app.RunTx(execModeProcessProposal, txBz, tx, -1, nil, nil) if err != nil { return nil, err } diff --git a/baseapp/genesis.go b/baseapp/genesis.go index 4662d1187b4a..547a1322d8a7 100644 --- a/baseapp/genesis.go +++ b/baseapp/genesis.go @@ -13,7 +13,7 @@ var _ genesis.TxHandler = (*BaseApp)(nil) // ExecuteGenesisTx implements genesis.GenesisState from // cosmossdk.io/core/genesis to set initial state in genesis func (ba *BaseApp) ExecuteGenesisTx(tx []byte) error { - res := ba.deliverTx(tx) + res := ba.deliverTx(tx, nil, -1, nil) if res.Code != types.CodeTypeOK { return errors.New(res.Log) diff --git a/baseapp/options.go b/baseapp/options.go index 94cf81334015..41d845e29ce7 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -124,6 +124,11 @@ func SetOptimisticExecution(opts ...func(*oe.OptimisticExecution)) func(*BaseApp } } +// SetBlockSTMTxRunner sets the block stm tx runner for the BaseApp for parallel execution. +func (app *BaseApp) SetBlockSTMTxRunner(txRunner sdk.TxRunner) { + app.txRunner = txRunner +} + // DisableBlockGasMeter disables the block gas meter. func DisableBlockGasMeter() func(*BaseApp) { return func(app *BaseApp) { app.SetDisableBlockGasMeter(true) } diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index c254a2463055..6144552490b2 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -19,13 +19,13 @@ func (app *BaseApp) SimCheck(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, * return sdk.GasInfo{}, nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - gasInfo, result, _, err := app.runTx(execModeCheck, bz, tx) + gasInfo, result, _, err := app.RunTx(execModeCheck, bz, tx, -1, nil, nil) return gasInfo, result, err } // Simulate executes a tx in simulate mode to get result and gas info. func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { - gasInfo, result, _, err := app.runTx(execModeSimulate, txBytes, nil) + gasInfo, result, _, err := app.RunTx(execModeSimulate, txBytes, nil, -1, nil, nil) return gasInfo, result, err } @@ -36,7 +36,7 @@ func (app *BaseApp) SimDeliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, return sdk.GasInfo{}, nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - gasInfo, result, _, err := app.runTx(execModeFinalize, bz, tx) + gasInfo, result, _, err := app.RunTx(execModeFinalize, bz, tx, -1, nil, nil) return gasInfo, result, err } @@ -47,7 +47,7 @@ func (app *BaseApp) SimTxFinalizeBlock(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk. return sdk.GasInfo{}, nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - gasInfo, result, _, err := app.runTx(execModeFinalize, bz, tx) + gasInfo, result, _, err := app.RunTx(execModeFinalize, bz, tx, -1, nil, nil) return gasInfo, result, err } @@ -77,9 +77,9 @@ func (app *BaseApp) NewUncachedContext(isCheckTx bool, header cmtproto.Header) s } func (app *BaseApp) GetContextForFinalizeBlock(txBytes []byte) sdk.Context { - return app.getContextForTx(execModeFinalize, txBytes) + return app.getContextForTx(execModeFinalize, txBytes, -1) } func (app *BaseApp) GetContextForCheckTx(txBytes []byte) sdk.Context { - return app.getContextForTx(execModeCheck, txBytes) + return app.getContextForTx(execModeCheck, txBytes, -1) } diff --git a/baseapp/txnrunner/default.go b/baseapp/txnrunner/default.go new file mode 100644 index 000000000000..d92f8099d4dd --- /dev/null +++ b/baseapp/txnrunner/default.go @@ -0,0 +1,59 @@ +package txnrunner + +import ( + "context" + + abci "github.com/cometbft/cometbft/abci/types" + + storetypes "cosmossdk.io/store/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +var _ sdk.TxRunner = DefaultRunner{} + +func NewDefaultRunner(txDecoder sdk.TxDecoder) *DefaultRunner { + return &DefaultRunner{ + txDecoder: txDecoder, + } +} + +// DefaultRunner is the default TxnRunner implementation which executes the transactions in a block sequentially. +type DefaultRunner struct { + txDecoder sdk.TxDecoder +} + +func (d DefaultRunner) Run(ctx context.Context, _ storetypes.MultiStore, txs [][]byte, deliverTx sdk.DeliverTxFunc) ([]*abci.ExecTxResult, error) { + // Fallback to the default execution logic + txResults := make([]*abci.ExecTxResult, 0, len(txs)) + for i, rawTx := range txs { + var response *abci.ExecTxResult + + if _, err := d.txDecoder(rawTx); err == nil { + response = deliverTx(rawTx, nil, i, nil) + } else { + // In the case where a transaction included in a block proposal is malformed, + // we still want to return a default response to comet. This is because comet + // expects a response for each transaction included in a block proposal. + response = sdkerrors.ResponseExecTxResultWithEvents( + sdkerrors.ErrTxDecode, + 0, + 0, + nil, + false, + ) + } + + // check after every tx if we should abort + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + // continue + } + + txResults = append(txResults, response) + } + return txResults, nil +} diff --git a/baseapp/txnrunner/default_test.go b/baseapp/txnrunner/default_test.go new file mode 100644 index 000000000000..a74cb1d2ffb1 --- /dev/null +++ b/baseapp/txnrunner/default_test.go @@ -0,0 +1,168 @@ +package txnrunner + +import ( + "context" + "errors" + "sync/atomic" + "testing" + + abci "github.com/cometbft/cometbft/abci/types" + "github.com/stretchr/testify/require" + + storetypes "cosmossdk.io/store/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// Mock TxDecoder for testing +func mockTxDecoder(txBytes []byte) (sdk.Tx, error) { + if len(txBytes) == 0 { + return nil, errors.New("empty tx") + } + // Valid transaction if first byte is not 0xFF + if txBytes[0] == 0xFF { + return nil, errors.New("invalid tx") + } + return nil, nil +} + +// TestNewDefaultRunner tests the constructor +func TestNewDefaultRunner(t *testing.T) { + runner := NewDefaultRunner(nil) + + require.NotNil(t, runner) + require.Nil(t, runner.txDecoder) +} + +// TestDefaultRunner_Run_Success tests successful execution of transactions +func TestDefaultRunner_Run_Success(t *testing.T) { + decoder := mockTxDecoder + runner := NewDefaultRunner(decoder) + + txs := [][]byte{ + {0x01, 0x02, 0x03}, + {0x04, 0x05, 0x06}, + {0x07, 0x08, 0x09}, + } + + executionCount := atomic.Int32{} + deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { + executionCount.Add(1) + return &abci.ExecTxResult{ + Code: 0, + Data: tx, + } + } + + ctx := context.Background() + results, err := runner.Run(ctx, nil, txs, deliverTx) + + require.NoError(t, err) + require.Len(t, results, len(txs)) + require.Equal(t, int32(len(txs)), executionCount.Load()) + + for i, result := range results { + require.Equal(t, uint32(0), result.Code) + require.Equal(t, txs[i], result.Data) + } +} + +// TestDefaultRunner_Run_EmptyTxs tests execution with no transactions +func TestDefaultRunner_Run_EmptyTxs(t *testing.T) { + decoder := mockTxDecoder + runner := NewDefaultRunner(decoder) + + deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { + t.Fatal("deliverTx should not be called for empty txs") + return nil + } + + ctx := context.Background() + results, err := runner.Run(ctx, nil, [][]byte{}, deliverTx) + + require.NoError(t, err) + require.Empty(t, results) +} + +// TestDefaultRunner_Run_InvalidTx tests handling of invalid transactions +func TestDefaultRunner_Run_InvalidTx(t *testing.T) { + decoder := mockTxDecoder + runner := NewDefaultRunner(decoder) + + txs := [][]byte{ + {0x01, 0x02, 0x03}, // valid + {0xFF, 0xFF, 0xFF}, // invalid (0xFF marker) + {0x07, 0x08, 0x09}, // valid + } + + validTxCount := atomic.Int32{} + deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { + validTxCount.Add(1) + return &abci.ExecTxResult{Code: 0} + } + + ctx := context.Background() + results, err := runner.Run(ctx, nil, txs, deliverTx) + + require.NoError(t, err) + require.Len(t, results, len(txs)) + // Only 2 valid transactions should be executed + require.Equal(t, int32(2), validTxCount.Load()) + + // The invalid tx should get an error response + require.Equal(t, sdkerrors.ErrTxDecode.ABCICode(), results[1].Code) +} + +// TestDefaultRunner_Run_ContextCancellation tests that execution stops on context cancellation +func TestDefaultRunner_Run_ContextCancellation(t *testing.T) { + decoder := mockTxDecoder + runner := NewDefaultRunner(decoder) + + txs := [][]byte{ + {0x01, 0x02, 0x03}, + {0x04, 0x05, 0x06}, + {0x07, 0x08, 0x09}, + {0x0A, 0x0B, 0x0C}, + } + + ctx, cancel := context.WithCancel(context.Background()) + + executionCount := atomic.Int32{} + deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { + count := executionCount.Add(1) + // Cancel after second transaction + if count == 2 { + cancel() + } + return &abci.ExecTxResult{Code: 0} + } + + _, err := runner.Run(ctx, nil, txs, deliverTx) + + require.Error(t, err) + require.Equal(t, context.Canceled, err) + // Results may be nil or partial depending on when cancellation occurs + // The key assertion is that execution was stopped + require.LessOrEqual(t, executionCount.Load(), int32(len(txs))) +} + +// TestDefaultRunner_Run_MultiStoreIsNil tests that nil multistore is handled correctly +func TestDefaultRunner_Run_MultiStoreIsNil(t *testing.T) { + decoder := mockTxDecoder + runner := NewDefaultRunner(decoder) + + txs := [][]byte{{0x01}} + + deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { + require.Nil(t, ms, "multistore should be nil for DefaultRunner") + require.Nil(t, cache, "cache should be nil for DefaultRunner") + return &abci.ExecTxResult{Code: 0} + } + + ctx := context.Background() + results, err := runner.Run(ctx, nil, txs, deliverTx) + + require.NoError(t, err) + require.Len(t, results, 1) +} diff --git a/blockstm/txnrunner.go b/blockstm/txnrunner.go index ad4c32cdf1ec..9e50c60522ea 100644 --- a/blockstm/txnrunner.go +++ b/blockstm/txnrunner.go @@ -11,58 +11,9 @@ import ( storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -var ( - _ sdk.TxRunner = DefaultRunner{} - _ sdk.TxRunner = STMRunner{} -) - -func NewDefaultRunner(txDecoder sdk.TxDecoder) *DefaultRunner { - return &DefaultRunner{ - txDecoder: txDecoder, - } -} - -// DefaultRunner default executor without parallelism -type DefaultRunner struct { - txDecoder sdk.TxDecoder -} - -func (d DefaultRunner) Run(ctx context.Context, _ storetypes.MultiStore, txs [][]byte, deliverTx sdk.DeliverTxFunc) ([]*abci.ExecTxResult, error) { - // Fallback to the default execution logic - txResults := make([]*abci.ExecTxResult, 0, len(txs)) - for i, rawTx := range txs { - var response *abci.ExecTxResult - - if _, err := d.txDecoder(rawTx); err == nil { - response = deliverTx(rawTx, nil, i, nil) - } else { - // In the case where a transaction included in a block proposal is malformed, - // we still want to return a default response to comet. This is because comet - // expects a response for each transaction included in a block proposal. - response = sdkerrors.ResponseExecTxResultWithEvents( - sdkerrors.ErrTxDecode, - 0, - 0, - nil, - false, - ) - } - - // check after every tx if we should abort - select { - case <-ctx.Done(): - return nil, ctx.Err() - default: - // continue - } - - txResults = append(txResults, response) - } - return txResults, nil -} +var _ sdk.TxRunner = STMRunner{} func NewSTMRunner( txDecoder sdk.TxDecoder, diff --git a/blockstm/txnrunner_test.go b/blockstm/txnrunner_test.go index 76791b0e6951..0dc0779f8088 100644 --- a/blockstm/txnrunner_test.go +++ b/blockstm/txnrunner_test.go @@ -14,8 +14,8 @@ import ( "cosmossdk.io/collections" storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/baseapp/txnrunner" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // Mock TxDecoder for testing @@ -78,147 +78,6 @@ func mockTxDecoderWithFeeTx(txBytes []byte) (sdk.Tx, error) { }, nil } -// TestNewDefaultRunner tests the constructor -func TestNewDefaultRunner(t *testing.T) { - decoder := mockTxDecoder - runner := NewDefaultRunner(decoder) - - require.NotNil(t, runner) - require.NotNil(t, runner.txDecoder) -} - -// TestDefaultRunner_Run_Success tests successful execution of transactions -func TestDefaultRunner_Run_Success(t *testing.T) { - decoder := mockTxDecoder - runner := NewDefaultRunner(decoder) - - txs := [][]byte{ - {0x01, 0x02, 0x03}, - {0x04, 0x05, 0x06}, - {0x07, 0x08, 0x09}, - } - - executionCount := atomic.Int32{} - deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { - executionCount.Add(1) - return &abci.ExecTxResult{ - Code: 0, - Data: tx, - } - } - - ctx := context.Background() - results, err := runner.Run(ctx, nil, txs, deliverTx) - - require.NoError(t, err) - require.Len(t, results, len(txs)) - require.Equal(t, int32(len(txs)), executionCount.Load()) - - for i, result := range results { - require.Equal(t, uint32(0), result.Code) - require.Equal(t, txs[i], result.Data) - } -} - -// TestDefaultRunner_Run_EmptyTxs tests execution with no transactions -func TestDefaultRunner_Run_EmptyTxs(t *testing.T) { - decoder := mockTxDecoder - runner := NewDefaultRunner(decoder) - - deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { - t.Fatal("deliverTx should not be called for empty txs") - return nil - } - - ctx := context.Background() - results, err := runner.Run(ctx, nil, [][]byte{}, deliverTx) - - require.NoError(t, err) - require.Empty(t, results) -} - -// TestDefaultRunner_Run_InvalidTx tests handling of invalid transactions -func TestDefaultRunner_Run_InvalidTx(t *testing.T) { - decoder := mockTxDecoder - runner := NewDefaultRunner(decoder) - - txs := [][]byte{ - {0x01, 0x02, 0x03}, // valid - {0xFF, 0xFF, 0xFF}, // invalid (0xFF marker) - {0x07, 0x08, 0x09}, // valid - } - - validTxCount := atomic.Int32{} - deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { - validTxCount.Add(1) - return &abci.ExecTxResult{Code: 0} - } - - ctx := context.Background() - results, err := runner.Run(ctx, nil, txs, deliverTx) - - require.NoError(t, err) - require.Len(t, results, len(txs)) - // Only 2 valid transactions should be executed - require.Equal(t, int32(2), validTxCount.Load()) - - // The invalid tx should get an error response - require.Equal(t, sdkerrors.ErrTxDecode.ABCICode(), results[1].Code) -} - -// TestDefaultRunner_Run_ContextCancellation tests that execution stops on context cancellation -func TestDefaultRunner_Run_ContextCancellation(t *testing.T) { - decoder := mockTxDecoder - runner := NewDefaultRunner(decoder) - - txs := [][]byte{ - {0x01, 0x02, 0x03}, - {0x04, 0x05, 0x06}, - {0x07, 0x08, 0x09}, - {0x0A, 0x0B, 0x0C}, - } - - ctx, cancel := context.WithCancel(context.Background()) - - executionCount := atomic.Int32{} - deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { - count := executionCount.Add(1) - // Cancel after second transaction - if count == 2 { - cancel() - } - return &abci.ExecTxResult{Code: 0} - } - - _, err := runner.Run(ctx, nil, txs, deliverTx) - - require.Error(t, err) - require.Equal(t, context.Canceled, err) - // Results may be nil or partial depending on when cancellation occurs - // The key assertion is that execution was stopped - require.LessOrEqual(t, executionCount.Load(), int32(len(txs))) -} - -// TestDefaultRunner_Run_MultiStoreIsNil tests that nil multistore is handled correctly -func TestDefaultRunner_Run_MultiStoreIsNil(t *testing.T) { - decoder := mockTxDecoder - runner := NewDefaultRunner(decoder) - - txs := [][]byte{{0x01}} - - deliverTx := func(tx []byte, ms storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { - require.Nil(t, ms, "multistore should be nil for DefaultRunner") - require.Nil(t, cache, "cache should be nil for DefaultRunner") - return &abci.ExecTxResult{Code: 0} - } - - ctx := context.Background() - results, err := runner.Run(ctx, nil, txs, deliverTx) - - require.NoError(t, err) - require.Len(t, results, 1) -} - // TestNewSTMRunner tests the STMRunner constructor func TestNewSTMRunner(t *testing.T) { decoder := mockTxDecoder @@ -567,7 +426,6 @@ func TestPreEstimates_KeyEncoding(t *testing.T) { func TestTxRunnerInterface(t *testing.T) { decoder := mockTxDecoder - var _ sdk.TxRunner = NewDefaultRunner(decoder) var _ sdk.TxRunner = NewSTMRunner(decoder, []storetypes.StoreKey{}, 1, false, "") } @@ -612,44 +470,6 @@ func TestSTMRunner_Integration(t *testing.T) { require.Len(t, results, blk.Size()) } -// TestDefaultRunner_Integration tests integration with sequential execution -func TestDefaultRunner_Integration(t *testing.T) { - decoder := mockTxDecoder - runner := NewDefaultRunner(decoder) - - ctx := context.Background() - storeIndex := map[storetypes.StoreKey]int{ - StoreKeyAuth: 0, - StoreKeyBank: 1, - } - msRaw := NewMultiMemDB(storeIndex) - - // Create a mock block - blk := noConflictBlock(10) - - deliverTx := func(tx []byte, _ storetypes.MultiStore, txIndex int, cache map[string]any) *abci.ExecTxResult { - if txIndex < blk.Size() { - blk.ExecuteTx(TxnIndex(txIndex), msRaw) - } - return &abci.ExecTxResult{Code: 0} - } - - txs := make([][]byte, blk.Size()) - for i := range txs { - txs[i] = []byte{byte(i)} - } - - results, err := runner.Run(ctx, nil, txs, deliverTx) - - require.NoError(t, err) - require.Len(t, results, blk.Size()) - - // Verify all transactions succeeded - for i, err := range blk.Results { - require.NoError(t, err, "transaction %d should succeed", i) - } -} - // TestRunnerComparison tests that both DefaultRunner and STMRunner can execute successfully func TestRunnerComparison(t *testing.T) { decoder := mockTxDecoder @@ -670,7 +490,7 @@ func TestRunnerComparison(t *testing.T) { // Test DefaultRunner t.Run("DefaultRunner", func(t *testing.T) { - runner := NewDefaultRunner(decoder) + runner := txnrunner.NewDefaultRunner(decoder) executionCount.Store(0) results, err := runner.Run(ctx, nil, txs, deliverTx) diff --git a/client/v2/CHANGELOG.md b/client/v2/CHANGELOG.md index bf334e7769cd..5631bd5ea3a2 100644 --- a/client/v2/CHANGELOG.md +++ b/client/v2/CHANGELOG.md @@ -34,11 +34,12 @@ Ref: https://keepachangelog.com/en/1.0.0/ # Changelog -## UNRELEASED +## [v2.0.0-beta.11](https://github.com/cosmos/cosmos-sdk/tree/client/v2.0.0-beta.11) - 2025-05-30 ### Bug Fixes -* [#24722](https://github.com/cosmos/cosmos-sdk/pull/24722) Fix msg parsing when no pulsar file is present. +* [#24722](https://github.com/cosmos/cosmos-sdk/pull/24722) Fix msg parsing in when no pulsar file is present. + ## [v2.0.0-beta.9](https://github.com/cosmos/cosmos-sdk/tree/client/v2.0.0-beta.9) - 2025-04-24 @@ -48,7 +49,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements -* [#22890](https://github.com/cosmos/cosmos-sdk/pull/22890) Added support for flattening inner message fields in autocli as positional arguments. +* [#22890](https://github.com/cosmos/cosmos-sdk/pull/22890) Added support for flattening inner message fields in autocli as positional arguments. ### Bug Fixes diff --git a/client/v2/go.mod b/client/v2/go.mod index 76f5e3187ec4..49c6564864ca 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/client/v2 -go 1.24.0 +go 1.25.0 require ( cosmossdk.io/api v0.9.2 @@ -174,4 +174,5 @@ require ( replace ( cosmossdk.io/store => ../../store github.com/cosmos/cosmos-sdk => ../../. + github.com/tidwall/btree => github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 ) diff --git a/client/v2/go.sum b/client/v2/go.sum index 0c7cc26ed9dd..cdc51cec2ae5 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -145,6 +145,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 h1:dC3GJcS8bJiSEe7VAFDDFgFnVM1G9nBdGOgqJsmsZwM= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY= github.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= @@ -508,9 +510,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= -github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -688,8 +689,6 @@ github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDd github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= -github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= diff --git a/client/v2/internal/testpbgogo/msg.proto b/client/v2/internal/testpbgogo/msg.proto index 65f978f0bd8f..c8699413995a 100644 --- a/client/v2/internal/testpbgogo/msg.proto +++ b/client/v2/internal/testpbgogo/msg.proto @@ -25,4 +25,4 @@ message MsgRequestGogoOnly { message MsgResponseGoGoOnly { MsgRequestGogoOnly request = 1; -} \ No newline at end of file +} diff --git a/client/v2/internal/testpbpulsar/msg.proto b/client/v2/internal/testpbpulsar/msg.proto index ce1f35a12aac..6cedc40d2dcc 100644 --- a/client/v2/internal/testpbpulsar/msg.proto +++ b/client/v2/internal/testpbpulsar/msg.proto @@ -59,4 +59,4 @@ message MsgResponse { message MsgClawbackRequest {} -message MsgClawbackResponse {} \ No newline at end of file +message MsgClawbackResponse {} diff --git a/core/go.mod b/core/go.mod index 6a2d4176df4d..832c84df444c 100644 --- a/core/go.mod +++ b/core/go.mod @@ -46,6 +46,7 @@ require ( github.com/spf13/cast v1.8.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect golang.org/x/net v0.42.0 // indirect golang.org/x/sys v0.34.0 // indirect @@ -53,7 +54,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) // Version tagged too early and incompatible with v0.50 (latest at the time of tagging) diff --git a/core/go.sum b/core/go.sum index c6b6732905eb..784278e4b1cd 100644 --- a/core/go.sum +++ b/core/go.sum @@ -75,7 +75,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -159,6 +158,10 @@ go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mx go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= +go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -255,5 +258,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/go.mod b/go.mod index 01f4b5db4754..10f9880faca8 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -go 1.24.0 +go 1.25.0 module github.com/cosmos/cosmos-sdk @@ -175,7 +175,6 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/nxadm/tail v1.4.11 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect @@ -235,6 +234,7 @@ require ( // Here are the short-lived replace from the Cosmos SDK // Replace here are pending PRs, or version to be tagged +replace cosmossdk.io/store => ./store // Below are the long-lived replace of the Cosmos SDK replace ( @@ -252,9 +252,10 @@ replace ( github.com/tidwall/btree => github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 ) -replace cosmossdk.io/store => ./store - retract ( + // incorrect tag for patch version + v0.53.1 + // false start by tagging the wrong branch v0.50.0 // revert fix https://github.com/cosmos/cosmos-sdk/pull/16331 diff --git a/go.sum b/go.sum index 2888a8635af6..8dc8e90ad9a9 100644 --- a/go.sum +++ b/go.sum @@ -305,7 +305,6 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= @@ -615,9 +614,8 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= -github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -1012,7 +1010,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/simapp/app.go b/simapp/app.go index be6cbcee4ac8..4d8547817fc5 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -114,7 +114,8 @@ var ( stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, protocolpooltypes.ModuleName: nil, - protocolpooltypes.ProtocolPoolEscrowAccount: nil} + protocolpooltypes.ProtocolPoolEscrowAccount: nil, + } ) var ( @@ -521,6 +522,7 @@ func NewSimApp( epochstypes.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( + banktypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, genutiltypes.ModuleName, diff --git a/simapp/app_config.go b/simapp/app_config.go index 1e5b27df1406..bd78bdead489 100644 --- a/simapp/app_config.go +++ b/simapp/app_config.go @@ -109,6 +109,7 @@ var ( epochstypes.ModuleName, }, EndBlockers: []string{ + banktypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, feegrant.ModuleName, diff --git a/simapp/go.mod b/simapp/go.mod index 2c0f875e7250..8a8da38b88c3 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/simapp -go 1.24.0 +go 1.25.0 require ( cosmossdk.io/api v0.9.2 @@ -232,11 +232,7 @@ require ( sigs.k8s.io/yaml v1.6.0 // indirect ) -// Here are the short-lived replace from the SimApp -// Replace here are pending PRs, or version to be tagged -// replace ( -// -// ) +// cosmossdk.io/store => ../store replace cosmossdk.io/store => ../store // Below are the long-lived replace of the SimApp @@ -250,4 +246,6 @@ replace ( github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.1 // replace broken goleveldb github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + // Use fork for blockstm + github.com/tidwall/btree => github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 ) diff --git a/simapp/go.sum b/simapp/go.sum index e042a8ac8826..f9036d2cc5c8 100644 --- a/simapp/go.sum +++ b/simapp/go.sum @@ -221,6 +221,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 h1:dC3GJcS8bJiSEe7VAFDDFgFnVM1G9nBdGOgqJsmsZwM= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY= github.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= @@ -622,9 +624,8 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= -github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -805,8 +806,6 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= -github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= diff --git a/store/CHANGELOG.md b/store/CHANGELOG.md index 6cec5188637d..ec3ecd4910be 100644 --- a/store/CHANGELOG.md +++ b/store/CHANGELOG.md @@ -45,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#21574](https://github.com/cosmos/cosmos-sdk/pull/21574) Upgrade IVL to IAVL 1.2.0. + ## v1.1.0 (March 20, 2024) ### Improvements diff --git a/store/go.mod b/store/go.mod index 4793c33c8a31..5b668259c06d 100644 --- a/store/go.mod +++ b/store/go.mod @@ -2,6 +2,8 @@ module cosmossdk.io/store go 1.24.0 +replace github.com/tidwall/btree => github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 + require ( cosmossdk.io/errors v1.0.2 cosmossdk.io/log v1.6.1 diff --git a/store/go.sum b/store/go.sum index d82f3280c682..3398f546c8e4 100644 --- a/store/go.sum +++ b/store/go.sum @@ -55,6 +55,8 @@ github.com/cockroachdb/tokenbucket v0.0.0-20250429170803-42689b6311bb/go.mod h1: github.com/cometbft/cometbft v0.39.0-beta.2 h1:OfP4Qlw2L66xqvrNYSlVufYwXXP9frOPBnwYPyDttOk= github.com/cometbft/cometbft v0.39.0-beta.2/go.mod h1:6Lt9liF9HxSth+zDotxtv94SuGMzRfuHmI287USgjlw= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 h1:dC3GJcS8bJiSEe7VAFDDFgFnVM1G9nBdGOgqJsmsZwM= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/cosmos/cosmos-db v1.1.1 h1:FezFSU37AlBC8S98NlSagL76oqBRWq/prTPvFcEJNCM= github.com/cosmos/cosmos-db v1.1.1/go.mod h1:AghjcIPqdhSLP/2Z0yha5xPH3nLnskz81pBx3tcVSAw= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= @@ -298,8 +300,6 @@ github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jq github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= -github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= diff --git a/systemtests/go.mod b/systemtests/go.mod index 30162393ad1d..ab33d41bab85 100644 --- a/systemtests/go.mod +++ b/systemtests/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/systemtests -go 1.24.0 +go 1.25.0 require ( cosmossdk.io/math v1.5.3 @@ -173,3 +173,6 @@ require ( replace cosmossdk.io/store => ../store replace github.com/cosmos/cosmos-sdk => ../ + +// Use fork for blockstm +replace github.com/tidwall/btree => github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 diff --git a/systemtests/go.sum b/systemtests/go.sum index 30a042a90509..971aa7cb9d89 100644 --- a/systemtests/go.sum +++ b/systemtests/go.sum @@ -141,6 +141,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 h1:dC3GJcS8bJiSEe7VAFDDFgFnVM1G9nBdGOgqJsmsZwM= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY= github.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= @@ -506,9 +508,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= -github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -686,8 +687,6 @@ github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDd github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= -github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/tests/go.mod b/tests/go.mod index 960e3fa8fd0f..b13c8e20bbe3 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -1,6 +1,6 @@ module github.com/cosmos/cosmos-sdk/tests -go 1.24.0 +go 1.25.0 require ( cosmossdk.io/api v0.9.2 @@ -245,4 +245,6 @@ replace ( // Fix upstream GHSA-h395-qcrw-5vmq and GHSA-3vp4-m3rf-835h vulnerabilities. // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.1 + // Use fork for blockstm + github.com/tidwall/btree => github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 ) diff --git a/tests/go.sum b/tests/go.sum index b70d2543d5c1..dcfeb4ec19b1 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -219,6 +219,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 h1:dC3GJcS8bJiSEe7VAFDDFgFnVM1G9nBdGOgqJsmsZwM= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY= github.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= @@ -617,9 +619,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= -github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -804,8 +805,6 @@ github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDd github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= -github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= diff --git a/tests/systemtests/go.mod b/tests/systemtests/go.mod index e0360179dd59..9c9ab923811c 100644 --- a/tests/systemtests/go.mod +++ b/tests/systemtests/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/tests/systemtests -go 1.24.0 +go 1.25.0 replace ( // always use latest versions in tests @@ -177,4 +177,8 @@ require ( sigs.k8s.io/yaml v1.6.0 // indirect ) -replace cosmossdk.io/store => ../../store +replace ( + cosmossdk.io/store => ../../store + // Use fork for blockstm + github.com/tidwall/btree => github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 +) diff --git a/tests/systemtests/go.sum b/tests/systemtests/go.sum index a911ddb51aef..89dca96d2f51 100644 --- a/tests/systemtests/go.sum +++ b/tests/systemtests/go.sum @@ -141,6 +141,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951 h1:dC3GJcS8bJiSEe7VAFDDFgFnVM1G9nBdGOgqJsmsZwM= +github.com/cosmos/btree v0.0.0-20250924232609-2c6195d95951/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY= github.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= @@ -506,9 +508,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= -github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -686,8 +687,6 @@ github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDd github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= -github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/testutil/context.go b/testutil/context.go index 288f7fc55bcd..cd31fdf6b126 100644 --- a/testutil/context.go +++ b/testutil/context.go @@ -80,3 +80,18 @@ func DefaultContextWithDB(tb testing.TB, key, tkey storetypes.StoreKey) TestCont return TestContext{ctx, db, cms} } + +func DefaultContextWithObjectStore(tb testing.TB, key, tkey, okey storetypes.StoreKey) TestContext { + tb.Helper() + db := dbm.NewMemDB() + cms := store.NewCommitMultiStore(db, log.NewNopLogger(), metrics.NewNoOpMetrics()) + cms.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db) + cms.MountStoreWithDB(tkey, storetypes.StoreTypeTransient, db) + cms.MountStoreWithDB(okey, storetypes.StoreTypeObject, db) + err := cms.LoadLatestVersion() + assert.NoError(tb, err) + + ctx := sdk.NewContext(cms, cmtproto.Header{Time: time.Now()}, false, log.NewNopLogger()) + + return TestContext{ctx, db, cms} +} diff --git a/tools/benchmark/go.mod b/tools/benchmark/go.mod index 43f3fa9639c3..9e3c6f69cbb6 100644 --- a/tools/benchmark/go.mod +++ b/tools/benchmark/go.mod @@ -16,8 +16,9 @@ require ( google.golang.org/grpc v1.76.0 ) +require cosmossdk.io/collections v1.3.1 // indirect + require ( - cosmossdk.io/collections v1.3.1 // indirect cosmossdk.io/errors v1.0.2 // indirect cosmossdk.io/math v1.5.3 // indirect cosmossdk.io/schema v1.1.0 // indirect diff --git a/tools/confix/go.mod b/tools/confix/go.mod index cbc3e2052409..73d787bc45d3 100644 --- a/tools/confix/go.mod +++ b/tools/confix/go.mod @@ -12,6 +12,8 @@ require ( gotest.tools/v3 v3.5.2 ) +require go.yaml.in/yaml/v2 v2.4.3 // indirect + require ( cosmossdk.io/api v1.0.0-rc.1 // indirect cosmossdk.io/collections v1.3.1 // indirect @@ -139,7 +141,7 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/zondax/golem v0.27.0 // indirect github.com/zondax/hid v0.9.2 // indirect - github.com/zondax/ledger-go v1.0.1 // indirect; indirectÎ + github.com/zondax/ledger-go v1.0.1 // indirect go.etcd.io/bbolt v1.4.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.37.0 // indirect @@ -148,7 +150,6 @@ require ( go.uber.org/mock v0.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.21.0 // indirect golang.org/x/crypto v0.43.0 // indirect diff --git a/types/context.go b/types/context.go index d8d4e76308bc..4e762cc15943 100644 --- a/types/context.go +++ b/types/context.go @@ -64,6 +64,19 @@ type Context struct { streamingManager storetypes.StreamingManager cometInfo comet.BlockInfo headerInfo header.Info + + // For block-stm + // // the index of the current tx in the block, -1 means not in finalize block context + txIndex int + // the index of the current msg in the tx, -1 means not in finalize block context + msgIndex int + // the total number of transactions in current block + txCount int + // sum the gas used by all the transactions in the current block, only accessible by end blocker + blockGasUsed uint64 + incarnationCache map[string]any // incarnationCache is shared between multiple incarnations of the same transaction, it must only cache stateless computation results that only depends on tx body and block level information that don't change during block execution, like the result of tx signature verification. + // sum the gas wanted by all the transactions in the current block, only accessible by end blocker + blockGasWanted uint64 } // Proposed rename, not done to avoid API breakage @@ -94,6 +107,12 @@ func (c Context) TransientKVGasConfig() storetypes.GasConfig { return c.trans func (c Context) StreamingManager() storetypes.StreamingManager { return c.streamingManager } func (c Context) CometInfo() comet.BlockInfo { return c.cometInfo } func (c Context) HeaderInfo() header.Info { return c.headerInfo } +func (c Context) TxIndex() int { return c.txIndex } +func (c Context) MsgIndex() int { return c.msgIndex } +func (c Context) TxCount() int { return c.txCount } +func (c Context) BlockGasUsed() uint64 { return c.blockGasUsed } +func (c Context) IncarnationCache() map[string]any { return c.incarnationCache } +func (c Context) BlockGasWanted() uint64 { return c.blockGasWanted } // BlockHeader returns the header by value. func (c Context) BlockHeader() cmtproto.Header { @@ -139,6 +158,8 @@ func NewContext(ms storetypes.MultiStore, header cmtproto.Header, isCheckTx bool eventManager: NewEventManager(), kvGasConfig: storetypes.KVGasConfig(), transientKVGasConfig: storetypes.TransientGasConfig(), + txIndex: -1, + msgIndex: -1, } } @@ -318,6 +339,31 @@ func (c Context) WithHeaderInfo(headerInfo header.Info) Context { return c } +func (c Context) WithTxIndex(txIndex int) Context { + c.txIndex = txIndex + return c +} + +func (c Context) WithTxCount(txCount int) Context { + c.txCount = txCount + return c +} + +func (c Context) WithMsgIndex(msgIndex int) Context { + c.msgIndex = msgIndex + return c +} + +func (c Context) WithBlockGasUsed(gasUsed uint64) Context { + c.blockGasUsed = gasUsed + return c +} + +func (c Context) WithBlockGasWanted(gasWanted uint64) Context { + c.blockGasWanted = gasWanted + return c +} + // TODO: remove??? func (c Context) IsZero() bool { @@ -372,6 +418,27 @@ func (c Context) CacheContext() (cc Context, writeCache func()) { return cc, writeCache } +func (c Context) GetIncarnationCache(key string) (any, bool) { + if c.incarnationCache == nil { + return nil, false + } + val, ok := c.incarnationCache[key] + return val, ok +} + +func (c Context) SetIncarnationCache(key string, value any) { + if c.incarnationCache == nil { + // noop if cache is not initialized + return + } + c.incarnationCache[key] = value +} + +func (c Context) WithIncarnationCache(cache map[string]any) Context { + c.incarnationCache = cache + return c +} + var ( _ context.Context = Context{} _ storetypes.Context = Context{} diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index b65800a151aa..1c027d4f7e79 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -32,6 +32,8 @@ var ( key = make([]byte, secp256k1.PubKeySize) simSecp256k1Pubkey = &secp256k1.PubKey{Key: key} simSecp256k1Sig [64]byte + + SigVerificationResultCacheKey = "ante:SigVerificationResult" ) func init() { @@ -303,10 +305,10 @@ func OnlyLegacyAminoSigners(sigData signing.SignatureData) bool { } } -func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { +func (svd SigVerificationDecorator) anteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool) error { sigTx, ok := tx.(authsigning.Tx) if !ok { - return ctx, errorsmod.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") + return errorsmod.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") } utx, ok := tx.(sdk.TxWithUnordered) @@ -314,24 +316,24 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul unorderedEnabled := svd.ak.UnorderedTransactionsEnabled() if isUnordered && !unorderedEnabled { - return ctx, errorsmod.Wrap(sdkerrors.ErrNotSupported, "unordered transactions are not enabled") + return errorsmod.Wrap(sdkerrors.ErrNotSupported, "unordered transactions are not enabled") } // stdSigs contains the sequence number, account number, and signatures. // When simulating, this would just be a 0-length slice. sigs, err := sigTx.GetSignaturesV2() if err != nil { - return ctx, err + return err } signers, err := sigTx.GetSigners() if err != nil { - return ctx, err + return err } // check that signer length and signature length are the same if len(sigs) != len(signers) { - return ctx, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signers), len(sigs)) + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signers), len(sigs)) } // In normal transactions, each signer has a sequence value. In unordered transactions, the nonce value is at the tx body level, @@ -339,29 +341,29 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul // Because of this, we verify the unordered nonce outside the sigs loop, to avoid verifying the same nonce multiple times. if isUnordered { if err := svd.verifyUnorderedNonce(ctx, utx); err != nil { - return ctx, err + return err } } for i, sig := range sigs { if sig.Sequence > 0 && isUnordered { - return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "sequence is not allowed for unordered transactions") + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "sequence is not allowed for unordered transactions") } acc, err := GetSignerAcc(ctx, svd.ak, signers[i]) if err != nil { - return ctx, err + return err } // retrieve pubkey pubKey := acc.GetPubKey() if !simulate && pubKey == nil { - return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set") + return errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set") } // Check account sequence number. if !isUnordered { if sig.Sequence != acc.GetSequence() { - return ctx, errorsmod.Wrapf( + return errorsmod.Wrapf( sdkerrors.ErrWrongSequence, "account sequence mismatch, expected %d, got %d", acc.GetSequence(), sig.Sequence, ) @@ -392,7 +394,7 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul } adaptableTx, ok := tx.(authsigning.V2AdaptableTx) if !ok { - return ctx, fmt.Errorf("expected tx to implement V2AdaptableTx, got %T", tx) + return fmt.Errorf("expected tx to implement V2AdaptableTx, got %T", tx) } txData := adaptableTx.GetSigningTxData() err = authsigning.VerifySignature(ctx, pubKey, signerData, sig.Data, svd.signModeHandler, txData) @@ -405,12 +407,28 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul } else { errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d) and chain-id (%s): (%s)", accNum, chainID, err.Error()) } - return ctx, errorsmod.Wrap(sdkerrors.ErrUnauthorized, errMsg) + return errorsmod.Wrap(sdkerrors.ErrUnauthorized, errMsg) } } } + return nil +} + +func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + if v, ok := ctx.GetIncarnationCache(SigVerificationResultCacheKey); ok { + // can't convert `nil` to interface + if v != nil { + err = v.(error) + } + } else { + err = svd.anteHandle(ctx, tx, simulate) + ctx.SetIncarnationCache(SigVerificationResultCacheKey, err) + } + if err != nil { + return ctx, err + } return next(ctx, tx, simulate) } diff --git a/x/bank/keeper/collections_test.go b/x/bank/keeper/collections_test.go index 97b5e3e8bca0..6818fa0f6fca 100644 --- a/x/bank/keeper/collections_test.go +++ b/x/bank/keeper/collections_test.go @@ -26,7 +26,8 @@ import ( func TestBankStateCompatibility(t *testing.T) { key := storetypes.NewKVStoreKey(banktypes.StoreKey) - testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) + oKey := storetypes.NewObjectStoreKey(banktypes.ObjectStoreKey) + testCtx := testutil.DefaultContextWithObjectStore(t, key, storetypes.NewTransientStoreKey("transient_test"), oKey) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: cmttime.Now()}) encCfg := moduletestutil.MakeTestEncodingConfig() @@ -45,6 +46,7 @@ func TestBankStateCompatibility(t *testing.T) { authtypes.NewModuleAddress("gov").String(), log.NewNopLogger(), ) + k = k.WithObjStoreKey(oKey) // test we can decode balances without problems // using the old value format of the denom to address index diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index ec5520d12f4b..ed5b3492c982 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -8,6 +8,7 @@ import ( errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -24,6 +25,7 @@ var _ Keeper = (*BaseKeeper)(nil) type Keeper interface { SendKeeper WithMintCoinsRestriction(types.MintingRestrictionFn) BaseKeeper + WithObjStoreKey(storetypes.StoreKey) BaseKeeper InitGenesis(context.Context, *types.GenesisState) ExportGenesis(context.Context) *types.GenesisState @@ -46,6 +48,12 @@ type Keeper interface { MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error BurnCoins(ctx context.Context, moduleName string, amt sdk.Coins) error + SendCoinsFromAccountToModuleVirtual(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + SendCoinsFromModuleToAccountVirtual(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + CreditVirtualAccounts(ctx context.Context) error + SendCoinsFromVirtual(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsToVirtual(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error + DelegateCoins(ctx context.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error UndelegateCoins(ctx context.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error @@ -63,6 +71,11 @@ type BaseKeeper struct { logger log.Logger } +func (k BaseKeeper) WithObjStoreKey(okey storetypes.StoreKey) BaseKeeper { + k.objStoreKey = okey + return k +} + // GetPaginatedTotalSupply queries for the supply, ignoring 0 coins, with a given pagination func (k BaseKeeper) GetPaginatedTotalSupply(ctx context.Context, pagination *query.PageRequest) (sdk.Coins, *query.PageResponse, error) { coins, pageResp, err := query.CollectionPaginate(ctx, k.Supply, pagination, func(key string, value math.Int) (sdk.Coin, error) { diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index e6f8b65a2b68..224f1efc0b5e 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -132,7 +132,8 @@ func TestKeeperTestSuite(t *testing.T) { func (suite *KeeperTestSuite) SetupTest() { key := storetypes.NewKVStoreKey(banktypes.StoreKey) - testCtx := testutil.DefaultContextWithDB(suite.T(), key, storetypes.NewTransientStoreKey("transient_test")) + oKey := storetypes.NewObjectStoreKey(banktypes.ObjectStoreKey) + testCtx := testutil.DefaultContextWithObjectStore(suite.T(), key, storetypes.NewTransientStoreKey("transient_test"), oKey) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: cmttime.Now()}) encCfg := moduletestutil.MakeTestEncodingConfig() @@ -152,6 +153,7 @@ func (suite *KeeperTestSuite) SetupTest() { authtypes.NewModuleAddress(govtypes.ModuleName).String(), log.NewNopLogger(), ) + suite.bankKeeper = suite.bankKeeper.WithObjStoreKey(oKey) banktypes.RegisterInterfaces(encCfg.InterfaceRegistry) @@ -174,6 +176,16 @@ func (suite *KeeperTestSuite) mockMintCoins(moduleAcc *authtypes.ModuleAccount) suite.authKeeper.EXPECT().GetModuleAccount(suite.ctx, moduleAcc.Name).Return(moduleAcc) } +func (suite *KeeperTestSuite) mockSendCoinsFromAccountToModuleVirtual(acc *authtypes.BaseAccount, moduleAcc *authtypes.ModuleAccount) { + suite.authKeeper.EXPECT().GetModuleAccount(suite.ctx, moduleAcc.Name).Return(moduleAcc) + suite.authKeeper.EXPECT().GetAccount(suite.ctx, acc.GetAddress()).Return(acc) +} + +func (suite *KeeperTestSuite) mockSendCoinsFromModuleToAccountVirtual(moduleAcc *authtypes.ModuleAccount, accAddr sdk.AccAddress) { + suite.authKeeper.EXPECT().GetModuleAddress(moduleAcc.Name).Return(moduleAcc.GetAddress()) + suite.authKeeper.EXPECT().HasAccount(suite.ctx, accAddr).Return(true) +} + func (suite *KeeperTestSuite) mockSendCoinsFromModuleToAccount(moduleAcc *authtypes.ModuleAccount, accAddr sdk.AccAddress) { suite.authKeeper.EXPECT().GetModuleAddress(moduleAcc.Name).Return(moduleAcc.GetAddress()) suite.authKeeper.EXPECT().GetAccount(suite.ctx, moduleAcc.GetAddress()).Return(moduleAcc) @@ -634,6 +646,38 @@ func (suite *KeeperTestSuite) TestSendCoinsNewAccount() { require.Equal(acc1Balances, updatedAcc1Bal) } +func (suite *KeeperTestSuite) TestSendCoinsVirtual() { + ctx := suite.ctx + require := suite.Require() + keeper := suite.bankKeeper + sdkCtx := sdk.UnwrapSDKContext(ctx) + acc0 := authtypes.NewBaseAccountWithAddress(accAddrs[0]) + feeDenom1 := "fee1" + feeDenom2 := "fee2" + + balances := sdk.NewCoins(sdk.NewInt64Coin(feeDenom1, 100), sdk.NewInt64Coin(feeDenom2, 100)) + suite.mockFundAccount(accAddrs[0]) + require.NoError(banktestutil.FundAccount(ctx, suite.bankKeeper, accAddrs[0], balances)) + + sendAmt := sdk.NewCoins(sdk.NewInt64Coin(feeDenom1, 50), sdk.NewInt64Coin(feeDenom2, 50)) + suite.mockSendCoinsFromAccountToModuleVirtual(acc0, burnerAcc) + require.NoError( + keeper.SendCoinsFromAccountToModuleVirtual(sdkCtx, accAddrs[0], authtypes.Burner, sendAmt), + ) + + refundAmt := sdk.NewCoins(sdk.NewInt64Coin(feeDenom1, 25), sdk.NewInt64Coin(feeDenom2, 25)) + suite.mockSendCoinsFromModuleToAccountVirtual(burnerAcc, accAddrs[0]) + require.NoError( + keeper.SendCoinsFromModuleToAccountVirtual(sdkCtx, authtypes.Burner, accAddrs[0], refundAmt), + ) + + suite.authKeeper.EXPECT().HasAccount(suite.ctx, burnerAcc.GetAddress()).Return(true) + require.NoError(keeper.CreditVirtualAccounts(ctx)) + + require.Equal(math.NewInt(25), keeper.GetBalance(suite.ctx, burnerAcc.GetAddress(), feeDenom1).Amount) + require.Equal(math.NewInt(25), keeper.GetBalance(suite.ctx, burnerAcc.GetAddress(), feeDenom2).Amount) +} + func (suite *KeeperTestSuite) TestInputOutputNewAccount() { ctx := suite.ctx require := suite.Require() diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 96fa6f2a089b..38322c77322d 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -9,6 +9,7 @@ import ( errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/telemetry" @@ -60,6 +61,7 @@ type BaseSendKeeper struct { ak types.AccountKeeper storeService store.KVStoreService logger log.Logger + objStoreKey storetypes.StoreKey // list of addresses that are restricted from receiving transactions blockedAddrs map[string]bool @@ -240,6 +242,12 @@ func (k BaseSendKeeper) SendCoins(ctx context.Context, fromAddr, toAddr sdk.AccA return err } + k.ensureAccountCreated(ctx, toAddr) + k.emitSendCoinsEvents(ctx, fromAddr, toAddr, amt) + return nil +} + +func (k BaseSendKeeper) ensureAccountCreated(ctx context.Context, toAddr sdk.AccAddress) { // Create account if recipient does not exist. // // NOTE: This should ultimately be removed in favor a more flexible approach @@ -249,7 +257,10 @@ func (k BaseSendKeeper) SendCoins(ctx context.Context, fromAddr, toAddr sdk.AccA defer telemetry.IncrCounter(1, "new", "account") k.ak.SetAccount(ctx, k.ak.NewAccountWithAddress(ctx, toAddr)) } +} +// emitSendCoinsEvents emit send coins events. +func (k BaseSendKeeper) emitSendCoinsEvents(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) { // bech32 encoding is expensive! Only do it once for fromAddr fromAddrString := fromAddr.String() sdkCtx := sdk.UnwrapSDKContext(ctx) @@ -265,8 +276,6 @@ func (k BaseSendKeeper) SendCoins(ctx context.Context, fromAddr, toAddr sdk.AccA sdk.NewAttribute(types.AttributeKeySender, fromAddrString), ), }) - - return nil } // subUnlockedCoins removes the unlocked amt coins of the given account. diff --git a/x/bank/keeper/virtual.go b/x/bank/keeper/virtual.go new file mode 100644 index 000000000000..d56ce71ea6d0 --- /dev/null +++ b/x/bank/keeper/virtual.go @@ -0,0 +1,184 @@ +package keeper + +import ( + "bytes" + "context" + "encoding/binary" + "encoding/hex" + "fmt" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// SendCoinsFromAccountToModuleVirtual sends coins from account to a virtual module account. +func (k BaseSendKeeper) SendCoinsFromAccountToModuleVirtual( + ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins, +) error { + recipientAcc := k.ak.GetModuleAccount(ctx, recipientModule) + if recipientAcc == nil { + panic(errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", recipientModule)) + } + + return k.SendCoinsToVirtual(ctx, senderAddr, recipientAcc.GetAddress(), amt) +} + +// SendCoinsFromModuleToAccountVirtual sends coins from account to a virtual module account. +func (k BaseSendKeeper) SendCoinsFromModuleToAccountVirtual( + ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins, +) error { + senderAddr := k.ak.GetModuleAddress(senderModule) + if senderAddr == nil { + panic(errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", senderModule)) + } + + if k.BlockedAddr(recipientAddr) { + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", recipientAddr) + } + + return k.SendCoinsFromVirtual(ctx, senderAddr, recipientAddr, amt) +} + +// SendCoinsToVirtual accumulate the recipient's coins in a per-transaction transient state, +// which are sumed up and added to the real account at the end of block. +// Events are emiited the same as normal send. +func (k BaseSendKeeper) SendCoinsToVirtual(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error { + var err error + err = k.subUnlockedCoins(ctx, fromAddr, amt) + if err != nil { + return err + } + + toAddr, err = k.sendRestriction.apply(ctx, fromAddr, toAddr, amt) + if err != nil { + return err + } + + k.addVirtualCoins(ctx, toAddr, amt) + k.emitSendCoinsEvents(ctx, fromAddr, toAddr, amt) + return nil +} + +// SendCoinsFromVirtual deduct coins from virtual from account and send to recipient account. +func (k BaseSendKeeper) SendCoinsFromVirtual(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error { + var err error + err = k.subVirtualCoins(ctx, fromAddr, amt) + if err != nil { + return err + } + + toAddr, err = k.sendRestriction.apply(ctx, fromAddr, toAddr, amt) + if err != nil { + return err + } + + err = k.addCoins(ctx, toAddr, amt) + if err != nil { + return err + } + + k.ensureAccountCreated(ctx, toAddr) + k.emitSendCoinsEvents(ctx, fromAddr, toAddr, amt) + return nil +} + +func (k BaseSendKeeper) addVirtualCoins(ctx context.Context, addr sdk.AccAddress, amt sdk.Coins) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + store := sdkCtx.ObjectStore(k.objStoreKey) + + // bytes containing account address followed by the txn index + key := make([]byte, len(addr)+8) + copy(key, addr) + binary.BigEndian.PutUint64(key[len(addr):], uint64(sdkCtx.TxIndex())) + + var coins sdk.Coins + value := store.Get(key) + if value != nil { + coins = value.(sdk.Coins) + } + coins = coins.Add(amt...) + store.Set(key, coins) +} + +func (k BaseSendKeeper) subVirtualCoins(ctx context.Context, addr sdk.AccAddress, amt sdk.Coins) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + store := sdkCtx.ObjectStore(k.objStoreKey) + + key := make([]byte, len(addr)+8) + copy(key, addr) + binary.BigEndian.PutUint64(key[len(addr):], uint64(sdkCtx.TxIndex())) + + value := store.Get(key) + if value == nil { + return errorsmod.Wrapf( + sdkerrors.ErrInsufficientFunds, + "spendable balance 0 is smaller than %s", + amt, + ) + } + spendable := value.(sdk.Coins) + balance, hasNeg := spendable.SafeSub(amt...) + if hasNeg { + return errorsmod.Wrapf( + sdkerrors.ErrInsufficientFunds, + "spendable balance %s is smaller than %s", + spendable, amt, + ) + } + if balance.IsZero() { + store.Delete(key) + } else { + store.Set(key, balance) + } + + return nil +} + +// CreditVirtualAccounts sum up the transient coins and add them to the real account, +// should be called at end blocker. +func (k BaseSendKeeper) CreditVirtualAccounts(ctx context.Context) error { + // No-op if we're not using the objStore to accumulate to module accounts + if k.objStoreKey == nil { + return nil + } + store := sdk.UnwrapSDKContext(ctx).ObjectStore(k.objStoreKey) + + var toAddr sdk.AccAddress + sum := sdk.NewMapCoins(nil) + flushCurrentAddr := func() error { + if len(sum) == 0 { + // nothing to flush + return nil + } + + if err := k.addCoins(ctx, toAddr, sum.ToCoins()); err != nil { + return err + } + clear(sum) + + k.ensureAccountCreated(ctx, toAddr) + return nil + } + + it := store.Iterator(nil, nil) + defer it.Close() + for ; it.Valid(); it.Next() { + if len(it.Key()) <= 8 { + return fmt.Errorf("unexpected key length: %s", hex.EncodeToString(it.Key())) + } + + addr := it.Key()[:len(it.Key())-8] + if !bytes.Equal(toAddr, addr) { + if err := flushCurrentAddr(); err != nil { + return err + } + toAddr = addr + } + + sum.Add(it.Value().(sdk.Coins)...) + } + + return flushCurrentAddr() +} diff --git a/x/bank/module.go b/x/bank/module.go index e7140af204a9..b14032e1f6ac 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -44,7 +44,8 @@ var ( _ module.HasGenesis = AppModule{} _ module.HasServices = AppModule{} - _ appmodule.AppModule = AppModule{} + _ appmodule.AppModule = AppModule{} + _ appmodule.HasEndBlocker = AppModule{} ) // AppModuleBasic defines the basic application module used by the bank module. @@ -202,6 +203,10 @@ func (am AppModule) WeightedOperationsX(weights simsx.WeightSource, reg simsx.Re reg.Add(weights.Get("msg_multisend", 10), simulation.MsgMultiSendFactory()) } +func (am AppModule) EndBlock(ctx context.Context) error { + return am.keeper.CreditVirtualAccounts(ctx) +} + // App Wiring Setup func init() { diff --git a/x/bank/types/keys.go b/x/bank/types/keys.go index b4ea683d4b69..485d1cdb9ef0 100644 --- a/x/bank/types/keys.go +++ b/x/bank/types/keys.go @@ -17,6 +17,9 @@ const ( // RouterKey defines the module's message routing key RouterKey = ModuleName + + // ObjectStoreKey defines the store name for the object store + ObjectStoreKey = "object:" + ModuleName ) // KVStore keys diff --git a/x/gov/testutil/expected_keepers_mocks.go b/x/gov/testutil/expected_keepers_mocks.go index 64a678b21741..3c5b098bb417 100644 --- a/x/gov/testutil/expected_keepers_mocks.go +++ b/x/gov/testutil/expected_keepers_mocks.go @@ -15,11 +15,12 @@ import ( address "cosmossdk.io/core/address" math "cosmossdk.io/math" - types "github.com/cosmos/cosmos-sdk/types" + types "cosmossdk.io/store/types" + types0 "github.com/cosmos/cosmos-sdk/types" query "github.com/cosmos/cosmos-sdk/types/query" keeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - types0 "github.com/cosmos/cosmos-sdk/x/bank/types" - types1 "github.com/cosmos/cosmos-sdk/x/staking/types" + types1 "github.com/cosmos/cosmos-sdk/x/bank/types" + types2 "github.com/cosmos/cosmos-sdk/x/staking/types" gomock "go.uber.org/mock/gomock" ) @@ -62,10 +63,10 @@ func (mr *MockAccountKeeperMockRecorder) AddressCodec() *gomock.Call { } // GetAccount mocks base method. -func (m *MockAccountKeeper) GetAccount(ctx context.Context, addr types.AccAddress) types.AccountI { +func (m *MockAccountKeeper) GetAccount(ctx context.Context, addr types0.AccAddress) types0.AccountI { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAccount", ctx, addr) - ret0, _ := ret[0].(types.AccountI) + ret0, _ := ret[0].(types0.AccountI) return ret0 } @@ -76,10 +77,10 @@ func (mr *MockAccountKeeperMockRecorder) GetAccount(ctx, addr any) *gomock.Call } // GetModuleAccount mocks base method. -func (m *MockAccountKeeper) GetModuleAccount(ctx context.Context, name string) types.ModuleAccountI { +func (m *MockAccountKeeper) GetModuleAccount(ctx context.Context, name string) types0.ModuleAccountI { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetModuleAccount", ctx, name) - ret0, _ := ret[0].(types.ModuleAccountI) + ret0, _ := ret[0].(types0.ModuleAccountI) return ret0 } @@ -90,10 +91,10 @@ func (mr *MockAccountKeeperMockRecorder) GetModuleAccount(ctx, name any) *gomock } // GetModuleAddress mocks base method. -func (m *MockAccountKeeper) GetModuleAddress(name string) types.AccAddress { +func (m *MockAccountKeeper) GetModuleAddress(name string) types0.AccAddress { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetModuleAddress", name) - ret0, _ := ret[0].(types.AccAddress) + ret0, _ := ret[0].(types0.AccAddress) return ret0 } @@ -104,7 +105,7 @@ func (mr *MockAccountKeeperMockRecorder) GetModuleAddress(name any) *gomock.Call } // IterateAccounts mocks base method. -func (m *MockAccountKeeper) IterateAccounts(ctx context.Context, cb func(types.AccountI) bool) { +func (m *MockAccountKeeper) IterateAccounts(ctx context.Context, cb func(types0.AccountI) bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "IterateAccounts", ctx, cb) } @@ -116,7 +117,7 @@ func (mr *MockAccountKeeperMockRecorder) IterateAccounts(ctx, cb any) *gomock.Ca } // SetModuleAccount mocks base method. -func (m *MockAccountKeeper) SetModuleAccount(arg0 context.Context, arg1 types.ModuleAccountI) { +func (m *MockAccountKeeper) SetModuleAccount(arg0 context.Context, arg1 types0.ModuleAccountI) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetModuleAccount", arg0, arg1) } @@ -152,10 +153,10 @@ func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder { } // AllBalances mocks base method. -func (m *MockBankKeeper) AllBalances(arg0 context.Context, arg1 *types0.QueryAllBalancesRequest) (*types0.QueryAllBalancesResponse, error) { +func (m *MockBankKeeper) AllBalances(arg0 context.Context, arg1 *types1.QueryAllBalancesRequest) (*types1.QueryAllBalancesResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AllBalances", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryAllBalancesResponse) + ret0, _ := ret[0].(*types1.QueryAllBalancesResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -167,7 +168,7 @@ func (mr *MockBankKeeperMockRecorder) AllBalances(arg0, arg1 any) *gomock.Call { } // AppendSendRestriction mocks base method. -func (m *MockBankKeeper) AppendSendRestriction(restriction types0.SendRestrictionFn) { +func (m *MockBankKeeper) AppendSendRestriction(restriction types1.SendRestrictionFn) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendSendRestriction", restriction) } @@ -179,10 +180,10 @@ func (mr *MockBankKeeperMockRecorder) AppendSendRestriction(restriction any) *go } // Balance mocks base method. -func (m *MockBankKeeper) Balance(arg0 context.Context, arg1 *types0.QueryBalanceRequest) (*types0.QueryBalanceResponse, error) { +func (m *MockBankKeeper) Balance(arg0 context.Context, arg1 *types1.QueryBalanceRequest) (*types1.QueryBalanceResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Balance", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryBalanceResponse) + ret0, _ := ret[0].(*types1.QueryBalanceResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -194,7 +195,7 @@ func (mr *MockBankKeeperMockRecorder) Balance(arg0, arg1 any) *gomock.Call { } // BlockedAddr mocks base method. -func (m *MockBankKeeper) BlockedAddr(addr types.AccAddress) bool { +func (m *MockBankKeeper) BlockedAddr(addr types0.AccAddress) bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockedAddr", addr) ret0, _ := ret[0].(bool) @@ -208,7 +209,7 @@ func (mr *MockBankKeeperMockRecorder) BlockedAddr(addr any) *gomock.Call { } // BurnCoins mocks base method. -func (m *MockBankKeeper) BurnCoins(ctx context.Context, moduleName string, amt types.Coins) error { +func (m *MockBankKeeper) BurnCoins(ctx context.Context, moduleName string, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BurnCoins", ctx, moduleName, amt) ret0, _ := ret[0].(error) @@ -233,8 +234,22 @@ func (mr *MockBankKeeperMockRecorder) ClearSendRestriction() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClearSendRestriction", reflect.TypeOf((*MockBankKeeper)(nil).ClearSendRestriction)) } +// CreditVirtualAccounts mocks base method. +func (m *MockBankKeeper) CreditVirtualAccounts(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreditVirtualAccounts", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreditVirtualAccounts indicates an expected call of CreditVirtualAccounts. +func (mr *MockBankKeeperMockRecorder) CreditVirtualAccounts(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreditVirtualAccounts", reflect.TypeOf((*MockBankKeeper)(nil).CreditVirtualAccounts), ctx) +} + // DelegateCoins mocks base method. -func (m *MockBankKeeper) DelegateCoins(ctx context.Context, delegatorAddr, moduleAccAddr types.AccAddress, amt types.Coins) error { +func (m *MockBankKeeper) DelegateCoins(ctx context.Context, delegatorAddr, moduleAccAddr types0.AccAddress, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DelegateCoins", ctx, delegatorAddr, moduleAccAddr, amt) ret0, _ := ret[0].(error) @@ -248,7 +263,7 @@ func (mr *MockBankKeeperMockRecorder) DelegateCoins(ctx, delegatorAddr, moduleAc } // DelegateCoinsFromAccountToModule mocks base method. -func (m *MockBankKeeper) DelegateCoinsFromAccountToModule(ctx context.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins) error { +func (m *MockBankKeeper) DelegateCoinsFromAccountToModule(ctx context.Context, senderAddr types0.AccAddress, recipientModule string, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DelegateCoinsFromAccountToModule", ctx, senderAddr, recipientModule, amt) ret0, _ := ret[0].(error) @@ -279,10 +294,10 @@ func (mr *MockBankKeeperMockRecorder) DeleteSendEnabled(ctx any, denoms ...any) } // DenomMetadata mocks base method. -func (m *MockBankKeeper) DenomMetadata(arg0 context.Context, arg1 *types0.QueryDenomMetadataRequest) (*types0.QueryDenomMetadataResponse, error) { +func (m *MockBankKeeper) DenomMetadata(arg0 context.Context, arg1 *types1.QueryDenomMetadataRequest) (*types1.QueryDenomMetadataResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DenomMetadata", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryDenomMetadataResponse) + ret0, _ := ret[0].(*types1.QueryDenomMetadataResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -294,10 +309,10 @@ func (mr *MockBankKeeperMockRecorder) DenomMetadata(arg0, arg1 any) *gomock.Call } // DenomMetadataByQueryString mocks base method. -func (m *MockBankKeeper) DenomMetadataByQueryString(arg0 context.Context, arg1 *types0.QueryDenomMetadataByQueryStringRequest) (*types0.QueryDenomMetadataByQueryStringResponse, error) { +func (m *MockBankKeeper) DenomMetadataByQueryString(arg0 context.Context, arg1 *types1.QueryDenomMetadataByQueryStringRequest) (*types1.QueryDenomMetadataByQueryStringResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DenomMetadataByQueryString", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryDenomMetadataByQueryStringResponse) + ret0, _ := ret[0].(*types1.QueryDenomMetadataByQueryStringResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -309,10 +324,10 @@ func (mr *MockBankKeeperMockRecorder) DenomMetadataByQueryString(arg0, arg1 any) } // DenomOwners mocks base method. -func (m *MockBankKeeper) DenomOwners(arg0 context.Context, arg1 *types0.QueryDenomOwnersRequest) (*types0.QueryDenomOwnersResponse, error) { +func (m *MockBankKeeper) DenomOwners(arg0 context.Context, arg1 *types1.QueryDenomOwnersRequest) (*types1.QueryDenomOwnersResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DenomOwners", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryDenomOwnersResponse) + ret0, _ := ret[0].(*types1.QueryDenomOwnersResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -324,10 +339,10 @@ func (mr *MockBankKeeperMockRecorder) DenomOwners(arg0, arg1 any) *gomock.Call { } // DenomOwnersByQuery mocks base method. -func (m *MockBankKeeper) DenomOwnersByQuery(arg0 context.Context, arg1 *types0.QueryDenomOwnersByQueryRequest) (*types0.QueryDenomOwnersByQueryResponse, error) { +func (m *MockBankKeeper) DenomOwnersByQuery(arg0 context.Context, arg1 *types1.QueryDenomOwnersByQueryRequest) (*types1.QueryDenomOwnersByQueryResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DenomOwnersByQuery", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryDenomOwnersByQueryResponse) + ret0, _ := ret[0].(*types1.QueryDenomOwnersByQueryResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -339,10 +354,10 @@ func (mr *MockBankKeeperMockRecorder) DenomOwnersByQuery(arg0, arg1 any) *gomock } // DenomsMetadata mocks base method. -func (m *MockBankKeeper) DenomsMetadata(arg0 context.Context, arg1 *types0.QueryDenomsMetadataRequest) (*types0.QueryDenomsMetadataResponse, error) { +func (m *MockBankKeeper) DenomsMetadata(arg0 context.Context, arg1 *types1.QueryDenomsMetadataRequest) (*types1.QueryDenomsMetadataResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DenomsMetadata", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryDenomsMetadataResponse) + ret0, _ := ret[0].(*types1.QueryDenomsMetadataResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -354,10 +369,10 @@ func (mr *MockBankKeeperMockRecorder) DenomsMetadata(arg0, arg1 any) *gomock.Cal } // ExportGenesis mocks base method. -func (m *MockBankKeeper) ExportGenesis(arg0 context.Context) *types0.GenesisState { +func (m *MockBankKeeper) ExportGenesis(arg0 context.Context) *types1.GenesisState { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ExportGenesis", arg0) - ret0, _ := ret[0].(*types0.GenesisState) + ret0, _ := ret[0].(*types1.GenesisState) return ret0 } @@ -368,10 +383,10 @@ func (mr *MockBankKeeperMockRecorder) ExportGenesis(arg0 any) *gomock.Call { } // GetAccountsBalances mocks base method. -func (m *MockBankKeeper) GetAccountsBalances(ctx context.Context) []types0.Balance { +func (m *MockBankKeeper) GetAccountsBalances(ctx context.Context) []types1.Balance { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAccountsBalances", ctx) - ret0, _ := ret[0].([]types0.Balance) + ret0, _ := ret[0].([]types1.Balance) return ret0 } @@ -382,10 +397,10 @@ func (mr *MockBankKeeperMockRecorder) GetAccountsBalances(ctx any) *gomock.Call } // GetAllBalances mocks base method. -func (m *MockBankKeeper) GetAllBalances(ctx context.Context, addr types.AccAddress) types.Coins { +func (m *MockBankKeeper) GetAllBalances(ctx context.Context, addr types0.AccAddress) types0.Coins { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAllBalances", ctx, addr) - ret0, _ := ret[0].(types.Coins) + ret0, _ := ret[0].(types0.Coins) return ret0 } @@ -396,10 +411,10 @@ func (mr *MockBankKeeperMockRecorder) GetAllBalances(ctx, addr any) *gomock.Call } // GetAllDenomMetaData mocks base method. -func (m *MockBankKeeper) GetAllDenomMetaData(ctx context.Context) []types0.Metadata { +func (m *MockBankKeeper) GetAllDenomMetaData(ctx context.Context) []types1.Metadata { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAllDenomMetaData", ctx) - ret0, _ := ret[0].([]types0.Metadata) + ret0, _ := ret[0].([]types1.Metadata) return ret0 } @@ -410,10 +425,10 @@ func (mr *MockBankKeeperMockRecorder) GetAllDenomMetaData(ctx any) *gomock.Call } // GetAllSendEnabledEntries mocks base method. -func (m *MockBankKeeper) GetAllSendEnabledEntries(ctx context.Context) []types0.SendEnabled { +func (m *MockBankKeeper) GetAllSendEnabledEntries(ctx context.Context) []types1.SendEnabled { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAllSendEnabledEntries", ctx) - ret0, _ := ret[0].([]types0.SendEnabled) + ret0, _ := ret[0].([]types1.SendEnabled) return ret0 } @@ -438,10 +453,10 @@ func (mr *MockBankKeeperMockRecorder) GetAuthority() *gomock.Call { } // GetBalance mocks base method. -func (m *MockBankKeeper) GetBalance(ctx context.Context, addr types.AccAddress, denom string) types.Coin { +func (m *MockBankKeeper) GetBalance(ctx context.Context, addr types0.AccAddress, denom string) types0.Coin { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBalance", ctx, addr, denom) - ret0, _ := ret[0].(types.Coin) + ret0, _ := ret[0].(types0.Coin) return ret0 } @@ -466,10 +481,10 @@ func (mr *MockBankKeeperMockRecorder) GetBlockedAddresses() *gomock.Call { } // GetDenomMetaData mocks base method. -func (m *MockBankKeeper) GetDenomMetaData(ctx context.Context, denom string) (types0.Metadata, bool) { +func (m *MockBankKeeper) GetDenomMetaData(ctx context.Context, denom string) (types1.Metadata, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetDenomMetaData", ctx, denom) - ret0, _ := ret[0].(types0.Metadata) + ret0, _ := ret[0].(types1.Metadata) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -481,10 +496,10 @@ func (mr *MockBankKeeperMockRecorder) GetDenomMetaData(ctx, denom any) *gomock.C } // GetPaginatedTotalSupply mocks base method. -func (m *MockBankKeeper) GetPaginatedTotalSupply(ctx context.Context, pagination *query.PageRequest) (types.Coins, *query.PageResponse, error) { +func (m *MockBankKeeper) GetPaginatedTotalSupply(ctx context.Context, pagination *query.PageRequest) (types0.Coins, *query.PageResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPaginatedTotalSupply", ctx, pagination) - ret0, _ := ret[0].(types.Coins) + ret0, _ := ret[0].(types0.Coins) ret1, _ := ret[1].(*query.PageResponse) ret2, _ := ret[2].(error) return ret0, ret1, ret2 @@ -497,10 +512,10 @@ func (mr *MockBankKeeperMockRecorder) GetPaginatedTotalSupply(ctx, pagination an } // GetParams mocks base method. -func (m *MockBankKeeper) GetParams(ctx context.Context) types0.Params { +func (m *MockBankKeeper) GetParams(ctx context.Context) types1.Params { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetParams", ctx) - ret0, _ := ret[0].(types0.Params) + ret0, _ := ret[0].(types1.Params) return ret0 } @@ -511,10 +526,10 @@ func (mr *MockBankKeeperMockRecorder) GetParams(ctx any) *gomock.Call { } // GetSendEnabledEntry mocks base method. -func (m *MockBankKeeper) GetSendEnabledEntry(ctx context.Context, denom string) (types0.SendEnabled, bool) { +func (m *MockBankKeeper) GetSendEnabledEntry(ctx context.Context, denom string) (types1.SendEnabled, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSendEnabledEntry", ctx, denom) - ret0, _ := ret[0].(types0.SendEnabled) + ret0, _ := ret[0].(types1.SendEnabled) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -526,10 +541,10 @@ func (mr *MockBankKeeperMockRecorder) GetSendEnabledEntry(ctx, denom any) *gomoc } // GetSupply mocks base method. -func (m *MockBankKeeper) GetSupply(ctx context.Context, denom string) types.Coin { +func (m *MockBankKeeper) GetSupply(ctx context.Context, denom string) types0.Coin { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupply", ctx, denom) - ret0, _ := ret[0].(types.Coin) + ret0, _ := ret[0].(types0.Coin) return ret0 } @@ -540,7 +555,7 @@ func (mr *MockBankKeeperMockRecorder) GetSupply(ctx, denom any) *gomock.Call { } // HasBalance mocks base method. -func (m *MockBankKeeper) HasBalance(ctx context.Context, addr types.AccAddress, amt types.Coin) bool { +func (m *MockBankKeeper) HasBalance(ctx context.Context, addr types0.AccAddress, amt types0.Coin) bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HasBalance", ctx, addr, amt) ret0, _ := ret[0].(bool) @@ -582,7 +597,7 @@ func (mr *MockBankKeeperMockRecorder) HasSupply(ctx, denom any) *gomock.Call { } // InitGenesis mocks base method. -func (m *MockBankKeeper) InitGenesis(arg0 context.Context, arg1 *types0.GenesisState) { +func (m *MockBankKeeper) InitGenesis(arg0 context.Context, arg1 *types1.GenesisState) { m.ctrl.T.Helper() m.ctrl.Call(m, "InitGenesis", arg0, arg1) } @@ -594,7 +609,7 @@ func (mr *MockBankKeeperMockRecorder) InitGenesis(arg0, arg1 any) *gomock.Call { } // InputOutputCoins mocks base method. -func (m *MockBankKeeper) InputOutputCoins(ctx context.Context, input types0.Input, outputs []types0.Output) error { +func (m *MockBankKeeper) InputOutputCoins(ctx context.Context, input types1.Input, outputs []types1.Output) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InputOutputCoins", ctx, input, outputs) ret0, _ := ret[0].(error) @@ -608,7 +623,7 @@ func (mr *MockBankKeeperMockRecorder) InputOutputCoins(ctx, input, outputs any) } // IsSendEnabledCoin mocks base method. -func (m *MockBankKeeper) IsSendEnabledCoin(ctx context.Context, coin types.Coin) bool { +func (m *MockBankKeeper) IsSendEnabledCoin(ctx context.Context, coin types0.Coin) bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsSendEnabledCoin", ctx, coin) ret0, _ := ret[0].(bool) @@ -622,7 +637,7 @@ func (mr *MockBankKeeperMockRecorder) IsSendEnabledCoin(ctx, coin any) *gomock.C } // IsSendEnabledCoins mocks base method. -func (m *MockBankKeeper) IsSendEnabledCoins(ctx context.Context, coins ...types.Coin) error { +func (m *MockBankKeeper) IsSendEnabledCoins(ctx context.Context, coins ...types0.Coin) error { m.ctrl.T.Helper() varargs := []any{ctx} for _, a := range coins { @@ -655,7 +670,7 @@ func (mr *MockBankKeeperMockRecorder) IsSendEnabledDenom(ctx, denom any) *gomock } // IterateAccountBalances mocks base method. -func (m *MockBankKeeper) IterateAccountBalances(ctx context.Context, addr types.AccAddress, cb func(types.Coin) bool) { +func (m *MockBankKeeper) IterateAccountBalances(ctx context.Context, addr types0.AccAddress, cb func(types0.Coin) bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "IterateAccountBalances", ctx, addr, cb) } @@ -667,7 +682,7 @@ func (mr *MockBankKeeperMockRecorder) IterateAccountBalances(ctx, addr, cb any) } // IterateAllBalances mocks base method. -func (m *MockBankKeeper) IterateAllBalances(ctx context.Context, cb func(types.AccAddress, types.Coin) bool) { +func (m *MockBankKeeper) IterateAllBalances(ctx context.Context, cb func(types0.AccAddress, types0.Coin) bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "IterateAllBalances", ctx, cb) } @@ -679,7 +694,7 @@ func (mr *MockBankKeeperMockRecorder) IterateAllBalances(ctx, cb any) *gomock.Ca } // IterateAllDenomMetaData mocks base method. -func (m *MockBankKeeper) IterateAllDenomMetaData(ctx context.Context, cb func(types0.Metadata) bool) { +func (m *MockBankKeeper) IterateAllDenomMetaData(ctx context.Context, cb func(types1.Metadata) bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "IterateAllDenomMetaData", ctx, cb) } @@ -703,7 +718,7 @@ func (mr *MockBankKeeperMockRecorder) IterateSendEnabledEntries(ctx, cb any) *go } // IterateTotalSupply mocks base method. -func (m *MockBankKeeper) IterateTotalSupply(ctx context.Context, cb func(types.Coin) bool) { +func (m *MockBankKeeper) IterateTotalSupply(ctx context.Context, cb func(types0.Coin) bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "IterateTotalSupply", ctx, cb) } @@ -715,10 +730,10 @@ func (mr *MockBankKeeperMockRecorder) IterateTotalSupply(ctx, cb any) *gomock.Ca } // LockedCoins mocks base method. -func (m *MockBankKeeper) LockedCoins(ctx context.Context, addr types.AccAddress) types.Coins { +func (m *MockBankKeeper) LockedCoins(ctx context.Context, addr types0.AccAddress) types0.Coins { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LockedCoins", ctx, addr) - ret0, _ := ret[0].(types.Coins) + ret0, _ := ret[0].(types0.Coins) return ret0 } @@ -729,7 +744,7 @@ func (mr *MockBankKeeperMockRecorder) LockedCoins(ctx, addr any) *gomock.Call { } // MintCoins mocks base method. -func (m *MockBankKeeper) MintCoins(ctx context.Context, moduleName string, amt types.Coins) error { +func (m *MockBankKeeper) MintCoins(ctx context.Context, moduleName string, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MintCoins", ctx, moduleName, amt) ret0, _ := ret[0].(error) @@ -743,10 +758,10 @@ func (mr *MockBankKeeperMockRecorder) MintCoins(ctx, moduleName, amt any) *gomoc } // Params mocks base method. -func (m *MockBankKeeper) Params(arg0 context.Context, arg1 *types0.QueryParamsRequest) (*types0.QueryParamsResponse, error) { +func (m *MockBankKeeper) Params(arg0 context.Context, arg1 *types1.QueryParamsRequest) (*types1.QueryParamsResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Params", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryParamsResponse) + ret0, _ := ret[0].(*types1.QueryParamsResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -758,7 +773,7 @@ func (mr *MockBankKeeperMockRecorder) Params(arg0, arg1 any) *gomock.Call { } // PrependSendRestriction mocks base method. -func (m *MockBankKeeper) PrependSendRestriction(restriction types0.SendRestrictionFn) { +func (m *MockBankKeeper) PrependSendRestriction(restriction types1.SendRestrictionFn) { m.ctrl.T.Helper() m.ctrl.Call(m, "PrependSendRestriction", restriction) } @@ -770,7 +785,7 @@ func (mr *MockBankKeeperMockRecorder) PrependSendRestriction(restriction any) *g } // SendCoins mocks base method. -func (m *MockBankKeeper) SendCoins(ctx context.Context, fromAddr, toAddr types.AccAddress, amt types.Coins) error { +func (m *MockBankKeeper) SendCoins(ctx context.Context, fromAddr, toAddr types0.AccAddress, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendCoins", ctx, fromAddr, toAddr, amt) ret0, _ := ret[0].(error) @@ -784,7 +799,7 @@ func (mr *MockBankKeeperMockRecorder) SendCoins(ctx, fromAddr, toAddr, amt any) } // SendCoinsFromAccountToModule mocks base method. -func (m *MockBankKeeper) SendCoinsFromAccountToModule(ctx context.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins) error { +func (m *MockBankKeeper) SendCoinsFromAccountToModule(ctx context.Context, senderAddr types0.AccAddress, recipientModule string, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendCoinsFromAccountToModule", ctx, senderAddr, recipientModule, amt) ret0, _ := ret[0].(error) @@ -797,8 +812,22 @@ func (mr *MockBankKeeperMockRecorder) SendCoinsFromAccountToModule(ctx, senderAd return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromAccountToModule", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromAccountToModule), ctx, senderAddr, recipientModule, amt) } +// SendCoinsFromAccountToModuleVirtual mocks base method. +func (m *MockBankKeeper) SendCoinsFromAccountToModuleVirtual(ctx context.Context, senderAddr types0.AccAddress, recipientModule string, amt types0.Coins) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendCoinsFromAccountToModuleVirtual", ctx, senderAddr, recipientModule, amt) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendCoinsFromAccountToModuleVirtual indicates an expected call of SendCoinsFromAccountToModuleVirtual. +func (mr *MockBankKeeperMockRecorder) SendCoinsFromAccountToModuleVirtual(ctx, senderAddr, recipientModule, amt any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromAccountToModuleVirtual", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromAccountToModuleVirtual), ctx, senderAddr, recipientModule, amt) +} + // SendCoinsFromModuleToAccount mocks base method. -func (m *MockBankKeeper) SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins) error { +func (m *MockBankKeeper) SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr types0.AccAddress, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendCoinsFromModuleToAccount", ctx, senderModule, recipientAddr, amt) ret0, _ := ret[0].(error) @@ -811,8 +840,22 @@ func (mr *MockBankKeeperMockRecorder) SendCoinsFromModuleToAccount(ctx, senderMo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromModuleToAccount", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromModuleToAccount), ctx, senderModule, recipientAddr, amt) } +// SendCoinsFromModuleToAccountVirtual mocks base method. +func (m *MockBankKeeper) SendCoinsFromModuleToAccountVirtual(ctx context.Context, senderModule string, recipientAddr types0.AccAddress, amt types0.Coins) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendCoinsFromModuleToAccountVirtual", ctx, senderModule, recipientAddr, amt) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendCoinsFromModuleToAccountVirtual indicates an expected call of SendCoinsFromModuleToAccountVirtual. +func (mr *MockBankKeeperMockRecorder) SendCoinsFromModuleToAccountVirtual(ctx, senderModule, recipientAddr, amt any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromModuleToAccountVirtual", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromModuleToAccountVirtual), ctx, senderModule, recipientAddr, amt) +} + // SendCoinsFromModuleToModule mocks base method. -func (m *MockBankKeeper) SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt types.Coins) error { +func (m *MockBankKeeper) SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendCoinsFromModuleToModule", ctx, senderModule, recipientModule, amt) ret0, _ := ret[0].(error) @@ -825,11 +868,39 @@ func (mr *MockBankKeeperMockRecorder) SendCoinsFromModuleToModule(ctx, senderMod return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromModuleToModule", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromModuleToModule), ctx, senderModule, recipientModule, amt) } +// SendCoinsFromVirtual mocks base method. +func (m *MockBankKeeper) SendCoinsFromVirtual(ctx context.Context, fromAddr, toAddr types0.AccAddress, amt types0.Coins) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendCoinsFromVirtual", ctx, fromAddr, toAddr, amt) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendCoinsFromVirtual indicates an expected call of SendCoinsFromVirtual. +func (mr *MockBankKeeperMockRecorder) SendCoinsFromVirtual(ctx, fromAddr, toAddr, amt any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromVirtual", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromVirtual), ctx, fromAddr, toAddr, amt) +} + +// SendCoinsToVirtual mocks base method. +func (m *MockBankKeeper) SendCoinsToVirtual(ctx context.Context, fromAddr, toAddr types0.AccAddress, amt types0.Coins) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendCoinsToVirtual", ctx, fromAddr, toAddr, amt) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendCoinsToVirtual indicates an expected call of SendCoinsToVirtual. +func (mr *MockBankKeeperMockRecorder) SendCoinsToVirtual(ctx, fromAddr, toAddr, amt any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsToVirtual", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsToVirtual), ctx, fromAddr, toAddr, amt) +} + // SendEnabled mocks base method. -func (m *MockBankKeeper) SendEnabled(arg0 context.Context, arg1 *types0.QuerySendEnabledRequest) (*types0.QuerySendEnabledResponse, error) { +func (m *MockBankKeeper) SendEnabled(arg0 context.Context, arg1 *types1.QuerySendEnabledRequest) (*types1.QuerySendEnabledResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendEnabled", arg0, arg1) - ret0, _ := ret[0].(*types0.QuerySendEnabledResponse) + ret0, _ := ret[0].(*types1.QuerySendEnabledResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -841,7 +912,7 @@ func (mr *MockBankKeeperMockRecorder) SendEnabled(arg0, arg1 any) *gomock.Call { } // SetAllSendEnabled mocks base method. -func (m *MockBankKeeper) SetAllSendEnabled(ctx context.Context, sendEnableds []*types0.SendEnabled) { +func (m *MockBankKeeper) SetAllSendEnabled(ctx context.Context, sendEnableds []*types1.SendEnabled) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetAllSendEnabled", ctx, sendEnableds) } @@ -853,7 +924,7 @@ func (mr *MockBankKeeperMockRecorder) SetAllSendEnabled(ctx, sendEnableds any) * } // SetDenomMetaData mocks base method. -func (m *MockBankKeeper) SetDenomMetaData(ctx context.Context, denomMetaData types0.Metadata) { +func (m *MockBankKeeper) SetDenomMetaData(ctx context.Context, denomMetaData types1.Metadata) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetDenomMetaData", ctx, denomMetaData) } @@ -865,7 +936,7 @@ func (mr *MockBankKeeperMockRecorder) SetDenomMetaData(ctx, denomMetaData any) * } // SetParams mocks base method. -func (m *MockBankKeeper) SetParams(ctx context.Context, params types0.Params) error { +func (m *MockBankKeeper) SetParams(ctx context.Context, params types1.Params) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetParams", ctx, params) ret0, _ := ret[0].(error) @@ -891,10 +962,10 @@ func (mr *MockBankKeeperMockRecorder) SetSendEnabled(ctx, denom, value any) *gom } // SpendableBalanceByDenom mocks base method. -func (m *MockBankKeeper) SpendableBalanceByDenom(arg0 context.Context, arg1 *types0.QuerySpendableBalanceByDenomRequest) (*types0.QuerySpendableBalanceByDenomResponse, error) { +func (m *MockBankKeeper) SpendableBalanceByDenom(arg0 context.Context, arg1 *types1.QuerySpendableBalanceByDenomRequest) (*types1.QuerySpendableBalanceByDenomResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SpendableBalanceByDenom", arg0, arg1) - ret0, _ := ret[0].(*types0.QuerySpendableBalanceByDenomResponse) + ret0, _ := ret[0].(*types1.QuerySpendableBalanceByDenomResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -906,10 +977,10 @@ func (mr *MockBankKeeperMockRecorder) SpendableBalanceByDenom(arg0, arg1 any) *g } // SpendableBalances mocks base method. -func (m *MockBankKeeper) SpendableBalances(arg0 context.Context, arg1 *types0.QuerySpendableBalancesRequest) (*types0.QuerySpendableBalancesResponse, error) { +func (m *MockBankKeeper) SpendableBalances(arg0 context.Context, arg1 *types1.QuerySpendableBalancesRequest) (*types1.QuerySpendableBalancesResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SpendableBalances", arg0, arg1) - ret0, _ := ret[0].(*types0.QuerySpendableBalancesResponse) + ret0, _ := ret[0].(*types1.QuerySpendableBalancesResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -921,10 +992,10 @@ func (mr *MockBankKeeperMockRecorder) SpendableBalances(arg0, arg1 any) *gomock. } // SpendableCoin mocks base method. -func (m *MockBankKeeper) SpendableCoin(ctx context.Context, addr types.AccAddress, denom string) types.Coin { +func (m *MockBankKeeper) SpendableCoin(ctx context.Context, addr types0.AccAddress, denom string) types0.Coin { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SpendableCoin", ctx, addr, denom) - ret0, _ := ret[0].(types.Coin) + ret0, _ := ret[0].(types0.Coin) return ret0 } @@ -935,10 +1006,10 @@ func (mr *MockBankKeeperMockRecorder) SpendableCoin(ctx, addr, denom any) *gomoc } // SpendableCoins mocks base method. -func (m *MockBankKeeper) SpendableCoins(ctx context.Context, addr types.AccAddress) types.Coins { +func (m *MockBankKeeper) SpendableCoins(ctx context.Context, addr types0.AccAddress) types0.Coins { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SpendableCoins", ctx, addr) - ret0, _ := ret[0].(types.Coins) + ret0, _ := ret[0].(types0.Coins) return ret0 } @@ -949,10 +1020,10 @@ func (mr *MockBankKeeperMockRecorder) SpendableCoins(ctx, addr any) *gomock.Call } // SupplyOf mocks base method. -func (m *MockBankKeeper) SupplyOf(arg0 context.Context, arg1 *types0.QuerySupplyOfRequest) (*types0.QuerySupplyOfResponse, error) { +func (m *MockBankKeeper) SupplyOf(arg0 context.Context, arg1 *types1.QuerySupplyOfRequest) (*types1.QuerySupplyOfResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SupplyOf", arg0, arg1) - ret0, _ := ret[0].(*types0.QuerySupplyOfResponse) + ret0, _ := ret[0].(*types1.QuerySupplyOfResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -964,10 +1035,10 @@ func (mr *MockBankKeeperMockRecorder) SupplyOf(arg0, arg1 any) *gomock.Call { } // TotalSupply mocks base method. -func (m *MockBankKeeper) TotalSupply(arg0 context.Context, arg1 *types0.QueryTotalSupplyRequest) (*types0.QueryTotalSupplyResponse, error) { +func (m *MockBankKeeper) TotalSupply(arg0 context.Context, arg1 *types1.QueryTotalSupplyRequest) (*types1.QueryTotalSupplyResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "TotalSupply", arg0, arg1) - ret0, _ := ret[0].(*types0.QueryTotalSupplyResponse) + ret0, _ := ret[0].(*types1.QueryTotalSupplyResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -979,7 +1050,7 @@ func (mr *MockBankKeeperMockRecorder) TotalSupply(arg0, arg1 any) *gomock.Call { } // UndelegateCoins mocks base method. -func (m *MockBankKeeper) UndelegateCoins(ctx context.Context, moduleAccAddr, delegatorAddr types.AccAddress, amt types.Coins) error { +func (m *MockBankKeeper) UndelegateCoins(ctx context.Context, moduleAccAddr, delegatorAddr types0.AccAddress, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UndelegateCoins", ctx, moduleAccAddr, delegatorAddr, amt) ret0, _ := ret[0].(error) @@ -993,7 +1064,7 @@ func (mr *MockBankKeeperMockRecorder) UndelegateCoins(ctx, moduleAccAddr, delega } // UndelegateCoinsFromModuleToAccount mocks base method. -func (m *MockBankKeeper) UndelegateCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins) error { +func (m *MockBankKeeper) UndelegateCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr types0.AccAddress, amt types0.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UndelegateCoinsFromModuleToAccount", ctx, senderModule, recipientAddr, amt) ret0, _ := ret[0].(error) @@ -1007,7 +1078,7 @@ func (mr *MockBankKeeperMockRecorder) UndelegateCoinsFromModuleToAccount(ctx, se } // ValidateBalance mocks base method. -func (m *MockBankKeeper) ValidateBalance(ctx context.Context, addr types.AccAddress) error { +func (m *MockBankKeeper) ValidateBalance(ctx context.Context, addr types0.AccAddress) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ValidateBalance", ctx, addr) ret0, _ := ret[0].(error) @@ -1021,7 +1092,7 @@ func (mr *MockBankKeeperMockRecorder) ValidateBalance(ctx, addr any) *gomock.Cal } // WithMintCoinsRestriction mocks base method. -func (m *MockBankKeeper) WithMintCoinsRestriction(arg0 types0.MintingRestrictionFn) keeper.BaseKeeper { +func (m *MockBankKeeper) WithMintCoinsRestriction(arg0 types1.MintingRestrictionFn) keeper.BaseKeeper { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WithMintCoinsRestriction", arg0) ret0, _ := ret[0].(keeper.BaseKeeper) @@ -1034,6 +1105,20 @@ func (mr *MockBankKeeperMockRecorder) WithMintCoinsRestriction(arg0 any) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithMintCoinsRestriction", reflect.TypeOf((*MockBankKeeper)(nil).WithMintCoinsRestriction), arg0) } +// WithObjStoreKey mocks base method. +func (m *MockBankKeeper) WithObjStoreKey(arg0 types.StoreKey) keeper.BaseKeeper { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WithObjStoreKey", arg0) + ret0, _ := ret[0].(keeper.BaseKeeper) + return ret0 +} + +// WithObjStoreKey indicates an expected call of WithObjStoreKey. +func (mr *MockBankKeeperMockRecorder) WithObjStoreKey(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithObjStoreKey", reflect.TypeOf((*MockBankKeeper)(nil).WithObjStoreKey), arg0) +} + // MockStakingKeeper is a mock of StakingKeeper interface. type MockStakingKeeper struct { ctrl *gomock.Controller @@ -1074,7 +1159,7 @@ func (mr *MockStakingKeeperMockRecorder) BondDenom(ctx any) *gomock.Call { } // IterateBondedValidatorsByPower mocks base method. -func (m *MockStakingKeeper) IterateBondedValidatorsByPower(arg0 context.Context, arg1 func(int64, types1.ValidatorI) bool) error { +func (m *MockStakingKeeper) IterateBondedValidatorsByPower(arg0 context.Context, arg1 func(int64, types2.ValidatorI) bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IterateBondedValidatorsByPower", arg0, arg1) ret0, _ := ret[0].(error) @@ -1088,7 +1173,7 @@ func (mr *MockStakingKeeperMockRecorder) IterateBondedValidatorsByPower(arg0, ar } // IterateDelegations mocks base method. -func (m *MockStakingKeeper) IterateDelegations(ctx context.Context, delegator types.AccAddress, fn func(int64, types1.DelegationI) bool) error { +func (m *MockStakingKeeper) IterateDelegations(ctx context.Context, delegator types0.AccAddress, fn func(int64, types2.DelegationI) bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IterateDelegations", ctx, delegator, fn) ret0, _ := ret[0].(error) @@ -1169,7 +1254,7 @@ func (m *MockDistributionKeeper) EXPECT() *MockDistributionKeeperMockRecorder { } // FundCommunityPool mocks base method. -func (m *MockDistributionKeeper) FundCommunityPool(ctx context.Context, amount types.Coins, sender types.AccAddress) error { +func (m *MockDistributionKeeper) FundCommunityPool(ctx context.Context, amount types0.Coins, sender types0.AccAddress) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FundCommunityPool", ctx, amount, sender) ret0, _ := ret[0].(error) diff --git a/x/protocolpool/README.md b/x/protocolpool/README.md index d88b1ee1289a..6a695375a011 100644 --- a/x/protocolpool/README.md +++ b/x/protocolpool/README.md @@ -54,7 +54,7 @@ CommunityPoolSpend can be called by the module authority (default governance mod ### CreateContinuousFund CreateContinuousFund is a message used to initiate a continuous fund for a specific recipient. The proposed percentage of funds will be distributed only on withdraw request for the recipient. The fund distribution continues until expiry time is reached or continuous fund request is canceled. -NOTE: This feature is designed to work with the SDK's default bond denom. +NOTE: This feature is designed to work with the SDK's default bond denom. ```protobuf // CreateContinuousFund defines a method to distribute a percentage of funds to an address continuously. @@ -91,7 +91,7 @@ https://github.com/cosmos/cosmos-sdk/blob/release/v0.53.x/proto/cosmos/protocolp ```go func (k Keeper) FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error { - return k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, amount) + return k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, amount) } ``` @@ -110,7 +110,7 @@ The message will fail under the following conditions: ```go func (k Keeper) DistributeFromCommunityPool(ctx context.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error { - return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, receiveAddr, amount) + return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, receiveAddr, amount) } ``` @@ -138,7 +138,7 @@ https://github.com/cosmos/cosmos-sdk/blob/release/v0.53.x/x/protocolpool/keeper/ ### MsgCancelContinuousFund -This message is used to cancel an existing continuous fund proposal for a specific recipient. Once canceled, the continuous fund will no longer distribute funds at each begin block, and the state object will be removed. +This message is used to cancel an existing continuous fund proposal for a specific recipient. Once canceled, the continuous fund will no longer distribute funds at each begin block, and the state object will be removed. ```protobuf reference https://github.com/cosmos/cosmos-sdk/blob/release/v0.53.x/x/protocolpool/proto/cosmos/protocolpool/v1/tx.proto#L136-L161