From 26f5797de15c2c9f3354555591ff69a8ccc442b5 Mon Sep 17 00:00:00 2001 From: Segfault <5221072+Segfaultd@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:10:53 +0200 Subject: [PATCH] Added queue pruning and other before-operation changes --- x/beam/abci.go | 19 --- x/beam/genesis.go | 33 +---- x/beam/keeper/keeper.go | 13 ++ x/beam/keeper/msg_server.go | 206 +-------------------------- x/beam/migrations/migrator.go | 5 + x/beam/migrations/v162/store.go | 34 +++++ x/beam/migrations/v162/store_test.go | 1 + x/beam/types/keys.go | 2 +- 8 files changed, 58 insertions(+), 255 deletions(-) create mode 100644 x/beam/migrations/v162/store.go create mode 100644 x/beam/migrations/v162/store_test.go diff --git a/x/beam/abci.go b/x/beam/abci.go index 738c495b..6976b541 100644 --- a/x/beam/abci.go +++ b/x/beam/abci.go @@ -1,30 +1,11 @@ package beam import ( - "fmt" - "time" - - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/lum-network/chain/x/beam/keeper" - "github.com/lum-network/chain/x/beam/types" ) // EndBlocker Called every block, process the beam expiration and auto close func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) { - // Notify the telemetry module - defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker) - - // Acquire the list of beams - ids := keeper.GetBeamIDsFromBlockQueue(ctx, int(ctx.BlockHeight())) - - // Process beams expirations - for _, value := range ids { - err := keeper.UpdateBeamStatus(ctx, value, types.BeamState_StateCanceled) - if err != nil { - panic(err) - } - keeper.Logger(ctx).Info(fmt.Sprintf("Canceling beam #%s due to crossed auto close thresold", value), "height", ctx.BlockHeight()) - } } diff --git a/x/beam/genesis.go b/x/beam/genesis.go index 9655c3a2..7fa4e8aa 100644 --- a/x/beam/genesis.go +++ b/x/beam/genesis.go @@ -1,8 +1,6 @@ package beam import ( - "fmt" - abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,39 +11,10 @@ import ( // InitGenesis initializes the capability module's state from a provided genesis state. func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) (res []abci.ValidatorUpdate) { - k.CreateBeamModuleAccount(ctx, genState.ModuleAccountBalance) - - // Persist the beams to raw store - for _, beam := range genState.Beams { - k.SetBeam(ctx, beam.GetId(), beam) - - // Append to the correct queue from the beam state - toQueue := false - if beam.GetStatus() == types.BeamState_StateClosed || beam.GetStatus() == types.BeamState_StateCanceled { - k.InsertClosedBeamQueue(ctx, beam.GetId()) - toQueue = true - } else if beam.GetStatus() == types.BeamState_StateOpen { - // Make sure we don't add a beam that is intended to be already closed at the current height - if beam.GetClosesAtBlock() > 0 && int(beam.GetClosesAtBlock()) > int(ctx.BlockHeight()) { - k.InsertOpenBeamByBlockQueue(ctx, int(beam.GetClosesAtBlock()), beam.GetId()) - toQueue = true - } - } else { - ctx.Logger().Info(fmt.Sprintf("Not appending beam %s to any queue due to unhandled status", beam.GetId()), "height", ctx.BlockHeight(), "state", beam.GetStatus()) - } - - ctx.Logger().Info(fmt.Sprintf("Persisted beam %s from genesis file", beam.GetId()), "height", ctx.BlockHeight(), "state", beam.GetStatus(), "added_in_queue", toQueue) - } - return nil } // ExportGenesis returns the capability module's exported genesis. func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { - beams := k.ListBeams(ctx) - - return &types.GenesisState{ - Beams: beams, - ModuleAccountBalance: k.GetBeamAccountBalance(ctx), - } + return &types.GenesisState{} } diff --git a/x/beam/keeper/keeper.go b/x/beam/keeper/keeper.go index 5499d000..76c38c74 100644 --- a/x/beam/keeper/keeper.go +++ b/x/beam/keeper/keeper.go @@ -180,6 +180,19 @@ func (k Keeper) RemoveFromClosedBeamQueue(ctx sdk.Context, beamID string) { store.Delete(types.GetClosedBeamQueueKey(beamID)) } +// DeleteBeam Delete a beam by its ID and return error in case of non-existent entity +func (k Keeper) DeleteBeam(ctx sdk.Context, key string) error { + // Acquire the store instance + store := ctx.KVStore(k.storeKey) + + // Delete the beam if it exists + if !store.Has(types.GetBeamKey(key)) { + return errorsmod.Wrapf(types.ErrBeamNotFound, "beam not found: %s", key) + } + store.Delete(types.GetBeamKey(key)) + return nil +} + // GetBeam Return a beam instance for the given key func (k Keeper) GetBeam(ctx sdk.Context, key string) (types.Beam, error) { // Acquire the store instance diff --git a/x/beam/keeper/msg_server.go b/x/beam/keeper/msg_server.go index fdc07238..1beabb10 100644 --- a/x/beam/keeper/msg_server.go +++ b/x/beam/keeper/msg_server.go @@ -2,13 +2,8 @@ package keeper import ( "context" - "strings" - - errorsmod "cosmossdk.io/errors" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/lum-network/chain/utils" "github.com/lum-network/chain/x/beam/types" ) @@ -26,211 +21,16 @@ var _ types.MsgServer = msgServer{} // OpenBeam Create a new beam instance func (k Keeper) OpenBeam(goCtx context.Context, msg *types.MsgOpenBeam) (*types.MsgOpenBeamResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - // Make sure the ID is in the correct format - if strings.Contains(msg.GetId(), types.MemStoreQueueSeparator) { - return nil, types.ErrBeamIdContainsForbiddenChar - } - - // If the generated ID already exists, refuse the payload - if k.HasBeam(ctx, msg.GetId()) { - return nil, types.ErrBeamAlreadyExists - } - - // Acquire the staking params for default bond denom - params := k.StakingKeeper.GetParams(ctx) - - var beam = &types.Beam{ - CreatorAddress: msg.GetCreatorAddress(), - Id: msg.GetId(), - Secret: msg.GetSecret(), - Status: types.BeamState_StateOpen, - Amount: sdk.NewCoin(params.GetBondDenom(), sdk.NewInt(0)), - FundsWithdrawn: false, - Claimed: false, - HideContent: false, - CancelReason: "", - Schema: msg.GetSchema(), - Data: msg.GetData(), - CreatedAt: ctx.BlockTime(), - } - - if msg.GetAmount() != nil && msg.GetAmount().IsPositive() { - beam.Amount = *msg.GetAmount() - } - - // If the payload includes an owner field, we auto claim it - if len(msg.GetClaimAddress()) > 0 { - beam.ClaimAddress = msg.GetClaimAddress() - beam.Claimed = true - } - - if msg.GetClosesAtBlock() > 0 { - if int(msg.GetClosesAtBlock()) <= int(ctx.BlockHeight()) { - return nil, types.ErrBeamAutoCloseInThePast - } - beam.ClosesAtBlock = msg.GetClosesAtBlock() - } - - if msg.GetClaimExpiresAtBlock() > 0 { - beam.ClaimExpiresAtBlock = msg.GetClaimExpiresAtBlock() - } - - // Only try to process coins move if present - if msg.GetAmount() != nil && msg.GetAmount().IsPositive() { - creatorAddress, err := sdk.AccAddressFromBech32(msg.GetCreatorAddress()) - if err != nil { - return nil, sdkerrors.ErrInvalidAddress - } - err = k.moveCoinsToModuleAccount(ctx, creatorAddress, *msg.GetAmount()) - if err != nil { - return nil, err - } - } - - k.SetBeam(ctx, beam.GetId(), beam) - - // If the beam is actually intended to auto close, we put it inside the by-block queue - if beam.GetClosesAtBlock() > 0 { - k.InsertOpenBeamByBlockQueue(ctx, int(msg.GetClosesAtBlock()), beam.GetId()) - } - - ctx.EventManager().Events().AppendEvents(sdk.Events{ - sdk.NewEvent(types.EventTypeOpenBeam, sdk.NewAttribute(types.AttributeKeyOpener, msg.GetCreatorAddress())), - }) - return &types.MsgOpenBeamResponse{}, nil + return &types.MsgOpenBeamResponse{}, sdkerrors.ErrNotSupported } // UpdateBeam Update a beam instance and proceeds any require state machine update func (k Keeper) UpdateBeam(goCtx context.Context, msg *types.MsgUpdateBeam) (*types.MsgUpdateBeamResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - // Does the beam exists? - if !k.HasBeam(ctx, msg.Id) { - return nil, types.ErrBeamNotFound - } - - // Acquire the beam instance - beam, err := k.GetBeam(ctx, msg.Id) - if err != nil { - return nil, err - } - - // Is the beam still updatable - if beam.GetStatus() != types.BeamState_StateOpen { - return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "Beam is closed and thus cannot be updated") - } - - // Make sure transaction signer is authorized - if beam.GetCreatorAddress() != msg.GetUpdaterAddress() { - return nil, types.ErrBeamNotAuthorized - } - - // First update the metadata before making change since we could want to f.e close but still update metadata - if msg.GetData() != nil { - beam.Data = msg.GetData() - } - - if msg.GetAmount() != nil && msg.GetAmount().IsPositive() { - updaterAddress, err := sdk.AccAddressFromBech32(msg.GetUpdaterAddress()) - if err != nil { - return nil, sdkerrors.ErrInvalidAddress - } - - err = k.moveCoinsToModuleAccount(ctx, updaterAddress, *msg.GetAmount()) - if err != nil { - return nil, err - } - - beam.Amount = beam.GetAmount().Add(*msg.GetAmount()) - } - - if len(msg.GetClaimAddress()) > 0 { - beam.ClaimAddress = msg.GetClaimAddress() - beam.Claimed = true - } - - if msg.GetClosesAtBlock() > 0 { - beam.ClosesAtBlock = msg.GetClosesAtBlock() - } - - if msg.GetClaimExpiresAtBlock() > 0 { - beam.ClaimExpiresAtBlock = msg.GetClaimExpiresAtBlock() - } - - if msg.GetHideContent() != beam.GetHideContent() { - beam.HideContent = msg.GetHideContent() - } - - if msg.GetCancelReason() != beam.GetCancelReason() { - beam.CancelReason = msg.GetCancelReason() - } - - if msg.GetHideContent() != beam.GetHideContent() { - beam.HideContent = msg.GetHideContent() - } - k.SetBeam(ctx, beam.GetId(), &beam) - - // We then check the status and return if required - if msg.GetStatus() != types.BeamState_StateUnspecified { - err = k.UpdateBeamStatus(ctx, beam.GetId(), msg.GetStatus()) - if err != nil { - return nil, err - } - } - - ctx.EventManager().Events().AppendEvents(sdk.Events{ - sdk.NewEvent(types.EventTypeUpdateBeam, sdk.NewAttribute(types.AttributeKeyUpdater, msg.GetUpdaterAddress())), - }) - return &types.MsgUpdateBeamResponse{}, nil + return &types.MsgUpdateBeamResponse{}, sdkerrors.ErrNotSupported } // ClaimBeam Final user endpoint to claim and acquire the money func (k Keeper) ClaimBeam(goCtx context.Context, msg *types.MsgClaimBeam) (*types.MsgClaimBeamResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - // Does the beam exists? - if !k.HasBeam(ctx, msg.Id) { - return nil, types.ErrBeamNotFound - } - - // Acquire the beam instance - beam, err := k.GetBeam(ctx, msg.Id) - if err != nil { - return nil, err - } - - // If beam is already claimed, we should not be able to - if beam.GetClaimed() { - return nil, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "Beam is already claimed") - } - - // Make sure transaction signer is authorized - if !utils.CompareHashAndString(beam.Secret, msg.Secret) { - return nil, types.ErrBeamInvalidSecret - } - - // Acquire the claimer address - claimerAddress, err := sdk.AccAddressFromBech32(msg.GetClaimerAddress()) - if err != nil { - return nil, sdkerrors.ErrInvalidAddress - } - - // Transfer funds only if beam is already closed - if beam.GetStatus() == types.BeamState_StateClosed && !beam.GetFundsWithdrawn() { - if beam.GetAmount().IsPositive() { - if err = k.moveCoinsToAccount(ctx, claimerAddress, beam.GetAmount()); err != nil { - return nil, err - } - beam.FundsWithdrawn = true - } - } - - // Update beam status - beam.Claimed = true - beam.ClaimAddress = msg.GetClaimerAddress() - k.SetBeam(ctx, msg.Id, &beam) + return &types.MsgClaimBeamResponse{}, sdkerrors.ErrNotSupported - ctx.EventManager().Events().AppendEvents(sdk.Events{ - sdk.NewEvent(types.EventTypeClaimBeam, sdk.NewAttribute(types.AttributeKeyClaimer, msg.GetClaimerAddress())), - }) - return &types.MsgClaimBeamResponse{}, nil } diff --git a/x/beam/migrations/migrator.go b/x/beam/migrations/migrator.go index e2459b20..e3b475db 100644 --- a/x/beam/migrations/migrator.go +++ b/x/beam/migrations/migrator.go @@ -2,6 +2,7 @@ package migrations import ( sdk "github.com/cosmos/cosmos-sdk/types" + v162 "github.com/lum-network/chain/x/beam/migrations/v162" keeper2 "github.com/lum-network/chain/x/beam/keeper" v110 "github.com/lum-network/chain/x/beam/migrations/v110" @@ -19,3 +20,7 @@ func NewMigrator(keeper keeper2.Keeper) Migrator { func (m Migrator) Migrate1To2(ctx sdk.Context) error { return v110.MigrateBeamQueues(ctx, m.keeper) } + +func (m Migrator) Migrate2To3(ctx sdk.Context) error { + return v162.DeleteBeamsData(ctx, m.keeper) +} diff --git a/x/beam/migrations/v162/store.go b/x/beam/migrations/v162/store.go new file mode 100644 index 00000000..3f43224c --- /dev/null +++ b/x/beam/migrations/v162/store.go @@ -0,0 +1,34 @@ +package v162 + +import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + beamkeeper "github.com/lum-network/chain/x/beam/keeper" + beamtypes "github.com/lum-network/chain/x/beam/types" +) + +func DeleteBeamsData(ctx sdk.Context, bk beamkeeper.Keeper) error { + bk.IterateOpenBeamsQueue(ctx, func(beam beamtypes.Beam) bool { + bk.RemoveFromOpenBeamQueue(ctx, beam.GetId()) + bk.Logger(ctx).Info(fmt.Sprintf("Removed beam %s from open beam queue", beam.GetId())) + return false + }) + bk.IterateClosedBeamsQueue(ctx, func(beam beamtypes.Beam) bool { + bk.RemoveFromClosedBeamQueue(ctx, beam.GetId()) + bk.Logger(ctx).Info(fmt.Sprintf("Removed beam %s from open beam queue", beam.GetId())) + return false + }) + bk.IterateOpenBeamsByBlockQueue(ctx, func(beam beamtypes.Beam) bool { + bk.RemoveFromOpenBeamByBlockQueue(ctx, int(beam.GetClosesAtBlock()), beam.GetId()) + bk.Logger(ctx).Info(fmt.Sprintf("Removed beam %s from open beam by block queue", beam.GetId())) + return false + }) + bk.IterateBeams(ctx, func(beam beamtypes.Beam) bool { + if err := bk.DeleteBeam(ctx, beam.GetId()); err != nil { + panic(err) + } + bk.Logger(ctx).Info(fmt.Sprintf("Deleted beam entity with ID %s", beam.GetId())) + return false + }) + return nil +} diff --git a/x/beam/migrations/v162/store_test.go b/x/beam/migrations/v162/store_test.go new file mode 100644 index 00000000..0e0a62b9 --- /dev/null +++ b/x/beam/migrations/v162/store_test.go @@ -0,0 +1 @@ +package v162 diff --git a/x/beam/types/keys.go b/x/beam/types/keys.go index 55d5c381..adc5758c 100644 --- a/x/beam/types/keys.go +++ b/x/beam/types/keys.go @@ -7,7 +7,7 @@ const ( ModuleName = "beam" // ModuleVersion defines the current module version - ModuleVersion = 2 + ModuleVersion = 3 // StoreKey defines the primary module store key StoreKey = ModuleName