What changed, and why it matters
This commit is a straightforward internal code reorganization. It moves the database-reading logic for three channel-state queries from the OpenChannel object to a new ChannelStateDB helper, and adds matching method declarations to an interface. The actual data format, read behavior, and locking are unchanged. There is no visible security fix or vulnerability being introduced.
No security action required; treat as normal refactoring. Reviewers may verify that the delegation preserves the existing RLock behavior and that callers still obtain the same values.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors three read-only methods—CommitmentHeight, LatestCommitments, and RemoteRevocationStore—so the KV view transaction bodies live on ChannelStateDB instead of OpenChannel. The OpenChannel receivers now delegate to c.Db.
Changed components
channeldb/channel.gochanstate/interface.goInspect captured patch +57 / −10
diff --git a/channeldb/channel.go b/channeldb/channel.go
index 3972916..97ae6a5 100644
--- a/channeldb/channel.go
+++ b/channeldb/channel.go
@@ -3595,12 +3595,24 @@ func (c *OpenChannel) CommitmentHeight() (uint64, error) {
c.RLock()
defer c.RUnlock()
+ return c.Db.CommitmentHeight(c)
+}
+
+// CommitmentHeight returns the current commitment height. The commitment
+// height represents the number of updates to the commitment state to date.
+// This value is always monotonically increasing. This method is provided in
+// order to allow multiple instances of a particular open channel to obtain a
+// consistent view of the number of channel updates to date.
+func (c *ChannelStateDB) CommitmentHeight(channel *OpenChannel) (
+ uint64, error) {
+
var height uint64
- err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
+ err := kvdb.View(c.backend, func(tx kvdb.RTx) error {
// Get the bucket dedicated to storing the metadata for open
// channels.
chanBucket, err := fetchChanBucket(
- tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
+ tx, channel.IdentityPub, &channel.FundingOutpoint,
+ channel.ChainHash,
)
if err != nil {
return err
@@ -4089,21 +4101,32 @@ func (c *OpenChannel) Copy() *OpenChannel {
// latest fully committed state is returned. The first commitment returned is
// the local commitment, and the second returned is the remote commitment.
func (c *OpenChannel) LatestCommitments() (*ChannelCommitment, *ChannelCommitment, error) {
- err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
+ return c.Db.LatestCommitments(c)
+}
+
+// LatestCommitments returns the two latest commitments for both the local and
+// remote party. These commitments are read from disk to ensure that only the
+// latest fully committed state is returned. The first commitment returned is
+// the local commitment, and the second returned is the remote commitment.
+func (c *ChannelStateDB) LatestCommitments(channel *OpenChannel) (
+ *ChannelCommitment, *ChannelCommitment, error) {
+
+ err := kvdb.View(c.backend, func(tx kvdb.RTx) error {
chanBucket, err := fetchChanBucket(
- tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
+ tx, channel.IdentityPub, &channel.FundingOutpoint,
+ channel.ChainHash,
)
if err != nil {
return err
}
- return fetchChanCommitments(chanBucket, c)
+ return fetchChanCommitments(chanBucket, channel)
}, func() {})
if err != nil {
return nil, nil, err
}
- return &c.LocalCommitment, &c.RemoteCommitment, nil
+ return &channel.LocalCommitment, &channel.RemoteCommitment, nil
}
// RemoteRevocationStore returns the most up to date commitment version of the
@@ -4111,21 +4134,32 @@ func (c *OpenChannel) LatestCommitments() (*ChannelCommitment, *ChannelCommitmen
// acting on a possible contract breach to ensure, that the caller has the most
// up to date information required to deliver justice.
func (c *OpenChannel) RemoteRevocationStore() (shachain.Store, error) {
- err := kvdb.View(c.Db.backend, func(tx kvdb.RTx) error {
+ return c.Db.RemoteRevocationStore(c)
+}
+
+// RemoteRevocationStore returns the most up to date commitment version of the
+// revocation storage tree for the remote party. This method can be used when
+// acting on a possible contract breach to ensure, that the caller has the most
+// up to date information required to deliver justice.
+func (c *ChannelStateDB) RemoteRevocationStore(channel *OpenChannel) (
+ shachain.Store, error) {
+
+ err := kvdb.View(c.backend, func(tx kvdb.RTx) error {
chanBucket, err := fetchChanBucket(
- tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
+ tx, channel.IdentityPub, &channel.FundingOutpoint,
+ channel.ChainHash,
)
if err != nil {
return err
}
- return fetchChanRevocationState(chanBucket, c)
+ return fetchChanRevocationState(chanBucket, channel)
}, func() {})
if err != nil {
return nil, err
}
- return c.RevocationStore, nil
+ return channel.RevocationStore, nil
}
// AbsoluteThawHeight determines a frozen channel's absolute thaw height. If the
diff --git a/chanstate/interface.go b/chanstate/interface.go
index 919f997..8730184 100644
--- a/chanstate/interface.go
+++ b/chanstate/interface.go
@@ -9,6 +9,7 @@ import (
"github.com/lightningnetwork/lnd/graph/db/models"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
+ "github.com/lightningnetwork/lnd/shachain"
)
// Store is the full persistence contract for the channel-state subsystem.
@@ -264,6 +265,18 @@ type OpenChannelCommitmentStore[Channel any] interface {
AdvanceCommitChainTail(channel Channel, fwdPkg *FwdPkg,
updates []LogUpdate, ourOutputIndex,
theirOutputIndex uint32) error
+
+ // CommitmentHeight returns the current persisted commitment height.
+ CommitmentHeight(channel Channel) (uint64, error)
+
+ // LatestCommitments returns the two latest commitments for both the
+ // local and remote party.
+ LatestCommitments(channel Channel) (*ChannelCommitment,
+ *ChannelCommitment, error)
+
+ // RemoteRevocationStore returns the most up to date commitment version
+ // of the revocation storage tree for the remote party.
+ RemoteRevocationStore(channel Channel) (shachain.Store, error)
}
// OpenChannelFwdPkgStore owns forwarding packages tied to open channel records.
Why this scored 12/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.