Skip to content

chanstate: move channel state kv store methods#10960

Open
ziggie1984 wants to merge 60 commits into
lightningnetwork:masterfrom
ziggie1984:chanstate-kv-store-move-part2
Open

chanstate: move channel state kv store methods#10960
ziggie1984 wants to merge 60 commits into
lightningnetwork:masterfrom
ziggie1984:chanstate-kv-store-move-part2

Conversation

@ziggie1984

Copy link
Copy Markdown
Collaborator

Context

Part 2 of the channel-state KV-store split. This builds on #10812 and includes the full stacked branch when viewed against master.

What changed

  • Moves channel-state KV storage building blocks into chanstate.
  • Moves higher-level channel-state store methods from channeldb wrappers onto chanstate.KVStore.
  • Delegates ChannelStateDB lifecycle, status, shutdown, close-tx, commitment, forwarding-package, final-HTLC, closed-summary, historical-channel, open-channel read, and abandon-
    channel paths to chanstate.
  • Keeps compatibility wrappers in channeldb while callers are migrated incrementally.

Stack

Verification

  • go test ./chanstate ./channeldb
  • make lint

ziggie1984 added 30 commits July 7, 2026 19:05
Move the funding transaction presence check onto OpenChannel so the
decision lives with the channel-state domain type instead of the KV
serialization helpers in channeldb.

This keeps the existing channeldb encoding behavior unchanged while
removing one backend-independent helper from the KV package.
Move the shared database element codec into the chanstate package so
channel-state serialization helpers can use it without depending on
channeldb. Leave compatibility wrappers in channeldb for existing
callers and keep the peer flap time serialization helpers there because
they are not channel-state code.
Move the current forwarding-package KV implementation into
chanstate/kv_forwarding_package.go and leave channeldb with the
temporary compatibility aliases used by existing callers.

This keeps the forwarding-package store as its own review slice and
leaves migration code untouched.
Move the forwarding-package KV tests next to the implementation in
chanstate. The change keeps the package references updated while leaving
the compatibility aliases in channeldb for existing callers.
Move the current revocation-log KV put and fetch helpers into chanstate
while leaving deprecated-bucket compatibility in channeldb.

The deprecated path still depends on the old commitment decoder, so it
remains with the channeldb commitment serialization until that store is
moved separately.
Move the final-HTLC bucket helpers, byte encoding, and log-update
processing into chanstate so the KV-specific implementation lives with
the channel state package.

Keep channeldb wrappers and aliases in place so existing callers and
tests continue to compile while the remaining channel-state code moves
over in later commits.
Move the shutdown-info key, serialization, and channel-bucket put/fetch
helpers into chanstate.

Leave ChannelStateDB responsible for opening the channel bucket so this
commit only moves the backend-specific record handling for shutdown
state.
Move the data-loss commit point key and channel-bucket put/fetch helpers
into chanstate.

The channeldb methods still own the transaction and status mutation, but
the backend-specific record handling now lives with the channel state
package.
Move the force-close and coop-close transaction keys plus the
channel-bucket put/fetch helpers into chanstate.

ChannelStateDB still owns the status mutation and transaction lookup,
while the backend-specific record encoding now lives with the channel
state package.
Move the temporary channel-opening state bucket and transaction helpers
into chanstate.

Keep channeldb as the compatibility surface and alias ErrChannelNotFound
from chanstate so existing callers keep the same error name while
setup-state storage moves packages.
Move the frozen-channel thaw height key and channel-bucket
fetch/store/delete helpers into chanstate.

The channeldb functions remain as compatibility wrappers while the
larger open-channel storage code is still being moved incrementally.
Move the live channel-state bucket and record key definitions into
chanstate while keeping channeldb aliases for the current callers.

This keeps the on-disk layout documentation next to the channel-state
package before the larger open-channel serialization code is moved.
Move the open-channel bucket lookup helpers and outpoint-closed reader
into chanstate.

Keep channeldb wrappers for the current call sites, and alias the
related lookup errors back from chanstate while the larger channel
storage code continues to move incrementally.
Move outpoint-index status encoding and the closed-index update helper
into chanstate.

