Skip to content

Commit c36c527

Browse files
committed
assets+loopdb: implement functionality to list asset deposits
This commit adds the necessary changes to the asset deposit manager, the underlying sql store and the asset deposit subserver to be able to list asset deposits.
1 parent ee774bb commit c36c527

File tree

6 files changed

+288
-1
lines changed

6 files changed

+288
-1
lines changed

assets/deposit/manager.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,3 +598,40 @@ func (m *Manager) markDepositConfirmed(ctx context.Context, d *Deposit,
598598

599599
return nil
600600
}
601+
602+
// ListDeposits returns all deposits that are in the given range of
603+
// confirmations.
604+
func (m *Manager) ListDeposits(ctx context.Context, minConfs, maxConfs uint32) (
605+
[]Deposit, error) {
606+
607+
bestBlock, err := m.GetBestBlock()
608+
if err != nil {
609+
return nil, err
610+
}
611+
612+
deposits, err := m.store.GetAllDeposits(ctx)
613+
if err != nil {
614+
return nil, err
615+
}
616+
617+
// Only filter based on confirmations if the user has set a min or max
618+
// confs.
619+
filterConfs := minConfs != 0 || maxConfs != 0
620+
621+
// Prefilter deposits based on the min/max confs.
622+
filteredDeposits := make([]Deposit, 0, len(deposits))
623+
for _, deposit := range deposits {
624+
if filterConfs {
625+
// Check that the deposit suits our min/max confs
626+
// criteria.
627+
confs := bestBlock - deposit.ConfirmationHeight
628+
if confs < minConfs || confs > maxConfs {
629+
continue
630+
}
631+
}
632+
633+
filteredDeposits = append(filteredDeposits, deposit)
634+
}
635+
636+
return filteredDeposits, nil
637+
}

assets/deposit/server.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,44 @@ func (s *Server) ListAssetDeposits(ctx context.Context,
8383
in *looprpc.ListAssetDepositsRequest) (
8484
*looprpc.ListAssetDepositsResponse, error) {
8585

86-
return nil, status.Error(codes.Unimplemented, "unimplemented")
86+
if s.manager == nil {
87+
return nil, ErrAssetDepositsUnavailable
88+
}
89+
90+
if in.MinConfs < in.MaxConfs {
91+
return nil, status.Error(codes.InvalidArgument,
92+
"max_confs must be greater than or equal to min_confs")
93+
}
94+
95+
deposits, err := s.manager.ListDeposits(ctx, in.MinConfs, in.MaxConfs)
96+
if err != nil {
97+
return nil, status.Error(codes.Internal, err.Error())
98+
}
99+
100+
filteredDeposits := make([]*looprpc.AssetDeposit, 0, len(deposits))
101+
for _, d := range deposits {
102+
rpcDeposit := &looprpc.AssetDeposit{
103+
DepositId: d.ID,
104+
CreatedAt: d.CreatedAt.Unix(),
105+
AssetId: d.AssetID.String(),
106+
Amount: d.Amount,
107+
DepositAddr: d.Addr,
108+
State: d.State.String(),
109+
ConfirmationHeight: d.ConfirmationHeight,
110+
Expiry: d.ConfirmationHeight + d.CsvExpiry,
111+
SweepAddr: d.SweepAddr,
112+
}
113+
114+
if d.Outpoint != nil {
115+
rpcDeposit.AnchorOutpoint = d.Outpoint.String()
116+
}
117+
118+
filteredDeposits = append(filteredDeposits, rpcDeposit)
119+
}
120+
121+
return &looprpc.ListAssetDepositsResponse{
122+
FilteredDeposits: filteredDeposits,
123+
}, nil
87124
}
88125

89126
// RevealAssetDepositKey is the rpc endpoint for loop clients to reveal the

assets/deposit/sql_store.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ package deposit
33
import (
44
"context"
55
"database/sql"
6+
"fmt"
67

8+
"github.com/btcsuite/btcd/btcec/v2"
79
"github.com/btcsuite/btcd/chaincfg"
10+
"github.com/btcsuite/btcd/wire"
811
"github.com/lightninglabs/loop/loopdb"
912
"github.com/lightninglabs/loop/loopdb/sqlc"
1013
"github.com/lightninglabs/taproot-assets/address"
14+
"github.com/lightninglabs/taproot-assets/asset"
1115
"github.com/lightningnetwork/lnd/clock"
16+
"github.com/lightningnetwork/lnd/keychain"
1217
)
1318

1419
// Querier is a subset of the methods we need from the postgres.querier
@@ -21,6 +26,9 @@ type Querier interface {
2126

2227
MarkDepositConfirmed(ctx context.Context,
2328
arg sqlc.MarkDepositConfirmedParams) error
29+
30+
GetAssetDeposits(ctx context.Context) ([]sqlc.GetAssetDepositsRow,
31+
error)
2432
}
2533

