Skip to content

Commit 26a36c3

Browse files
committed
WIP: add chain notifier readiness guard
- add waitForChainNotifierReady helper that retries RegisterBlockEpochNtfn until the notifier accepts a stream or the context cancels - call the helper immediately after the full lnd client connects so every integrated subserver starts only after lnd’s chain notifier is ready
1 parent aabf8e9 commit 26a36c3

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

chain_notifier_wait.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package terminal
2+
3+
import (
4+
"context"
5+
"strings"
6+
"time"
7+
8+
"github.com/lightninglabs/lndclient"
9+
"google.golang.org/grpc/codes"
10+
"google.golang.org/grpc/status"
11+
)
12+
13+
const (
14+
chainNotifierStartupMessage = "chain notifier RPC is still in the " +
15+
"process of starting"
16+
)
17+
18+
// waitForChainNotifierReady blocks until lnd's chain notifier accepts a block
19+
// epoch subscription or the provided context is canceled.
20+
func waitForChainNotifierReady(ctx context.Context,
21+
notifier lndclient.ChainNotifierClient) error {
22+
23+
const (
24+
initialBackoff = 200 * time.Millisecond
25+
maxBackoff = 5 * time.Second
26+
streamGrace = 2 * time.Second
27+
)
28+
29+
backoff := initialBackoff
30+
31+
for {
32+
select {
33+
case <-ctx.Done():
34+
return ctx.Err()
35+
36+
default:
37+
}
38+
39+
attemptCtx, cancel := context.WithCancel(ctx)
40+
blockChan, errChan, err := notifier.RegisterBlockEpochNtfn(attemptCtx)
41+
if err != nil {
42+
cancel()
43+
44+
isStartupErr := status.Code(err) == codes.Unavailable ||
45+
strings.Contains(err.Error(),
46+
chainNotifierStartupMessage)
47+
if !isStartupErr {
48+
return err
49+
}
50+
51+
log.Warnf("Chain notifier RPC not ready, retrying in %v: %v",
52+
backoff, err)
53+
} else {
54+
timer := time.NewTimer(streamGrace)
55+
56+
select {
57+
case <-blockChan:
58+
go drainReadinessNtfn(
59+
attemptCtx, cancel, blockChan, errChan,
60+
)
61+
return nil
62+
63+
case err = <-errChan:
64+
cancel()
65+
66+
log.Warnf("Chain notifier stream ended early, "+
67+
"retrying: %v", err)
68+
69+
case <-timer.C:
70+
go drainReadinessNtfn(
71+
attemptCtx, cancel, blockChan, errChan,
72+
)
73+
return nil
74+
75+
case <-ctx.Done():
76+
cancel()
77+
return ctx.Err()
78+
}
79+
}
80+
81+
select {
82+
case <-time.After(backoff):
83+
84+
case <-ctx.Done():
85+
return ctx.Err()
86+
}
87+
88+
backoff *= 2
89+
if backoff > maxBackoff {
90+
backoff = maxBackoff
91+
}
92+
}
93+
}
94+
95+
// drainReadinessNtfn discards notifications until the daemon shuts down,
96+
// allowing the readiness subscription to stay open without affecting lnd logs.
97+
func drainReadinessNtfn(ctx context.Context, cancel func(),
98+
blockChan <-chan int32, errChan <-chan error) {
99+
100+
defer cancel()
101+
102+
for {
103+
select {
104+
case <-blockChan:
105+
106+
case <-errChan:
107+
return
108+
109+
case <-ctx.Done():
110+
return
111+
}
112+
}
113+
}

docs/release-notes/release-notes-0.16.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,15 @@ and also added coverage to verify support for channel versioning:
4141

4242
* Updated [`lnd` to
4343
`v0.20.0-beta.rc2`](https://github.com/lightninglabs/lightning-terminal/pull/1163).
44+
* Updated [`lnd` to
45+
`v0.20.0-beta`](https://github.com/lightninglabs/lightning-terminal/pull/1173).
4446

4547
### Loop
4648

4749
* Updated [`loop` to
4850
`v0.31.5-beta`](https://github.com/lightninglabs/lightning-terminal/pull/1163).
51+
* Updated [`loop` to
52+
`v0.31.6-beta`](https://github.com/lightninglabs/lightning-terminal/pull/1173).
4953

5054
### Pool
5155

@@ -55,5 +59,7 @@ and also added coverage to verify support for channel versioning:
5559

5660
* Updated [`taproot-assets` to
5761
`v0.7.0-rc2`](https://github.com/lightninglabs/lightning-terminal/pull/1163).
62+
* Updated [`taproot-assets` to
63+
`v0.7.0`](https://github.com/lightninglabs/lightning-terminal/pull/1173).
5864

5965
# Contributors (Alphabetical Order)

terminal.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,16 @@ func (g *LightningTerminal) setupFullLNDClient(ctx context.Context,
956956
if err == nil {
957957
log.Infof("Full lnd client connected")
958958

959+
log.Infof("Waiting for chain notifier to become available")
960+
err = waitForChainNotifierReady(
961+
ctx, g.lndClient.ChainNotifier,
962+
)
963+
if err != nil {
964+
return fmt.Errorf("waiting for chain notifier: %w",
965+
err)
966+
}
967+
log.Infof("Chain notifier ready")
968+
959969
break
960970
}
961971

0 commit comments

Comments
 (0)