Skip to content

Commit d132819

Browse files
committed
assets+loopdb: recover active deposits on startup
This commit adds deposit recovery to the deposit manager's startup process. All deposits that have not yet been spent by the server or swept by the client are recovered from the store.
1 parent cec8076 commit d132819

File tree

5 files changed

+184
-0
lines changed

5 files changed

+184
-0
lines changed

assets/deposit/manager.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ func (m *Manager) Run(ctx context.Context, bestBlock uint32) error {
152152

153153
m.currentHeight = bestBlock
154154

155+
err := m.recoverDeposits(ctx)
156+
if err != nil {
157+
log.Errorf("Unable to recover deposits: %v", err)
158+
159+
return err
160+
}
161+
155162
blockChan, blockErrChan, err := m.chainNotifier.RegisterBlockEpochNtfn(
156163
ctxc,
157164
)
@@ -224,6 +231,56 @@ func (m *Manager) criticalError(err error) {
224231
}
225232
}
226233

234+
// recoverDeposits recovers all active deppsits when the deposit manager starts.
235+
func (m *Manager) recoverDeposits(ctx context.Context) error {
236+
// Fetch all active deposits from the store to kick-off the manager.
237+
activeDeposits, err := m.store.GetActiveDeposits(ctx)
238+
if err != nil {
239+
log.Errorf("Unable to fetch deposits from store: %v", err)
240+
241+
return err
242+
}
243+
244+
for i := range activeDeposits {
245+
d := &activeDeposits[i]
246+
log.Infof("Recovering deposit %v (state=%s)", d.ID, d.State)
247+
248+
m.deposits[d.ID] = d
249+
_, _, _, err = m.isDepositFunded(ctx, d)
250+
if err != nil {
251+
return err
252+
}
253+
254+
if d.State == StateInitiated {
255+
// If the deposit has just been initiated, then we need
256+
// to ensure that it is funded.
257+
err = m.fundDepositIfNeeded(ctx, d)
258+
if err != nil {
259+
log.Errorf("Unable to fund deposit %v: %v",
260+
d.ID, err)
261+
262+
return err
263+
}
264+
} else {
265+
// Cache proof info of the deposit in-memory.
266+
err = m.cacheProofInfo(ctx, d)
267+
if err != nil {
268+
return err
269+
}
270+
271+
// Register the deposit as known so that we can claim
272+
// the funds committed to the OP_TRUE script. If the
273+
// deposit is already registered, this will be a no-op.
274+
err = m.registerDepositAsKnown(ctx, d)
275+
if err != nil {
276+
return err
277+
}
278+
}
279+
}
280+
281+
return nil
282+
}
283+
227284
// handleBlockEpoch is called when a new block is added to the chain.
228285
func (m *Manager) handleBlockEpoch(ctx context.Context, height uint32) error {
229286
for _, d := range m.deposits {

assets/deposit/sql_store.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ type Querier interface {
3232

3333
SetAssetDepositSweepKeys(ctx context.Context,
3434
arg sqlc.SetAssetDepositSweepKeysParams) error
35+
36+
GetActiveAssetDeposits(ctx context.Context) (
37+
[]sqlc.GetActiveAssetDepositsRow, error)
3538
}
3639

3740
// DepositBaseDB is the interface that contains all the queries generated
@@ -283,3 +286,27 @@ func sqlcDepositToDeposit(sqlDeposit sqlc.GetAssetDepositsRow,
283286
DepositInfo: depositInfo,
284287
}, nil
285288
}
289+
290+
// GetActiveDeposits returns all active deposits from the database. Active
291+
// deposits are those that have not yet been spent or swept.
292+
func (s *SQLStore) GetActiveDeposits(ctx context.Context) ([]Deposit, error) {
293+
sqlDeposits, err := s.db.GetActiveAssetDeposits(ctx)
294+
if err != nil {
295+
return nil, err
296+
}
297+
298+
deposits := make([]Deposit, 0, len(sqlDeposits))
299+
for _, sqlDeposit := range sqlDeposits {
300+
deposit, err := sqlcDepositToDeposit(
301+
sqlc.GetAssetDepositsRow(sqlDeposit),
302+
&s.addressParams,
303+
)
304+
if err != nil {
305+
return nil, err
306+
}
307+
308+
deposits = append(deposits, deposit)
309+
}
310+
311+
return deposits, nil
312+
}

loopdb/sqlc/asset_deposits.sql.go

Lines changed: 84 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: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,18 @@ ORDER BY d.created_at ASC;
4444
UPDATE asset_deposits
4545
SET sweep_script_pubkey = $2, sweep_internal_pubkey = $3
4646
WHERE deposit_id = $1;
47+
48+
-- name: GetActiveAssetDeposits :many
49+
SELECT d.*, u.update_state, u.update_timestamp
50+
FROM asset_deposits d
51+
JOIN asset_deposit_updates u
52+
ON u.deposit_id = d.deposit_id
53+
WHERE u.id = (
54+
SELECT id
55+
FROM asset_deposit_updates
56+
WHERE deposit_id = d.deposit_id
57+
ORDER BY update_timestamp DESC
58+
LIMIT 1
59+
)
60+
AND u.update_state IN (0, 1, 2, 3, 4, 5, 6);
61+

0 commit comments

Comments
 (0)