The channel open and close flows still live in channeldb, but their
outpoint-index record handling now uses the channel-state KV helpers.
Move the HTLC serialization helpers into chanstate now that the shared
element codec is available there. Keep channeldb wrappers for the
exported helpers so existing callers continue to compile while follow-up
commits move more channel state code.
Move channel commitment serialization into chanstate now that the codec
and HTLC serialization helpers are available there. Leave thin channeldb
wrappers for legacy revocation-log callers while the remaining channeldb
channel state code is split apart.
Move commit diff serialization and the commitment auxiliary TLV helpers
into chanstate so pending remote commitment state no longer depends on
channeldb codecs. Update channeldb callers to use the chanstate helpers
while leaving open-channel bucket persistence in place for later
backend-specific splits.
Move open-channel auxiliary TLV serialization and the key-locator TLV
adapter into chanstate with the rest of the channel-state codecs. Keep
channeldb compatibility wrappers for the exported key-locator encoder
helpers used by existing tests.
Move ChannelConfig serialization helpers next to the ChannelConfig type
instead of adding a standalone serialization file. Keep channeldb
wrappers for existing callers while later commits continue moving the
surrounding open-channel storage code.
Move the commitment, HTLC, commit-diff, and commitment auxiliary TLV
codecs into a single kv_commitment file. This keeps storage
serialization grouped by the commitment domain while preserving the kv_
prefix for backend-specific on-disk helpers.
Move the generic log update serialization helpers into the KV store
files that use them. Keep the shared byte order with the codec, place
commit-diff log update list serialization with commitment storage, and
give forwarding and revocation logs their own key helpers.
Rename the open channel TLV data helper into the KV open channel domain
and fold in the key locator TLV adapter. This keeps the open channel
storage records and their encode/decode helpers in one KV store file
without changing the exported helper API.
Move channel config read/write helpers out of the pure config type file
and into the open channel KV domain file. This keeps storage
serialization colocated with the KV record helpers that use it while
preserving the existing exported helper names.
Move revocation log stream serialization and deserialization helpers
into the revocation KV store file. This keeps the pure revocation log
types separate from the on-disk encoding helpers while preserving the
existing function bodies and comments.
Move AddRef and PkgFilter persistence codecs from the forwarding domain
file into the forwarding KV store file. The forwarding domain types keep
their pure behavior while the KV-specific byte encoding stays next to
the bucket code that stores those values.
Move the SparsePayHash TLV adapter and HTLCEntry stream builder into the
revocation KV store file. These helpers describe the revocation log
on-disk TLV layout, so keep them with the rest of the KV serialization
while the domain file keeps the exported types and constructors.
Move close summary serialization and closed-channel bucket writes into a
dedicated channel state KV store file. Keep the existing channeldb
helper names as thin wrappers so current call sites continue to work
while the storage implementation moves into chanstate.
Move open channel info serialization and upfront shutdown script
persistence into the open channel KV store file. Keep channeldb helper
names as thin wrappers so the remaining channel linker code can continue
using the existing call sites during the move.
Move channel commitment and revocation state bucket persistence into the
channel state KV commitment file. Keep the existing channeldb helper
names as thin wrappers so current call sites continue to work while the
storage implementation moves into chanstate.
Move complete open channel read and write composition into the channel
state KV open channel file. Keep the channeldb helper names as wrappers
so existing store methods can continue to call through while their
implementations move in later commits.
Move the borked-channel bucket check into the channel state KV open
channel file with its existing documentation. Keep channeldb using the
same helper name as a wrapper so commitment update paths continue to
call through unchanged.
Move simple open channel metadata update paths into the channel state KV
open channel file. Keep the ChannelStateDB methods in channeldb as
wrappers while the backend-specific transaction logic shifts into
chanstate.
Move open channel status update logic into the channel state KV open
channel file, including the callback-capable helper used by related
status paths. Keep channeldb methods delegating through their existing
names while transaction and bucket logic continues moving into
chanstate.
Move the channel data-loss status and commit-point fetch paths into the
channel state KV data-loss file. Keep channeldb methods as wrappers so
callers continue using the existing Store interface while KV transaction
logic moves into chanstate.
Move close transaction status updates and close transaction fetch logic
into the channel state KV close transaction file. Keep channeldb methods
delegating to chanstate while preserving the public store surface used
by channel callers.
Move channel shutdown info store and fetch logic into the channel state
KV shutdown file. Keep channeldb methods as wrappers while preserving
the Store interface and shifting KV transaction handling into chanstate.
Move forwarding package store methods into the channel state KV
forwarding package file beside the packager implementation. Keep
channeldb Store methods as wrappers so callers retain the same interface
while forwarding KV transactions move into chanstate.
Move remote commitment tip, unsigned update reads, and next revocation
persistence into the channel state KV commitment file. Keep channeldb
methods as wrappers while commitment transaction logic continues moving
into chanstate.
Move the commit-chain mutation and read paths into the chanstate KV
store implementation. Keep channeldb as a thin wrapper while callers
still use the existing ChannelStateDB surface.
Move revocation-log lookup compatibility and tail-height queries into
the chanstate KV store implementation. Keep channeldb wrappers for
existing tests and callers while the package boundary is being moved.
Move the local commitment update path into the chanstate KV store
implementation. Keep channeldb as the public wrapper and pass the
final-HTLC storage option through to preserve existing behavior.
Move the close/archive channel paths into the chanstate KV store
implementation. Keep channeldb as the public wrapper and preserve the
existing sync/tombstone strategy selection at the boundary.
Move the refresh path into the chanstate open-channel KV store
implementation. Keep channeldb as a public wrapper and remove private
helpers that were only used by the old refresh implementation.
Move the pending open-channel write into the chanstate KV store
implementation while keeping link-node creation in channeldb. Preserve
the existing transaction boundary used by pending channels and restores.
Fold the channel key and thaw-height helpers into the store files
that own them, instead of keeping separate kv files that do not
represent their own stores.

