What changed, and why it matters
This commit is a straightforward internal code refactor. It moves the logic for saving a newly created pending Lightning channel from one place in the code to another, without changing what data is written or how users interact with the software. There is no indication of a security fix or vulnerability.
No security action required. Review as normal code-quality refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors the pending-channel persistence path in LND’s channeldb. It introduces a SyncPendingChannel method on ChannelStateDB and adds it to the chanstate.OpenChannelLifecycleStore interface. The OpenChannel.SyncPending receiver is changed to delegate to c.Db.SyncPendingChannel(...). The syncNewChannel helper now takes the kvdb.Backend explicitly rather than reading it from c.Db.backend. This is an architectural cleanup to keep backend references out of OpenChannel and centralize lifecycle store operations; no security-relevant behavioral change is visible in the diff.
Changed components
channeldb/channel.gochanneldb/db.gochanstate/interface.goInspect captured patch +24 / −7
diff --git a/channeldb/channel.go b/channeldb/channel.go
index 5b02de1..bd810e7 100644
--- a/channeldb/channel.go
+++ b/channeldb/channel.go
@@ -2347,16 +2347,26 @@ func (c *OpenChannel) SyncPending(addr net.Addr, pendingHeight uint32) error {
c.Lock()
defer c.Unlock()
- c.FundingBroadcastHeight = pendingHeight
+ return c.Db.SyncPendingChannel(c, addr, pendingHeight)
+}
- return kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
- return syncNewChannel(tx, c, []net.Addr{addr})
+// SyncPendingChannel writes a pending channel to the store and records the
+// funding broadcast height.
+func (c *ChannelStateDB) SyncPendingChannel(channel *OpenChannel,
+ addr net.Addr, pendingHeight uint32) error {
+
+ channel.FundingBroadcastHeight = pendingHeight
+
+ return kvdb.Update(c.backend, func(tx kvdb.RwTx) error {
+ return syncNewChannel(tx, channel, []net.Addr{addr}, c.backend)
}, func() {})
}
// syncNewChannel will write the passed channel to disk, and also create a
// LinkNode (if needed) for the channel peer.
-func syncNewChannel(tx kvdb.RwTx, c *OpenChannel, addrs []net.Addr) error {
+func syncNewChannel(tx kvdb.RwTx, c *OpenChannel, addrs []net.Addr,
+ backend kvdb.Backend) error {
+
// First, sync all the persistent channel state to disk.
if err := fullSyncOpenChannel(tx, c); err != nil {
return err
@@ -2378,8 +2388,8 @@ func syncNewChannel(tx kvdb.RwTx, c *OpenChannel, addrs []net.Addr) error {
// for this channel. The LinkNode metadata contains reachability,
// up-time, and service bits related information.
linkNode := NewLinkNode(
- &LinkNodeDB{backend: c.Db.backend},
- wire.MainNet, c.IdentityPub, addrs...,
+ &LinkNodeDB{backend: backend}, wire.MainNet, c.IdentityPub,
+ addrs...,
)
// TODO(roasbeef): do away with link node all together?
diff --git a/channeldb/db.go b/channeldb/db.go
index a516242..1f80c8d 100644
--- a/channeldb/db.go
+++ b/channeldb/db.go
@@ -1702,7 +1702,7 @@ func (c *ChannelStateDB) RestoreChannelShells(channelShells ...*ChannelShell) er
// is idempotent, we'll continue to the next step.
channel.Db = c
err := syncNewChannel(
- tx, channel, channelShell.NodeAddrs,
+ tx, channel, channelShell.NodeAddrs, c.backend,
)
if err != nil {
return err
diff --git a/chanstate/interface.go b/chanstate/interface.go
index 3752661..6f9888a 100644
--- a/chanstate/interface.go
+++ b/chanstate/interface.go
@@ -1,6 +1,8 @@
package chanstate
import (
+ "net"
+
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/wire/v2"
"github.com/lightningnetwork/lnd/fn/v2"
@@ -122,6 +124,11 @@ type HistoricalChannelStore[Channel any] interface {
// OpenChannelLifecycleStore owns persisted lifecycle state for open channel
// records.
type OpenChannelLifecycleStore[Channel any] interface {
+ // SyncPendingChannel writes a pending channel to the store and records
+ // the funding broadcast height.
+ SyncPendingChannel(channel Channel, addr net.Addr,
+ pendingHeight uint32) error
+
// RefreshChannel updates the in-memory channel state using the latest
// state observed on disk.
RefreshChannel(channel Channel) error
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.