2634
// DepositBaseDB is the interface that contains all the queries generated
@@ -130,3 +138,115 @@ func (s *SQLStore) UpdateDeposit(ctx context.Context, d *Deposit) error {
130138
)
131139
})
132140
}
141+
142+
func (s *SQLStore) GetAllDeposits(ctx context.Context) ([]Deposit, error) {
143+
sqlDeposits, err := s.db.GetAssetDeposits(ctx)
144+
if err != nil {
145+
return nil, err
146+
}
147+
148+
deposits := make([]Deposit, 0, len(sqlDeposits))
149+
for _, sqlDeposit := range sqlDeposits {
150+
deposit, err := sqlcDepositToDeposit(
151+
sqlDeposit, &s.addressParams,
152+
)
153+
if err != nil {
154+
return nil, err
155+
}
156+
157+
deposits = append(deposits, deposit)
158+
}
159+
160+
return deposits, nil
161+
}
162+
163+
func sqlcDepositToDeposit(sqlDeposit sqlc.GetAssetDepositsRow,
164+
addressParams *address.ChainParams) (Deposit, error) {
165+
166+
clientScriptPubKey, err := btcec.ParsePubKey(
167+
sqlDeposit.ClientScriptPubkey,
168+
)
169+
if err != nil {
170+
return Deposit{}, err
171+
}
172+
173+
serverScriptPubKey, err := btcec.ParsePubKey(
174+
sqlDeposit.ServerScriptPubkey,
175+
)
176+
if err != nil {
177+
return Deposit{}, err
178+
}
179+
180+
clientInteralPubKey, err := btcec.ParsePubKey(
181+
sqlDeposit.ClientInternalPubkey,
182+
)
183+
if err != nil {
184+
return Deposit{}, err
185+
}
186+
187+
serverInternalPubKey, err := btcec.ParsePubKey(
188+
sqlDeposit.ServerInternalPubkey,
189+
)
190+
if err != nil {
191+
return Deposit{}, err
192+
}
193+
194+
clientKeyLocator := keychain.KeyLocator{
195+
Family: keychain.KeyFamily(
196+
sqlDeposit.ClientKeyFamily,
197+
),
198+
Index: uint32(sqlDeposit.ClientKeyIndex),
199+
}
200+
201+
if len(sqlDeposit.AssetID) != len(asset.ID{}) {
202+
return Deposit{}, fmt.Errorf("malformed asset ID for deposit: "+
203+
"%v", sqlDeposit.DepositID)
204+
}
205+
206+
depositInfo := &DepositInfo{
207+
ID: sqlDeposit.DepositID,
208+
Version: AssetDepositProtocolVersion(
209+
sqlDeposit.ProtocolVersion,
210+
),
211+
CreatedAt: sqlDeposit.CreatedAt.Local(),
212+
Amount: uint64(sqlDeposit.Amount),
213+
Addr: sqlDeposit.Addr,
214+
State: State(sqlDeposit.UpdateState),
215+
}
216+
217+
if sqlDeposit.ConfirmationHeight.Valid {
218+
depositInfo.ConfirmationHeight = uint32(
219+
sqlDeposit.ConfirmationHeight.Int32,
220+
)
221+
}
222+
223+
if sqlDeposit.Outpoint.Valid {
224+
outpoint, err := wire.NewOutPointFromString(
225+
sqlDeposit.Outpoint.String,
226+
)
227+
if err != nil {
228+
return Deposit{}, err
229+
}
230+
231+
depositInfo.Outpoint = outpoint
232+
}
233+
234+
if sqlDeposit.SweepAddr.Valid {
235+
depositInfo.SweepAddr = sqlDeposit.SweepAddr.String
236+
}
237+
238+
kit, err := NewKit(
239+
clientScriptPubKey, clientInteralPubKey, serverScriptPubKey,
240+
serverInternalPubKey, clientKeyLocator,
241+
asset.ID(sqlDeposit.AssetID), uint32(sqlDeposit.Expiry),
242+
addressParams,
243+
)
244+
if err != nil {
245+
return Deposit{}, err
246+
}
247+
248+
return Deposit{
249+
Kit: kit,
250+
DepositInfo: depositInfo,
251+
}, nil
252+
}

loopdb/sqlc/asset_deposits.sql.go

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

loopdb/sqlc/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

loopdb/sqlc/queries/asset_deposits.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,15 @@ INSERT INTO asset_deposit_updates (
2727
UPDATE asset_deposits
2828
SET confirmation_height = $2, outpoint = $3, pk_script = $4
2929
WHERE deposit_id = $1;
30+
31+
-- name: GetAssetDeposits :many
32+
SELECT d.*, u.update_state, u.update_timestamp
33+
FROM asset_deposits d
34+
JOIN asset_deposit_updates u ON u.id = (
35+
SELECT id
36+
FROM asset_deposit_updates
37+
WHERE deposit_id = d.deposit_id
38+
ORDER BY update_timestamp DESC
39+
LIMIT 1
40+
)
41+
ORDER BY d.created_at ASC;

0 commit comments

Comments
 (0)