Skip to content

Commit 6de0615

Browse files
committed
protofsm: allow multiple internal events to be emitted
In this commit, we update the execution logic to allow multiple internal events to be emitted. This is useful to handle potential out of order state transitions, as they can be cached, then emitted once the relevant pre-conditions have been met.
1 parent 847c1a7 commit 6de0615

File tree

3 files changed

+25
-25
lines changed

3 files changed

+25
-25
lines changed

protofsm/log.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var log btclog.Logger
1212

1313
// The default amount of logging is none.
1414
func init() {
15-
UseLogger(build.NewSubLogger("PRCL", nil))
15+
UseLogger(build.NewSubLogger("PFSM", nil))
1616
}
1717

1818
// DisableLog disables all library log output. Logging output is disabled

protofsm/state_machine.go

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"github.com/btcsuite/btcd/btcec/v2"
99
"github.com/btcsuite/btcd/chaincfg/chainhash"
1010
"github.com/btcsuite/btcd/wire"
11-
"github.com/davecgh/go-spew/spew"
1211
"github.com/lightningnetwork/lnd/chainntnfs"
1312
"github.com/lightningnetwork/lnd/fn"
1413
"github.com/lightningnetwork/lnd/lnutils"
@@ -28,7 +27,7 @@ type EmittedEvent[Event any] struct {
2827
// InternalEvent is an optional internal event that is to be routed
2928
// back to the target state. This enables state to trigger one or many
3029
// state transitions without a new external event.
31-
InternalEvent fn.Option[Event]
30+
InternalEvent fn.Option[[]Event]
3231

3332
// ExternalEvent is an optional external event that is to be sent to
3433
// the daemon for dispatch. Usually, this is some form of I/O.
@@ -329,7 +328,7 @@ func (s *StateMachine[Event, Env]) executeDaemonEvent( //nolint:funlen
329328
// any preconditions as well as post-send events.
330329
case *SendMsgEvent[Event]:
331330
sendAndCleanUp := func() error {
332-
log.Debugf("FSM(%v): sending message to target(%v): "+
331+
log.Debugf("FSM(%v): sending message to target(%x): "+
333332
"%v", s.cfg.Env.Name(),
334333
daemonEvent.TargetPeer.SerializeCompressed(),
335334
lnutils.SpewLogClosure(daemonEvent.Msgs),
@@ -451,7 +450,11 @@ func (s *StateMachine[Event, Env]) executeDaemonEvent( //nolint:funlen
451450
defer s.wg.Done()
452451
for {
453452
select {
454-
case spend := <-spendEvent.Spend:
453+
case spend, ok := <-spendEvent.Spend:
454+
if !ok {
455+
return
456+
}
457+
455458
// If there's a post-send event, then
456459
// we'll send that into the current
457460
// state now.
@@ -522,11 +525,8 @@ func (s *StateMachine[Event, Env]) applyEvents(currentState State[Event, Env],
522525
newEvent Event) (State[Event, Env], error) {
523526

524527
log.Debugf("FSM(%v): applying new event", s.cfg.Env.Name(),
525-
lnutils.NewLogClosure(func() string {
526-
return spew.Sdump(newEvent)
527-
}),
528+
lnutils.SpewLogClosure(newEvent),
528529
)
529-
530530
eventQueue := fn.NewQueue(newEvent)
531531

532532
// Given the next event to handle, we'll process the event, then add
@@ -539,9 +539,7 @@ func (s *StateMachine[Event, Env]) applyEvents(currentState State[Event, Env],
539539
err := fn.MapOptionZ(nextEvent, func(event Event) error {
540540
log.Debugf("FSM(%v): processing event: %v",
541541
s.cfg.Env.Name(),
542-
lnutils.NewLogClosure(func() string {
543-
return spew.Sdump(event)
544-
}),
542+
lnutils.SpewLogClosure(event),
545543
)
546544

547545
// Apply the state transition function of the current
@@ -584,19 +582,19 @@ func (s *StateMachine[Event, Env]) applyEvents(currentState State[Event, Env],
584582
// our event queue.
585583
//
586584
//nolint:lll
587-
events.InternalEvent.WhenSome(func(es Event) {
588-
log.Debugf("FSM(%v): adding "+
589-
"new internal event "+
590-
"to queue: %v",
591-
s.cfg.Env.Name(),
592-
lnutils.NewLogClosure(func() string { //nolint:lll
593-
return spew.Sdump( //nolint:lll
594-
es,
595-
)
596-
}),
597-
)
585+
events.InternalEvent.WhenSome(func(es []Event) {
586+
for _, inEvent := range es {
587+
log.Debugf("FSM(%v): adding "+
588+
"new internal event "+
589+
"to queue: %v",
590+
s.cfg.Env.Name(),
591+
lnutils.SpewLogClosure(
592+
inEvent,
593+
),
594+
)
598595

599-
eventQueue.Enqueue(es)
596+
eventQueue.Enqueue(inEvent)
597+
}
600598
})
601599

602600
return nil

protofsm/state_machine_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ func (d *dummyStateStart) ProcessEvent(event dummyEvents, env *dummyEnv,
8080
return &StateTransition[dummyEvents, *dummyEnv]{
8181
NextState: &dummyStateStart{},
8282
NewEvents: fn.Some(EmittedEvent[dummyEvents]{
83-
InternalEvent: fn.Some(dummyEvents(&goToFin{})),
83+
InternalEvent: fn.Some(
84+
[]dummyEvents{&goToFin{}},
85+
),
8486
}),
8587
}, nil
8688

0 commit comments

Comments
 (0)