Skip to content

Commit c9f33db

Browse files
committed
add paginated query for loans by status
1 parent f14f239 commit c9f33db

File tree

3 files changed

+114
-14
lines changed

3 files changed

+114
-14
lines changed

x/lending/keeper/loan.go

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package keeper
22

33
import (
44
sdkmath "cosmossdk.io/math"
5+
"cosmossdk.io/store/prefix"
56
storetypes "cosmossdk.io/store/types"
67
sdk "github.com/cosmos/cosmos-sdk/types"
8+
"github.com/cosmos/cosmos-sdk/types/query"
79

810
"github.com/sideprotocol/side/x/lending/types"
911
)
@@ -14,6 +16,8 @@ func (k Keeper) SetLoan(ctx sdk.Context, loan *types.Loan) {
1416

1517
bz := k.cdc.MustMarshal(loan)
1618

19+
k.SetLoanStatus(ctx, loan.VaultAddress, loan.Status)
20+
1721
store.Set(types.LoanKey(loan.VaultAddress), bz)
1822
}
1923

@@ -24,6 +28,26 @@ func (k Keeper) SetLoanByAddress(ctx sdk.Context, loan *types.Loan) {
2428
store.Set(types.LoanByAddressKey(loan.VaultAddress, loan.Borrower), []byte{})
2529
}
2630

