reservation: update reservation state machine

This commit updates the reservation statemachine to
allow for locking and spending of the
initial reservation.
pull/633/head
sputn1ck 8 months ago
parent 2df4327cf7
commit b2b8a9523a
No known key found for this signature in database
GPG Key ID: 671103D881A5F0E4

@ -86,8 +86,8 @@ func (r *FSM) SubscribeToConfirmationAction(_ fsm.EventContext) fsm.EventType {
r.reservation.InitiationHeight)
confChan, errConfChan, err := r.cfg.ChainNotifier.RegisterConfirmationsNtfn(
r.ctx, nil, pkscript, DefaultConfTarget,
r.reservation.InitiationHeight,
r.ctx, nil, pkscript, 1,
r.reservation.InitiationHeight-1,
)
if err != nil {
r.Errorf("unable to subscribe to conf notification: %v", err)
@ -143,28 +143,47 @@ func (r *FSM) SubscribeToConfirmationAction(_ fsm.EventContext) fsm.EventType {
// ReservationConfirmedAction waits for the reservation to be either expired or
// waits for other actions to happen.
func (r *FSM) ReservationConfirmedAction(_ fsm.EventContext) fsm.EventType {
blockHeightChan, errEpochChan, err := r.cfg.ChainNotifier.
RegisterBlockEpochNtfn(r.ctx)
func (f *FSM) ReservationConfirmedAction(_ fsm.EventContext) fsm.EventType {
blockHeightChan, errEpochChan, err := f.cfg.ChainNotifier.
RegisterBlockEpochNtfn(f.ctx)
if err != nil {
return r.HandleError(err)
return f.HandleError(err)
}
pkSCript, err := f.reservation.GetPkScript()
if err != nil {
return f.HandleError(err)
}
spendChan, errSpendChan, err := f.cfg.ChainNotifier.RegisterSpendNtfn(
f.ctx, f.reservation.Outpoint, pkSCript,
f.reservation.InitiationHeight,
)
if err != nil {
return f.HandleError(err)
}
for {
select {
case err := <-errEpochChan:
return r.HandleError(err)
return f.HandleError(err)
case err := <-errSpendChan:
return f.HandleError(err)
case blockHeight := <-blockHeightChan:
expired := blockHeight >= int32(r.reservation.Expiry)
expired := blockHeight >= int32(f.reservation.Expiry)
if expired {
r.Debugf("Reservation %v expired",
r.reservation.ID)
f.Debugf("Reservation %v expired",
f.reservation.ID)
return OnTimedOut
}
case <-r.ctx.Done():
case <-spendChan:
return OnSpent
case <-f.ctx.Done():
return fsm.NoOp
}
}

@ -90,7 +90,11 @@ var (
// Failed is the state where the reservation has failed.
Failed = fsm.StateType("Failed")
// Swept is the state where the reservation has been swept by the server.
// Spent is the state where a spend tx has been confirmed.
Spent = fsm.StateType("Spent")
// Swept is the state where the reservation has been swept by the
// server.
Swept = fsm.StateType("Swept")
)
@ -119,6 +123,10 @@ var (
// OnRecover is the event that is triggered when the reservation FSM
// recovers from a restart.
OnRecover = fsm.EventType("OnRecover")
// OnSpent is the event that is triggered when the reservation has been
// spent.
OnSpent = fsm.EventType("OnSpent")
)
// GetReservationStates returns the statemap that defines the reservation
@ -149,6 +157,7 @@ func (f *FSM) GetReservationStates() fsm.States {
},
Confirmed: fsm.State{
Transitions: fsm.Transitions{
OnSpent: Spent,
OnTimedOut: TimedOut,
OnRecover: Confirmed,
},
@ -157,6 +166,11 @@ func (f *FSM) GetReservationStates() fsm.States {
TimedOut: fsm.State{
Action: fsm.NoOpAction,
},
Spent: fsm.State{
Action: fsm.NoOpAction,
},
Failed: fsm.State{
Action: fsm.NoOpAction,
},
@ -208,7 +222,7 @@ func (r *FSM) Errorf(format string, args ...interface{}) {
// isFinalState returns true if the state is a final state.
func isFinalState(state fsm.StateType) bool {
switch state {
case Failed, Swept, TimedOut:
case Failed, Swept, TimedOut, Spent:
return true
}
return false

@ -251,3 +251,22 @@ func (m *Manager) RecoverReservations(ctx context.Context) error {
func (m *Manager) GetReservations(ctx context.Context) ([]*Reservation, error) {
return m.cfg.Store.ListReservations(ctx)
}
// GetReservation returns the reservation for the given id.
func (m *Manager) GetReservation(ctx context.Context, id ID) (*Reservation,
error) {
return m.cfg.Store.GetReservation(ctx, id)
}
// LockReservation locks the reservation for the given id.
func (m *Manager) LockReservation(ctx context.Context, id ID) error {
// TODO(sputn1ck): implement
return nil
}
// UnlockReservation unlocks the reservation for the given id.
func (m *Manager) UnlockReservation(ctx context.Context, id ID) error {
// TODO(sputn1ck): implement
return nil
}

@ -2,6 +2,7 @@
stateDiagram-v2
[*] --> Init: OnServerRequest
Confirmed
Confirmed --> SpendBroadcasted: OnSpendBroadcasted
Confirmed --> TimedOut: OnTimedOut
Confirmed --> Confirmed: OnRecover
Failed
@ -9,6 +10,9 @@ Init
Init --> Failed: OnError
Init --> WaitForConfirmation: OnBroadcast
Init --> Failed: OnRecover
SpendBroadcasted
SpendBroadcasted --> SpendConfirmed: OnSpendConfirmed
SpendConfirmed
TimedOut
WaitForConfirmation
WaitForConfirmation --> WaitForConfirmation: OnRecover

Loading…
Cancel
Save