@@ -29,6 +29,7 @@ type transitionCall struct {
2929}
3030
3131type mockDepositManager struct {
32+ activeDeposits []* deposit.Deposit
3233 openingDeposits []* deposit.Deposit
3334 getErr error
3435 transitionErrs map [fsm.EventType ]error
@@ -44,15 +45,19 @@ func (m *mockDepositManager) AllOutpointsActiveDeposits([]wire.OutPoint,
4445func (m * mockDepositManager ) GetActiveDepositsInState (stateFilter fsm.StateType ) (
4546 []* deposit.Deposit , error ) {
4647
47- if stateFilter != deposit .OpeningChannel {
48- return nil , nil
49- }
48+ switch stateFilter {
49+ case deposit .Deposited :
50+ return m .activeDeposits , nil
51+
52+ case deposit .OpeningChannel :
53+ if m .getErr != nil {
54+ return nil , m .getErr
55+ }
5056
51- if m .getErr != nil {
52- return nil , m .getErr
57+ return m .openingDeposits , nil
5358 }
5459
55- return m . openingDeposits , nil
60+ return nil , nil
5661}
5762
5863func (m * mockDepositManager ) TransitionDeposits (_ context.Context ,
@@ -464,6 +469,97 @@ func TestOpenChannelDuplicateOutpoints(t *testing.T) {
464469 require .ErrorContains (t , err , "duplicate outpoint" )
465470}
466471
472+ // TestOpenChannelSkipsUnconfirmedAutoSelection verifies that automatic coin
473+ // selection ignores mempool deposits and keeps using confirmed ones.
474+ func TestOpenChannelSkipsUnconfirmedAutoSelection (t * testing.T ) {
475+ t .Parallel ()
476+
477+ confirmedA := & deposit.Deposit {
478+ OutPoint : testOutPoint (1 ),
479+ Value : 160_000 ,
480+ ConfirmationHeight : 10 ,
481+ }
482+ confirmedB := & deposit.Deposit {
483+ OutPoint : testOutPoint (2 ),
484+ Value : 140_000 ,
485+ ConfirmationHeight : 11 ,
486+ }
487+ unconfirmed := & deposit.Deposit {
488+ OutPoint : testOutPoint (3 ),
489+ Value : 500_000 ,
490+ }
491+
492+ depositManager := & mockDepositManager {
493+ activeDeposits : []* deposit.Deposit {
494+ unconfirmed , confirmedA , confirmedB ,
495+ },
496+ transitionErrs : map [fsm.EventType ]error {
497+ deposit .OnOpeningChannel : errors .New ("stop after selection" ),
498+ },
499+ }
500+ manager := & Manager {
501+ cfg : & Config {
502+ DepositManager : depositManager ,
503+ },
504+ }
505+
506+ req := & lnrpc.OpenChannelRequest {
507+ NodePubkey : make ([]byte , 33 ),
508+ LocalFundingAmount : 100_000 ,
509+ SatPerVbyte : 10 ,
510+ }
511+
512+ _ , err := manager .OpenChannel (context .Background (), req )
513+ require .ErrorContains (t , err , "stop after selection" )
514+ require .Len (t , depositManager .calls , 1 )
515+ require .Equal (t , deposit .OnOpeningChannel , depositManager .calls [0 ].event )
516+ require .NotContains (t , depositManager .calls [0 ].outpoints , unconfirmed .OutPoint )
517+ }
518+
519+ // TestOpenChannelFundMaxSkipsUnconfirmed verifies that fundmax only locks
520+ // confirmed deposits.
521+ func TestOpenChannelFundMaxSkipsUnconfirmed (t * testing.T ) {
522+ t .Parallel ()
523+
524+ confirmed := & deposit.Deposit {
525+ OutPoint : testOutPoint (1 ),
526+ Value : 200_000 ,
527+ ConfirmationHeight : 10 ,
528+ }
529+ unconfirmed := & deposit.Deposit {
530+ OutPoint : testOutPoint (2 ),
531+ Value : 300_000 ,
532+ }
533+
534+ depositManager := & mockDepositManager {
535+ activeDeposits : []* deposit.Deposit {
536+ unconfirmed , confirmed ,
537+ },
538+ transitionErrs : map [fsm.EventType ]error {
539+ deposit .OnOpeningChannel : errors .New ("stop after selection" ),
540+ },
541+ }
542+ manager := & Manager {
543+ cfg : & Config {
544+ DepositManager : depositManager ,
545+ },
546+ }
547+
548+ req := & lnrpc.OpenChannelRequest {
549+ NodePubkey : make ([]byte , 33 ),
550+ FundMax : true ,
551+ SatPerVbyte : 10 ,
552+ }
553+
554+ _ , err := manager .OpenChannel (context .Background (), req )
555+ require .ErrorContains (t , err , "stop after selection" )
556+ require .Len (t , depositManager .calls , 1 )
557+ require .Equal (
558+ t , []wire.OutPoint {confirmed .OutPoint },
559+ depositManager .calls [0 ].outpoints ,
560+ )
561+ }
562+
467563// TestValidateInitialPsbtFlags verifies that request fields incompatible with
468564// PSBT funding are rejected early, before any deposits are locked.
469565func TestValidateInitialPsbtFlags (t * testing.T ) {
0 commit comments