31+
// SetLoanStatus sets the status store of the given loan
32+
func (k Keeper) SetLoanStatus(ctx sdk.Context, id string, status types.LoanStatus) {
33+
store := ctx.KVStore(k.storeKey)
34+
35+
if k.HasLoan(ctx, id) {
36+
k.RemoveLoanStatus(ctx, id)
37+
}
38+
39+
store.Set(types.LoanByStatusKey(status, id), []byte{})
40+
}
41+
42+
// RemoveLoanStatus removes the status store of the given loan
43+
func (k Keeper) RemoveLoanStatus(ctx sdk.Context, id string) {
44+
store := ctx.KVStore(k.storeKey)
45+
46+
loan := k.GetLoan(ctx, id)
47+
48+
store.Delete(types.LoanByStatusKey(loan.Status, id))
49+
}
50+
2751
// HasLoan returns true if the given loan exists, false otherwise
2852
func (k Keeper) HasLoan(ctx sdk.Context, id string) bool {
2953
store := ctx.KVStore(k.storeKey)
@@ -46,17 +70,58 @@ func (k Keeper) GetLoan(ctx sdk.Context, id string) *types.Loan {
4670
func (k Keeper) GetLoans(ctx sdk.Context, status types.LoanStatus) []*types.Loan {
4771
var loans []*types.Loan
4872

49-
k.IterateLoans(ctx, func(loan *types.Loan) (stop bool) {
50-
if loan.Status == status {
51-
loans = append(loans, loan)
52-
}
53-
73+
k.IterateLoansByStatus(ctx, status, func(loan *types.Loan) (stop bool) {
74+
loans = append(loans, loan)
5475
return false
5576
})
5677

5778
return loans
5879
}
5980

81+
// GetLoansByStatusWithPagination gets loans by the given status with pagination
82+
func (k Keeper) GetLoansByStatusWithPagination(ctx sdk.Context, status types.LoanStatus, pagination *query.PageRequest) ([]*types.Loan, *query.PageResponse, error) {
83+
store := ctx.KVStore(k.storeKey)
84+
loanStatusStore := prefix.NewStore(store, append(types.LoanByStatusKeyPrefix, sdk.Uint64ToBigEndian(uint64(status))...))
85+
86+
var loans []*types.Loan
87+
88+
pageRes, err := query.Paginate(loanStatusStore, pagination, func(key []byte, value []byte) error {
89+
id := string(key)
90+
loan := k.GetLoan(ctx, id)
91+
92+
loans = append(loans, loan)
93+
94+
return nil
95+
})
96+
if err != nil {
97+
return nil, nil, err
98+
}
99+
100+
return loans, pageRes, nil
101+
}
102+
103+
// GetLoansWithPagination gets loans with pagination
104+
func (k Keeper) GetLoansWithPagination(ctx sdk.Context, pagination *query.PageRequest) ([]*types.Loan, *query.PageResponse, error) {
105+
store := ctx.KVStore(k.storeKey)
106+
loanStore := prefix.NewStore(store, types.LoanKeyPrefix)
107+
108+
var loans []*types.Loan
109+
110+
pageRes, err := query.Paginate(loanStore, pagination, func(key []byte, value []byte) error {
111+
var loan types.Loan
112+
k.cdc.MustUnmarshal(value, &loan)
113+
114+
loans = append(loans, &loan)
115+
116+
return nil
117+
})
118+
if err != nil {
119+
return nil, nil, err
120+
}
121+
122+
return loans, pageRes, nil
123+
}
124+
60125
// GetPendingLoans gets the requested or authorized loans
61126
func (k Keeper) GetPendingLoans(ctx sdk.Context) []*types.Loan {
62127
var loans []*types.Loan
@@ -118,6 +183,27 @@ func (k Keeper) IterateLoans(ctx sdk.Context, cb func(loan *types.Loan) (stop bo
118183
}
119184
}
120185

186+
// IterateLoansByStatus iterates through loans by the given status
187+
func (k Keeper) IterateLoansByStatus(ctx sdk.Context, status types.LoanStatus, cb func(loan *types.Loan) (stop bool)) {
188+
store := ctx.KVStore(k.storeKey)
189+
190+
keyPrefix := append(types.LoanByStatusKeyPrefix, sdk.Uint64ToBigEndian(uint64(status))...)
191+
192+
iterator := storetypes.KVStorePrefixIterator(store, keyPrefix)
193+
defer iterator.Close()
194+
195+
for ; iterator.Valid(); iterator.Next() {
196+
key := iterator.Key()
197+
198+
id := string(key[len(keyPrefix):])
199+
loan := k.GetLoan(ctx, id)
200+
201+
if cb(loan) {
202+
break
203+
}
204+
}
205+
}
206+
121207
// IterateLoansByAddress iterates through loans by the given address
122208
func (k Keeper) IterateLoansByAddress(ctx sdk.Context, address string, cb func(loan *types.Loan) (stop bool)) {
123209
store := ctx.KVStore(k.storeKey)

x/lending/keeper/queries.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/btcsuite/btcd/btcec/v2/schnorr"
1111

1212
sdk "github.com/cosmos/cosmos-sdk/types"
13+
"github.com/cosmos/cosmos-sdk/types/query"
1314

1415
"github.com/sideprotocol/side/x/lending/types"
1516
)
@@ -179,15 +180,21 @@ func (k Keeper) Loans(goCtx context.Context, req *types.QueryLoansRequest) (*typ
179180

180181
ctx := sdk.UnwrapSDKContext(goCtx)
181182

183+
var err error
182184
var loans []*types.Loan
185+
var pagination *query.PageResponse
183186

184187
if req.Status == types.LoanStatus_Unspecified {
185-
loans = k.GetAllLoans(ctx)
188+
loans, pagination, err = k.GetLoansWithPagination(ctx, req.Pagination)
186189
} else {
187-
loans = k.GetLoans(ctx, req.Status)
190+
loans, pagination, err = k.GetLoansByStatusWithPagination(ctx, req.Status, req.Pagination)
191+
}
192+
193+
if err != nil {
194+
return nil, status.Error(codes.Internal, err.Error())
188195
}
189196

190-
return &types.QueryLoansResponse{Loans: loans}, nil
197+
return &types.QueryLoansResponse{Loans: loans, Pagination: pagination}, nil
191198
}
192199

193200
// LoansByAddress implements types.QueryServer.

x/lending/types/keys.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ var (
3131

3232
PoolKeyPrefix = []byte{0x10}
3333
LoanKeyPrefix = []byte{0x11}
34-
LoanByAddressKeyPrefix = []byte{0x12}
35-
AuthorizationIdKeyPrefix = []byte{0x13}
36-
DepositLogKeyPrefix = []byte{0x14}
37-
RepaymentKeyPrefix = []byte{0x15}
38-
DLCMetaKeyPrefix = []byte{0x16}
39-
RedemptionKeyPrefix = []byte{0x17}
34+
LoanByStatusKeyPrefix = []byte{0x12}
35+
LoanByAddressKeyPrefix = []byte{0x13}
36+
AuthorizationIdKeyPrefix = []byte{0x14}
37+
DepositLogKeyPrefix = []byte{0x15}
38+
RepaymentKeyPrefix = []byte{0x16}
39+
DLCMetaKeyPrefix = []byte{0x17}
40+
RedemptionKeyPrefix = []byte{0x18}
4041

4142
ReferrerKeyPrefix = []byte{0x20}
4243
)
@@ -49,6 +50,12 @@ func LoanKey(id string) []byte {
4950
return append(LoanKeyPrefix, []byte(id)...)
5051
}
5152

53+
func LoanByStatusKey(status LoanStatus, id string) []byte {
54+
key := append(LoanByStatusKeyPrefix, sdk.Uint64ToBigEndian(uint64(status))...)
55+
56+
return append(key, []byte(id)...)
57+
}
58+
5259
func LoanByAddressKey(id string, address string) []byte {
5360
return append(append(LoanByAddressKeyPrefix, []byte(address)...), []byte(id)...)
5461
}

0 commit comments

Comments
 (0)