mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
staticaddr/deposit: ignore queued expiry in final states
A block notification can queue OnExpiry before a deposit reaches a final state. If the final transition wins that race first, the stale expiry event must not overwrite the terminal outcome. Keep LoopedIn and Withdrawn as self-loops on OnExpiry, matching the other final states. Add a focused FSM test that sends OnExpiry directly to each final state and verifies the state is preserved.
This commit is contained in:
parent
d8b24d31c0
commit
f468f24e6f
2 changed files with 49 additions and 2 deletions
|
|
@ -393,7 +393,7 @@ func (f *FSM) DepositStatesV0() fsm.States {
|
|||
},
|
||||
LoopedIn: fsm.State{
|
||||
Transitions: fsm.Transitions{
|
||||
OnExpiry: Expired,
|
||||
OnExpiry: LoopedIn,
|
||||
},
|
||||
Action: f.FinalizeDepositAction,
|
||||
},
|
||||
|
|
@ -412,7 +412,7 @@ func (f *FSM) DepositStatesV0() fsm.States {
|
|||
},
|
||||
Withdrawn: fsm.State{
|
||||
Transitions: fsm.Transitions{
|
||||
OnExpiry: Expired,
|
||||
OnExpiry: Withdrawn,
|
||||
OnWithdrawn: Withdrawn,
|
||||
},
|
||||
Action: f.FinalizeDepositAction,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,53 @@ func TestHandleBlockNotificationIgnoresFinalStates(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestFinalStatesIgnoreQueuedExpiry verifies that a queued OnExpiry event cannot
|
||||
// overwrite a deposit that already reached a final state.
|
||||
func TestFinalStatesIgnoreQueuedExpiry(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
finalStates := []fsm.StateType{
|
||||
Expired,
|
||||
Withdrawn,
|
||||
LoopedIn,
|
||||
HtlcTimeoutSwept,
|
||||
ChannelPublished,
|
||||
}
|
||||
|
||||
for i, state := range finalStates {
|
||||
t.Run(string(state), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
outpoint := wire.OutPoint{
|
||||
Hash: chainhash.Hash{byte(i + 1)},
|
||||
Index: uint32(i),
|
||||
}
|
||||
deposit := &Deposit{
|
||||
OutPoint: outpoint,
|
||||
}
|
||||
deposit.SetState(state)
|
||||
|
||||
depositFSM := &FSM{
|
||||
cfg: &ManagerConfig{
|
||||
Store: new(mockStore),
|
||||
},
|
||||
deposit: deposit,
|
||||
quitChan: make(chan struct{}),
|
||||
finalizedDepositChan: make(chan wire.OutPoint, 1),
|
||||
}
|
||||
depositFSM.StateMachine = fsm.NewStateMachineWithState(
|
||||
depositFSM.DepositStatesV0(), state,
|
||||
DefaultObserverSize,
|
||||
)
|
||||
depositFSM.ActionEntryFunc = depositFSM.updateDeposit
|
||||
|
||||
err := depositFSM.SendEvent(t.Context(), OnExpiry, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, state, deposit.GetState())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestLoopingInTransitionsToSweepHtlcTimeout verifies that a deposit selected
|
||||
// by a loop-in can be moved into the timeout sweep state if the server confirms
|
||||
// the HTLC without paying the invoice.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue