What changed, and why it matters
This commit fixes a bug in LND's code that creates a copy of an open Lightning payment channel. The copy function was accidentally leaving out two pieces of channel data: the height at which the channel was confirmed as closed, and a database reference. That meant any code working on a copy could see slightly different channel state than the original, which could lead to wrong decisions about closing, settling, or recording channels. The fix simply copies those two missing fields. There is no direct evidence this is exploitable as an attack, but silent data divergence in financial software is a security-relevant bug.
Treat as a correctness/security hygiene fix: review all consumers of OpenChannel.Copy() to confirm no stale or inconsistent state was relied upon, include in routine release notes, and consider backporting to stable branches. No immediate emergency response is indicated by the supplied evidence.
Security signals we found
Silent data divergence in channel state copy
Missing close-confirmation height in clone
Missing database handle in clone
Potential inconsistent state for downstream consumers
No explicit security disclosure or CVE in commit or references
Evidence from the diff
OpenChannel.Copy() in chanstate/open_channel.go omitted CloseConfirmationHeight and Db when constructing a clone. CloseConfirmationHeight tracks the block height at which a channel close was confirmed; Db is the channel’s database handle. Consumers that rely on Copy() to produce a faithful snapshot therefore operated on a subtly inconsistent view of the channel. The patch adds both fields to the copied struct. Because the bug is a silent omission rather than an obvious crash, it could mask incorrect state transitions or reporting. No exploit path, CVE, or vendor security disclosure is present in the supplied materials.
Changed components
chanstate/open_channel.goOpenChannel.Copy() methodLightning Network channel state managementInspect captured patch +2 / −0
diff --git a/chanstate/open_channel.go b/chanstate/open_channel.go
index 5aefc18..2b96a07 100644
--- a/chanstate/open_channel.go
+++ b/chanstate/open_channel.go
@@ -1118,6 +1118,7 @@ func (c *OpenChannel) Copy() *OpenChannel {
chanStatus: c.chanStatus,
FundingBroadcastHeight: c.FundingBroadcastHeight,
ConfirmationHeight: c.ConfirmationHeight,
+ CloseConfirmationHeight: c.CloseConfirmationHeight,
NumConfsRequired: c.NumConfsRequired,
ChannelFlags: c.ChannelFlags,
IdentityPub: c.IdentityPub,
@@ -1139,6 +1140,7 @@ func (c *OpenChannel) Copy() *OpenChannel {
RevocationKeyLocator: c.RevocationKeyLocator,
confirmedScid: c.confirmedScid,
TapscriptRoot: c.TapscriptRoot,
+ Db: c.Db,
}
if c.FundingTxn != nil {
Why this scored 30/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.