Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optimize gas usage #39

Merged
merged 16 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions app/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,18 @@ 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 {
numInitiallyBonded = numAccs
}

fmt.Printf(
`Selected randomly generated parameters for simulated genesis:
{
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
2 changes: 1 addition & 1 deletion x/liquidstaking/keeper/invariants.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion x/liquidstaking/keeper/invariants_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
2 changes: 0 additions & 2 deletions x/liquidstaking/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"

"github.com/tendermint/tendermint/libs/log"

"github.com/Canto-Network/Canto/v7/x/liquidstaking/types"
Expand Down Expand Up @@ -40,7 +39,6 @@ func NewKeeper(
if !subspace.HasKeyTable() {
subspace = subspace.WithKeyTable(types.ParamKeyTable())
}

return Keeper{
storeKey: storeKey,
cdc: cdc,
Expand Down
2 changes: 1 addition & 1 deletion x/liquidstaking/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
82 changes: 40 additions & 42 deletions x/liquidstaking/keeper/liquidstaking.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
})
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)),
),
)
Expand Down Expand Up @@ -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),
),
Expand All @@ -590,18 +590,21 @@ func (k Keeper) DoLiquidStake(ctx sdk.Context, msg *types.MsgLiquidStake) (
return
}
chunksToCreate := amount.Amount.Quo(types.ChunkSize)
nas := k.GetNetAmountStateEssentials(ctx)
if nas.RemainingChunkSlots.LT(chunksToCreate) {

nase, _, _, _ := k.GetNetAmountStateEssentials(ctx)

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
}

pairingInsurances, validatorMap := k.GetPairingInsurances(ctx)

numPairingInsurances := sdk.NewIntFromUint64(uint64(len(pairingInsurances)))
if chunksToCreate.GT(numPairingInsurances) {
err = types.ErrNoPairingInsurance
Expand Down Expand Up @@ -644,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())
Expand Down Expand Up @@ -684,29 +687,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)
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
}

pairedIns, validator, _ := k.mustValidatePairedChunk(ctx, chunk)
if _, ok := validatorMap[pairedIns.GetValidator().String()]; !ok {
validatorMap[pairedIns.ValidatorAddress] = validator
delete(pairedChunksWithInsuranceId, pairedIns.Id)
continue
}
insurances = append(insurances, pairedIns)
chunksWithInsId[pairedIns.Id] = chunk
return false
})
purelyPairedInsurances = append(purelyPairedInsurances, pairedIns)
}

pairedChunks := int64(len(chunksWithInsId))
pairedChunks := int64(len(pairedChunksWithInsuranceId))
if pairedChunks == 0 {
err = types.ErrNoPairedChunk
return
Expand All @@ -721,16 +717,16 @@ 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)

// How much ls tokens must be burned
nas := k.GetNetAmountStateEssentials(ctx)

liquidBondDenom := k.GetLiquidBondDenom(ctx)
for i := int64(0); i < chunksToLiquidUnstake; i++ {
// 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(
Expand All @@ -739,8 +735,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(
Expand All @@ -757,7 +753,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)
}
Expand Down Expand Up @@ -906,6 +902,7 @@ 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
}

return
}

Expand All @@ -919,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
Expand All @@ -952,6 +949,7 @@ func (k Keeper) DoClaimDiscountedReward(ctx sdk.Context, msg *types.MsgClaimDisc
if err = k.bankKeeper.SendCoins(ctx, types.RewardPool, msg.GetRequestser(), claimCoins); err != nil {
return
}

return
}

Expand Down Expand Up @@ -1608,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
}
}
Expand Down
Loading
Loading