github.com/Finschia/finschia-sdk@v0.48.1/x/gov/keeper/deposit.go (about) 1 package keeper 2 3 import ( 4 "fmt" 5 6 sdk "github.com/Finschia/finschia-sdk/types" 7 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 8 "github.com/Finschia/finschia-sdk/x/gov/types" 9 ) 10 11 // GetDeposit gets the deposit of a specific depositor on a specific proposal 12 func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) (deposit types.Deposit, found bool) { 13 store := ctx.KVStore(keeper.storeKey) 14 bz := store.Get(types.DepositKey(proposalID, depositorAddr)) 15 if bz == nil { 16 return deposit, false 17 } 18 19 keeper.cdc.MustUnmarshal(bz, &deposit) 20 21 return deposit, true 22 } 23 24 // SetDeposit sets a Deposit to the gov store 25 func (keeper Keeper) SetDeposit(ctx sdk.Context, deposit types.Deposit) { 26 store := ctx.KVStore(keeper.storeKey) 27 bz := keeper.cdc.MustMarshal(&deposit) 28 depositor := sdk.MustAccAddressFromBech32(deposit.Depositor) 29 30 store.Set(types.DepositKey(deposit.ProposalId, depositor), bz) 31 } 32 33 // GetAllDeposits returns all the deposits from the store 34 func (keeper Keeper) GetAllDeposits(ctx sdk.Context) (deposits types.Deposits) { 35 keeper.IterateAllDeposits(ctx, func(deposit types.Deposit) bool { 36 deposits = append(deposits, deposit) 37 return false 38 }) 39 40 return 41 } 42 43 // GetDeposits returns all the deposits from a proposal 44 func (keeper Keeper) GetDeposits(ctx sdk.Context, proposalID uint64) (deposits types.Deposits) { 45 keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool { 46 deposits = append(deposits, deposit) 47 return false 48 }) 49 50 return 51 } 52 53 // DeleteDeposits deletes all the deposits on a specific proposal without refunding them 54 func (keeper Keeper) DeleteDeposits(ctx sdk.Context, proposalID uint64) { 55 store := ctx.KVStore(keeper.storeKey) 56 57 keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool { 58 err := keeper.bankKeeper.BurnCoins(ctx, types.ModuleName, deposit.Amount) 59 if err != nil { 60 panic(err) 61 } 62 63 depositor := sdk.MustAccAddressFromBech32(deposit.Depositor) 64 65 store.Delete(types.DepositKey(proposalID, depositor)) 66 return false 67 }) 68 } 69 70 // IterateAllDeposits iterates over the all the stored deposits and performs a callback function 71 func (keeper Keeper) IterateAllDeposits(ctx sdk.Context, cb func(deposit types.Deposit) (stop bool)) { 72 store := ctx.KVStore(keeper.storeKey) 73 iterator := sdk.KVStorePrefixIterator(store, types.DepositsKeyPrefix) 74 75 defer iterator.Close() 76 77 for ; iterator.Valid(); iterator.Next() { 78 var deposit types.Deposit 79 80 keeper.cdc.MustUnmarshal(iterator.Value(), &deposit) 81 82 if cb(deposit) { 83 break 84 } 85 } 86 } 87 88 // IterateDeposits iterates over the all the proposals deposits and performs a callback function 89 func (keeper Keeper) IterateDeposits(ctx sdk.Context, proposalID uint64, cb func(deposit types.Deposit) (stop bool)) { 90 store := ctx.KVStore(keeper.storeKey) 91 iterator := sdk.KVStorePrefixIterator(store, types.DepositsKey(proposalID)) 92 93 defer iterator.Close() 94 95 for ; iterator.Valid(); iterator.Next() { 96 var deposit types.Deposit 97 98 keeper.cdc.MustUnmarshal(iterator.Value(), &deposit) 99 100 if cb(deposit) { 101 break 102 } 103 } 104 } 105 106 // AddDeposit adds or updates a deposit of a specific depositor on a specific proposal 107 // Activates voting period when appropriate 108 func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) { 109 // Checks to see if proposal exists 110 proposal, ok := keeper.GetProposal(ctx, proposalID) 111 if !ok { 112 return false, sdkerrors.Wrapf(types.ErrUnknownProposal, "%d", proposalID) 113 } 114 115 // Check if proposal is still depositable 116 if (proposal.Status != types.StatusDepositPeriod) && (proposal.Status != types.StatusVotingPeriod) { 117 return false, sdkerrors.Wrapf(types.ErrInactiveProposal, "%d", proposalID) 118 } 119 120 // update the governance module's account coins pool 121 err := keeper.bankKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositAmount) 122 if err != nil { 123 return false, err 124 } 125 126 // Update proposal 127 proposal.TotalDeposit = proposal.TotalDeposit.Add(depositAmount...) 128 keeper.SetProposal(ctx, proposal) 129 130 // Check if deposit has provided sufficient total funds to transition the proposal into the voting period 131 activatedVotingPeriod := false 132 133 if proposal.Status == types.StatusDepositPeriod && proposal.TotalDeposit.IsAllGTE(keeper.GetDepositParams(ctx).MinDeposit) { 134 keeper.ActivateVotingPeriod(ctx, proposal) 135 136 activatedVotingPeriod = true 137 } 138 139 // Add or update deposit object 140 deposit, found := keeper.GetDeposit(ctx, proposalID, depositorAddr) 141 142 if found { 143 deposit.Amount = deposit.Amount.Add(depositAmount...) 144 } else { 145 deposit = types.NewDeposit(proposalID, depositorAddr, depositAmount) 146 } 147 148 // called when deposit has been added to a proposal, however the proposal may not be active 149 keeper.AfterProposalDeposit(ctx, proposalID, depositorAddr) 150 151 ctx.EventManager().EmitEvent( 152 sdk.NewEvent( 153 types.EventTypeProposalDeposit, 154 sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.String()), 155 sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)), 156 ), 157 ) 158 159 keeper.SetDeposit(ctx, deposit) 160 161 return activatedVotingPeriod, nil 162 } 163 164 // RefundDeposits refunds and deletes all the deposits on a specific proposal 165 func (keeper Keeper) RefundDeposits(ctx sdk.Context, proposalID uint64) { 166 store := ctx.KVStore(keeper.storeKey) 167 168 keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool { 169 depositor := sdk.MustAccAddressFromBech32(deposit.Depositor) 170 171 err := keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, deposit.Amount) 172 if err != nil { 173 panic(err) 174 } 175 176 store.Delete(types.DepositKey(proposalID, depositor)) 177 return false 178 }) 179 }