mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
staticaddr: require confirmed deposits for withdraws and channel opens
Deposited can now include mempool outputs for static loop-ins, but withdrawals and static channel opens still require confirmed funding inputs. Filter automatic channel-open selection to confirmed deposits and reject explicit unconfirmed selections, including withdraw-all requests that would otherwise silently include mempool deposits.
This commit is contained in:
parent
e8dd3aa009
commit
557ba99513
5 changed files with 225 additions and 9 deletions
|
|
@ -1805,8 +1805,9 @@ func (s *swapClientServer) WithdrawDeposits(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
for _, d := range deposits {
|
||||
outpoints = append(outpoints, d.OutPoint)
|
||||
outpoints, err = withdrawAllDepositOutpoints(deposits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
case isUtxoSelected:
|
||||
|
|
@ -1829,6 +1830,25 @@ func (s *swapClientServer) WithdrawDeposits(ctx context.Context,
|
|||
}, err
|
||||
}
|
||||
|
||||
// withdrawAllDepositOutpoints returns all deposit outpoints for an `all`
|
||||
// withdrawal request. The request must fail if any deposited output is still
|
||||
// unconfirmed because `all` should not silently downgrade to a subset.
|
||||
func withdrawAllDepositOutpoints(deposits []*deposit.Deposit) ([]wire.OutPoint,
|
||||
error) {
|
||||
|
||||
outpoints := make([]wire.OutPoint, 0, len(deposits))
|
||||
for _, d := range deposits {
|
||||
if d.GetConfirmationHeight() <= 0 {
|
||||
return nil, fmt.Errorf("can't withdraw all deposits while " +
|
||||
"some deposits are unconfirmed")
|
||||
}
|
||||
|
||||
outpoints = append(outpoints, d.OutPoint)
|
||||
}
|
||||
|
||||
return outpoints, nil
|
||||
}
|
||||
|
||||
// ListStaticAddressDeposits returns a list of all sufficiently confirmed
|
||||
// deposits behind the static address and displays properties like value,
|
||||
// state or blocks til expiry.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ package loopd
|
|||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightninglabs/loop/staticaddr/deposit"
|
||||
)
|
||||
|
||||
// TestDepositBlocksUntilExpiry checks blocks-until-expiry handling for
|
||||
|
|
@ -21,3 +25,62 @@ func TestDepositBlocksUntilExpiry(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestWithdrawAllDepositOutpoints checks `all` withdrawal handling for
|
||||
// confirmed and unconfirmed deposits.
|
||||
func TestWithdrawAllDepositOutpoints(t *testing.T) {
|
||||
t.Run("rejects unconfirmed", func(t *testing.T) {
|
||||
deposits := []*deposit.Deposit{
|
||||
{
|
||||
OutPoint: wire.OutPoint{
|
||||
Hash: chainhash.Hash{1},
|
||||
Index: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
OutPoint: wire.OutPoint{
|
||||
Hash: chainhash.Hash{2},
|
||||
Index: 2,
|
||||
},
|
||||
ConfirmationHeight: 123,
|
||||
},
|
||||
}
|
||||
|
||||
_, err := withdrawAllDepositOutpoints(deposits)
|
||||
if err == nil {
|
||||
t.Fatal("expected unconfirmed deposit to fail all withdrawal")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("returns all confirmed", func(t *testing.T) {
|
||||
first := wire.OutPoint{
|
||||
Hash: chainhash.Hash{3},
|
||||
Index: 3,
|
||||
}
|
||||
second := wire.OutPoint{
|
||||
Hash: chainhash.Hash{4},
|
||||
Index: 4,
|
||||
}
|
||||
deposits := []*deposit.Deposit{
|
||||
{
|
||||
OutPoint: first,
|
||||
ConfirmationHeight: 123,
|
||||
},
|
||||
{
|
||||
OutPoint: second,
|
||||
ConfirmationHeight: 124,
|
||||
},
|
||||
}
|
||||
|
||||
outpoints, err := withdrawAllDepositOutpoints(deposits)
|
||||
if err != nil {
|
||||
t.Fatalf("expected confirmed deposits to succeed: %v", err)
|
||||
}
|
||||
if len(outpoints) != 2 {
|
||||
t.Fatalf("expected 2 outpoints, got %d", len(outpoints))
|
||||
}
|
||||
if outpoints[0] != first || outpoints[1] != second {
|
||||
t.Fatal("expected all confirmed outpoints to remain selected")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue