lnwallet: add new WithCoinSelectLock method to fix coin select race conditions
In this commit, we add a new method WithCoinSelectLock. This method will allow us to fix bugs in the project atm that can arise if a channel funding is attempted (either manually or by autopilot) while a users is attempting to send an on-chain transaction. If this happens concurrently, then both contexts will grab the set of UTXOs and attempt to lock them one by one. However, since they didn't obtain an exclusive snapshot of the UTXO set of the wallet, they may both attempt to lock the same input. We also ensure that calls to SendMany cannot run into this issue by using the WithCoinSelectLock synchronization when attempting to instruct the internal wallet to send payments.
This commit is contained in:
2 files changed
+29
-1
No files matched your search
+18
-1
@@ -804,7 +804,24 @@ func (r *rpcServer) SendMany(ctx context.Context,
|
||||
rpcsLog.Infof("[sendmany] outputs=%v, sat/kw=%v",
|
||||
spew.Sdump(in.AddrToAmount), int64(feePerKw))
|
||||
|
||||
txid, err := r.sendCoinsOnChain(in.AddrToAmount, feePerKw)
|
||||
var txid *chainhash.Hash
|
||||
|
||||
// We'll attempt to send to the target set of outputs, ensuring that we
|
||||
// synchronize with any other ongoing coin selection attempts which
|
||||
// happen to also be concurrently executing.
|
||||
wallet := r.server.cc.wallet
|
||||
err = wallet.WithCoinSelectLock(func() error {
|
||||
sendManyTXID, err := r.sendCoinsOnChain(
|
||||
in.AddrToAmount, feePerKw,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txid = sendManyTXID
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user