Skip to content

Commit 508b78d

Browse files
committed
assets+loopdb: publish cooperative deposit withdrawal transaction
This commit implements the full cooperative deposit withdrawal flow. The client first fetches keys for any pending withdrawals, then publishes sweep transactions using the revealed key to sign the deposit sweep. Once the sweep confirms, the deposit’s state is updated in the deposit store.
1 parent 8a32efd commit 508b78d

File tree

7 files changed

+162
-44
lines changed

7 files changed

+162
-44
lines changed

assets/deposit/manager.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ func (m *Manager) Run(ctx context.Context, bestBlock uint32) error {
163163
return err
164164
}
165165

166+
// Wake the manager up very 10 seconds to check if there're any pending
167+
// chores to do.
168+
const wakeupInterval = time.Duration(10) * time.Second
169+
166170
for {
167171
select {
168172
case <-m.callEnter:
@@ -182,6 +186,15 @@ func (m *Manager) Run(ctx context.Context, bestBlock uint32) error {
182186
return err
183187
}
184188

189+
case <-time.After(wakeupInterval):
190+
err := m.publishPendingWithdrawals(ctx)
191+
if err != nil {
192+
log.Errorf("Unable to publish pending "+
193+
"withdrawals: %v", err)
194+
195+
return err
196+
}
197+
185198
case err := <-blockErrChan:
186199
log.Errorf("received error from block epoch "+
187200
"notification: %v", err)
@@ -871,6 +884,8 @@ func (m *Manager) handleDepositSpend(ctx context.Context, d *Deposit,
871884

872885
switch d.State {
873886
case StateTimeoutSweepPublished:
887+
fallthrough
888+
case StateCooperativeSweepPublished:
874889
log.Infof("Deposit %s withdrawn in: %s", d.ID, outpoint)
875890
d.State = StateSwept
876891

@@ -1016,3 +1031,68 @@ func (m *Manager) WithdrawDeposits(ctx context.Context,
10161031

10171032
return nil
10181033
}
1034+
1035+
// publishPendingWithdrawals publishes any pending deposit withdrawals.
1036+
func (m *Manager) publishPendingWithdrawals(ctx context.Context) error {
1037+
for _, d := range m.deposits {
1038+
// TODO(bhandras): republish on StateCooperativeSweepPublished.
1039+
if d.State != StateWithdrawn {
1040+
continue
1041+
}
1042+
1043+
// Start monitoring the sweep unless we're already doing so.
1044+
if _, ok := m.pendingSweeps[d.ID]; !ok {
1045+
err := m.waitForDepositSpend(ctx, d)
1046+
if err != nil {
1047+
log.Errorf("Unable to wait for deposit %v "+
1048+
"spend: %v", d.ID, err)
1049+
1050+
return err
1051+
}
1052+
1053+
m.pendingSweeps[d.ID] = struct{}{}
1054+
}
1055+
1056+
serverKey, err := m.store.GetAssetDepositServerKey(
1057+
ctx, d.ID,
1058+
)
1059+
if err != nil {
1060+
return err
1061+
}
1062+
1063+
lockID, err := d.lockID()
1064+
if err != nil {
1065+
return err
1066+
}
1067+
1068+
sweepAddr, err := address.DecodeAddress(
1069+
d.SweepAddr, &m.addressParams,
1070+
)
1071+
if err != nil {
1072+
return err
1073+
}
1074+
1075+
// TODO(bhandras): conf target should be dynamic/configrable.
1076+
const confTarget = 2
1077+
feeRateSatPerKw, err := m.walletKit.EstimateFeeRate(
1078+
ctx, confTarget,
1079+
)
1080+
1081+
funder := true
1082+
sendAssetResp, err := m.sweeper.PublishDepositSweepMuSig2(
1083+
ctx, d.Kit, funder, d.Proof, serverKey, sweepAddr,
1084+
feeRateSatPerKw.FeePerVByte(), lockID, lockExpiration,
1085+
)
1086+
if err != nil {
1087+
log.Errorf("Unable to publish deposit sweep for %v: %v",
1088+
d.ID, err)
1089+
} else {
1090+
log.Infof("Published sweep for deposit %v: %v", d.ID,
1091+
sendAssetResp.Transfer.AnchorTxHash)
1092+
1093+
d.State = StateCooperativeSweepPublished
1094+
}
1095+
}
1096+
1097+
return nil
1098+
}

assets/deposit/sql_store.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ type Querier interface {
3838

3939
SetAssetDepositServerInternalKey(ctx context.Context,
4040
arg sqlc.SetAssetDepositServerInternalKeyParams) error
41+
42+
GetAssetDepositServerInternalKey(ctx context.Context,
43+
depositID string) ([]byte, error)
4144
}
4245

4346
// DepositBaseDB is the interface that contains all the queries generated
@@ -314,3 +317,19 @@ func (s *SQLStore) SetAssetDepositServerKey(ctx context.Context,
314317
},
315318
)
316319
}
320+
321+
func (s *SQLStore) GetAssetDepositServerKey(ctx context.Context,
322+
depositID string) (*btcec.PrivateKey, error) {
323+
324+
keyBytes, err := s.db.GetAssetDepositServerInternalKey(ctx, depositID)
325+
if err != nil {
326+
return nil, err
327+
}
328+
329+
key, _ := btcec.PrivKeyFromBytes(keyBytes)
330+
if err != nil {
331+
return nil, err
332+
}
333+
334+
return key, nil
335+
}

go.mod

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ require (
66
github.com/btcsuite/btcd/btcutil v1.1.5
77
github.com/btcsuite/btcd/btcutil/psbt v1.1.10
88
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
9-
github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318
10-
github.com/btcsuite/btcwallet v0.16.13
9+
github.com/btcsuite/btclog/v2 v2.0.1-0.20250602222548-9967d19bb084
10+
github.com/btcsuite/btcwallet v0.16.14
1111
github.com/btcsuite/btcwallet/wtxmgr v1.5.6
1212
github.com/davecgh/go-spew v1.1.1
1313
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0
@@ -19,17 +19,17 @@ require (
1919
github.com/jessevdk/go-flags v1.4.0
2020
github.com/lib/pq v1.10.9
2121
github.com/lightninglabs/aperture v0.3.13-beta
22-
github.com/lightninglabs/lndclient v0.19.0-7
22+
github.com/lightninglabs/lndclient v0.19.0-9
2323
github.com/lightninglabs/loop/looprpc v1.0.7
2424
github.com/lightninglabs/loop/swapserverrpc v1.0.14
2525
github.com/lightninglabs/taproot-assets v0.6.0-rc2.0.20250526132410-324bce0a1a7b
26-
github.com/lightninglabs/taproot-assets/taprpc v1.0.5
27-
github.com/lightningnetwork/lnd v0.19.0-beta
26+
github.com/lightninglabs/taproot-assets/taprpc v1.0.9
27+
github.com/lightningnetwork/lnd v0.19.2-beta.rc2
2828
github.com/lightningnetwork/lnd/cert v1.2.2
2929
github.com/lightningnetwork/lnd/clock v1.1.1
3030
github.com/lightningnetwork/lnd/queue v1.1.1
3131
github.com/lightningnetwork/lnd/ticker v1.1.1
32-
github.com/lightningnetwork/lnd/tlv v1.3.1
32+
github.com/lightningnetwork/lnd/tlv v1.3.2
3333
github.com/lightningnetwork/lnd/tor v1.1.6
3434
github.com/ory/dockertest/v3 v3.10.0
3535
github.com/stretchr/testify v1.10.0
@@ -79,7 +79,6 @@ require (
7979
github.com/docker/go-units v0.5.0 // indirect
8080
github.com/dustin/go-humanize v1.0.1 // indirect
8181
github.com/fergusstrange/embedded-postgres v1.25.0 // indirect
82-
github.com/go-errors/errors v1.0.1 // indirect
8382
github.com/go-logr/logr v1.4.2 // indirect
8483
github.com/go-logr/stdr v1.2.2 // indirect
8584
github.com/go-macaroon-bakery/macaroonpb v1.0.0 // indirect
@@ -122,11 +121,11 @@ require (
122121
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.3 // indirect
123122
github.com/lightninglabs/neutrino v0.16.1 // indirect
124123
github.com/lightninglabs/neutrino/cache v1.1.2 // indirect
125-
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb // indirect
124+
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240815225420-8b40adf04ab9 // indirect
126125
github.com/lightningnetwork/lnd/fn/v2 v2.0.8 // indirect
127126
github.com/lightningnetwork/lnd/healthcheck v1.2.6 // indirect
128127
github.com/lightningnetwork/lnd/kvdb v1.4.16 // indirect
129-
github.com/lightningnetwork/lnd/sqldb v1.0.9 // indirect
128+
github.com/lightningnetwork/lnd/sqldb v1.0.10 // indirect
130129
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 // indirect
131130
github.com/mattn/go-isatty v0.0.20 // indirect
132131
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
@@ -212,8 +211,22 @@ replace google.golang.org/protobuf => github.com/lightninglabs/protobuf-go-hex-d
212211
// did not yet make it into the upstream repository.
213212
replace github.com/golang-migrate/migrate/v4 => github.com/lightninglabs/migrate/v4 v4.18.2-9023d66a-fork-pr-2
214213

214+
replace github.com/btcsuite/btcwallet => github.com/bhandras/btcwallet v0.11.1-0.20250507171803-0de1c46b1cfc
215+
216+
replace github.com/btcsuite/btcd => github.com/bhandras/btcd v0.22.0-beta.0.20250507171227-f18160c86e92
217+
215218
replace github.com/lightninglabs/loop/swapserverrpc => ./swapserverrpc
216219

217220
replace github.com/lightninglabs/loop/looprpc => ./looprpc
218221

222+
replace github.com/lightningnetwork/lnd => ../lnd
223+
224+
replace github.com/lightningnetwork/lnd/sqldb => ../lnd/sqldb
225+
226+
replace github.com/lightninglabs/lndclient => ../lndclient
227+
228+
replace github.com/lightninglabs/taproot-assets => ../taproot-assets
229+
230+
replace github.com/lightninglabs/taproot-assets/taprpc => ../taproot-assets/taprpc
231+
219232
go 1.23.9

0 commit comments

Comments
 (0)