Skip to content

Commit

Permalink
Added queue pruning and other before-operation changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Segfaultd committed Oct 17, 2023
1 parent 0f96fc6 commit 26f5797
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 255 deletions.
19 changes: 0 additions & 19 deletions x/beam/abci.go
Original file line number Diff line number Diff line change
@@ -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())
}
}
33 changes: 1 addition & 32 deletions x/beam/genesis.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package beam

import (
"fmt"

abci "github.com/cometbft/cometbft/abci/types"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -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{}
}
13 changes: 13 additions & 0 deletions x/beam/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
206 changes: 3 additions & 203 deletions x/beam/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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
}
5 changes: 5 additions & 0 deletions x/beam/migrations/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
}
34 changes: 34 additions & 0 deletions x/beam/migrations/v162/store.go
Original file line number Diff line number Diff line change
@@ -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
}
1 change: 1 addition & 0 deletions x/beam/migrations/v162/store_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package v162
2 changes: 1 addition & 1 deletion x/beam/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 26f5797

Please sign in to comment.