The open-channel keys and thaw-height helpers now live with
kv_open_channel, closed-channel bucket ownership lives with
kv_close_summary, and commitment/update keys live with kv_commitment.
Move the KV-backed ChannelSetupStore implementation onto the
chanstate KVStore. This includes both channel-opening state and initial
forwarding policy persistence, which together make up the setup store
facet.

Keep the channeldb ChannelStateDB methods as compatibility wrappers so
callers can continue using the old package while the concrete KV store
implementation moves by facet.
Move the KV-backed FinalHTLCStore implementation onto KVStore. The
ChannelStateDB methods keep compatibility wrappers while final HTLC
lookup and on-chain outcome writes now live with the final HTLC KV store
code.

Carry the store-final-resolution option into KVStore so the on-chain
outcome path keeps the existing opt-in behavior.
Move the KV-backed OpenChannelFwdPkgStore implementation onto
KVStore. ChannelStateDB keeps the existing wrapper methods, but now
delegates through the channelstate KV store instead of passing its
backend into package-level helpers.

This keeps forwarding package persistence grouped with the existing
kv_forwarding_package code while removing another direct backend use
from the channeldb compatibility layer.
Move the KV-backed OpenChannelShutdownStore methods onto KVStore.
ChannelStateDB keeps the existing compatibility methods, but shutdown
state now flows through the channelstate KV store rather than backend
helper functions.

The bucket-level shutdown codec helper stays in kv_shutdown because it
is still the local serialization primitive used by the store method.
Move the KV-backed OpenChannelCloseTxStore implementation onto
KVStore. ChannelStateDB keeps compatibility wrappers for marking and
fetching broadcast close transactions while the KV logic now lives in
kv_close_tx.

Keep the generic close transaction fetch helper private to KVStore and
expose only the domain methods required by the channelstate interface.
Move the KV-backed OpenChannelStatusStore implementation onto
KVStore. ChannelStateDB keeps compatibility wrappers while status
updates, data-loss commit point lookup, and borked marking now flow
through the channelstate KV store.

Keep the status write helper private to KVStore so related KV store
facets can share the same status mutation path without passing raw
backends around.
Move the backend-local open channel lifecycle mutations onto KVStore.
ChannelStateDB keeps compatibility wrappers for refreshing channel state
and marking confirmation, open, real scid, and scid-alias negotiation
state.

Leave SyncPendingChannel in channeldb for now because that path still
creates link-node records, and LinkNodeDB ownership remains in channeldb
for this refactor.
Move the KV-backed open channel commitment store methods onto
KVStore. ChannelStateDB keeps compatibility wrappers for commitment
updates, pending commit diffs, revocation queries, and previous-state
lookups.

Carry the no-rev-log-amount-data option into KVStore alongside the
existing final HTLC option so revocation log and final-resolution writes
preserve their previous configuration behavior.
Move the KV-backed revocation log tail helper onto KVStore. This
removes the last direct backend call from the channeldb open channel
compatibility methods while keeping the test-facing helper in place.
Move closed-channel summary reads and CloseChannel onto KVStore.
ChannelStateDB keeps compatibility wrappers, while the KV code for close
summary lookup and close archiving now lives with kv_close_summary.

Carry the tombstone-close option into KVStore so the existing close
strategy selection remains unchanged. Leave MarkChanFullyClosed and
AbandonChannel in channeldb because they still coordinate link-node
pruning and cross-store behavior.
Move historical channel bucket lookup and FetchHistoricalChannel onto
KVStore. The channeldb wrapper still attaches itself to channel.Db so
existing callers continue to receive a compatibility store reference.

