chanstate: add commitment store subinterface
What changed, and why it matters
This commit is a straightforward internal code reorganization. It moves the existing logic for saving channel commitment updates from one place in the code to another, without changing what the logic actually does. There is no user-facing change and no indication of a security fix.
No security action required. Review as normal refactoring if desired.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch extracts the persistence logic previously embedded in OpenChannel.UpdateCommitment into a new ChannelStateDB.UpdateChannelCommitment method and adds a corresponding OpenChannelCommitmentStore interface in chanstate/interface.go. The KV transaction body, error handling, and returned values remain identical; only the call path and receiver change. OpenChannel.UpdateCommitment now delegates to c.Db.UpdateChannelCommitment and then updates its in-memory LocalCommitment field.
Changed components
channeldb/channel.gochanstate/interface.goInspect captured patch +41 / −8
diff --git a/channeldb/channel.go b/channeldb/channel.go
index e4f12ee..7ded835 100644
--- a/channeldb/channel.go
+++ b/channeldb/channel.go
@@ -2326,11 +2326,29 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
return nil, ErrNoRestoredChannelMutation
}
+ finalHtlcs, err := c.Db.UpdateChannelCommitment(
+ c, newCommitment, unsignedAckedUpdates,
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ c.LocalCommitment = *newCommitment
+
+ return finalHtlcs, nil
+}
+
+// UpdateChannelCommitment updates the local commitment state.
+func (c *ChannelStateDB) UpdateChannelCommitment(channel *OpenChannel,
+ newCommitment *ChannelCommitment,
+ unsignedAckedUpdates []LogUpdate) (map[uint64]bool, error) {
+
var finalHtlcs = make(map[uint64]bool)
- err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
+ err := kvdb.Update(c.backend, func(tx kvdb.RwTx) error {
chanBucket, err := fetchChanBucketRw(
- tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
+ tx, channel.IdentityPub, &channel.FundingOutpoint,
+ channel.ChainHash,
)
if err != nil {
return err
@@ -2338,7 +2356,7 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
// If the channel is marked as borked, then for safety reasons,
// we shouldn't attempt any further updates.
- isBorked, err := c.isBorked(chanBucket)
+ isBorked, err := channel.isBorked(chanBucket)
if err != nil {
return err
}
@@ -2346,7 +2364,7 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
return ErrChanBorked
}
- if err = putChanInfo(chanBucket, c); err != nil {
+ if err = putChanInfo(chanBucket, channel); err != nil {
return fmt.Errorf("unable to store chan info: %w", err)
}
@@ -2401,9 +2419,9 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
// Get the bucket where settled htlcs are recorded if the user
// opted in to storing this information.
var finalHtlcsBucket kvdb.RwBucket
- if c.Db.parent.storeFinalHtlcResolutions {
+ if c.parent.storeFinalHtlcResolutions {
bucket, err := fetchFinalHtlcsBucketRw(
- tx, c.ShortChannelID,
+ tx, channel.ShortChannelID,
)
if err != nil {
return err
@@ -2452,8 +2470,6 @@ func (c *OpenChannel) UpdateCommitment(newCommitment *ChannelCommitment,
return nil, err
}
- c.LocalCommitment = *newCommitment
-
return finalHtlcs, nil
}
diff --git a/chanstate/interface.go b/chanstate/interface.go
index 6f9888a..3e26f2d 100644
--- a/chanstate/interface.go
+++ b/chanstate/interface.go
@@ -41,6 +41,10 @@ type Store[Channel any] interface {
// OpenChannelCloseTxStore owns persisted closing transaction state.
OpenChannelCloseTxStore[Channel]
+ // OpenChannelCommitmentStore owns persisted commitment state for open
+ // channel records.
+ OpenChannelCommitmentStore[Channel]
+
// ClosedChannelStore owns closed-channel summaries and lifecycle
// mutations.
ClosedChannelStore[Channel]
@@ -217,6 +221,19 @@ type OpenChannelCloseTxStore[Channel any] interface {
error)
}
+// OpenChannelCommitmentStore owns persisted commitment state for open channel
+// records.
+type OpenChannelCommitmentStore[Channel any] interface {
+ // UpdateChannelCommitment updates the local commitment state. It
+ // locks in pending local updates received from the remote party and
+ // persists remote log updates that have been acked, but not signed
+ // for yet. The returned map contains all HTLC resolutions locked into
+ // this commitment, keyed by HTLC index.
+ UpdateChannelCommitment(channel Channel,
+ newCommitment *ChannelCommitment,
+ unsignedAckedUpdates []LogUpdate) (map[uint64]bool, error)
+}
+
// ClosedChannelStore owns closed-channel summaries and lifecycle mutations.
type ClosedChannelStore[Channel any] interface {
// FetchClosedChannels attempts to fetch all closed channels from the
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.