diff --git a/app/ante/ante.go b/app/ante/ante.go index 364733ba..0e3a1ac0 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -75,7 +75,6 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { anteDecorators := []sdk.AnteDecorator{ ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), - moveante.NewSimulationFlagDecorator(), moveante.NewGasPricesDecorator(), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), diff --git a/app/app.go b/app/app.go index 51c1a14a..cdd9a375 100644 --- a/app/app.go +++ b/app/app.go @@ -849,7 +849,7 @@ func NewInitiaApp( capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, nil), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, *app.FeeGrantKeeper, app.interfaceRegistry), - gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), + gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.MoveKeeper.GetPostHandler()), reward.NewAppModule(appCodec, *app.RewardKeeper), slashing.NewAppModule(appCodec, *app.SlashingKeeper), distr.NewAppModule(appCodec, *app.DistrKeeper), diff --git a/x/gov/abci.go b/x/gov/abci.go index ca6e0cf7..2ecb2fa9 100644 --- a/x/gov/abci.go +++ b/x/gov/abci.go @@ -18,7 +18,7 @@ import ( ) // EndBlocker called every block, process inflation, update validator set. -func EndBlocker(ctx sdk.Context, k *keeper.Keeper) error { +func EndBlocker(ctx sdk.Context, k *keeper.Keeper, postHandler sdk.PostHandler) error { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker) logger := k.Logger(ctx) @@ -139,7 +139,7 @@ func EndBlocker(ctx sdk.Context, k *keeper.Keeper) error { return false, err } - err = handleTallyResult(ctx, k, proposal, passed, burnDeposits, tallyResults) + err = handleTallyResult(ctx, k, proposal, passed, burnDeposits, tallyResults, postHandler) if err != nil { return false, err } @@ -177,8 +177,8 @@ func EndBlocker(ctx sdk.Context, k *keeper.Keeper) error { } return false, err } - cacheCtx, writeCache := ctx.CacheContext() + cacheCtx, writeCache := ctx.CacheContext() quorumReached, passed, burnDeposits, tallyResults, err := k.Tally(cacheCtx, proposal) if err != nil { return false, err @@ -199,7 +199,7 @@ func EndBlocker(ctx sdk.Context, k *keeper.Keeper) error { // quorum reached; commit the state changes from k.Tally() writeCache() - err = handleTallyResult(ctx, k, proposal, passed, burnDeposits, tallyResults) + err = handleTallyResult(ctx, k, proposal, passed, burnDeposits, tallyResults, postHandler) if err != nil { return false, err } @@ -216,6 +216,7 @@ func handleTallyResult( proposal customtypes.Proposal, passed, burnDeposits bool, tallyResults v1.TallyResult, + postHandler sdk.PostHandler, ) (err error) { // If an expedited proposal fails, we do not want to update // the deposit at this point since the proposal is converted to regular. @@ -283,6 +284,16 @@ func handleTallyResult( events = append(events, res.GetEvents()...) } + // run post handler (for move cache invalidate) + if postHandler != nil { + newCtx, err := postHandler(ctx, nil, false, err == nil) + if err != nil { + return err + } + + ctx = newCtx + } + // `err == nil` when all handlers passed. // Or else, `idx` and `err` are populated with the msg index and error. if err == nil { diff --git a/x/gov/abci_test.go b/x/gov/abci_test.go index 6c44e73b..37676815 100644 --- a/x/gov/abci_test.go +++ b/x/gov/abci_test.go @@ -42,6 +42,7 @@ func TestSimpleProposalPassedEndblocker(t *testing.T) { ctx = ctx.WithBlockHeader(newHeader) proposal, err = app.GovKeeper.Proposals.Get(ctx, 1) + require.NoError(t, err) require.True(t, proposal.SubmitTime.Equal(initTime)) require.True(t, proposal.DepositEndTime.Equal(initTime.Add(depositPeriod))) require.Equal(t, proposal.Status, v1.StatusVotingPeriod) @@ -50,8 +51,10 @@ func TestSimpleProposalPassedEndblocker(t *testing.T) { voteMsg := createVoteMsg(t, addrs[0], proposal.Id, v1.OptionYes) _, err = govMsgSvr.Vote(ctx, voteMsg) + require.NoError(t, err) voteMsg = createVoteMsg(t, addrs[1], proposal.Id, v1.OptionYes) _, err = govMsgSvr.Vote(ctx, voteMsg) + require.NoError(t, err) voteMsg = createVoteMsg(t, addrs[2], proposal.Id, v1.OptionYes) _, err = govMsgSvr.Vote(ctx, voteMsg) require.NoError(t, err) @@ -60,7 +63,7 @@ func TestSimpleProposalPassedEndblocker(t *testing.T) { newHeader.Time = ctx.BlockHeader().Time.Add(votingPeriod) ctx = ctx.WithBlockHeader(newHeader) - err = gov.EndBlocker(ctx, app.GovKeeper) + err = gov.EndBlocker(ctx, app.GovKeeper, app.MoveKeeper.GetPostHandler()) require.NoError(t, err) proposal, err = app.GovKeeper.Proposals.Get(ctx, 1) @@ -83,6 +86,7 @@ func TestEmergencyProposalPassedEndblocker(t *testing.T) { ctx = ctx.WithBlockHeader(newHeader) proposal, err := app.GovKeeper.Proposals.Get(ctx, 1) + require.NoError(t, err) require.True(t, proposal.Emergency) require.True(t, proposal.EmergencyStartTime.Equal(ctx.BlockTime().Add(-time.Minute))) require.True(t, proposal.EmergencyNextTallyTime.Equal(ctx.BlockTime().Add(emergencyTallyInterval-time.Minute))) @@ -112,7 +116,7 @@ func TestEmergencyProposalPassedEndblocker(t *testing.T) { newHeader.Time = ctx.BlockHeader().Time.Add(time.Minute) ctx = ctx.WithBlockHeader(newHeader) - err = gov.EndBlocker(ctx, app.GovKeeper) + err = gov.EndBlocker(ctx, app.GovKeeper, app.MoveKeeper.GetPostHandler()) require.NoError(t, err) proposal, err = app.GovKeeper.Proposals.Get(ctx, 1) require.NoError(t, err) @@ -124,18 +128,13 @@ func TestEmergencyProposalPassedEndblocker(t *testing.T) { require.True(t, ctx.BlockHeader().Time.Equal(*proposal.EmergencyNextTallyTime)) - err = gov.EndBlocker(ctx, app.GovKeeper) + err = gov.EndBlocker(ctx, app.GovKeeper, app.MoveKeeper.GetPostHandler()) require.NoError(t, err) proposal, err = app.GovKeeper.Proposals.Get(ctx, 1) require.NoError(t, err) require.Equal(t, proposal.Status, v1.StatusPassed) } -type tickTestResult struct { - status v1.ProposalStatus - emergency bool -} - func TestTickSingleProposal(t *testing.T) { testCases := []struct { name string @@ -250,7 +249,7 @@ func TestTickSingleProposal(t *testing.T) { voteCheck = true } - err = gov.EndBlocker(ctx, app.GovKeeper) + err = gov.EndBlocker(ctx, app.GovKeeper, app.MoveKeeper.GetPostHandler()) require.NoError(t, err) } proposal, err := app.GovKeeper.Proposals.Get(ctx, 1) diff --git a/x/gov/common_test.go b/x/gov/common_test.go index eaec48a4..0f43b793 100644 --- a/x/gov/common_test.go +++ b/x/gov/common_test.go @@ -6,7 +6,6 @@ import ( "time" initiaapp "github.com/initia-labs/initia/app" - stakingtypes "github.com/initia-labs/initia/x/mstaking/types" "github.com/stretchr/testify/require" "cosmossdk.io/math" @@ -42,14 +41,6 @@ var ( sdk.AccAddress(pubKeys[4].Address()), } - valAddrs = []sdk.ValAddress{ - sdk.ValAddress(pubKeys[0].Address()), - sdk.ValAddress(pubKeys[1].Address()), - sdk.ValAddress(pubKeys[2].Address()), - sdk.ValAddress(pubKeys[3].Address()), - sdk.ValAddress(pubKeys[4].Address()), - } - validators = []*cmtypes.Validator{ cmtypes.NewValidator(pubKeys[0], 1000000), cmtypes.NewValidator(pubKeys[1], 1000000), @@ -58,8 +49,6 @@ var ( cmtypes.NewValidator(pubKeys[4], 1000000), } - commissionRates = stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()) - genCoins = sdk.NewCoins(sdk.NewCoin(bondDenom, math.NewInt(10000000))).Sort() minDepositRatio = "0.01" @@ -106,6 +95,7 @@ func createAppWithSimpleValidators(t *testing.T) *initiaapp.InitiaApp { params.VotingPeriod = votingPeriod params.EmergencyTallyInterval = emergencyTallyInterval err = app.GovKeeper.Params.Set(ctx, params) + require.NoError(t, err) _, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: app.LastBlockHeight() + 1}) require.NoError(t, err) return app diff --git a/x/gov/module.go b/x/gov/module.go index fbaea496..37124bfb 100644 --- a/x/gov/module.go +++ b/x/gov/module.go @@ -131,15 +131,24 @@ type AppModule struct { keeper *keeper.Keeper accountKeeper types.AccountKeeper bankKeeper types.BankKeeper + + postHandler sdk.PostHandler } // NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, keeper *keeper.Keeper, ak types.AccountKeeper, bk types.BankKeeper) AppModule { +func NewAppModule( + cdc codec.Codec, + keeper *keeper.Keeper, + ak types.AccountKeeper, + bk types.BankKeeper, + postHandler sdk.PostHandler, +) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, accountKeeper: ak, bankKeeper: bk, + postHandler: postHandler, } } @@ -169,6 +178,7 @@ type ModuleInputs struct { BankKeeper types.BankKeeper StakingKeeper customtypes.StakingKeeper DistributionKeeper types.DistributionKeeper + PostHandler sdk.PostHandler } type ModuleOutputs struct { @@ -202,7 +212,8 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { defaultConfig, authority.String(), ) - m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper) + + m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.PostHandler) hr := v1beta1.HandlerRoute{Handler: v1beta1.ProposalHandler, RouteKey: types.RouterKey} return ModuleOutputs{Module: m, Keeper: k, HandlerRoute: hr} @@ -299,5 +310,5 @@ func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion } // updates. func (am AppModule) EndBlock(ctx context.Context) error { c := sdk.UnwrapSDKContext(ctx) - return EndBlocker(c, am.keeper) + return EndBlocker(c, am.keeper, am.postHandler) } diff --git a/x/move/ante/context_keys.go b/x/move/ante/context_keys.go index a368f7fc..25c7b80d 100644 --- a/x/move/ante/context_keys.go +++ b/x/move/ante/context_keys.go @@ -1,6 +1,8 @@ package ante +// private type creates an interface key for Context that cannot be accessed by any other package +type contextKey int + const ( - SimulationFlagContextKey = iota - GasPricesContextKey + GasPricesContextKey contextKey = iota ) diff --git a/x/move/ante/simulation_flag.go b/x/move/ante/simulation_flag.go deleted file mode 100644 index 4ad52c9c..00000000 --- a/x/move/ante/simulation_flag.go +++ /dev/null @@ -1,24 +0,0 @@ -package ante - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// SimulationFlagDecorator ante decorator to set simulation flag to a context -type SimulationFlagDecorator struct{} - -// NewSimulationFlagDecorator constructor of the SimulationFlagDecorator -func NewSimulationFlagDecorator() *SimulationFlagDecorator { - return &SimulationFlagDecorator{} -} - -// AnteHandle that set simulation flag to a context to let the move keeper know tx mode. -func (d SimulationFlagDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - ctx = ctx.WithValue(SimulationFlagContextKey, simulate) - - if next != nil { - return next(ctx, tx, simulate) - } - - return ctx, nil -} diff --git a/x/move/ante/simulation_flag_test.go b/x/move/ante/simulation_flag_test.go deleted file mode 100644 index 6c5cdb48..00000000 --- a/x/move/ante/simulation_flag_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package ante_test - -import ( - "context" - "testing" - - "github.com/initia-labs/initia/x/move/ante" - - "github.com/stretchr/testify/require" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func TestSimulationFlagDecorator(t *testing.T) { - specs := map[string]struct { - simulation bool - expErr interface{} - }{ - "simulation mode": { - simulation: true, - }, - "non simulation mode": { - simulation: false, - }, - } - for name, spec := range specs { - t.Run(name, func(t *testing.T) { - ctx := sdk.Context{}.WithContext(context.Background()) - decorator := ante.NewSimulationFlagDecorator() - ctx, err := decorator.AnteHandle(ctx, nil, spec.simulation, nil) - require.NoError(t, err) - require.Equal(t, spec.simulation, ctx.Value(ante.SimulationFlagContextKey).(bool)) - }) - } -} diff --git a/x/move/keeper/handler.go b/x/move/keeper/handler.go index 6996173c..8601170c 100644 --- a/x/move/keeper/handler.go +++ b/x/move/keeper/handler.go @@ -17,20 +17,15 @@ import ( vmtypes "github.com/initia-labs/initiavm/types" ) -func isSimulationOrCheckTx( +func isSimulation( ctx context.Context, ) bool { sdkCtx := sdk.UnwrapSDKContext(ctx) - if sdkCtx.IsCheckTx() || sdkCtx.IsReCheckTx() { - return true - } - - simulate := sdkCtx.Value(ante.SimulationFlagContextKey) - if simulate == nil { - return false - } - return simulate.(bool) + // only executed when ExecMode is + // * simulate + // * finalize + return sdkCtx.ExecMode() == sdk.ExecModeSimulate } // extract module address and module name from the compiled module bytes @@ -157,8 +152,8 @@ func (k Keeper) ExecuteEntryFunctionWithMultiSenders( gasMeter := sdkCtx.GasMeter() gasForRuntime := gasMeter.Limit() - gasMeter.GasConsumedToLimit() - isSimulationOrCheckTx := isSimulationOrCheckTx(ctx) - if isSimulationOrCheckTx { + isSimulation := isSimulation(ctx) + if isSimulation { vm = k.buildSimulationVM() defer vm.Destroy() @@ -182,7 +177,7 @@ func (k Keeper) ExecuteEntryFunctionWithMultiSenders( ) // Mark loader cache loads new published modules. - if !isSimulationOrCheckTx { + if !isSimulation { k.postHandler.SetNewPublishedModulesLoaded(execRes.NewPublishedModulesLoaded) } @@ -257,8 +252,8 @@ func (k Keeper) ExecuteScriptWithMultiSenders( gasMeter := sdkCtx.GasMeter() gasForRuntime := gasMeter.Limit() - gasMeter.GasConsumedToLimit() - isSimulationOrCheckTx := isSimulationOrCheckTx(ctx) - if isSimulationOrCheckTx { + isSimulation := isSimulation(ctx) + if isSimulation { vm = k.buildSimulationVM() defer vm.Destroy() @@ -282,7 +277,7 @@ func (k Keeper) ExecuteScriptWithMultiSenders( ) // Mark loader cache loads new published modules. - if !isSimulationOrCheckTx { + if !isSimulation { k.postHandler.SetNewPublishedModulesLoaded(execRes.NewPublishedModulesLoaded) } diff --git a/x/move/keeper/msg_server_test.go b/x/move/keeper/msg_server_test.go index d761ce14..9493955e 100644 --- a/x/move/keeper/msg_server_test.go +++ b/x/move/keeper/msg_server_test.go @@ -17,7 +17,7 @@ func TestScriptMsg(t *testing.T) { moduleAddr := sdk.AccAddress([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}) wrongAddr := sdk.AccAddress([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}) msgServer := keeper.NewMsgServerImpl(input.MoveKeeper) - _, err := msgServer.Publish(sdk.WrapSDKContext(ctx), &types.MsgPublish{ + _, err := msgServer.Publish(ctx, &types.MsgPublish{ Sender: moduleAddr.String(), CodeBytes: [][]byte{basicCoinModule}, UpgradePolicy: types.UpgradePolicy_COMPATIBLE, @@ -25,7 +25,7 @@ func TestScriptMsg(t *testing.T) { require.NoError(t, err) // wrong addr - _, err = msgServer.Script(sdk.WrapSDKContext(ctx), &types.MsgScript{ + _, err = msgServer.Script(ctx, &types.MsgScript{ Sender: wrongAddr.String(), CodeBytes: basicCoinMintScript, TypeArgs: []string{"0x1::BasicCoin::Initia", "bool"}, @@ -34,7 +34,7 @@ func TestScriptMsg(t *testing.T) { require.Error(t, err) // invalid type args - _, err = msgServer.Script(sdk.WrapSDKContext(ctx), &types.MsgScript{ + _, err = msgServer.Script(ctx, &types.MsgScript{ Sender: moduleAddr.String(), CodeBytes: basicCoinMintScript, TypeArgs: []string{}, @@ -43,7 +43,7 @@ func TestScriptMsg(t *testing.T) { require.Error(t, err) // correct args - _, err = msgServer.Script(sdk.WrapSDKContext(ctx), &types.MsgScript{ + _, err = msgServer.Script(ctx, &types.MsgScript{ Sender: moduleAddr.String(), CodeBytes: basicCoinMintScript, TypeArgs: []string{"0x1::BasicCoin::Initia", "bool"}, diff --git a/x/move/keeper/abci_listener.go b/x/move/keeper/post_handler.go similarity index 89% rename from x/move/keeper/abci_listener.go rename to x/move/keeper/post_handler.go index add02627..5c9e7e43 100644 --- a/x/move/keeper/abci_listener.go +++ b/x/move/keeper/post_handler.go @@ -26,7 +26,7 @@ func (listener *PostHandler) GetNewPublishedModulesLoaded() bool { } // ListenDeliverTx updates the steaming service with the latest DeliverTx messages -func (listener *PostHandler) PostHandle(ctx sdk.Context, tx sdk.Tx, simulate, success bool) (newCtx sdk.Context, err error) { +func (listener *PostHandler) PostHandle(ctx sdk.Context, _ sdk.Tx, _, success bool) (newCtx sdk.Context, err error) { // When there is no newly published modules, skip below if !listener.GetNewPublishedModulesLoaded() { return ctx, nil @@ -36,7 +36,7 @@ func (listener *PostHandler) PostHandle(ctx sdk.Context, tx sdk.Tx, simulate, su listener.SetNewPublishedModulesLoaded(false) // check tx failed - if success { + if !success { // mark loader cache as invalid to flush vm cache if err := listener.vm.MarkLoaderCacheAsInvalid(); err != nil { return ctx, err