github.com/KiraCore/sekai@v0.3.43/x/layer2/keeper/abci.go (about) 1 package keeper 2 3 import ( 4 "fmt" 5 6 "github.com/KiraCore/sekai/x/layer2/types" 7 spendingtypes "github.com/KiraCore/sekai/x/spending/types" 8 sdk "github.com/cosmos/cosmos-sdk/types" 9 ) 10 11 func (k Keeper) BeginBlocker(ctx sdk.Context) { 12 13 } 14 15 func (k Keeper) EndBlocker(ctx sdk.Context) { 16 dapps := k.GetAllDapps(ctx) 17 properties := k.gk.GetNetworkProperties(ctx) 18 currTimestamp := uint64(ctx.BlockTime().Unix()) 19 for _, dapp := range dapps { 20 if dapp.Status == types.Bootstrap && dapp.CreationTime+properties.DappBondDuration <= currTimestamp { 21 k.FinishDappBootstrap(ctx, dapp) 22 } 23 24 if dapp.PremintTime+dapp.Pool.Drip < uint64(ctx.BlockTime().Unix()) && 25 dapp.Issurance.Postmint.IsPositive() && 26 dapp.Status == types.Active { 27 teamReserve := sdk.MustAccAddressFromBech32(dapp.TeamReserve) 28 dappBondLpToken := dapp.LpToken() 29 premintCoin := sdk.NewCoin(dappBondLpToken, dapp.Issurance.Premint) 30 err := k.bk.SendCoinsFromModuleToAccount(ctx, types.ModuleName, teamReserve, sdk.Coins{premintCoin}) 31 if err != nil { 32 panic(err) 33 } 34 dapp.PostMintPaid = true 35 k.SetDapp(ctx, dapp) 36 } 37 38 if dapp.Status == types.Active { 39 session := k.GetDappSession(ctx, dapp.Name) 40 // session not started yet during denounce time 41 if session.NextSession != nil && 42 session.NextSession.Start+properties.DappAutoDenounceTime <= currTimestamp && 43 session.NextSession.Status == types.SessionScheduled { 44 operator := k.GetDappOperator(ctx, dapp.Name, session.NextSession.Leader) 45 operator.Status = types.OperatorJailed 46 k.SetDappOperator(ctx, operator) 47 48 // update next session with new info 49 k.ResetNewSession(ctx, dapp.Name, session.CurrSession.Leader) 50 } 51 52 // If the KEX collateral in the pool falls below dapp_liquidation_threshold (by default set to 100’000 KEX) 53 // then the dApp will enter a depreciation phase lasting dapp_liquidation_period (by default set to 2419200, that is ~28d) 54 // after which the execution will be stopped. 55 if dapp.LiquidationStart+properties.DappLiquidationPeriod < uint64(ctx.BlockTime().Unix()) { 56 dapp.Status = types.Halted 57 k.SetDapp(ctx, dapp) 58 } 59 } 60 } 61 62 // handle bridge xam time outs 63 for _, xam := range k.GetXAMs(ctx) { 64 if xam.Req.SourceDapp != 0 && xam.Res.Src == 0 { 65 account := k.GetBridgeAccount(ctx, xam.Req.SourceDapp) 66 dapp := k.GetDapp(ctx, account.DappName) 67 if xam.ReqTime+2*dapp.UpdateTimeMax < uint64(ctx.BlockTime().Unix()) { 68 xam.Res.Src = 498 69 k.SetXAM(ctx, xam) 70 } 71 } 72 73 if xam.Req.DestDapp != 0 && xam.Res.Drc == 0 { 74 account := k.GetBridgeAccount(ctx, xam.Req.DestDapp) 75 dapp := k.GetDapp(ctx, account.DappName) 76 if xam.ReqTime+2*dapp.UpdateTimeMax < uint64(ctx.BlockTime().Unix()) { 77 xam.Res.Drc = 498 78 k.SetXAM(ctx, xam) 79 } 80 } 81 } 82 // - **Deposit** funds from personal account (source application `src == 0`) to destination `dst` application beneficiary `ben` address. 83 // - Deposit must be accepted by the `dst` application or funds returned back to the user kira account outside of ABR 84 // - Max time for accepting deposit is `max(2 blocks, 2 * update_time_max<DstApp>)` after which transaction must fail (internal response `irc` code `522`) 85 // - **Transfer** funds from the source `src` application account `acc` address to another destination `dst` application beneficiary `ben` address 86 // - Withdrawal from `src` application must be permissionless, the source `src` app does not need to confirm it but can speed it up by setting source response `src` code to `200` 87 // - Deposit to destination `dst` app must be accepted by the `dst` app with destination app response code `drc` set to `200` or funds **returned through deposit like process** 88 // - If Deposit fails to `dst` fails then `src` must accept the re-deposit otherwise if re-deposit fails the funds must be returned to the kira account outside of ABR 89 // - Max time for accepting withdrawal by `src` app must be `max(2 blocks, 2 * update_time_max<SrcApp>)` otherwise the withdrawal must automatically succeed 90 // - Max time for accepting deposit by `dst` app must be `max(2 blocks, 2 * update_time_max<DstApp>)` otherwise the deposit must automatically fail with internal response `irc` code set to `522` 91 // - If redeposit must be executed the new transaction must be created with new `xid`. Rules for re-deposit are same as for the deposit (if re-deposit fails funds must be returned to kira address outside of ABR) 92 // - **Withdrawal** funds from the source `src` application account `acc` address to kira address outside the ABR (`dst == 0`) to beneficiary `ben` address 93 // - Withdrawal from `src` application must be permissionless, the source `src` app does not need to confirm it but can speed it up by setting source response `src` code to `200` 94 // - Max time for accepting withdrawal by `src` app must be `max(2 blocks, 2 * update_time_max<SrcApp>)` otherwise the withdrawal must automatically succeed 95 96 } 97 98 func (k Keeper) FinishDappBootstrap(ctx sdk.Context, dapp types.Dapp) { 99 properties := k.gk.GetNetworkProperties(ctx) 100 minDappBond := sdk.NewInt(int64(properties.MinDappBond)).Mul(sdk.NewInt(1000_000)) 101 if dapp.TotalBond.Amount.LT(minDappBond) { 102 cacheCtx, write := ctx.CacheContext() 103 err := k.ExecuteDappRemove(cacheCtx, dapp) 104 if err == nil { 105 write() 106 } 107 } else { 108 userBonds := k.GetUserDappBonds(ctx, dapp.Name) 109 beneficiaries := []spendingtypes.WeightedAccount{} 110 for _, userBond := range userBonds { 111 beneficiaries = append(beneficiaries, spendingtypes.WeightedAccount{ 112 Account: userBond.User, 113 Weight: userBond.Bond.Amount.ToLegacyDec(), 114 }) 115 } 116 117 dappBondLpToken := dapp.LpToken() 118 err := sdk.ValidateDenom(dappBondLpToken) 119 if err != nil { 120 return 121 } 122 123 spendingPoolDeposit := dapp.GetSpendingPoolLpDeposit() 124 totalSupply := dapp.GetLpTokenSupply() 125 drip := dapp.Pool.Drip 126 if drip == 0 { 127 drip = 1 128 } 129 rate := sdk.NewDecFromInt(spendingPoolDeposit).Quo(sdk.NewDec(int64(drip))) 130 err = k.bk.MintCoins(ctx, types.ModuleName, sdk.Coins{sdk.NewCoin(dappBondLpToken, totalSupply)}) 131 if err != nil { 132 panic(err) 133 } 134 135 cacheCtx, write := ctx.CacheContext() 136 blockTime := uint64(ctx.BlockTime().Unix()) 137 spendingPoolName := fmt.Sprintf("dp_%s", dapp.Name) 138 err = k.spk.CreateSpendingPool(cacheCtx, spendingtypes.SpendingPool{ 139 Name: spendingPoolName, 140 ClaimStart: blockTime, 141 ClaimEnd: blockTime + drip, 142 Rates: sdk.NewDecCoins(sdk.NewDecCoinFromDec(dappBondLpToken, rate)), 143 VoteQuorum: dapp.VoteQuorum, 144 VotePeriod: dapp.VotePeriod, 145 VoteEnactment: dapp.VoteEnactment, 146 Owners: &spendingtypes.PermInfo{ 147 OwnerRoles: dapp.Controllers.Whitelist.Roles, 148 OwnerAccounts: dapp.Controllers.Whitelist.Addresses, 149 }, 150 Beneficiaries: &spendingtypes.WeightedPermInfo{ 151 Accounts: beneficiaries, 152 }, 153 Balances: []sdk.Coin{}, 154 DynamicRate: false, 155 DynamicRatePeriod: 0, 156 LastDynamicRateCalcTime: 0, 157 }) 158 if err == nil { 159 write() 160 } 161 162 cacheCtx, write = ctx.CacheContext() 163 coin := sdk.NewCoin(dappBondLpToken, spendingPoolDeposit) 164 err = k.spk.DepositSpendingPoolFromModule(cacheCtx, types.ModuleName, spendingPoolName, sdk.Coins{coin}) 165 if err == nil { 166 write() 167 } 168 169 dapp.Status = types.Halted 170 dapp.Pool.Deposit = spendingPoolName 171 dapp.PremintTime = blockTime 172 k.SetDapp(ctx, dapp) 173 174 // register bridge account for dapp 175 helper := k.GetBridgeRegistrarHelper(ctx) 176 k.SetBridgeAccount(ctx, types.BridgeAccount{ 177 Index: helper.NextUser, 178 Address: dapp.GetAccount().String(), 179 DappName: dapp.Name, 180 Balances: []types.BridgeBalance{}, 181 }) 182 helper.NextUser += 1 183 k.SetBridgeRegistrarHelper(ctx, helper) 184 185 for _, userBond := range userBonds { 186 k.DeleteUserDappBond(ctx, dapp.Name, userBond.User) 187 } 188 189 // send premint amount to team reserve 190 if dapp.Issurance.Premint.IsPositive() { 191 teamReserve := sdk.MustAccAddressFromBech32(dapp.TeamReserve) 192 premintCoin := sdk.NewCoin(dappBondLpToken, dapp.Issurance.Premint) 193 err = k.bk.SendCoinsFromModuleToAccount(ctx, types.ModuleName, teamReserve, sdk.Coins{premintCoin}) 194 if err != nil { 195 panic(err) 196 } 197 } 198 } 199 }