diff --git a/x/delegation/keeper/genesis.go b/x/delegation/keeper/genesis.go index 00474c0cf..ed2c5c417 100644 --- a/x/delegation/keeper/genesis.go +++ b/x/delegation/keeper/genesis.go @@ -3,6 +3,7 @@ package keeper import ( "fmt" + assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -22,7 +23,7 @@ func (k Keeper) InitGenesis( operatorAddress := c.OperatorAddress // #nosec G703 // already validated accAddress, _ := sdk.AccAddressFromBech32(operatorAddress) - amount := c.Amount + amount := c.Amount // delegation amount if !k.operatorKeeper.IsOperator(ctx, accAddress) { // the operator must be registered first, so the // genesis of the operator module comes before this module @@ -33,7 +34,8 @@ func (k Keeper) InitGenesis( ), ) } - // at genesis, the operator cannot be frozen so skip that. + // at genesis, the operator cannot be frozen so skip that check. + // validate that enough deposits exist before delegation. info, err := k.assetsKeeper.GetStakerSpecifiedAssetInfo(ctx, stakerID, assetID) if err != nil { panic(err) @@ -60,6 +62,16 @@ func (k Keeper) InitGenesis( ); err != nil { panic(err) } + // also tell the assetsKeeper to mark this as a delegation. + if err := k.assetsKeeper.UpdateStakerAssetState( + ctx, stakerID, assetID, assetstype.StakerSingleAssetChangeInfo{ + WithdrawableAmount: amount.Neg(), + }); err != nil { + panic(err) + } + // we have checked that delegation amount > deposit amount for each asset. + // we don't need to check for the total amount, since this genesis only handles + // delegation amounts (others are implicitly zero). } } } diff --git a/x/operator/keeper/genesis.go b/x/operator/keeper/genesis.go index 0fbd9383a..4c80a8782 100644 --- a/x/operator/keeper/genesis.go +++ b/x/operator/keeper/genesis.go @@ -1,6 +1,10 @@ package keeper import ( + "fmt" + + "cosmossdk.io/math" + delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -37,10 +41,17 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) []abci.Va } } // state_update.go + stakerAssetOperatorMap := make(map[string]map[string]map[string]math.Int) for _, level1 := range state.StakerRecords { stakerID := level1.StakerID + if _, ok := stakerAssetOperatorMap[stakerID]; !ok { + stakerAssetOperatorMap[stakerID] = make(map[string]map[string]math.Int) + } for _, level2 := range level1.StakerDetails { assetID := level2.AssetID + if _, ok := stakerAssetOperatorMap[stakerID][assetID]; !ok { + stakerAssetOperatorMap[stakerID][assetID] = make(map[string]math.Int) + } for _, level3 := range level2.Details { operatorAddress := level3.OperatorAddress amount := level3.Amount @@ -49,10 +60,27 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) []abci.Va ); err != nil { panic(err) } - + if _, ok := stakerAssetOperatorMap[stakerID][assetID][operatorAddress]; !ok { + stakerAssetOperatorMap[stakerID][assetID][operatorAddress] = math.ZeroInt() + } + stakerAssetOperatorMap[stakerID][assetID][operatorAddress].Add(amount) } } } + // validate the information in the delegation keeper, + // which has validated it in the assets keeper. + checkFunc := func( + stakerID, assetID, operatorAddress string, state *delegationtypes.DelegationAmounts, + ) error { + valueHere := stakerAssetOperatorMap[stakerID][assetID][operatorAddress] + if !valueHere.Equal(state.UndelegatableAmount) { + panic(fmt.Sprintf("undelegatable amount mismatch: %s", operatorAddress)) + } + return nil + } + // since this module only knows the delegated value (and not the deposit value), + // it cannot do any further validation with the data in the assets keeper. + k.delegationKeeper.IterateDelegationState(ctx, checkFunc) return []abci.ValidatorUpdate{} }