From 98ccceb17044a300267b8ace9a8f50173d0ac0c7 Mon Sep 17 00:00:00 2001 From: zsystm Date: Mon, 14 Aug 2023 15:45:58 +0900 Subject: [PATCH 01/14] tmp: add logger to analyze gas consumption logs gas consumption at fileLogger --- x/liquidstaking/keeper/insurance.go | 3 + x/liquidstaking/keeper/keeper.go | 14 ++- x/liquidstaking/keeper/liquidstaking.go | 105 +++++++++++++++++- .../keeper/net_amount_essentials.go | 16 +++ 4 files changed, 136 insertions(+), 2 deletions(-) diff --git a/x/liquidstaking/keeper/insurance.go b/x/liquidstaking/keeper/insurance.go index ee65680d..a7d742e9 100644 --- a/x/liquidstaking/keeper/insurance.go +++ b/x/liquidstaking/keeper/insurance.go @@ -43,6 +43,7 @@ func (k Keeper) GetPairingInsurances(ctx sdk.Context) ( validatorMap map[string]stakingtypes.Validator, ) { validatorMap = make(map[string]stakingtypes.Validator) + iterCnt := 0 k.IterateAllInsurances(ctx, func(ins types.Insurance) bool { if ins.Status != types.INSURANCE_STATUS_PAIRING { return false @@ -58,8 +59,10 @@ func (k Keeper) GetPairingInsurances(ctx sdk.Context) ( validatorMap[ins.ValidatorAddress] = validator } pairingInsurances = append(pairingInsurances, ins) + iterCnt++ return false }) + k.fileLogger.Debug("GetPairingInsurances", "pairing insurances", iterCnt) return } diff --git a/x/liquidstaking/keeper/keeper.go b/x/liquidstaking/keeper/keeper.go index 793f26f2..f36418e3 100644 --- a/x/liquidstaking/keeper/keeper.go +++ b/x/liquidstaking/keeper/keeper.go @@ -1,9 +1,13 @@ package keeper import ( + "fmt" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "os" + "path/filepath" + "time" "github.com/tendermint/tendermint/libs/log" @@ -22,6 +26,8 @@ type Keeper struct { stakingKeeper types.StakingKeeper slashingKeeper types.SlashingKeeper evidenceKeeper types.EvidenceKeeper + + fileLogger log.Logger } // NewKeeper creates a new mint Keeper instance @@ -40,7 +46,11 @@ func NewKeeper( if !subspace.HasKeyTable() { subspace = subspace.WithKeyTable(types.ParamKeyTable()) } - + file, err := os.OpenFile(filepath.Join(os.Getenv("HOME"), "logs", fmt.Sprintf("liquidstaking.log-%s", time.Now().Format(time.RFC3339))), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + panic(err) + } + fileLogger := log.NewTMLogger(log.NewSyncWriter(file)).With("module", "x/liquidstaking") return Keeper{ storeKey: storeKey, cdc: cdc, @@ -51,6 +61,8 @@ func NewKeeper( stakingKeeper: stakingKeeper, slashingKeeper: slashingKeeper, evidenceKeeper: evidenceKeeper, + + fileLogger: fileLogger, } } diff --git a/x/liquidstaking/keeper/liquidstaking.go b/x/liquidstaking/keeper/liquidstaking.go index 0f27075f..34588a40 100644 --- a/x/liquidstaking/keeper/liquidstaking.go +++ b/x/liquidstaking/keeper/liquidstaking.go @@ -579,6 +579,8 @@ func (k Keeper) RePairRankedInsurances( func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( chunks []types.Chunk, newShares sdk.Dec, lsTokenMintAmount sdk.Int, err error, ) { + g := ctx.GasMeter().GasConsumed() + k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) delAddr := msg.GetDelegator() amount := msg.Amount @@ -590,7 +592,17 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( return } chunksToCreate := amount.Amount.Quo(types.ChunkSize) + + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g + g = g2 + k.fileLogger.Debug("beforeGetNetAmountStateEssentials", "gas", g2, "diff", diff) nas := k.GetNetAmountStateEssentials(ctx) + + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("afterGetNetAmountStateEssentials", "gas", g2, "diff", diff) if nas.RemainingChunkSlots.LT(chunksToCreate) { err = sdkerrors.Wrapf( types.ErrExceedAvailableChunks, @@ -601,7 +613,16 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( return } + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("beforeGetPairingInsurances", "gas", g2, "diff", diff) pairingInsurances, validatorMap := k.GetPairingInsurances(ctx) + + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("afterGetPairingInsurances", "gas", g2, "diff", diff) numPairingInsurances := sdk.NewIntFromUint64(uint64(len(pairingInsurances))) if chunksToCreate.GT(numPairingInsurances) { err = types.ErrNoPairingInsurance @@ -617,6 +638,10 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( if chunksToCreate.IsZero() { break } + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("beforeEscrowAndMintLsTokens", "gas", g2, "diff", diff) cheapestIns := pairingInsurances[0] pairingInsurances = pairingInsurances[1:] @@ -659,9 +684,14 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( if err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, delAddr, sdk.NewCoins(mintedCoin)); err != nil { return } + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("afterEscrowAndMintLsTokens", "gas", g2, "diff", diff) chunks = append(chunks, chunk) chunksToCreate = chunksToCreate.Sub(sdk.OneInt()) } + k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g) return } @@ -672,6 +702,8 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) infos []types.UnpairingForUnstakingChunkInfo, err error, ) { + g := ctx.GasMeter().GasConsumed() + k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", ctx.GasMeter().GasConsumed()) delAddr := msg.GetDelegator() amount := msg.Amount @@ -687,6 +719,10 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) chunksWithInsId := make(map[uint64]types.Chunk) var insurances []types.Insurance validatorMap := make(map[string]stakingtypes.Validator) + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g + g = g2 + k.fileLogger.Debug("beforeIterateAllChunks", "gas", g2, "diff", diff) k.IterateAllChunks(ctx, func(chunk types.Chunk) (stop bool) { if chunk.Status != types.CHUNK_STATUS_PAIRED { return false @@ -705,7 +741,10 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) chunksWithInsId[pairedIns.Id] = chunk return false }) - + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("afterIterateAllChunks", "gas", g2, "diff", diff) pairedChunks := int64(len(chunksWithInsId)) if pairedChunks == 0 { err = types.ErrNoPairedChunk @@ -723,10 +762,23 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) // Sort insurances by descend order types.SortInsurances(validatorMap, insurances, true) + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("beforeGetNetAmountStateEssentials", "gas", g2, "diff", diff) // How much ls tokens must be burned nas := k.GetNetAmountStateEssentials(ctx) + + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("afterGetNetAmountStateEssentials", "gas", g2, "diff", diff) liquidBondDenom := k.GetLiquidBondDenom(ctx) for i := int64(0); i < chunksToLiquidUnstake; i++ { + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("beforeQueueLiquidUnstake", "gas", g2, "diff", diff) // Escrow ls tokens from the delegator lsTokenBurnAmount := types.ChunkSize if nas.LsTokensTotalSupply.IsPositive() { @@ -760,11 +812,18 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) toBeUnstakedChunks = append(toBeUnstakedChunks, chunksWithInsId[insurances[i].Id]) infos = append(infos, info) k.SetUnpairingForUnstakingChunkInfo(ctx, info) + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("afterQueueLiquidUnstake", "gas", g2, "diff", diff) } + k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g) return } func (k Keeper) DoProvideInsurance(ctx sdk.Context, msg *types.MsgProvideInsurance) (ins types.Insurance, err error) { + g := ctx.GasMeter().GasConsumed() + k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) providerAddr := msg.GetProvider() valAddr := msg.GetValidator() feeRate := msg.FeeRate @@ -805,10 +864,16 @@ func (k Keeper) DoProvideInsurance(ctx sdk.Context, msg *types.MsgProvideInsuran } k.SetInsurance(ctx, ins) + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g + g = g2 + k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } func (k Keeper) DoCancelProvideInsurance(ctx sdk.Context, msg *types.MsgCancelProvideInsurance) (ins types.Insurance, err error) { + g := ctx.GasMeter().GasConsumed() + k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) providerAddr := msg.GetProvider() insId := msg.Id @@ -834,6 +899,10 @@ func (k Keeper) DoCancelProvideInsurance(ctx sdk.Context, msg *types.MsgCancelPr return ins, err } k.DeleteInsurance(ctx, insId) + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g + g = g2 + k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } @@ -842,6 +911,8 @@ func (k Keeper) DoCancelProvideInsurance(ctx sdk.Context, msg *types.MsgCancelPr func (k Keeper) DoWithdrawInsurance(ctx sdk.Context, msg *types.MsgWithdrawInsurance) ( ins types.Insurance, req types.WithdrawInsuranceRequest, err error, ) { + g := ctx.GasMeter().GasConsumed() + k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) if ins, err = k.validateInsurance(ctx, msg.Id, msg.GetProvider(), types.INSURANCE_STATUS_UNSPECIFIED); err != nil { return } @@ -858,6 +929,10 @@ func (k Keeper) DoWithdrawInsurance(ctx sdk.Context, msg *types.MsgWithdrawInsur default: err = sdkerrors.Wrapf(types.ErrNotInWithdrawableStatus, "ins status: %s", ins.Status) } + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g + g = g2 + k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } @@ -866,6 +941,8 @@ func (k Keeper) DoWithdrawInsuranceCommission( ctx sdk.Context, msg *types.MsgWithdrawInsuranceCommission, ) (feePoolBals sdk.Coins, err error) { + g := ctx.GasMeter().GasConsumed() + k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) providerAddr := msg.GetProvider() insId := msg.Id @@ -886,11 +963,17 @@ func (k Keeper) DoWithdrawInsuranceCommission( if insBals.IsZero() && feePoolBals.IsZero() { k.DeleteInsurance(ctx, insId) } + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g + g = g2 + k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } // DoDepositInsurance deposits more coin to insurance. func (k Keeper) DoDepositInsurance(ctx sdk.Context, msg *types.MsgDepositInsurance) (err error) { + g := ctx.GasMeter().GasConsumed() + k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) providerAddr := msg.GetProvider() insuranceId := msg.Id amount := msg.Amount @@ -906,6 +989,11 @@ func (k Keeper) DoDepositInsurance(ctx sdk.Context, msg *types.MsgDepositInsuran if err = k.bankKeeper.SendCoins(ctx, providerAddr, ins.DerivedAddress(), sdk.NewCoins(amount)); err != nil { return } + + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g + g = g2 + k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } @@ -915,11 +1003,21 @@ func (k Keeper) DoClaimDiscountedReward(ctx sdk.Context, msg *types.MsgClaimDisc discountedMintRate sdk.Dec, err error, ) { + g := ctx.GasMeter().GasConsumed() + k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) if err = k.ShouldBeLiquidBondDenom(ctx, msg.Amount.Denom); err != nil { return } + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g + g = g2 + k.fileLogger.Debug("beforeGetNetAmountState", "gas", g2, "diff", diff) nas := k.GetNetAmountStateEssentials(ctx) + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug("afterGetNetAmountState", "gas", g2, "diff", diff) // discount rate >= minimum discount rate // if discount rate(e.g. 10%) is lower than minimum discount rate(e.g. 20%), then it is not profitable to claim reward. if nas.DiscountRate.LT(msg.MinimumDiscountRate) { @@ -952,6 +1050,11 @@ func (k Keeper) DoClaimDiscountedReward(ctx sdk.Context, msg *types.MsgClaimDisc if err = k.bankKeeper.SendCoins(ctx, types.RewardPool, msg.GetRequestser(), claimCoins); err != nil { return } + + g2 = ctx.GasMeter().GasConsumed() + diff = g2 - g + g = g2 + k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } diff --git a/x/liquidstaking/keeper/net_amount_essentials.go b/x/liquidstaking/keeper/net_amount_essentials.go index 2e4ea97f..a8ced96d 100644 --- a/x/liquidstaking/keeper/net_amount_essentials.go +++ b/x/liquidstaking/keeper/net_amount_essentials.go @@ -20,12 +20,15 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) (nase types.NetAmou // To reduce gas consumption, store validator info in map insValMap := make(map[string]stakingtypes.Validator) + pairedCnt, unbondingCnt, restCnt := 0, 0, 0 k.IterateAllChunks(ctx, func(chunk types.Chunk) (stop bool) { balance := k.bankKeeper.GetBalance(ctx, chunk.DerivedAddress(), k.stakingKeeper.BondDenom(ctx)) totalChunksBalance = totalChunksBalance.Add(balance.Amount) + g := ctx.GasMeter().GasConsumed() switch chunk.Status { case types.CHUNK_STATUS_PAIRED: + pairedCnt++ numPairedChunks = numPairedChunks.Add(sdk.OneInt()) pairedIns := k.mustGetInsurance(ctx, chunk.PairedInsuranceId) valAddr := pairedIns.GetValidator() @@ -61,18 +64,31 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) (nase types.NetAmou insuranceCommission := delReward.Mul(pairedIns.FeeRate) remainingReward := delReward.Sub(insuranceCommission) totalRemainingRewardsBeforeModuleFee = totalRemainingRewardsBeforeModuleFee.Add(remainingReward) + + diff := ctx.GasMeter().GasConsumed() - g + k.fileLogger.Debug("unit paired chunk gas consumption", "gas", diff) default: + checked := false k.stakingKeeper.IterateDelegatorUnbondingDelegations(ctx, chunk.DerivedAddress(), func(ubd stakingtypes.UnbondingDelegation) (stop bool) { + unbondingCnt++ + checked = true for _, entry := range ubd.Entries { unpairingIns := k.mustGetInsurance(ctx, chunk.UnpairingInsuranceId) tokenValue := k.calcTokenValueWithInsuranceCoverage(ctx, entry.Balance, unpairingIns) totalUnbondingChunksBalance = totalUnbondingChunksBalance.Add(tokenValue) } + diff := ctx.GasMeter().GasConsumed() - g + k.fileLogger.Debug("unit unbonding chunk gas consumption", "gas", diff) return false }) + if !checked { + restCnt++ + } } + return false }) + k.fileLogger.Debug("GetNetAmountEssentials", "paired chunks:", pairedCnt, "unbonding chunks", unbondingCnt, "rest chunks", restCnt) rewardPoolBalance := k.bankKeeper.GetBalance(ctx, types.RewardPool, bondDenom).Amount netAmountBeforeModuleFee := rewardPoolBalance.Add(totalChunksBalance). From 249e4f71f811160d4cb119d2610a59108970bbe1 Mon Sep 17 00:00:00 2001 From: zsystm Date: Wed, 16 Aug 2023 10:45:19 +0900 Subject: [PATCH 02/14] disable minus fee rate --- x/liquidstaking/types/msg.go | 5 ++++- x/liquidstaking/types/msg_test.go | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/x/liquidstaking/types/msg.go b/x/liquidstaking/types/msg.go index 27ccedb4..892a1656 100644 --- a/x/liquidstaking/types/msg.go +++ b/x/liquidstaking/types/msg.go @@ -117,7 +117,10 @@ func (msg MsgProvideInsurance) ValidateBasic() error { return err } if msg.FeeRate.IsNil() { - return ErrInvalidFeeRate + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "insurance fee rate must not be nil") + } + if msg.FeeRate.IsNegative() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "insurance fee rate must not be negative") } return nil } diff --git a/x/liquidstaking/types/msg_test.go b/x/liquidstaking/types/msg_test.go index 6733c61f..c2df6069 100644 --- a/x/liquidstaking/types/msg_test.go +++ b/x/liquidstaking/types/msg_test.go @@ -146,6 +146,11 @@ func (suite *msgTestSuite) TestMsgProvideInsurance() { "", types.NewMsgProvideInsurance(provider.String(), validator.String(), stakingCoin, tenPercent), }, + { + "success: zero fee rate is allowed to provide", + "", + types.NewMsgProvideInsurance(provider.String(), validator.String(), stakingCoin, sdk.ZeroDec()), + }, { "fail: empty provider address", "invalid provider address : empty address string is not allowed", @@ -171,9 +176,14 @@ func (suite *msgTestSuite) TestMsgProvideInsurance() { }, { "fail: empty rate", - "fee rate must not be nil", + "insurance fee rate must not be nil", types.NewMsgProvideInsurance(provider.String(), validator.String(), stakingCoin, sdk.Dec{}), }, + { + "fail: minus rate", + "insurance fee rate must not be negative", + types.NewMsgProvideInsurance(provider.String(), validator.String(), stakingCoin, sdk.ZeroDec().Sub(sdk.OneDec())), + }, } for _, tc := range tcs { @@ -193,7 +203,7 @@ func (suite *msgTestSuite) TestMsgProvideInsurance() { suite.Len(signers, 1) suite.Equal(tc.msg.GetProvider(), signers[0]) } else { - suite.EqualError(err, tc.expectedErr) + suite.ErrorContains(err, tc.expectedErr) } }) } From b4e6835ea2e49dbf11cafe91886118ac551e2f0a Mon Sep 17 00:00:00 2001 From: zsystm Date: Wed, 16 Aug 2023 10:45:38 +0900 Subject: [PATCH 03/14] chore: remove un-used errors and bump cosmos-sdk --- go.mod | 2 +- go.sum | 5 +++ x/liquidstaking/types/errors.go | 58 ++++++++++++++------------------- 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/go.mod b/go.mod index 08c97500..1f908a92 100644 --- a/go.mod +++ b/go.mod @@ -173,7 +173,7 @@ require ( replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 - github.com/cosmos/cosmos-sdk => github.com/b-harvest/cosmos-sdk v0.45.9-2-canto-lsm-sim + github.com/cosmos/cosmos-sdk => github.com/b-harvest/cosmos-sdk v0.45.9-3-canto-lsm-sim github.com/cosmos/ibc-go/v3 v3.2.0 => github.com/b-harvest/ibc-go/v3 v3.2.0-1-canto-lsm-sim github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/tendermint/tendermint => github.com/informalsystems/tendermint v0.34.25 diff --git a/go.sum b/go.sum index 61d29768..a1a5ecac 100644 --- a/go.sum +++ b/go.sum @@ -110,6 +110,8 @@ github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/b-harvest/cosmos-sdk v0.45.9-2-canto-lsm-sim h1:dPbp2D/U5uNX3+VSs06zGMYVjqgVLoFC6BxQ1AgCRsM= github.com/b-harvest/cosmos-sdk v0.45.9-2-canto-lsm-sim/go.mod h1:Z5M4TX7PsHNHlF/1XanI2DIpORQ+Q/st7oaeufEjnvU= +github.com/b-harvest/cosmos-sdk v0.45.9-3-canto-lsm-sim h1:XJNrdOLu6yYXdBJDXU+diaBwE5Rn8MGhfnC0V1LGMag= +github.com/b-harvest/cosmos-sdk v0.45.9-3-canto-lsm-sim/go.mod h1:Z5M4TX7PsHNHlF/1XanI2DIpORQ+Q/st7oaeufEjnvU= github.com/b-harvest/ibc-go/v3 v3.2.0-1-canto-lsm-sim h1:ODXVMtFDD5GX39xMSZEZEFxJYsgkxmv1pDEp/6EVi9M= github.com/b-harvest/ibc-go/v3 v3.2.0-1-canto-lsm-sim/go.mod h1:ZTUeC/y/r1WW7KXE2AUpax/ieECnDX+6hQ3Qwdd65sM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -315,6 +317,7 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -403,6 +406,7 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -827,6 +831,7 @@ github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNG github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= diff --git a/x/liquidstaking/types/errors.go b/x/liquidstaking/types/errors.go index b9c8dcdf..8d319dbe 100644 --- a/x/liquidstaking/types/errors.go +++ b/x/liquidstaking/types/errors.go @@ -5,38 +5,28 @@ import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" var ( ErrNoPairingInsurance = sdkerrors.Register(ModuleName, 30002, "pairing insurance must exist to accept liquid stake request.") ErrInvalidAmount = sdkerrors.Register(ModuleName, 30003, "amount of coin must be multiple of the chunk size") - ErrTombstonedValidator = sdkerrors.Register(ModuleName, 30005, "validator is tombstoned") - ErrInvalidValidatorStatus = sdkerrors.Register(ModuleName, 30006, "invalid validator status") - ErrNotProviderOfInsurance = sdkerrors.Register(ModuleName, 30008, "not provider of insurance") - ErrNotFoundInsurance = sdkerrors.Register(ModuleName, 30009, "insurance not found") - ErrNoPairedChunk = sdkerrors.Register(ModuleName, 30010, "no paired chunk") - ErrNotFoundChunk = sdkerrors.Register(ModuleName, 30011, "chunk not found") - ErrInvalidChunkStatus = sdkerrors.Register(ModuleName, 30012, "invalid chunk status") - ErrInvalidInsuranceStatus = sdkerrors.Register(ModuleName, 30013, "invalid insurance status") - ErrExceedAvailableChunks = sdkerrors.Register(ModuleName, 30014, "exceed available chunks") - ErrInvalidBondDenom = sdkerrors.Register(ModuleName, 30015, "invalid bond denom") - ErrInvalidLiquidBondDenom = sdkerrors.Register(ModuleName, 30016, "invalid liquid bond denom") - ErrNotInWithdrawableStatus = sdkerrors.Register(ModuleName, 30017, "insurance is not in withdrawable status") - ErrUnpairingChunkHavePairedChunk = sdkerrors.Register(ModuleName, 30018, "unpairing chunk cannot have paired chunk") - ErrUnbondingDelegationNotRemoved = sdkerrors.Register(ModuleName, 30019, "unbonding delegation not removed") - ErrNotFoundUnpairingForUnstakingChunkInfo = sdkerrors.Register(ModuleName, 30020, "unstake chunk info not found") - ErrNotFoundDelegation = sdkerrors.Register(ModuleName, 30021, "delegation not found") - ErrNotFoundValidator = sdkerrors.Register(ModuleName, 30022, "validator not found") - ErrInvalidChunkId = sdkerrors.Register(ModuleName, 30023, "invalid chunk id") - ErrInvalidInsuranceId = sdkerrors.Register(ModuleName, 30024, "invalid insurance id") - ErrNotFoundUnpairingForUnstakingChunkInfoChunkId = sdkerrors.Register(ModuleName, 30026, "unpairing for unstake chunk corresponding unpairing for unstaking info must exists") - ErrNotFoundWithdrawInsuranceRequestInsuranceId = sdkerrors.Register(ModuleName, 30027, "insurance corresponding withdraw insurance request must exists") - ErrAlreadyInQueue = sdkerrors.Register(ModuleName, 30030, "liquid ustaking is already in queue") - ErrDiscountRateTooLow = sdkerrors.Register(ModuleName, 30031, "discount rate must be gte than msg.minimum") - ErrInvalidEpochDuration = sdkerrors.Register(ModuleName, 30032, "epoch duration must be same with unbonding time") - ErrInvalidEpochStartTime = sdkerrors.Register(ModuleName, 30033, "epoch start time must be before current time") - ErrInvalidFeeRate = sdkerrors.Register(ModuleName, 30034, "fee rate must not be nil") - ErrNotFoundUnpairingInsurance = sdkerrors.Register(ModuleName, 30035, "unpairing insurance not found") - ErrNotFoundPairedInsurance = sdkerrors.Register(ModuleName, 30036, "paired insurance not found") - ErrMustOneRedelegation = sdkerrors.Register(ModuleName, 30037, "must have one redelegation") - ErrMustOneRedelegationEntry = sdkerrors.Register(ModuleName, 30038, "must have one redelegation entry") - ErrNotFoundRedelegationInfoChunkId = sdkerrors.Register(ModuleName, 30039, "redelegation info corresponding chunk id must exists") - ErrMustHaveNoPairedInsurance = sdkerrors.Register(ModuleName, 30040, "must have no paired insurance") - ErrMustHaveNoUnbondingDelegation = sdkerrors.Register(ModuleName, 30041, "must have no unbonding delegation") - ErrInsCommissionsNotWithdrawable = sdkerrors.Register(ModuleName, 30042, "insurance fee pool is not withdrawable") + ErrTombstonedValidator = sdkerrors.Register(ModuleName, 30004, "validator is tombstoned") + ErrInvalidValidatorStatus = sdkerrors.Register(ModuleName, 30005, "invalid validator status") + ErrNotProviderOfInsurance = sdkerrors.Register(ModuleName, 30006, "not provider of insurance") + ErrNotFoundInsurance = sdkerrors.Register(ModuleName, 30007, "insurance not found") + ErrNoPairedChunk = sdkerrors.Register(ModuleName, 30008, "no paired chunk") + ErrInvalidChunkStatus = sdkerrors.Register(ModuleName, 30009, "invalid chunk status") + ErrInvalidInsuranceStatus = sdkerrors.Register(ModuleName, 30010, "invalid insurance status") + ErrExceedAvailableChunks = sdkerrors.Register(ModuleName, 30011, "exceed available chunks") + ErrInvalidBondDenom = sdkerrors.Register(ModuleName, 30012, "invalid bond denom") + ErrInvalidLiquidBondDenom = sdkerrors.Register(ModuleName, 30013, "invalid liquid bond denom") + ErrNotInWithdrawableStatus = sdkerrors.Register(ModuleName, 30014, "insurance is not in withdrawable status") + ErrInvalidChunkId = sdkerrors.Register(ModuleName, 30015, "invalid chunk id") + ErrInvalidInsuranceId = sdkerrors.Register(ModuleName, 30016, "invalid insurance id") + ErrNotFoundUnpairingForUnstakingChunkInfoChunkId = sdkerrors.Register(ModuleName, 30016, "unpairing for unstake chunk corresponding unpairing for unstaking info must exists") + ErrNotFoundWithdrawInsuranceRequestInsuranceId = sdkerrors.Register(ModuleName, 30018, "insurance corresponding withdraw insurance request must exists") + ErrAlreadyInQueue = sdkerrors.Register(ModuleName, 30019, "liquid ustaking is already in queue") + ErrDiscountRateTooLow = sdkerrors.Register(ModuleName, 30020, "discount rate must be gte than msg.minimum") + ErrInvalidEpochDuration = sdkerrors.Register(ModuleName, 30021, "epoch duration must be same with unbonding time") + ErrInvalidEpochStartTime = sdkerrors.Register(ModuleName, 30022, "epoch start time must be before current time") + ErrNotFoundUnpairingInsurance = sdkerrors.Register(ModuleName, 30023, "unpairing insurance not found") + ErrNotFoundRedelegationInfoChunkId = sdkerrors.Register(ModuleName, 30024, "redelegation info corresponding chunk id must exists") + ErrMustHaveNoPairedInsurance = sdkerrors.Register(ModuleName, 30025, "must have no paired insurance") + ErrMustHaveNoUnbondingDelegation = sdkerrors.Register(ModuleName, 30026, "must have no unbonding delegation") + ErrInsCommissionsNotWithdrawable = sdkerrors.Register(ModuleName, 30027, "insurance fee pool is not withdrawable") ) From 72d66d01cefaa45228d9a01d0797ad034a7d69af Mon Sep 17 00:00:00 2001 From: zsystm Date: Wed, 16 Aug 2023 12:37:02 +0900 Subject: [PATCH 04/14] fix duplicate error code --- x/liquidstaking/types/errors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/liquidstaking/types/errors.go b/x/liquidstaking/types/errors.go index 8d319dbe..0396f7fc 100644 --- a/x/liquidstaking/types/errors.go +++ b/x/liquidstaking/types/errors.go @@ -18,7 +18,7 @@ var ( ErrNotInWithdrawableStatus = sdkerrors.Register(ModuleName, 30014, "insurance is not in withdrawable status") ErrInvalidChunkId = sdkerrors.Register(ModuleName, 30015, "invalid chunk id") ErrInvalidInsuranceId = sdkerrors.Register(ModuleName, 30016, "invalid insurance id") - ErrNotFoundUnpairingForUnstakingChunkInfoChunkId = sdkerrors.Register(ModuleName, 30016, "unpairing for unstake chunk corresponding unpairing for unstaking info must exists") + ErrNotFoundUnpairingForUnstakingChunkInfoChunkId = sdkerrors.Register(ModuleName, 30017, "unpairing for unstake chunk corresponding unpairing for unstaking info must exists") ErrNotFoundWithdrawInsuranceRequestInsuranceId = sdkerrors.Register(ModuleName, 30018, "insurance corresponding withdraw insurance request must exists") ErrAlreadyInQueue = sdkerrors.Register(ModuleName, 30019, "liquid ustaking is already in queue") ErrDiscountRateTooLow = sdkerrors.Register(ModuleName, 30020, "discount rate must be gte than msg.minimum") From a1855b97abc404b99a89b88d9d69cf7a6fdbb59b Mon Sep 17 00:00:00 2001 From: zsystm Date: Wed, 16 Aug 2023 15:53:59 +0900 Subject: [PATCH 05/14] update simop if calculated fee rate is negative, then apply zeroFeeRate --- x/liquidstaking/simulation/operations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x/liquidstaking/simulation/operations.go b/x/liquidstaking/simulation/operations.go index bf62560e..dc7b502d 100644 --- a/x/liquidstaking/simulation/operations.go +++ b/x/liquidstaking/simulation/operations.go @@ -331,6 +331,9 @@ func SimulateMsgProvideInsurance(ak types.AccountKeeper, bk types.BankKeeper, sk spendable = bk.SpendableCoins(ctx, provider) } + if feeRate.IsNegative() { + feeRate = sdk.ZeroDec() + } msg := types.NewMsgProvideInsurance(provider.String(), validator.GetOperator().String(), collaterals[0], feeRate) txCtx := simulation.OperationInput{ R: r, From afc6d6de040df9ec0ef12539dc0eeaf6ef044e46 Mon Sep 17 00:00:00 2001 From: zsystm Date: Thu, 17 Aug 2023 16:43:17 +0900 Subject: [PATCH 06/14] limit minting if it exceeds mainnet total supply --- x/liquidstaking/simulation/operations.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/x/liquidstaking/simulation/operations.go b/x/liquidstaking/simulation/operations.go index dc7b502d..015663f6 100644 --- a/x/liquidstaking/simulation/operations.go +++ b/x/liquidstaking/simulation/operations.go @@ -2,6 +2,7 @@ package simulation import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ethermint "github.com/evmos/ethermint/types" "math/rand" "github.com/Canto-Network/Canto/v7/app/params" @@ -37,6 +38,8 @@ var ( Amount: sdk.NewInt(0), }, } + // Canto mainnet supply is currently 1.05B + MainnetTotalSupply = sdk.TokensFromConsensusPower(1_050_000_000, ethermint.PowerReduction) ) // WeightedOperations returns all the operations from the module with their respective weights @@ -162,6 +165,9 @@ func SimulateMsgLiquidStake(ak types.AccountKeeper, bk types.BankKeeper, sk type ), ) if !spendable.AmountOf(bondDenom).GTE(stakingCoins[0].Amount) { + if totalSupplyAmt.Add(stakingCoins[0].Amount).GT(MainnetTotalSupply) { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgLiquidStake, "total supply is exceeded"), nil, nil + } if err := bk.MintCoins(ctx, types.ModuleName, stakingCoins); err != nil { panic(err) } @@ -322,6 +328,10 @@ func SimulateMsgProvideInsurance(ak types.AccountKeeper, bk types.BankKeeper, sk } if !spendable.AmountOf(bondDenom).GTE(collaterals[0].Amount) { + totalSupplyAmt := bk.GetSupply(ctx, bondDenom).Amount + if totalSupplyAmt.Add(collaterals[0].Amount).GT(MainnetTotalSupply) { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgProvideInsurance, "total supply is exceeded"), nil, nil + } if err := bk.MintCoins(ctx, types.ModuleName, collaterals); err != nil { panic(err) } @@ -457,6 +467,10 @@ func SimulateMsgDepositInsurance(ak types.AccountKeeper, bk types.BankKeeper, sk ) if !spendable.AmountOf(bondDenom).GTE(deposits[0].Amount) { + totalSupplyAmt := bk.GetSupply(ctx, bondDenom).Amount + if totalSupplyAmt.Add(deposits[0].Amount).GT(MainnetTotalSupply) { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgDepositInsurance, "total supply is exceeded"), nil, nil + } if err := bk.MintCoins(ctx, types.ModuleName, deposits); err != nil { panic(err) } From 91e6e5660e91b917017b9c2f5168e4c12eb7a713 Mon Sep 17 00:00:00 2001 From: zsystm Date: Thu, 17 Aug 2023 19:11:04 +0900 Subject: [PATCH 07/14] update: initialize at least one validator in AppStateRandomizedFn --- app/state.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/state.go b/app/state.go index 04aa1b4b..8e7e573a 100644 --- a/app/state.go +++ b/app/state.go @@ -158,7 +158,13 @@ func AppStateRandomizedFn( simappparams.InitiallyBondedValidators, &numInitiallyBonded, r, - func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(300)) }, + func(r *rand.Rand) { + numInitiallyBonded = int64(r.Intn(300)) + // at least 1 bonded validator + if numInitiallyBonded == 0 { + numInitiallyBonded = 1 + } + }, ) if numInitiallyBonded > numAccs { From 022f7582c25fe9bdd885391ed8a6948c82e4e649 Mon Sep 17 00:00:00 2001 From: zsystm Date: Mon, 21 Aug 2023 10:46:53 +0900 Subject: [PATCH 08/14] apply Canto mainnet supply based on mainnet supply, rich account get fund when initialize genesis on simulation testing. each operation which needs token should get fund from rich account. --- go.mod | 2 +- go.sum | 9 ++------ x/liquidstaking/simulation/operations.go | 28 ++++++++++-------------- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 1f908a92..8b2a195e 100644 --- a/go.mod +++ b/go.mod @@ -173,7 +173,7 @@ require ( replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 - github.com/cosmos/cosmos-sdk => github.com/b-harvest/cosmos-sdk v0.45.9-3-canto-lsm-sim + github.com/cosmos/cosmos-sdk => github.com/b-harvest/cosmos-sdk v0.45.9-4-canto-lsm-sim github.com/cosmos/ibc-go/v3 v3.2.0 => github.com/b-harvest/ibc-go/v3 v3.2.0-1-canto-lsm-sim github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/tendermint/tendermint => github.com/informalsystems/tendermint v0.34.25 diff --git a/go.sum b/go.sum index a1a5ecac..2af4e3b9 100644 --- a/go.sum +++ b/go.sum @@ -108,10 +108,8 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/b-harvest/cosmos-sdk v0.45.9-2-canto-lsm-sim h1:dPbp2D/U5uNX3+VSs06zGMYVjqgVLoFC6BxQ1AgCRsM= -github.com/b-harvest/cosmos-sdk v0.45.9-2-canto-lsm-sim/go.mod h1:Z5M4TX7PsHNHlF/1XanI2DIpORQ+Q/st7oaeufEjnvU= -github.com/b-harvest/cosmos-sdk v0.45.9-3-canto-lsm-sim h1:XJNrdOLu6yYXdBJDXU+diaBwE5Rn8MGhfnC0V1LGMag= -github.com/b-harvest/cosmos-sdk v0.45.9-3-canto-lsm-sim/go.mod h1:Z5M4TX7PsHNHlF/1XanI2DIpORQ+Q/st7oaeufEjnvU= +github.com/b-harvest/cosmos-sdk v0.45.9-4-canto-lsm-sim h1:qFttQEGIicTsXzsiPXpZoHwzlr99jCL9F1yVDxS88lY= +github.com/b-harvest/cosmos-sdk v0.45.9-4-canto-lsm-sim/go.mod h1:Z5M4TX7PsHNHlF/1XanI2DIpORQ+Q/st7oaeufEjnvU= github.com/b-harvest/ibc-go/v3 v3.2.0-1-canto-lsm-sim h1:ODXVMtFDD5GX39xMSZEZEFxJYsgkxmv1pDEp/6EVi9M= github.com/b-harvest/ibc-go/v3 v3.2.0-1-canto-lsm-sim/go.mod h1:ZTUeC/y/r1WW7KXE2AUpax/ieECnDX+6hQ3Qwdd65sM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -317,7 +315,6 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -406,7 +403,6 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -831,7 +827,6 @@ github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNG github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= diff --git a/x/liquidstaking/simulation/operations.go b/x/liquidstaking/simulation/operations.go index 015663f6..8bb37905 100644 --- a/x/liquidstaking/simulation/operations.go +++ b/x/liquidstaking/simulation/operations.go @@ -1,6 +1,7 @@ package simulation import ( + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ethermint "github.com/evmos/ethermint/types" "math/rand" @@ -40,6 +41,7 @@ var ( } // Canto mainnet supply is currently 1.05B MainnetTotalSupply = sdk.TokensFromConsensusPower(1_050_000_000, ethermint.PowerReduction) + RichAccount = authtypes.NewModuleAddress("fundAccount") ) // WeightedOperations returns all the operations from the module with their respective weights @@ -165,13 +167,11 @@ func SimulateMsgLiquidStake(ak types.AccountKeeper, bk types.BankKeeper, sk type ), ) if !spendable.AmountOf(bondDenom).GTE(stakingCoins[0].Amount) { - if totalSupplyAmt.Add(stakingCoins[0].Amount).GT(MainnetTotalSupply) { + richAccBalance := bk.GetBalance(ctx, RichAccount, bondDenom).Amount + if richAccBalance.LT(stakingCoins[0].Amount) { return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgLiquidStake, "total supply is exceeded"), nil, nil } - if err := bk.MintCoins(ctx, types.ModuleName, stakingCoins); err != nil { - panic(err) - } - if err := bk.SendCoinsFromModuleToAccount(ctx, types.ModuleName, delegator, stakingCoins); err != nil { + if err := bk.SendCoins(ctx, RichAccount, delegator, stakingCoins); err != nil { panic(err) } spendable = bk.SpendableCoins(ctx, delegator) @@ -328,14 +328,11 @@ func SimulateMsgProvideInsurance(ak types.AccountKeeper, bk types.BankKeeper, sk } if !spendable.AmountOf(bondDenom).GTE(collaterals[0].Amount) { - totalSupplyAmt := bk.GetSupply(ctx, bondDenom).Amount - if totalSupplyAmt.Add(collaterals[0].Amount).GT(MainnetTotalSupply) { + richAccBalance := bk.GetBalance(ctx, RichAccount, bondDenom).Amount + if richAccBalance.LT(collaterals[0].Amount) { return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgProvideInsurance, "total supply is exceeded"), nil, nil } - if err := bk.MintCoins(ctx, types.ModuleName, collaterals); err != nil { - panic(err) - } - if err := bk.SendCoinsFromModuleToAccount(ctx, types.ModuleName, provider, collaterals); err != nil { + if err := bk.SendCoins(ctx, RichAccount, provider, collaterals); err != nil { panic(err) } spendable = bk.SpendableCoins(ctx, provider) @@ -467,14 +464,11 @@ func SimulateMsgDepositInsurance(ak types.AccountKeeper, bk types.BankKeeper, sk ) if !spendable.AmountOf(bondDenom).GTE(deposits[0].Amount) { - totalSupplyAmt := bk.GetSupply(ctx, bondDenom).Amount - if totalSupplyAmt.Add(deposits[0].Amount).GT(MainnetTotalSupply) { + richAccBalance := bk.GetBalance(ctx, RichAccount, bondDenom).Amount + if richAccBalance.LT(deposits[0].Amount) { return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgDepositInsurance, "total supply is exceeded"), nil, nil } - if err := bk.MintCoins(ctx, types.ModuleName, deposits); err != nil { - panic(err) - } - if err := bk.SendCoinsFromModuleToAccount(ctx, types.ModuleName, provider, deposits); err != nil { + if err := bk.SendCoins(ctx, RichAccount, provider, deposits); err != nil { panic(err) } spendable = bk.SpendableCoins(ctx, provider) From 28a62769d64c00f236239d1d1ae5bb147481fe00 Mon Sep 17 00:00:00 2001 From: zsystm Date: Mon, 21 Aug 2023 13:28:38 +0900 Subject: [PATCH 09/14] update CalcNetAmountStateEssentials: return multiple data structures this is for optimizing gas consumption when QueueLiquidUnstake instead of Iterate chunks separately, iterate it once when calc net amount state essentials. --- x/liquidstaking/keeper/invariants.go | 2 +- x/liquidstaking/keeper/invariants_test.go | 2 +- x/liquidstaking/keeper/keeper_test.go | 2 +- x/liquidstaking/keeper/liquidstaking.go | 77 ++++++++----------- x/liquidstaking/keeper/liquidstaking_test.go | 42 +++++----- x/liquidstaking/keeper/net_amount.go | 2 +- .../keeper/net_amount_essentials.go | 23 +++--- .../keeper/net_amount_essentials_test.go | 2 +- x/liquidstaking/types/insurance.go | 4 +- 9 files changed, 72 insertions(+), 84 deletions(-) diff --git a/x/liquidstaking/keeper/invariants.go b/x/liquidstaking/keeper/invariants.go index 289569b1..92bf0202 100644 --- a/x/liquidstaking/keeper/invariants.go +++ b/x/liquidstaking/keeper/invariants.go @@ -43,7 +43,7 @@ func AllInvariants(k Keeper) sdk.Invariant { func NetAmountEssentialsInvariant(k Keeper) sdk.Invariant { return func(ctx sdk.Context) (string, bool) { - nas := k.GetNetAmountStateEssentials(ctx) + nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) // if net amount is positive, it means that there are paired chunks. if nas.LsTokensTotalSupply.IsPositive() && !nas.NetAmount.IsPositive() { return "found positive lsToken supply with non-positive net amount", true diff --git a/x/liquidstaking/keeper/invariants_test.go b/x/liquidstaking/keeper/invariants_test.go index b563789e..6d3f8366 100644 --- a/x/liquidstaking/keeper/invariants_test.go +++ b/x/liquidstaking/keeper/invariants_test.go @@ -33,7 +33,7 @@ func (suite *KeeperTestSuite) TestNetAmountInvariant() { suite.ctx = suite.advanceEpoch(suite.ctx) suite.ctx = suite.advanceHeight(suite.ctx, 1, "module epoch reached") - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) oneChunk, _ := suite.app.LiquidStakingKeeper.GetMinimumRequirements(suite.ctx) suite.True(nase.Equal(types.NetAmountStateEssentials{ MintRate: sdk.MustNewDecFromStr("0.990373683313988266"), diff --git a/x/liquidstaking/keeper/keeper_test.go b/x/liquidstaking/keeper/keeper_test.go index 4df9c865..9da16c00 100644 --- a/x/liquidstaking/keeper/keeper_test.go +++ b/x/liquidstaking/keeper/keeper_test.go @@ -375,7 +375,7 @@ func (suite *KeeperTestSuite) setupLiquidStakeTestingEnv(env testingEnvOptions) // create numPairedChunks delegators delegators, delegatorBalances := suite.AddTestAddrsWithFunding(fundingAccount, env.numPairedChunks, oneChunk.Amount) - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) suite.True(nase.IsZeroState(), "nothing happened yet so it must be zero state") pairedChunks := suite.liquidStakes(suite.ctx, delegators, delegatorBalances) diff --git a/x/liquidstaking/keeper/liquidstaking.go b/x/liquidstaking/keeper/liquidstaking.go index 34588a40..5ba7cf2d 100644 --- a/x/liquidstaking/keeper/liquidstaking.go +++ b/x/liquidstaking/keeper/liquidstaking.go @@ -122,7 +122,7 @@ func (k Keeper) CollectRewardAndFee( // DistributeReward withdraws delegation rewards from all paired chunks // Keeper.CollectRewardAndFee will be called during withdrawing process. func (k Keeper) DistributeReward(ctx sdk.Context) { - nas := k.GetNetAmountStateEssentials(ctx) + nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) k.IterateAllChunks(ctx, func(chunk types.Chunk) bool { if chunk.Status != types.CHUNK_STATUS_PAIRED { return false @@ -598,11 +598,13 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( g = g2 k.fileLogger.Debug("beforeGetNetAmountStateEssentials", "gas", g2, "diff", diff) nas := k.GetNetAmountStateEssentials(ctx) + k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) + nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) g2 = ctx.GasMeter().GasConsumed() diff = g2 - g g = g2 - k.fileLogger.Debug("afterGetNetAmountStateEssentials", "gas", g2, "diff", diff) + k.fileLogger.Debug(fmt.Sprintf("%s:afterGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) if nas.RemainingChunkSlots.LT(chunksToCreate) { err = sdkerrors.Wrapf( types.ErrExceedAvailableChunks, @@ -616,13 +618,13 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( g2 = ctx.GasMeter().GasConsumed() diff = g2 - g g = g2 - k.fileLogger.Debug("beforeGetPairingInsurances", "gas", g2, "diff", diff) + k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetPairingInsurances", msg.Type()), "gas", g2, "diff", diff) pairingInsurances, validatorMap := k.GetPairingInsurances(ctx) g2 = ctx.GasMeter().GasConsumed() diff = g2 - g g = g2 - k.fileLogger.Debug("afterGetPairingInsurances", "gas", g2, "diff", diff) + k.fileLogger.Debug(fmt.Sprintf("%s:afterGetPairingInsurances", msg.Type()), "gas", g2, "diff", diff) numPairingInsurances := sdk.NewIntFromUint64(uint64(len(pairingInsurances))) if chunksToCreate.GT(numPairingInsurances) { err = types.ErrNoPairingInsurance @@ -641,7 +643,7 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( g2 = ctx.GasMeter().GasConsumed() diff = g2 - g g = g2 - k.fileLogger.Debug("beforeEscrowAndMintLsTokens", "gas", g2, "diff", diff) + k.fileLogger.Debug(fmt.Sprintf("%s:beforeEscrowAndMintLsTokens", msg.Type()), "gas", g2, "diff", diff) cheapestIns := pairingInsurances[0] pairingInsurances = pairingInsurances[1:] @@ -687,7 +689,7 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( g2 = ctx.GasMeter().GasConsumed() diff = g2 - g g = g2 - k.fileLogger.Debug("afterEscrowAndMintLsTokens", "gas", g2, "diff", diff) + k.fileLogger.Debug(fmt.Sprintf("%s:afterEscrowAndMintLsTokens", msg.Type()), "gas", g2, "diff", diff) chunks = append(chunks, chunk) chunksToCreate = chunksToCreate.Sub(sdk.OneInt()) } @@ -716,36 +718,22 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) chunksToLiquidUnstake := amount.Amount.Quo(types.ChunkSize).Int64() - chunksWithInsId := make(map[uint64]types.Chunk) - var insurances []types.Insurance - validatorMap := make(map[string]stakingtypes.Validator) - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug("beforeIterateAllChunks", "gas", g2, "diff", diff) - k.IterateAllChunks(ctx, func(chunk types.Chunk) (stop bool) { - if chunk.Status != types.CHUNK_STATUS_PAIRED { - return false - } + nase, pairedChunksWithInsuranceId, pairedInsurances, validatorMap := k.GetNetAmountStateEssentials(ctx) + + // purelyPairedInsurances contains paired insurances which serve chunk which is not in queue for unstaking. + var purelyPairedInsurances []types.Insurance + for _, pairedIns := range pairedInsurances { + chunk := pairedChunksWithInsuranceId[pairedIns.Id] // check whether the chunk is already have unstaking requests in queue. _, found := k.GetUnpairingForUnstakingChunkInfo(ctx, chunk.Id) if found { - return false + delete(pairedChunksWithInsuranceId, pairedIns.Id) + continue } + purelyPairedInsurances = append(purelyPairedInsurances, pairedIns) + } - pairedIns, validator, _ := k.mustValidatePairedChunk(ctx, chunk) - if _, ok := validatorMap[pairedIns.GetValidator().String()]; !ok { - validatorMap[pairedIns.ValidatorAddress] = validator - } - insurances = append(insurances, pairedIns) - chunksWithInsId[pairedIns.Id] = chunk - return false - }) - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug("afterIterateAllChunks", "gas", g2, "diff", diff) - pairedChunks := int64(len(chunksWithInsId)) + pairedChunks := int64(len(pairedChunksWithInsuranceId)) if pairedChunks == 0 { err = types.ErrNoPairedChunk return @@ -760,19 +748,18 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) return } // Sort insurances by descend order - types.SortInsurances(validatorMap, insurances, true) + types.SortInsurances(validatorMap, purelyPairedInsurances, true) - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g + g2 := ctx.GasMeter().GasConsumed() + diff := g2 - g g = g2 - k.fileLogger.Debug("beforeGetNetAmountStateEssentials", "gas", g2, "diff", diff) + k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) // How much ls tokens must be burned - nas := k.GetNetAmountStateEssentials(ctx) g2 = ctx.GasMeter().GasConsumed() diff = g2 - g g = g2 - k.fileLogger.Debug("afterGetNetAmountStateEssentials", "gas", g2, "diff", diff) + k.fileLogger.Debug(fmt.Sprintf("%s:afterGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) liquidBondDenom := k.GetLiquidBondDenom(ctx) for i := int64(0); i < chunksToLiquidUnstake; i++ { g2 = ctx.GasMeter().GasConsumed() @@ -781,8 +768,8 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) k.fileLogger.Debug("beforeQueueLiquidUnstake", "gas", g2, "diff", diff) // Escrow ls tokens from the delegator lsTokenBurnAmount := types.ChunkSize - if nas.LsTokensTotalSupply.IsPositive() { - lsTokenBurnAmount = lsTokenBurnAmount.ToDec().Mul(nas.MintRate).TruncateInt() + if nase.LsTokensTotalSupply.IsPositive() { + lsTokenBurnAmount = lsTokenBurnAmount.ToDec().Mul(nase.MintRate).TruncateInt() } lsTokensToBurn := sdk.NewCoin(liquidBondDenom, lsTokenBurnAmount) if err = k.bankKeeper.SendCoins( @@ -791,8 +778,8 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) return } - mostExpensiveInsurance := insurances[i] - chunkToBeUndelegated := chunksWithInsId[mostExpensiveInsurance.Id] + mostExpensiveInsurance := purelyPairedInsurances[i] + chunkToBeUndelegated := pairedChunksWithInsuranceId[mostExpensiveInsurance.Id] _, found := k.GetUnpairingForUnstakingChunkInfo(ctx, chunkToBeUndelegated.Id) if found { err = sdkerrors.Wrapf( @@ -809,7 +796,7 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) msg.DelegatorAddress, lsTokensToBurn, ) - toBeUnstakedChunks = append(toBeUnstakedChunks, chunksWithInsId[insurances[i].Id]) + toBeUnstakedChunks = append(toBeUnstakedChunks, pairedChunksWithInsuranceId[mostExpensiveInsurance.Id]) infos = append(infos, info) k.SetUnpairingForUnstakingChunkInfo(ctx, info) g2 = ctx.GasMeter().GasConsumed() @@ -1012,12 +999,12 @@ func (k Keeper) DoClaimDiscountedReward(ctx sdk.Context, msg *types.MsgClaimDisc g2 := ctx.GasMeter().GasConsumed() diff := g2 - g g = g2 - k.fileLogger.Debug("beforeGetNetAmountState", "gas", g2, "diff", diff) - nas := k.GetNetAmountStateEssentials(ctx) + k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetNetAmountState", msg.Type()), "gas", g2, "diff", diff) + nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) g2 = ctx.GasMeter().GasConsumed() diff = g2 - g g = g2 - k.fileLogger.Debug("afterGetNetAmountState", "gas", g2, "diff", diff) + k.fileLogger.Debug(fmt.Sprintf("%s:afterGetNetAmountState", msg.Type()), "gas", g2, "diff", diff) // discount rate >= minimum discount rate // if discount rate(e.g. 10%) is lower than minimum discount rate(e.g. 20%), then it is not profitable to claim reward. if nas.DiscountRate.LT(msg.MinimumDiscountRate) { diff --git a/x/liquidstaking/keeper/liquidstaking_test.go b/x/liquidstaking/keeper/liquidstaking_test.go index 3324853d..db2c853f 100644 --- a/x/liquidstaking/keeper/liquidstaking_test.go +++ b/x/liquidstaking/keeper/liquidstaking_test.go @@ -243,7 +243,7 @@ func (suite *KeeperTestSuite) TestLiquidStakeSuccess() { suite.provideInsurances(suite.ctx, providers, valAddrs, balances, sdk.ZeroDec(), nil) delegators, balances := suite.AddTestAddrsWithFunding(fundingAccount, 10, oneChunk.Amount) - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) liquidBondDenom := suite.app.LiquidStakingKeeper.GetLiquidBondDenom(suite.ctx) // First try @@ -272,7 +272,7 @@ func (suite *KeeperTestSuite) TestLiquidStakeSuccess() { } // NetAmountStateEssentials should be updated correctly - afterNas := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + afterNas, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) { suite.True(afterNas.LsTokensTotalSupply.Equal(lsTokenMintAmount), "total ls token supply should be equal to minted amount") suite.True(nase.TotalLiquidTokens.Add(amt1.Amount).Equal(afterNas.TotalLiquidTokens)) @@ -291,7 +291,7 @@ func (suite *KeeperTestSuite) TestLiquidStakeFail() { ) oneChunk, oneInsurance := suite.app.LiquidStakingKeeper.GetMinimumRequirements(suite.ctx) suite.fundAccount(suite.ctx, fundingAccount, oneChunk.Amount.MulRaw(100).Add(oneInsurance.Amount.MulRaw(10))) - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) remainingChunkSlots := nase.RemainingChunkSlots suite.Equal( remainingChunkSlots, sdk.NewInt(10), @@ -380,7 +380,7 @@ func (suite *KeeperTestSuite) TestLiquidStakeWithAdvanceBlocks() { ) _, oneInsurance := suite.app.LiquidStakingKeeper.GetMinimumRequirements(suite.ctx) - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) is := suite.getInsuranceState(suite.ctx) pairedChunksInt := sdk.NewInt(int64(len(env.pairedChunks))) // 1 chunk size * number of paired chunks (=3) tokens are liquidated @@ -414,7 +414,7 @@ func (suite *KeeperTestSuite) TestLiquidStakeWithAdvanceBlocks() { suite.ctx = suite.advanceHeight(suite.ctx, 1, "") beforeNas := nase - nase = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) { suite.Equal( "80999676001295325000.000000000000000000", @@ -427,7 +427,7 @@ func (suite *KeeperTestSuite) TestLiquidStakeWithAdvanceBlocks() { beforeIs := is suite.ctx = suite.advanceEpoch(suite.ctx) suite.ctx = suite.advanceHeight(suite.ctx, 1, "delegation reward are distributed to insurance and reward module") - nase = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) is = suite.getInsuranceState(suite.ctx) { suite.Equal( @@ -469,7 +469,7 @@ func (suite *KeeperTestSuite) TestLiquidUnstakeWithAdvanceBlocks() { oneChunk, oneInsurance := suite.app.LiquidStakingKeeper.GetMinimumRequirements(suite.ctx) pairedChunksInt := sdk.NewInt(int64(len(env.pairedChunks))) mostExpensivePairedChunk := suite.getMostExpensivePairedChunk(env.pairedChunks) - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) is := suite.getInsuranceState(suite.ctx) // 1 chunk size * number of paired chunks (=3) tokens are liquidated currentLiquidatedTokens := types.ChunkSize.Mul(pairedChunksInt) @@ -502,7 +502,7 @@ func (suite *KeeperTestSuite) TestLiquidUnstakeWithAdvanceBlocks() { suite.ctx = suite.advanceHeight(suite.ctx, 1, "") beforeNas := nase - nase = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) { suite.Equal( "80999676001295325000.000000000000000000", @@ -552,7 +552,7 @@ func (suite *KeeperTestSuite) TestLiquidUnstakeWithAdvanceBlocks() { suite.ctx = suite.advanceHeight(suite.ctx, 1, "The actual unstaking started\nThe insurance commission and reward are claimed") beforeNas = nase beforeIs := is - nase = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) is = suite.getInsuranceState(suite.ctx) // Check NetAmounState changed right @@ -613,7 +613,7 @@ func (suite *KeeperTestSuite) TestLiquidUnstakeWithAdvanceBlocks() { suite.ctx = suite.advanceHeight(suite.ctx, 1, "The insurance commission and reward are claimed\nThe unstaking is completed") beforeNas = nase - nase = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) afterBondDenomBalance := suite.app.BankKeeper.GetBalance(suite.ctx, undelegator, env.bondDenom).Amount // Get bondDeno balance of undelegator { @@ -2795,7 +2795,7 @@ func (suite *KeeperTestSuite) TestDynamicFee() { }, ) { - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) fmt.Println(nase) // Check current state before reaching epoch suite.Equal( @@ -2807,10 +2807,10 @@ func (suite *KeeperTestSuite) TestDynamicFee() { nase.FeeRate.String(), ) } - beforeNas := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + beforeNas, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) suite.ctx = suite.advanceEpoch(suite.ctx) suite.ctx = suite.advanceHeight(suite.ctx, 1, "got rewards and dynamic fee is charged") - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) suite.True( nase.RewardModuleAccBalance.GT(beforeNas.RewardModuleAccBalance), "reward module account's balance increased", @@ -2859,7 +2859,7 @@ func (suite *KeeperTestSuite) TestCalcDiscountRate() { cachedCtx = suite.advanceHeight(cachedCtx, tc.numRewardEpochs-1, fmt.Sprintf("let's pass %d reward epoch", tc.numRewardEpochs)) cachedCtx = suite.advanceEpoch(cachedCtx) // reward is accumulated to reward pool cachedCtx = suite.advanceHeight(cachedCtx, 1, "liquid staking endblocker is triggered") - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx) suite.Equal(tc.expectedDiscountRate.String(), nase.DiscountRate.String()) }) } @@ -3006,11 +3006,9 @@ func (suite *KeeperTestSuite) TestDoClaimDiscountedReward() { cachedCtx = suite.advanceEpoch(cachedCtx) // reward is accumulated to reward pool cachedCtx = suite.advanceHeight(cachedCtx, 1, "liquid staking endblocker is triggered") requester := tc.msg.GetRequestser() - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx) suite.Equal(tc.expected.discountRate, nase.DiscountRate.String()) - discountedMintRate := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx).MintRate.Mul( - sdk.OneDec().Sub(nase.DiscountRate), - ) + discountedMintRate := nase.MintRate.Mul(sdk.OneDec().Sub(nase.DiscountRate)) claimableAmt := suite.app.BankKeeper.GetBalance(cachedCtx, types.RewardPool, suite.denom) lsTokenToGetAll := claimableAmt.Amount.ToDec().Mul(discountedMintRate).Ceil().TruncateInt() claimAmt := tc.msg.Amount.Amount.ToDec().Quo(discountedMintRate).TruncateInt() @@ -3020,14 +3018,16 @@ func (suite *KeeperTestSuite) TestDoClaimDiscountedReward() { suite.Equal(tc.expected.beforeTokenBal, suite.app.BankKeeper.GetBalance(cachedCtx, requester, suite.denom).Amount.String()) beforeLsTokenBal := suite.app.BankKeeper.GetBalance(cachedCtx, requester, liquidBondDenom).Amount suite.Equal(tc.expected.beforeLsTokenBal, beforeLsTokenBal.String()) - beforeMintRate := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx).MintRate + nase, _, _, _ = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx) + beforeMintRate := nase.MintRate suite.Equal(tc.expected.beforeMintRate, beforeMintRate.String()) _, _, err := suite.app.LiquidStakingKeeper.DoClaimDiscountedReward(cachedCtx, tc.msg) suite.NoError(err) suite.Equal(tc.afterTokenBal, suite.app.BankKeeper.GetBalance(cachedCtx, requester, suite.denom).Amount.String()) afterLsTokenBal := suite.app.BankKeeper.GetBalance(cachedCtx, requester, liquidBondDenom).Amount suite.Equal(tc.expected.afterLsTokenBal, afterLsTokenBal.String()) - afterMintRate := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx).MintRate + nase, _, _, _ = suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(cachedCtx) + afterMintRate := nase.MintRate suite.Equal(tc.expected.afterMintRate, afterMintRate.String()) suite.Equal(tc.expected.increasedMintRate, afterMintRate.Sub(beforeMintRate).String()) suite.Equal(tc.expected.decreasedLsTokenBal, beforeLsTokenBal.Sub(afterLsTokenBal).String()) @@ -3131,7 +3131,7 @@ func (suite *KeeperTestSuite) TestChunkPositiveBalanceBeforeEpoch() { suite.ctx = suite.advanceHeight(suite.ctx, 1, "liquid staking endblocker is triggered") originReardModuleAccBalance, _ := sdk.NewIntFromString("161999352002591325000") - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) { additionalCommissions := coin.Amount.ToDec().Mul(TenPercentFeeRate).TruncateInt() suite.Equal( diff --git a/x/liquidstaking/keeper/net_amount.go b/x/liquidstaking/keeper/net_amount.go index f9103875..df7980ad 100644 --- a/x/liquidstaking/keeper/net_amount.go +++ b/x/liquidstaking/keeper/net_amount.go @@ -7,7 +7,7 @@ import ( ) func (k Keeper) GetNetAmountState(ctx sdk.Context) types.NetAmountState { - nase := k.GetNetAmountStateEssentials(ctx) + nase, _, _, _ := k.GetNetAmountStateEssentials(ctx) nas := &types.NetAmountState{} deepcopier.Copy(&nase).To(nas) diff --git a/x/liquidstaking/keeper/net_amount_essentials.go b/x/liquidstaking/keeper/net_amount_essentials.go index a8ced96d..92e7f6c2 100644 --- a/x/liquidstaking/keeper/net_amount_essentials.go +++ b/x/liquidstaking/keeper/net_amount_essentials.go @@ -7,7 +7,10 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) (nase types.NetAmountStateEssentials) { +func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) ( + nase types.NetAmountStateEssentials, pairedChunkWithInsuranceId map[uint64]types.Chunk, + pairedInsurances []types.Insurance, validatorMap map[string]stakingtypes.Validator, +) { liquidBondDenom := k.GetLiquidBondDenom(ctx) bondDenom := k.stakingKeeper.BondDenom(ctx) totalDelShares := sdk.ZeroDec() @@ -18,29 +21,31 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) (nase types.NetAmou totalUnbondingChunksBalance := sdk.ZeroInt() numPairedChunks := sdk.ZeroInt() + pairedChunkWithInsuranceId = make(map[uint64]types.Chunk) // To reduce gas consumption, store validator info in map - insValMap := make(map[string]stakingtypes.Validator) + validatorMap = make(map[string]stakingtypes.Validator) pairedCnt, unbondingCnt, restCnt := 0, 0, 0 k.IterateAllChunks(ctx, func(chunk types.Chunk) (stop bool) { balance := k.bankKeeper.GetBalance(ctx, chunk.DerivedAddress(), k.stakingKeeper.BondDenom(ctx)) totalChunksBalance = totalChunksBalance.Add(balance.Amount) - g := ctx.GasMeter().GasConsumed() switch chunk.Status { case types.CHUNK_STATUS_PAIRED: pairedCnt++ numPairedChunks = numPairedChunks.Add(sdk.OneInt()) pairedIns := k.mustGetInsurance(ctx, chunk.PairedInsuranceId) + pairedChunkWithInsuranceId[chunk.PairedInsuranceId] = chunk + pairedInsurances = append(pairedInsurances, pairedIns) valAddr := pairedIns.GetValidator() // Use map to reduce gas consumption - if _, ok := insValMap[valAddr.String()]; !ok { + if _, ok := validatorMap[valAddr.String()]; !ok { validator, found := k.stakingKeeper.GetValidator(ctx, pairedIns.GetValidator()) if !found { panic(fmt.Sprintf("validator of paired ins %s not found(insuranceId: %d)", pairedIns.GetValidator(), pairedIns.Id)) } - insValMap[valAddr.String()] = validator + validatorMap[valAddr.String()] = validator } - validator := insValMap[valAddr.String()] + validator := validatorMap[valAddr.String()] // Get delegation of chunk del, found := k.stakingKeeper.GetDelegation(ctx, chunk.DerivedAddress(), validator.GetOperator()) @@ -65,8 +70,6 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) (nase types.NetAmou remainingReward := delReward.Sub(insuranceCommission) totalRemainingRewardsBeforeModuleFee = totalRemainingRewardsBeforeModuleFee.Add(remainingReward) - diff := ctx.GasMeter().GasConsumed() - g - k.fileLogger.Debug("unit paired chunk gas consumption", "gas", diff) default: checked := false k.stakingKeeper.IterateDelegatorUnbondingDelegations(ctx, chunk.DerivedAddress(), func(ubd stakingtypes.UnbondingDelegation) (stop bool) { @@ -77,8 +80,6 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) (nase types.NetAmou tokenValue := k.calcTokenValueWithInsuranceCoverage(ctx, entry.Balance, unpairingIns) totalUnbondingChunksBalance = totalUnbondingChunksBalance.Add(tokenValue) } - diff := ctx.GasMeter().GasConsumed() - g - k.fileLogger.Debug("unit unbonding chunk gas consumption", "gas", diff) return false }) if !checked { @@ -88,7 +89,6 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) (nase types.NetAmou return false }) - k.fileLogger.Debug("GetNetAmountEssentials", "paired chunks:", pairedCnt, "unbonding chunks", unbondingCnt, "rest chunks", restCnt) rewardPoolBalance := k.bankKeeper.GetBalance(ctx, types.RewardPool, bondDenom).Amount netAmountBeforeModuleFee := rewardPoolBalance.Add(totalChunksBalance). @@ -117,6 +117,7 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) (nase types.NetAmou nase.NetAmount = nase.CalcNetAmount() nase.MintRate = nase.CalcMintRate() nase.DiscountRate = nase.CalcDiscountRate(params.MaximumDiscountRate) + return } diff --git a/x/liquidstaking/keeper/net_amount_essentials_test.go b/x/liquidstaking/keeper/net_amount_essentials_test.go index cd85d48d..02c59c67 100644 --- a/x/liquidstaking/keeper/net_amount_essentials_test.go +++ b/x/liquidstaking/keeper/net_amount_essentials_test.go @@ -21,7 +21,7 @@ func (suite *KeeperTestSuite) TestGetNetAmountState_TotalRemainingRewards() { }) suite.ctx = suite.advanceHeight(suite.ctx, 100, "delegation rewards are accumulated") - nase := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) + nase, _, _, _ := suite.app.LiquidStakingKeeper.GetNetAmountStateEssentials(suite.ctx) cachedCtx, _ := suite.ctx.CacheContext() suite.app.DistrKeeper.WithdrawDelegationRewards(cachedCtx, env.pairedChunks[0].DerivedAddress(), env.insurances[0].GetValidator()) diff --git a/x/liquidstaking/types/insurance.go b/x/liquidstaking/types/insurance.go index 2f0f0977..d4a6bb52 100644 --- a/x/liquidstaking/types/insurance.go +++ b/x/liquidstaking/types/insurance.go @@ -55,8 +55,8 @@ func SortInsurances(validatorMap map[string]stakingtypes.Validator, insurances [ iInsurance := insurances[i] jInsurance := insurances[j] - iValidator := validatorMap[iInsurance.ValidatorAddress] - jValidator := validatorMap[jInsurance.ValidatorAddress] + iValidator := validatorMap[iInsurance.GetValidator().String()] + jValidator := validatorMap[jInsurance.GetValidator().String()] iFee := iValidator.Commission.Rate.Add(iInsurance.FeeRate) jFee := jValidator.Commission.Rate.Add(jInsurance.FeeRate) From 6ec0f107a752a83d4183256d2bb74807c191324c Mon Sep 17 00:00:00 2001 From: zsystm Date: Mon, 21 Aug 2023 15:24:19 +0900 Subject: [PATCH 10/14] refund gas used by cachedCtx --- x/liquidstaking/keeper/liquidstaking.go | 2 -- x/liquidstaking/keeper/net_amount_essentials.go | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/x/liquidstaking/keeper/liquidstaking.go b/x/liquidstaking/keeper/liquidstaking.go index 5ba7cf2d..51403ed7 100644 --- a/x/liquidstaking/keeper/liquidstaking.go +++ b/x/liquidstaking/keeper/liquidstaking.go @@ -596,8 +596,6 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( g2 := ctx.GasMeter().GasConsumed() diff := g2 - g g = g2 - k.fileLogger.Debug("beforeGetNetAmountStateEssentials", "gas", g2, "diff", diff) - nas := k.GetNetAmountStateEssentials(ctx) k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) diff --git a/x/liquidstaking/keeper/net_amount_essentials.go b/x/liquidstaking/keeper/net_amount_essentials.go index 92e7f6c2..88565079 100644 --- a/x/liquidstaking/keeper/net_amount_essentials.go +++ b/x/liquidstaking/keeper/net_amount_essentials.go @@ -59,9 +59,15 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) ( tokenValue = k.calcTokenValueWithInsuranceCoverage(ctx, tokenValue, pairedIns) totalLiquidTokens = totalLiquidTokens.Add(tokenValue) + beforeCachedCtxConsumed := ctx.GasMeter().GasConsumed() cachedCtx, _ := ctx.CacheContext() endingPeriod := k.distributionKeeper.IncrementValidatorPeriod(cachedCtx, validator) delRewards := k.distributionKeeper.CalculateDelegationRewards(cachedCtx, validator, del, endingPeriod) + afterCachedCtxConsumed := cachedCtx.GasMeter().GasConsumed() + cachedCtx.GasMeter().RefundGas( + afterCachedCtxConsumed-beforeCachedCtxConsumed, + "cachedCtx does not write state", + ) // chunk's remaining reward is calculated by // 1. rest = del_reward - insurance_commission // 2. remaining = rest x (1 - module_fee_rate) From 95bec0ab7105e0b200d57031223ba841566c992f Mon Sep 17 00:00:00 2001 From: zsystm Date: Mon, 21 Aug 2023 16:05:49 +0900 Subject: [PATCH 11/14] remove logger and print lines for debugging --- app/state.go | 1 - x/liquidstaking/keeper/insurance.go | 3 - x/liquidstaking/keeper/keeper.go | 14 --- x/liquidstaking/keeper/liquidstaking.go | 90 ------------------- .../keeper/net_amount_essentials.go | 4 - 5 files changed, 112 deletions(-) diff --git a/app/state.go b/app/state.go index 8e7e573a..5c87d773 100644 --- a/app/state.go +++ b/app/state.go @@ -170,7 +170,6 @@ func AppStateRandomizedFn( if numInitiallyBonded > numAccs { numInitiallyBonded = numAccs } - fmt.Printf( `Selected randomly generated parameters for simulated genesis: { diff --git a/x/liquidstaking/keeper/insurance.go b/x/liquidstaking/keeper/insurance.go index a7d742e9..ee65680d 100644 --- a/x/liquidstaking/keeper/insurance.go +++ b/x/liquidstaking/keeper/insurance.go @@ -43,7 +43,6 @@ func (k Keeper) GetPairingInsurances(ctx sdk.Context) ( validatorMap map[string]stakingtypes.Validator, ) { validatorMap = make(map[string]stakingtypes.Validator) - iterCnt := 0 k.IterateAllInsurances(ctx, func(ins types.Insurance) bool { if ins.Status != types.INSURANCE_STATUS_PAIRING { return false @@ -59,10 +58,8 @@ func (k Keeper) GetPairingInsurances(ctx sdk.Context) ( validatorMap[ins.ValidatorAddress] = validator } pairingInsurances = append(pairingInsurances, ins) - iterCnt++ return false }) - k.fileLogger.Debug("GetPairingInsurances", "pairing insurances", iterCnt) return } diff --git a/x/liquidstaking/keeper/keeper.go b/x/liquidstaking/keeper/keeper.go index f36418e3..7ac494dd 100644 --- a/x/liquidstaking/keeper/keeper.go +++ b/x/liquidstaking/keeper/keeper.go @@ -1,14 +1,9 @@ package keeper import ( - "fmt" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - "os" - "path/filepath" - "time" - "github.com/tendermint/tendermint/libs/log" "github.com/Canto-Network/Canto/v7/x/liquidstaking/types" @@ -26,8 +21,6 @@ type Keeper struct { stakingKeeper types.StakingKeeper slashingKeeper types.SlashingKeeper evidenceKeeper types.EvidenceKeeper - - fileLogger log.Logger } // NewKeeper creates a new mint Keeper instance @@ -46,11 +39,6 @@ func NewKeeper( if !subspace.HasKeyTable() { subspace = subspace.WithKeyTable(types.ParamKeyTable()) } - file, err := os.OpenFile(filepath.Join(os.Getenv("HOME"), "logs", fmt.Sprintf("liquidstaking.log-%s", time.Now().Format(time.RFC3339))), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - panic(err) - } - fileLogger := log.NewTMLogger(log.NewSyncWriter(file)).With("module", "x/liquidstaking") return Keeper{ storeKey: storeKey, cdc: cdc, @@ -61,8 +49,6 @@ func NewKeeper( stakingKeeper: stakingKeeper, slashingKeeper: slashingKeeper, evidenceKeeper: evidenceKeeper, - - fileLogger: fileLogger, } } diff --git a/x/liquidstaking/keeper/liquidstaking.go b/x/liquidstaking/keeper/liquidstaking.go index 51403ed7..472276d1 100644 --- a/x/liquidstaking/keeper/liquidstaking.go +++ b/x/liquidstaking/keeper/liquidstaking.go @@ -579,8 +579,6 @@ func (k Keeper) RePairRankedInsurances( func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( chunks []types.Chunk, newShares sdk.Dec, lsTokenMintAmount sdk.Int, err error, ) { - g := ctx.GasMeter().GasConsumed() - k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) delAddr := msg.GetDelegator() amount := msg.Amount @@ -593,16 +591,8 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( } chunksToCreate := amount.Amount.Quo(types.ChunkSize) - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:afterGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) if nas.RemainingChunkSlots.LT(chunksToCreate) { err = sdkerrors.Wrapf( types.ErrExceedAvailableChunks, @@ -613,16 +603,8 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( return } - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetPairingInsurances", msg.Type()), "gas", g2, "diff", diff) pairingInsurances, validatorMap := k.GetPairingInsurances(ctx) - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:afterGetPairingInsurances", msg.Type()), "gas", g2, "diff", diff) numPairingInsurances := sdk.NewIntFromUint64(uint64(len(pairingInsurances))) if chunksToCreate.GT(numPairingInsurances) { err = types.ErrNoPairingInsurance @@ -638,10 +620,6 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( if chunksToCreate.IsZero() { break } - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:beforeEscrowAndMintLsTokens", msg.Type()), "gas", g2, "diff", diff) cheapestIns := pairingInsurances[0] pairingInsurances = pairingInsurances[1:] @@ -684,14 +662,9 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( if err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, delAddr, sdk.NewCoins(mintedCoin)); err != nil { return } - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:afterEscrowAndMintLsTokens", msg.Type()), "gas", g2, "diff", diff) chunks = append(chunks, chunk) chunksToCreate = chunksToCreate.Sub(sdk.OneInt()) } - k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g) return } @@ -702,8 +675,6 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) infos []types.UnpairingForUnstakingChunkInfo, err error, ) { - g := ctx.GasMeter().GasConsumed() - k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", ctx.GasMeter().GasConsumed()) delAddr := msg.GetDelegator() amount := msg.Amount @@ -748,22 +719,10 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) // Sort insurances by descend order types.SortInsurances(validatorMap, purelyPairedInsurances, true) - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) // How much ls tokens must be burned - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:afterGetNetAmountStateEssentials", msg.Type()), "gas", g2, "diff", diff) liquidBondDenom := k.GetLiquidBondDenom(ctx) for i := int64(0); i < chunksToLiquidUnstake; i++ { - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug("beforeQueueLiquidUnstake", "gas", g2, "diff", diff) // Escrow ls tokens from the delegator lsTokenBurnAmount := types.ChunkSize if nase.LsTokensTotalSupply.IsPositive() { @@ -797,18 +756,11 @@ func (k Keeper) QueueLiquidUnstake(ctx sdk.Context, msg *types.MsgLiquidUnstake) toBeUnstakedChunks = append(toBeUnstakedChunks, pairedChunksWithInsuranceId[mostExpensiveInsurance.Id]) infos = append(infos, info) k.SetUnpairingForUnstakingChunkInfo(ctx, info) - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug("afterQueueLiquidUnstake", "gas", g2, "diff", diff) } - k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g) return } func (k Keeper) DoProvideInsurance(ctx sdk.Context, msg *types.MsgProvideInsurance) (ins types.Insurance, err error) { - g := ctx.GasMeter().GasConsumed() - k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) providerAddr := msg.GetProvider() valAddr := msg.GetValidator() feeRate := msg.FeeRate @@ -849,16 +801,10 @@ func (k Keeper) DoProvideInsurance(ctx sdk.Context, msg *types.MsgProvideInsuran } k.SetInsurance(ctx, ins) - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } func (k Keeper) DoCancelProvideInsurance(ctx sdk.Context, msg *types.MsgCancelProvideInsurance) (ins types.Insurance, err error) { - g := ctx.GasMeter().GasConsumed() - k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) providerAddr := msg.GetProvider() insId := msg.Id @@ -884,10 +830,6 @@ func (k Keeper) DoCancelProvideInsurance(ctx sdk.Context, msg *types.MsgCancelPr return ins, err } k.DeleteInsurance(ctx, insId) - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } @@ -896,8 +838,6 @@ func (k Keeper) DoCancelProvideInsurance(ctx sdk.Context, msg *types.MsgCancelPr func (k Keeper) DoWithdrawInsurance(ctx sdk.Context, msg *types.MsgWithdrawInsurance) ( ins types.Insurance, req types.WithdrawInsuranceRequest, err error, ) { - g := ctx.GasMeter().GasConsumed() - k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) if ins, err = k.validateInsurance(ctx, msg.Id, msg.GetProvider(), types.INSURANCE_STATUS_UNSPECIFIED); err != nil { return } @@ -914,10 +854,6 @@ func (k Keeper) DoWithdrawInsurance(ctx sdk.Context, msg *types.MsgWithdrawInsur default: err = sdkerrors.Wrapf(types.ErrNotInWithdrawableStatus, "ins status: %s", ins.Status) } - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } @@ -926,8 +862,6 @@ func (k Keeper) DoWithdrawInsuranceCommission( ctx sdk.Context, msg *types.MsgWithdrawInsuranceCommission, ) (feePoolBals sdk.Coins, err error) { - g := ctx.GasMeter().GasConsumed() - k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) providerAddr := msg.GetProvider() insId := msg.Id @@ -948,17 +882,11 @@ func (k Keeper) DoWithdrawInsuranceCommission( if insBals.IsZero() && feePoolBals.IsZero() { k.DeleteInsurance(ctx, insId) } - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } // DoDepositInsurance deposits more coin to insurance. func (k Keeper) DoDepositInsurance(ctx sdk.Context, msg *types.MsgDepositInsurance) (err error) { - g := ctx.GasMeter().GasConsumed() - k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) providerAddr := msg.GetProvider() insuranceId := msg.Id amount := msg.Amount @@ -975,10 +903,6 @@ func (k Keeper) DoDepositInsurance(ctx sdk.Context, msg *types.MsgDepositInsuran return } - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } @@ -988,21 +912,11 @@ func (k Keeper) DoClaimDiscountedReward(ctx sdk.Context, msg *types.MsgClaimDisc discountedMintRate sdk.Dec, err error, ) { - g := ctx.GasMeter().GasConsumed() - k.fileLogger.Debug(fmt.Sprintf("start-%s", msg.Type()), "gas", g) if err = k.ShouldBeLiquidBondDenom(ctx, msg.Amount.Denom); err != nil { return } - g2 := ctx.GasMeter().GasConsumed() - diff := g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:beforeGetNetAmountState", msg.Type()), "gas", g2, "diff", diff) nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("%s:afterGetNetAmountState", msg.Type()), "gas", g2, "diff", diff) // discount rate >= minimum discount rate // if discount rate(e.g. 10%) is lower than minimum discount rate(e.g. 20%), then it is not profitable to claim reward. if nas.DiscountRate.LT(msg.MinimumDiscountRate) { @@ -1036,10 +950,6 @@ func (k Keeper) DoClaimDiscountedReward(ctx sdk.Context, msg *types.MsgClaimDisc return } - g2 = ctx.GasMeter().GasConsumed() - diff = g2 - g - g = g2 - k.fileLogger.Debug(fmt.Sprintf("end-%s", msg.Type()), "gas", g2, "diff", diff) return } diff --git a/x/liquidstaking/keeper/net_amount_essentials.go b/x/liquidstaking/keeper/net_amount_essentials.go index 88565079..4c4c43ed 100644 --- a/x/liquidstaking/keeper/net_amount_essentials.go +++ b/x/liquidstaking/keeper/net_amount_essentials.go @@ -24,14 +24,12 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) ( pairedChunkWithInsuranceId = make(map[uint64]types.Chunk) // To reduce gas consumption, store validator info in map validatorMap = make(map[string]stakingtypes.Validator) - pairedCnt, unbondingCnt, restCnt := 0, 0, 0 k.IterateAllChunks(ctx, func(chunk types.Chunk) (stop bool) { balance := k.bankKeeper.GetBalance(ctx, chunk.DerivedAddress(), k.stakingKeeper.BondDenom(ctx)) totalChunksBalance = totalChunksBalance.Add(balance.Amount) switch chunk.Status { case types.CHUNK_STATUS_PAIRED: - pairedCnt++ numPairedChunks = numPairedChunks.Add(sdk.OneInt()) pairedIns := k.mustGetInsurance(ctx, chunk.PairedInsuranceId) pairedChunkWithInsuranceId[chunk.PairedInsuranceId] = chunk @@ -79,7 +77,6 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) ( default: checked := false k.stakingKeeper.IterateDelegatorUnbondingDelegations(ctx, chunk.DerivedAddress(), func(ubd stakingtypes.UnbondingDelegation) (stop bool) { - unbondingCnt++ checked = true for _, entry := range ubd.Entries { unpairingIns := k.mustGetInsurance(ctx, chunk.UnpairingInsuranceId) @@ -89,7 +86,6 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) ( return false }) if !checked { - restCnt++ } } From e7e41476f6e0fd72526f58b88c64b81b247ae57f Mon Sep 17 00:00:00 2001 From: zsystm Date: Mon, 21 Aug 2023 16:49:19 +0900 Subject: [PATCH 12/14] remove un-necessary lines --- x/liquidstaking/keeper/net_amount_essentials.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x/liquidstaking/keeper/net_amount_essentials.go b/x/liquidstaking/keeper/net_amount_essentials.go index 4c4c43ed..76663f31 100644 --- a/x/liquidstaking/keeper/net_amount_essentials.go +++ b/x/liquidstaking/keeper/net_amount_essentials.go @@ -75,9 +75,7 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) ( totalRemainingRewardsBeforeModuleFee = totalRemainingRewardsBeforeModuleFee.Add(remainingReward) default: - checked := false k.stakingKeeper.IterateDelegatorUnbondingDelegations(ctx, chunk.DerivedAddress(), func(ubd stakingtypes.UnbondingDelegation) (stop bool) { - checked = true for _, entry := range ubd.Entries { unpairingIns := k.mustGetInsurance(ctx, chunk.UnpairingInsuranceId) tokenValue := k.calcTokenValueWithInsuranceCoverage(ctx, entry.Balance, unpairingIns) @@ -85,8 +83,6 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) ( } return false }) - if !checked { - } } return false From 6871042c6d7f58cb433b28bc715cbb7bf49f2f66 Mon Sep 17 00:00:00 2001 From: zsystm Date: Mon, 21 Aug 2023 16:51:41 +0900 Subject: [PATCH 13/14] chore: change variable name --- x/liquidstaking/keeper/liquidstaking.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/x/liquidstaking/keeper/liquidstaking.go b/x/liquidstaking/keeper/liquidstaking.go index 472276d1..c695ad1a 100644 --- a/x/liquidstaking/keeper/liquidstaking.go +++ b/x/liquidstaking/keeper/liquidstaking.go @@ -122,7 +122,7 @@ func (k Keeper) CollectRewardAndFee( // DistributeReward withdraws delegation rewards from all paired chunks // Keeper.CollectRewardAndFee will be called during withdrawing process. func (k Keeper) DistributeReward(ctx sdk.Context) { - nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) + nase, _, _, _ := k.GetNetAmountStateEssentials(ctx) k.IterateAllChunks(ctx, func(chunk types.Chunk) bool { if chunk.Status != types.CHUNK_STATUS_PAIRED { return false @@ -133,7 +133,7 @@ func (k Keeper) DistributeReward(ctx sdk.Context) { panic(err) } - k.CollectRewardAndFee(ctx, nas.FeeRate, chunk, pairedIns) + k.CollectRewardAndFee(ctx, nase.FeeRate, chunk, pairedIns) return false }) } @@ -591,14 +591,14 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( } chunksToCreate := amount.Amount.Quo(types.ChunkSize) - nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) + nase, _, _, _ := k.GetNetAmountStateEssentials(ctx) - if nas.RemainingChunkSlots.LT(chunksToCreate) { + if nase.RemainingChunkSlots.LT(chunksToCreate) { err = sdkerrors.Wrapf( types.ErrExceedAvailableChunks, "requested chunks to create: %d, available chunks: %s", chunksToCreate, - nas.RemainingChunkSlots.String(), + nase.RemainingChunkSlots.String(), ) return } @@ -647,8 +647,8 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) ( // Mint the liquid staking token lsTokenMintAmount = types.ChunkSize - if nas.LsTokensTotalSupply.IsPositive() { - lsTokenMintAmount = nas.MintRate.MulTruncate(types.ChunkSize.ToDec()).TruncateInt() + if nase.LsTokensTotalSupply.IsPositive() { + lsTokenMintAmount = nase.MintRate.MulTruncate(types.ChunkSize.ToDec()).TruncateInt() } if !lsTokenMintAmount.IsPositive() { err = sdkerrors.Wrapf(types.ErrInvalidAmount, "amount must be greater than or equal to %s", amount.String()) @@ -916,14 +916,14 @@ func (k Keeper) DoClaimDiscountedReward(ctx sdk.Context, msg *types.MsgClaimDisc return } - nas, _, _, _ := k.GetNetAmountStateEssentials(ctx) + nase, _, _, _ := k.GetNetAmountStateEssentials(ctx) // discount rate >= minimum discount rate // if discount rate(e.g. 10%) is lower than minimum discount rate(e.g. 20%), then it is not profitable to claim reward. - if nas.DiscountRate.LT(msg.MinimumDiscountRate) { - err = sdkerrors.Wrapf(types.ErrDiscountRateTooLow, "current discount rate: %s", nas.DiscountRate) + if nase.DiscountRate.LT(msg.MinimumDiscountRate) { + err = sdkerrors.Wrapf(types.ErrDiscountRateTooLow, "current discount rate: %s", nase.DiscountRate) return } - discountedMintRate = nas.MintRate.Mul(sdk.OneDec().Sub(nas.DiscountRate)) + discountedMintRate = nase.MintRate.Mul(sdk.OneDec().Sub(nase.DiscountRate)) var claimableCoin sdk.Coin var burnAmt sdk.Coin From 8b66c5c4ec114e8d6dd189dda6cc4fff39efa6b9 Mon Sep 17 00:00:00 2001 From: zsystm Date: Tue, 22 Aug 2023 08:38:34 +0900 Subject: [PATCH 14/14] reduce computation GetValidator().String is a redundant computation. We can just use ValidatorAddress field. --- x/liquidstaking/keeper/liquidstaking.go | 12 ++++++------ x/liquidstaking/keeper/liquidstaking_test.go | 2 +- x/liquidstaking/keeper/net_amount_essentials.go | 7 +++---- x/liquidstaking/types/insurance.go | 4 ++-- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/x/liquidstaking/keeper/liquidstaking.go b/x/liquidstaking/keeper/liquidstaking.go index c695ad1a..02a496ad 100644 --- a/x/liquidstaking/keeper/liquidstaking.go +++ b/x/liquidstaking/keeper/liquidstaking.go @@ -341,7 +341,7 @@ func (k Keeper) RankInsurances(ctx sdk.Context) ( ins.Status != types.INSURANCE_STATUS_PAIRING { return false } - if _, ok := candidatesValidatorMap[ins.GetValidator().String()]; !ok { + if _, ok := candidatesValidatorMap[ins.ValidatorAddress]; !ok { // Only insurance which directs valid validator can be ranked in validator, found := k.stakingKeeper.GetValidator(ctx, ins.GetValidator()) if !found { @@ -411,7 +411,7 @@ func (k Keeper) RePairRankedInsurances( continue } // Happy case. Same validator so we can skip re-delegation - if newRankInIns.GetValidator().Equals(outIns.GetValidator()) { + if newRankInIns.ValidatorAddress == outIns.ValidatorAddress { // get chunk by outIns.ChunkId chunk := k.mustGetChunk(ctx, outIns.ChunkId) k.rePairChunkAndInsurance(ctx, chunk, newRankInIns, outIns) @@ -522,8 +522,8 @@ func (k Keeper) RePairRankedInsurances( types.EventTypeBeginRedelegate, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), sdk.NewAttribute(types.AttributeKeyChunkId, fmt.Sprintf("%d", chunk.Id)), - sdk.NewAttribute(types.AttributeKeySrcValidator, outIns.GetValidator().String()), - sdk.NewAttribute(types.AttributeKeyDstValidator, newIns.GetValidator().String()), + sdk.NewAttribute(types.AttributeKeySrcValidator, outIns.ValidatorAddress), + sdk.NewAttribute(types.AttributeKeyDstValidator, newIns.ValidatorAddress), sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.Format(time.RFC3339)), ), ) @@ -566,7 +566,7 @@ func (k Keeper) RePairRankedInsurances( types.EventTypeBeginUndelegate, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), sdk.NewAttribute(types.AttributeKeyChunkId, fmt.Sprintf("%d", chunk.Id)), - sdk.NewAttribute(types.AttributeKeyValidator, outIns.GetValidator().String()), + sdk.NewAttribute(types.AttributeKeyValidator, outIns.ValidatorAddress), sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.Format(time.RFC3339)), sdk.NewAttribute(types.AttributeKeyReason, types.AttributeValueReasonNoCandidateIns), ), @@ -1606,7 +1606,7 @@ func (k Keeper) isRepairingChunk(ctx sdk.Context, chunk types.Chunk) bool { if chunk.HasPairedInsurance() && chunk.HasUnpairingInsurance() { pairedIns := k.mustGetInsurance(ctx, chunk.PairedInsuranceId) unpairingIns := k.mustGetInsurance(ctx, chunk.UnpairingInsuranceId) - if pairedIns.GetValidator().Equals(unpairingIns.GetValidator()) { + if pairedIns.ValidatorAddress == unpairingIns.ValidatorAddress { return true } } diff --git a/x/liquidstaking/keeper/liquidstaking_test.go b/x/liquidstaking/keeper/liquidstaking_test.go index db2c853f..1afa3ca7 100644 --- a/x/liquidstaking/keeper/liquidstaking_test.go +++ b/x/liquidstaking/keeper/liquidstaking_test.go @@ -1228,7 +1228,7 @@ func (suite *KeeperTestSuite) TestEndBlocker() { toBeWithdrawnInsurance.GetValidator(), ) suite.True(found) - suite.Equal(toBeWithdrawnInsurance.GetValidator().String(), unbondingDelegation.ValidatorAddress) + suite.Equal(toBeWithdrawnInsurance.ValidatorAddress, unbondingDelegation.ValidatorAddress) } suite.ctx = suite.advanceHeight(suite.ctx, 1, "") diff --git a/x/liquidstaking/keeper/net_amount_essentials.go b/x/liquidstaking/keeper/net_amount_essentials.go index 76663f31..ee73e4c8 100644 --- a/x/liquidstaking/keeper/net_amount_essentials.go +++ b/x/liquidstaking/keeper/net_amount_essentials.go @@ -34,16 +34,15 @@ func (k Keeper) GetNetAmountStateEssentials(ctx sdk.Context) ( pairedIns := k.mustGetInsurance(ctx, chunk.PairedInsuranceId) pairedChunkWithInsuranceId[chunk.PairedInsuranceId] = chunk pairedInsurances = append(pairedInsurances, pairedIns) - valAddr := pairedIns.GetValidator() // Use map to reduce gas consumption - if _, ok := validatorMap[valAddr.String()]; !ok { + if _, ok := validatorMap[pairedIns.ValidatorAddress]; !ok { validator, found := k.stakingKeeper.GetValidator(ctx, pairedIns.GetValidator()) if !found { panic(fmt.Sprintf("validator of paired ins %s not found(insuranceId: %d)", pairedIns.GetValidator(), pairedIns.Id)) } - validatorMap[valAddr.String()] = validator + validatorMap[pairedIns.ValidatorAddress] = validator } - validator := validatorMap[valAddr.String()] + validator := validatorMap[pairedIns.ValidatorAddress] // Get delegation of chunk del, found := k.stakingKeeper.GetDelegation(ctx, chunk.DerivedAddress(), validator.GetOperator()) diff --git a/x/liquidstaking/types/insurance.go b/x/liquidstaking/types/insurance.go index d4a6bb52..2f0f0977 100644 --- a/x/liquidstaking/types/insurance.go +++ b/x/liquidstaking/types/insurance.go @@ -55,8 +55,8 @@ func SortInsurances(validatorMap map[string]stakingtypes.Validator, insurances [ iInsurance := insurances[i] jInsurance := insurances[j] - iValidator := validatorMap[iInsurance.GetValidator().String()] - jValidator := validatorMap[jInsurance.GetValidator().String()] + iValidator := validatorMap[iInsurance.ValidatorAddress] + jValidator := validatorMap[jInsurance.ValidatorAddress] iFee := iValidator.Commission.Rate.Add(iInsurance.FeeRate) jFee := jValidator.Commission.Rate.Add(jInsurance.FeeRate)