Move ErrNoHistoricalBucket into chanstate and keep the channeldb error
as an alias, matching the other channel-state errors that have moved.
Move the KV-backed open channel read and scan methods onto KVStore.
ChannelStateDB keeps compatibility wrappers that attach themselves to
returned OpenChannel values so existing receiver methods still use the
channeldb store.

Leave restore and sync paths in channeldb because they still coordinate
link-node creation and repair while LinkNodeDB ownership remains outside
chanstate.
Move the KV-backed AbandonChannel implementation onto KVStore.
ChannelStateDB keeps a compatibility wrapper while callers still import
channeldb for the channel-state store.

Keep the link-node-coupled close and repair methods in channeldb so
the follow-up LinkNode store can define that boundary explicitly.
@github-actions github-actions Bot added the severity-critical Requires expert review - security/consensus critical label Jul 10, 2026
@github-actions

Copy link
Copy Markdown

🔴 PR Severity: CRITICAL

File-based classification | 26 files | 12,610 lines changed (7,012 additions / 5,598 deletions)

🔴 Critical (23 files)
  • channeldb/channel.go - channeldb/* — channel state persistence
  • channeldb/codec.go - channeldb/* — channel state (de)serialization
  • channeldb/db.go - channeldb/* — core channel database
  • channeldb/error.go - channeldb/* — channel database errors
  • channeldb/forwarding_package.go - channeldb/* — HTLC forwarding package persistence
  • channeldb/forwarding_policy.go - channeldb/* — forwarding policy persistence
  • channeldb/legacy_serialization.go - channeldb/* — legacy channel state serialization
  • channeldb/revocation_log.go - channeldb/* — revocation log persistence
  • chanstate/codec.go - new package taking over channeldb (de)serialization logic
  • chanstate/errors.go - new package taking over channeldb error definitions
  • chanstate/forwarding.go - new package taking over forwarding-package logic
  • chanstate/kv_channel_setup.go - channel setup persistence (moved from channeldb)
  • chanstate/kv_close_summary.go - channel close summary persistence (moved from channeldb)
  • chanstate/kv_close_tx.go - channel close tx persistence (moved from channeldb)
  • chanstate/kv_commitment.go - commitment transaction persistence (moved from channeldb)
  • chanstate/kv_final_htlc.go - final HTLC resolution persistence (moved from channeldb)
  • chanstate/kv_forwarding_package.go - HTLC forwarding package persistence (moved from channeldb)
  • chanstate/kv_open_channel.go - open channel state persistence (moved from channeldb)
  • chanstate/kv_revocation_log.go - revocation log persistence (moved from channeldb)
  • chanstate/kv_shutdown.go - channel shutdown state persistence (moved from channeldb)
  • chanstate/kv_store.go - channel state KV store abstraction
  • chanstate/open_channel.go - open channel state types
  • chanstate/revocation_log.go - revocation log types
🟢 Low (3 files, test-only)
  • channeldb/channel_test.go - test-only change
  • channeldb/db_test.go - test-only change
  • chanstate/kv_forwarding_package_test.go - renamed/updated test file

Analysis

This PR touches channeldb/* directly (channel state persistence, one of the explicitly-listed CRITICAL packages), which alone sets the floor at CRITICAL.

Beyond the literal rule match, the diff shows a large-scale refactor: core channel-state persistence logic (open channel state, commitments, revocation logs, forwarding packages, close summaries/tx, shutdown state) is being extracted out of channeldb into a new chanstate package. The chanstate/* package isn't explicitly named in the severity rubric, but its contents are the direct successors of the CRITICAL-tier channeldb code being removed in this same PR (e.g. the ~3,000-line deletion in channeldb/channel.go lines up with the new chanstate/kv_open_channel.go, kv_commitment.go, kv_revocation_log.go, etc.). I classified chanstate/* as CRITICAL by content analogy rather than defaulting it to MEDIUM ("other Go files"), since treating a same-day move-and-rename of commitment/revocation logic as a routine change would understate the review risk.

Both severity-bump triggers are independently satisfied (23 non-test files > 20, and ~12,390 non-test lines > 500 threshold), but since CRITICAL is already the ceiling, this doesn't change the outcome — it does reinforce that this warrants careful, expert-level review given the size and sensitivity of the refactor (commitment tx and revocation log handling are directly fund-safety-critical).


To override, add a severity-override-{critical,high,medium,low} label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

severity-critical Requires expert review - security/consensus critical

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant