Skip to content

Commit 4bb7d5e

Browse files
authored
Merge pull request #1179 from GustavoStingelin/feat/static-address-fsm-diagrams
fsm: generate and verify static address diagrams
2 parents 9bccb64 + 2e80b92 commit 4bb7d5e

9 files changed

Lines changed: 198 additions & 46 deletions

File tree

.github/workflows/main.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ jobs:
124124
- name: check
125125
run: make docs-check
126126

127+
- name: check generated FSM diagrams
128+
run: make fsm-check
129+
127130
########################
128131
# run unit-test sqlite3 race
129132
########################

Makefile

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,20 @@ docs-check: docs
194194
fsm:
195195
@$(call print, "Generating state machine docs")
196196
./scripts/fsm-generate.sh;
197-
.PHONY: fsm
197+
198+
FSM_FILES := \
199+
fsm/example_fsm.md \
200+
instantout/fsm.md \
201+
instantout/reservation/fsm.md \
202+
staticaddr/deposit/fsm.md \
203+
staticaddr/loopin/fsm.md
204+
205+
fsm-check: fsm
206+
@$(call print, "Verifying generated state machine docs")
207+
if test -n "$$(git status --porcelain -- $(FSM_FILES))"; then \
208+
echo "Generated FSM diagrams are not up-to-date!"; \
209+
git status --porcelain -- $(FSM_FILES); \
210+
git diff -- $(FSM_FILES); \
211+
exit 1; \
212+
fi
213+
.PHONY: fsm fsm-check

fsm/example_fsm.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
stateDiagram-v2
33
[*] --> InitFSM: OnRequestStuff
44
InitFSM
5-
InitFSM --> StuffSentOut: OnStuffSentOut
65
InitFSM --> StuffFailed: OnError
6+
InitFSM --> StuffSentOut: OnStuffSentOut
77
StuffFailed
88
StuffSentOut
9-
StuffSentOut --> StuffSuccess: OnStuffSuccess
109
StuffSentOut --> StuffFailed: OnError
10+
StuffSentOut --> StuffSuccess: OnStuffSuccess
1111
StuffSuccess
1212
```

fsm/stateparser/stateparser.go

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ import (
1212
"github.com/lightninglabs/loop/fsm"
1313
"github.com/lightninglabs/loop/instantout"
1414
"github.com/lightninglabs/loop/instantout/reservation"
15+
"github.com/lightninglabs/loop/staticaddr/deposit"
16+
"github.com/lightninglabs/loop/staticaddr/loopin"
1517
)
1618

19+
var errInvalidFSMSelector = errors.New("missing or unknown fsm selector")
20+
1721
func main() {
1822
if err := run(); err != nil {
1923
fmt.Println(err)
@@ -35,35 +39,43 @@ func run() error {
3539
return err
3640
}
3741

38-
switch *stateMachine {
42+
states, err := getStates(*stateMachine)
43+
if err != nil {
44+
return err
45+
}
46+
47+
return writeMermaidFile(fp, states)
48+
}
49+
50+
func getStates(stateMachine string) (fsm.States, error) {
51+
switch stateMachine {
3952
case "example":
4053
exampleFSM := &fsm.ExampleFSM{}
41-
err = writeMermaidFile(fp, exampleFSM.GetStates())
42-
if err != nil {
43-
return err
44-
}
54+
return exampleFSM.GetStates(), nil
4555

4656
case "reservation":
4757
reservationFSM := &reservation.FSM{}
48-
err = writeMermaidFile(fp, reservationFSM.GetServerInitiatedReservationStates())
49-
if err != nil {
50-
return err
51-
}
58+
return reservationFSM.GetServerInitiatedReservationStates(), nil
5259

5360
case "instantout":
54-
instantout := &instantout.FSM{}
55-
err = writeMermaidFile(fp, instantout.GetV1ReservationStates())
56-
if err != nil {
57-
return err
58-
}
61+
instantOutFSM := &instantout.FSM{}
62+
return instantOutFSM.GetV1ReservationStates(), nil
63+
64+
case "staticaddr-deposit":
65+
depositFSM := &deposit.FSM{}
66+
return depositFSM.DepositStatesV0(), nil
67+
68+
case "staticaddr-loopin":
69+
loopInFSM := &loopin.FSM{}
70+
return loopInFSM.LoopInStatesV0(), nil
5971

6072
default:
61-
fmt.Println("Missing or wrong argument: fsm must be one of:")
62-
fmt.Println("\treservations")
63-
fmt.Println("\texample")
73+
return nil, fmt.Errorf(
74+
"%w %q; supported selectors: example, instantout, "+
75+
"reservation, staticaddr-deposit, staticaddr-loopin",
76+
errInvalidFSMSelector, stateMachine,
77+
)
6478
}
65-
66-
return nil
6779
}
6880

6981
func writeMermaidFile(filename string, states fsm.States) error {
@@ -86,8 +98,11 @@ func writeMermaidFile(filename string, states fsm.States) error {
8698
state = "[*]"
8799
}
88100
// write transitions
89-
for edge, target := range edges.Transitions {
90-
fmt.Fprintf(&b, "%s --> %s: %s\n", state, target, edge)
101+
for _, edge := range sortedTransitionKeys(edges.Transitions) {
102+
fmt.Fprintf(
103+
&b, "%s --> %s: %s\n", state,
104+
edges.Transitions[fsm.EventType(edge)], edge,
105+
)
91106
}
92107
}
93108

@@ -110,3 +125,14 @@ func sortedKeys(m fsm.States) []string {
110125
sort.Strings(keys)
111126
return keys
112127
}
128+
129+
func sortedTransitionKeys(m fsm.Transitions) []string {
130+
keys := make([]string, len(m))
131+
i := 0
132+
for k := range m {
133+
keys[i] = string(k)
134+
i++
135+
}
136+
sort.Strings(keys)
137+
return keys
138+
}

instantout/fsm.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,41 @@
22
stateDiagram-v2
33
[*] --> Init: OnStart
44
BuildHtlc
5+
BuildHtlc --> InstantOutFailed: OnError
56
BuildHtlc --> PushPreimage: OnHtlcSigReceived
6-
BuildHtlc --> InstantFailedOutFailed: OnError
7-
BuildHtlc --> InstantFailedOutFailed: OnRecover
7+
BuildHtlc --> InstantOutFailed: OnRecover
88
FailedHtlcSweep
9+
FailedHtlcSweep --> PublishHtlcSweep: OnRecover
10+
FinishedHtlcPreimageSweep
911
FinishedSweeplessSweep
1012
Init
13+
Init --> InstantOutFailed: OnError
1114
Init --> SendPaymentAndPollAccepted: OnInit
12-
Init --> InstantFailedOutFailed: OnError
13-
Init --> InstantFailedOutFailed: OnRecover
14-
InstantFailedOutFailed
15+
Init --> InstantOutFailed: OnRecover
16+
InstantOutFailed
1517
PublishHtlc
1618
PublishHtlc --> FailedHtlcSweep: OnError
19+
PublishHtlc --> PublishHtlcSweep: OnHtlcPublished
1720
PublishHtlc --> PublishHtlc: OnRecover
18-
PublishHtlc --> WaitForHtlcSweepConfirmed: OnHtlcBroadcasted
21+
PublishHtlcSweep
22+
PublishHtlcSweep --> FailedHtlcSweep: OnError
23+
PublishHtlcSweep --> WaitForHtlcSweepConfirmed: OnHtlcSweepPublished
24+
PublishHtlcSweep --> PublishHtlcSweep: OnRecover
1925
PushPreimage
26+
PushPreimage --> InstantOutFailed: OnError
27+
PushPreimage --> PublishHtlc: OnErrorPublishHtlc
2028
PushPreimage --> PushPreimage: OnRecover
2129
PushPreimage --> WaitForSweeplessSweepConfirmed: OnSweeplessSweepPublished
22-
PushPreimage --> InstantFailedOutFailed: OnError
23-
PushPreimage --> PublishHtlc: OnErrorPublishHtlc
2430
SendPaymentAndPollAccepted
31+
SendPaymentAndPollAccepted --> InstantOutFailed: OnError
2532
SendPaymentAndPollAccepted --> BuildHtlc: OnPaymentAccepted
26-
SendPaymentAndPollAccepted --> InstantFailedOutFailed: OnError
27-
SendPaymentAndPollAccepted --> InstantFailedOutFailed: OnRecover
33+
SendPaymentAndPollAccepted --> InstantOutFailed: OnRecover
2834
WaitForHtlcSweepConfirmed
35+
WaitForHtlcSweepConfirmed --> FailedHtlcSweep: OnError
2936
WaitForHtlcSweepConfirmed --> FinishedHtlcPreimageSweep: OnHtlcSwept
3037
WaitForHtlcSweepConfirmed --> WaitForHtlcSweepConfirmed: OnRecover
31-
WaitForHtlcSweepConfirmed --> FailedHtlcSweep: OnError
3238
WaitForSweeplessSweepConfirmed
33-
WaitForSweeplessSweepConfirmed --> FinishedSweeplessSweep: OnSweeplessSweepConfirmed
34-
WaitForSweeplessSweepConfirmed --> WaitForSweeplessSweepConfirmed: OnRecover
3539
WaitForSweeplessSweepConfirmed --> PublishHtlc: OnError
40+
WaitForSweeplessSweepConfirmed --> WaitForSweeplessSweepConfirmed: OnRecover
41+
WaitForSweeplessSweepConfirmed --> FinishedSweeplessSweep: OnSweeplessSweepConfirmed
3642
```
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,28 @@
22
stateDiagram-v2
33
[*] --> Init: OnServerRequest
44
Confirmed
5-
Confirmed --> SpendBroadcasted: OnSpendBroadcasted
6-
Confirmed --> TimedOut: OnTimedOut
5+
Confirmed --> Confirmed: OnError
6+
Confirmed --> Locked: OnLocked
77
Confirmed --> Confirmed: OnRecover
8+
Confirmed --> Spent: OnSpent
9+
Confirmed --> TimedOut: OnTimedOut
810
Failed
911
Init
1012
Init --> WaitForConfirmation: OnBroadcast
11-
Init --> Failed: OnRecover
1213
Init --> Failed: OnError
13-
SpendBroadcasted
14-
SpendBroadcasted --> SpendConfirmed: OnSpendConfirmed
15-
SpendConfirmed
14+
Init --> Failed: OnRecover
15+
Locked
16+
Locked --> Locked: OnError
17+
Locked --> Locked: OnRecover
18+
Locked --> Spent: OnSpent
19+
Locked --> TimedOut: OnTimedOut
20+
Locked --> Confirmed: OnUnlocked
21+
Spent
22+
Spent --> Spent: OnSpent
1623
TimedOut
24+
TimedOut --> TimedOut: OnTimedOut
1725
WaitForConfirmation
18-
WaitForConfirmation --> WaitForConfirmation: OnRecover
1926
WaitForConfirmation --> Confirmed: OnConfirmed
27+
WaitForConfirmation --> WaitForConfirmation: OnRecover
2028
WaitForConfirmation --> TimedOut: OnTimedOut
2129
```

scripts/fsm-generate.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
#!/usr/bin/env bash
2+
set -euo pipefail
3+
24
go run ./fsm/stateparser/stateparser.go --out ./fsm/example_fsm.md --fsm example
3-
go run ./fsm/stateparser/stateparser.go --out ./reservation/reservation_fsm.md --fsm reservation
4-
go run ./fsm/stateparser/stateparser.go --out ./instantout/fsm.md --fsm instantout
5+
go run ./fsm/stateparser/stateparser.go --out ./instantout/reservation/fsm.md --fsm reservation
6+
go run ./fsm/stateparser/stateparser.go --out ./instantout/fsm.md --fsm instantout
7+
go run ./fsm/stateparser/stateparser.go --out ./staticaddr/deposit/fsm.md --fsm staticaddr-deposit
8+
go run ./fsm/stateparser/stateparser.go --out ./staticaddr/loopin/fsm.md --fsm staticaddr-loopin

staticaddr/deposit/fsm.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
```mermaid
2+
stateDiagram-v2
3+
[*] --> Deposited: OnStart
4+
ChannelPublished
5+
ChannelPublished --> ChannelPublished: OnExpiry
6+
Deposited
7+
Deposited --> Deposited: OnError
8+
Deposited --> PublishExpirySweep: OnExpiry
9+
Deposited --> LoopingIn: OnLoopInInitiated
10+
Deposited --> OpeningChannel: OnOpeningChannel
11+
Deposited --> Deposited: OnRecover
12+
Deposited --> SweepHtlcTimeout: OnSweepingHtlcTimeout
13+
Deposited --> Withdrawing: OnWithdrawInitiated
14+
Expired
15+
Expired --> Expired: OnExpiry
16+
HtlcTimeoutSwept
17+
HtlcTimeoutSwept --> HtlcTimeoutSwept: OnExpiry
18+
LoopedIn
19+
LoopedIn --> LoopedIn: OnExpiry
20+
LoopingIn
21+
LoopingIn --> Deposited: OnError
22+
LoopingIn --> PublishExpirySweep: OnExpiry
23+
LoopingIn --> LoopingIn: OnLoopInInitiated
24+
LoopingIn --> LoopedIn: OnLoopedIn
25+
LoopingIn --> LoopingIn: OnRecover
26+
LoopingIn --> SweepHtlcTimeout: OnSweepingHtlcTimeout
27+
OpeningChannel
28+
OpeningChannel --> ChannelPublished: OnChannelPublished
29+
OpeningChannel --> Deposited: OnError
30+
OpeningChannel --> OpeningChannel: OnExpiry
31+
OpeningChannel --> OpeningChannel: OnRecover
32+
PublishExpirySweep
33+
PublishExpirySweep --> Deposited: OnError
34+
PublishExpirySweep --> WaitForExpirySweep: OnExpiryPublished
35+
PublishExpirySweep --> PublishExpirySweep: OnRecover
36+
SweepHtlcTimeout
37+
SweepHtlcTimeout --> HtlcTimeoutSwept: OnHtlcTimeoutSwept
38+
SweepHtlcTimeout --> SweepHtlcTimeout: OnRecover
39+
WaitForExpirySweep
40+
WaitForExpirySweep --> Deposited: OnError
41+
WaitForExpirySweep --> Expired: OnExpirySwept
42+
WaitForExpirySweep --> PublishExpirySweep: OnRecover
43+
Withdrawing
44+
Withdrawing --> Deposited: OnError
45+
Withdrawing --> Withdrawing: OnExpiry
46+
Withdrawing --> Withdrawing: OnRecover
47+
Withdrawing --> Withdrawing: OnWithdrawInitiated
48+
Withdrawing --> Withdrawn: OnWithdrawn
49+
Withdrawn
50+
Withdrawn --> Withdrawn: OnExpiry
51+
Withdrawn --> Withdrawn: OnWithdrawn
52+
```

staticaddr/loopin/fsm.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
```mermaid
2+
stateDiagram-v2
3+
[*] --> InitHtlcTx: OnInitHtlc
4+
Failed
5+
HtlcTimeoutSwept
6+
InitHtlcTx
7+
InitHtlcTx --> UnlockDeposits: OnError
8+
InitHtlcTx --> SignHtlcTx: OnHtlcInitiated
9+
InitHtlcTx --> UnlockDeposits: OnRecover
10+
MonitorHtlcTimeoutSweep
11+
MonitorHtlcTimeoutSweep --> Failed: OnError
12+
MonitorHtlcTimeoutSweep --> HtlcTimeoutSwept: OnHtlcTimeoutSwept
13+
MonitorHtlcTimeoutSweep --> MonitorHtlcTimeoutSweep: OnRecover
14+
MonitorInvoiceAndHtlcTx
15+
MonitorInvoiceAndHtlcTx --> UnlockDeposits: OnError
16+
MonitorInvoiceAndHtlcTx --> PaymentReceived: OnPaymentReceived
17+
MonitorInvoiceAndHtlcTx --> MonitorInvoiceAndHtlcTx: OnRecover
18+
MonitorInvoiceAndHtlcTx --> Failed: OnSwapTimedOut
19+
MonitorInvoiceAndHtlcTx --> SweepHtlcTimeout: OnSweepHtlcTimeout
20+
PaymentReceived
21+
PaymentReceived --> SucceededTransitioningFailed: OnError
22+
PaymentReceived --> Succeeded: OnRecover
23+
PaymentReceived --> Succeeded: OnSucceeded
24+
SignHtlcTx
25+
SignHtlcTx --> UnlockDeposits: OnError
26+
SignHtlcTx --> MonitorInvoiceAndHtlcTx: OnHtlcTxSigned
27+
SignHtlcTx --> UnlockDeposits: OnRecover
28+
Succeeded
29+
SucceededTransitioningFailed
30+
SweepHtlcTimeout
31+
SweepHtlcTimeout --> Failed: OnError
32+
SweepHtlcTimeout --> MonitorHtlcTimeoutSweep: OnHtlcTimeoutSweepPublished
33+
SweepHtlcTimeout --> SweepHtlcTimeout: OnRecover
34+
UnlockDeposits
35+
UnlockDeposits --> Failed: OnError
36+
UnlockDeposits --> UnlockDeposits: OnRecover
37+
```

0 commit comments

Comments
 (0)