What changed, and why it matters
This commit is a pure internal code reorganization. It moves several small channel-related data types (like channel configuration, status flags, close summaries, and helper types) from the channeldb package into a new chanstate package, then makes the chanstate.Store interface generic so callers can still use the existing channeldb.OpenChannel type. Existing code keeps compiling because channeldb now declares type aliases pointing to the new chanstate definitions. There are no behavior changes, no bug fixes, and no security-relevant logic changes.
No security action required. Treat as a normal refactoring review; verify that type aliases preserve API compatibility and that the new generic interface constraints compile across all callers.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors LND’s channel state abstractions. It introduces chanstate.ChannelConfig, ChannelStatus, ChannelCloseSummary, ChannelShell, ChanCount, FinalHtlcInfo, ClosureType, and related bounds/params structs in the chanstate package. channeldb replaces its concrete definitions with Go type aliases (e.g., type ChannelConfig = cstate.ChannelConfig). The chanstate.Store, OpenChannelStore, HistoricalChannelStore, and ClosedChannelStore interfaces are parameterized over a Channel type, and all current callers are instantiated with channeldb.OpenChannel. A compile-time assertion in channeldb/chanstate_assertions.go verifies that ChannelStateDB still satisfies chanstate.Store[*OpenChannel]. The diff removes the old cycle-breaking compile-time assertion from chanstate/interface.go and adds a new one in channeldb. No serialization, validation, or cryptographic logic is modified.
Changed components
channeldbchanstatechannelnotifierchanrestorecontractcourt/breach_arbitratorfunding/managerlnrpc/invoicesrpclnrpc/walletrpcpeer/brontideserversubrpcserver_configInspect captured patch +473 / −365
diff --git a/channeldb/channel.go b/channeldb/channel.go
index 4c299f8..a0f0eb7 100644
--- a/channeldb/channel.go
+++ b/channeldb/channel.go
@@ -9,8 +9,6 @@ import (
"fmt"
"io"
"net"
- "strconv"
- "strings"
"sync"
"github.com/btcsuite/btcd/btcec/v2"
@@ -19,6 +17,7 @@ import (
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
"github.com/btcsuite/btcwallet/walletdb"
+ cstate "github.com/lightningnetwork/lnd/chanstate"
"github.com/lightningnetwork/lnd/fn/v2"
graphdb "github.com/lightningnetwork/lnd/graph/db"
"github.com/lightningnetwork/lnd/graph/db/models"
@@ -556,105 +555,16 @@ func (c ChannelType) IsTaprootFinal() bool {
}
// ChannelStateBounds are the parameters from OpenChannel and AcceptChannel
-// that are responsible for providing bounds on the state space of the abstract
-// channel state. These values must be remembered for normal channel operation
-// but they do not impact how we compute the commitment transactions themselves.
-type ChannelStateBounds struct {
- // ChanReserve is an absolute reservation on the channel for the
- // owner of this set of constraints. This means that the current
- // settled balance for this node CANNOT dip below the reservation
- // amount. This acts as a defense against costless attacks when
- // either side no longer has any skin in the game.
- ChanReserve btcutil.Amount
-
- // MaxPendingAmount is the maximum pending HTLC value that the
- // owner of these constraints can offer the remote node at a
- // particular time.
- MaxPendingAmount lnwire.MilliSatoshi
-
- // MinHTLC is the minimum HTLC value that the owner of these
- // constraints can offer the remote node. If any HTLCs below this
- // amount are offered, then the HTLC will be rejected. This, in
- // tandem with the dust limit allows a node to regulate the
- // smallest HTLC that it deems economically relevant.
- MinHTLC lnwire.MilliSatoshi
-
- // MaxAcceptedHtlcs is the maximum number of HTLCs that the owner of
- // this set of constraints can offer the remote node. This allows each
- // node to limit their over all exposure to HTLCs that may need to be
- // acted upon in the case of a unilateral channel closure or a contract
- // breach.
- MaxAcceptedHtlcs uint16
-}
-
-// CommitmentParams are the parameters from OpenChannel and
-// AcceptChannel that are required to render an abstract channel state to a
-// concrete commitment transaction. These values are necessary to (re)compute
-// the commitment transaction. We treat these differently than the state space
-// bounds because their history needs to be stored in order to properly handle
-// chain resolution.
-type CommitmentParams struct {
- // DustLimit is the threshold (in satoshis) below which any outputs
- // should be trimmed. When an output is trimmed, it isn't materialized
- // as an actual output, but is instead burned to miner's fees.
- DustLimit btcutil.Amount
-
- // CsvDelay is the relative time lock delay expressed in blocks. Any
- // settled outputs that pay to the owner of this channel configuration
- // MUST ensure that the delay branch uses this value as the relative
- // time lock. Similarly, any HTLC's offered by this node should use
- // this value as well.
- CsvDelay uint16
-}
-
-// ChannelConfig is a struct that houses the various configuration opens for
-// channels. Each side maintains an instance of this configuration file as it
-// governs: how the funding and commitment transaction to be created, the
-// nature of HTLC's allotted, the keys to be used for delivery, and relative
-// time lock parameters.
-type ChannelConfig struct {
- // ChannelStateBounds is the set of constraints that must be
- // upheld for the duration of the channel for the owner of this channel
- // configuration. Constraints govern a number of flow control related
- // parameters, also including the smallest HTLC that will be accepted
- // by a participant.
- ChannelStateBounds
-
- // CommitmentParams is an embedding of the parameters
- // required to render an abstract channel state into a concrete
- // commitment transaction.
- CommitmentParams
-
- // MultiSigKey is the key to be used within the 2-of-2 output script
- // for the owner of this channel config.
- MultiSigKey keychain.KeyDescriptor
-
- // RevocationBasePoint is the base public key to be used when deriving
- // revocation keys for the remote node's commitment transaction. This
- // will be combined along with a per commitment secret to derive a
- // unique revocation key for each state.
- RevocationBasePoint keychain.KeyDescriptor
-
- // PaymentBasePoint is the base public key to be used when deriving
- // the key used within the non-delayed pay-to-self output on the
- // commitment transaction for a node. This will be combined with a
- // tweak derived from the per-commitment point to ensure unique keys
- // for each commitment transaction.
- PaymentBasePoint keychain.KeyDescriptor
-
- // DelayBasePoint is the base public key to be used when deriving the
- // key used within the delayed pay-to-self output on the commitment
- // transaction for a node. This will be combined with a tweak derived
- // from the per-commitment point to ensure unique keys for each
- // commitment transaction.
- DelayBasePoint keychain.KeyDescriptor
-
- // HtlcBasePoint is the base public key to be used when deriving the
- // local HTLC key. The derived key (combined with the tweak derived
- // from the per-commitment point) is used within the "to self" clause
- // within any HTLC output scripts.
- HtlcBasePoint keychain.KeyDescriptor
-}
+// that bound the abstract channel state.
+type ChannelStateBounds = cstate.ChannelStateBounds
+
+// CommitmentParams are the parameters from OpenChannel and AcceptChannel that
+// are required to render an abstract channel state to a concrete commitment
+// transaction.
+type CommitmentParams = cstate.CommitmentParams
+
+// ChannelConfig houses the channel configuration for one side of a channel.
+type ChannelConfig = cstate.ChannelConfig
// commitTlvData stores all the optional data that may be stored as a TLV stream
// at the _end_ of the normal serialized commit on disk.
@@ -834,108 +744,41 @@ func (c *ChannelCommitment) copy() ChannelCommitment {
// ChannelStatus is a bit vector used to indicate whether an OpenChannel is in
// the default usable state, or a state where it shouldn't be used.
-type ChannelStatus uint64
+type ChannelStatus = cstate.ChannelStatus
var (
// ChanStatusDefault is the normal state of an open channel.
- ChanStatusDefault ChannelStatus
+ ChanStatusDefault = cstate.ChanStatusDefault
// ChanStatusBorked indicates that the channel has entered an
- // irreconcilable state, triggered by a state desynchronization or
- // channel breach. Channels in this state should never be added to the
- // htlc switch.
- ChanStatusBorked ChannelStatus = 1
+ // irreconcilable state.
+ ChanStatusBorked = cstate.ChanStatusBorked
// ChanStatusCommitBroadcasted indicates that a commitment for this
// channel has been broadcasted.
- ChanStatusCommitBroadcasted ChannelStatus = 1 << 1
+ ChanStatusCommitBroadcasted = cstate.ChanStatusCommitBroadcasted
// ChanStatusLocalDataLoss indicates that we have lost channel state
- // for this channel, and broadcasting our latest commitment might be
- // considered a breach.
- //
- // TODO(halseh): actually enforce that we are not force closing such a
+ // for this channel.
+ ChanStatusLocalDataLoss = cstate.ChanStatusLocalDataLoss
+
+ // ChanStatusRestored signals that the channel has been restored and
+ // doesn't have all fields a typical channel will have.
+ ChanStatusRestored = cstate.ChanStatusRestored
+
+ // ChanStatusCoopBroadcasted indicates that a cooperative close for this
+ // channel has been broadcasted.
+ ChanStatusCoopBroadcasted = cstate.ChanStatusCoopBroadcasted
+
+ // ChanStatusLocalCloseInitiator indicates that we initiated closing the
// channel.
- ChanStatusLocalDataLoss ChannelStatus = 1 << 2
-
- // ChanStatusRestored is a status flag that signals that the channel
- // has been restored, and doesn't have all the fields a typical channel
- // will have.
- ChanStatusRestored ChannelStatus = 1 << 3
-
- // ChanStatusCoopBroadcasted indicates that a cooperative close for
- // this channel has been broadcasted. Older cooperatively closed
- // channels will only have this status set. Newer ones will also have
- // close initiator information stored using the local/remote initiator
- // status. This status is set in conjunction with the initiator status
- // so that we do not need to check multiple channel statues for
- // cooperative closes.
- ChanStatusCoopBroadcasted ChannelStatus = 1 << 4
-
- // ChanStatusLocalCloseInitiator indicates that we initiated closing
- // the channel.
- ChanStatusLocalCloseInitiator ChannelStatus = 1 << 5
+ ChanStatusLocalCloseInitiator = cstate.ChanStatusLocalCloseInitiator
// ChanStatusRemoteCloseInitiator indicates that the remote node
// initiated closing the channel.
- ChanStatusRemoteCloseInitiator ChannelStatus = 1 << 6
+ ChanStatusRemoteCloseInitiator = cstate.ChanStatusRemoteCloseInitiator
)
-// chanStatusStrings maps a ChannelStatus to a human friendly string that
-// describes that status.
-var chanStatusStrings = map[ChannelStatus]string{
- ChanStatusDefault: "ChanStatusDefault",
- ChanStatusBorked: "ChanStatusBorked",
- ChanStatusCommitBroadcasted: "ChanStatusCommitBroadcasted",
- ChanStatusLocalDataLoss: "ChanStatusLocalDataLoss",
- ChanStatusRestored: "ChanStatusRestored",
- ChanStatusCoopBroadcasted: "ChanStatusCoopBroadcasted",
- ChanStatusLocalCloseInitiator: "ChanStatusLocalCloseInitiator",
- ChanStatusRemoteCloseInitiator: "ChanStatusRemoteCloseInitiator",
-}
-
-// orderedChanStatusFlags is an in-order list of all that channel status flags.
-var orderedChanStatusFlags = []ChannelStatus{
- ChanStatusBorked,
- ChanStatusCommitBroadcasted,
- ChanStatusLocalDataLoss,
- ChanStatusRestored,
- ChanStatusCoopBroadcasted,
- ChanStatusLocalCloseInitiator,
- ChanStatusRemoteCloseInitiator,
-}
-
-// String returns a human-readable representation of the ChannelStatus.
-func (c ChannelStatus) String() string {
- // If no flags are set, then this is the default case.
- if c == ChanStatusDefault {
- return chanStatusStrings[ChanStatusDefault]
- }
-
- // Add individual bit flags.
- statusStr := ""
- for _, flag := range orderedChanStatusFlags {
- if c&flag == flag {
- statusStr += chanStatusStrings[flag] + "|"
- c -= flag
- }
- }
-
- // Remove anything to the right of the final bar, including it as well.
- statusStr = strings.TrimRight(statusStr, "|")
-
- // Add any remaining flags which aren't accounted for as hex.
- if c != 0 {
- statusStr += "|0x" + strconv.FormatUint(uint64(c), 16)
- }
-
- // If this was purely an unknown flag, then remove the extra bar at the
- // start of the string.
- statusStr = strings.TrimLeft(statusStr, "|")
-
- return statusStr
-}
-
// FinalHtlcByte defines a byte type that encodes information about the final
// htlc resolution.
type FinalHtlcByte byte
@@ -3652,15 +3495,7 @@ func (c *OpenChannel) AdvanceCommitChainTail(fwdPkg *FwdPkg,
}
// FinalHtlcInfo contains information about the final outcome of an htlc.
-type FinalHtlcInfo struct {
- // Settled is true is the htlc was settled. If false, the htlc was
- // failed.
- Settled bool
-
- // Offchain indicates whether the htlc was resolved off-chain or
- // on-chain.
- Offchain bool
-}
+type FinalHtlcInfo = cstate.FinalHtlcInfo
// putFinalHtlc writes the final htlc outcome to the database. Additionally it
// records whether the htlc was resolved off-chain or on-chain.
@@ -3908,122 +3743,39 @@ func (c *OpenChannel) FindPreviousState(
return rl, commit, nil
}
-// ClosureType is an enum like structure that details exactly _how_ a channel
-// was closed. Three closure types are currently possible: none, cooperative,
-// local force close, remote force close, and (remote) breach.
-type ClosureType uint8
+// ClosureType is an enum like structure that details exactly how a channel was
+// closed.
+type ClosureType = cstate.ClosureType
const (
// CooperativeClose indicates that a channel has been closed
- // cooperatively. This means that both channel peers were online and
- // signed a new transaction paying out the settled balance of the
- // contract.
- CooperativeClose ClosureType = 0
+ // cooperatively.
+ CooperativeClose = cstate.CooperativeClose
// LocalForceClose indicates that we have unilaterally broadcast our
// current commitment state on-chain.
- LocalForceClose ClosureType = 1
+ LocalForceClose = cstate.LocalForceClose
// RemoteForceClose indicates that the remote peer has unilaterally
// broadcast their current commitment state on-chain.
- RemoteForceClose ClosureType = 4
+ RemoteForceClose = cstate.RemoteForceClose
// BreachClose indicates that the remote peer attempted to broadcast a
- // prior _revoked_ channel state.
- BreachClose ClosureType = 2
+ // prior revoked channel state.
+ BreachClose = cstate.BreachClose
// FundingCanceled indicates that the channel never was fully opened
- // before it was marked as closed in the database. This can happen if
- // we or the remote fail at some point during the opening workflow, or
- // we timeout waiting for the funding transaction to be confirmed.
- FundingCanceled ClosureType = 3
-
- // Abandoned indicates that the channel state was removed without
- // any further actions. This is intended to clean up unusable
- // channels during development.
- Abandoned ClosureType = 5
+ // before it was marked as closed in the database.
+ FundingCanceled = cstate.FundingCanceled
+
+ // Abandoned indicates that the channel state was removed without any
+ // further actions.
+ Abandoned = cstate.Abandoned
)
// ChannelCloseSummary contains the final state of a channel at the point it
-// was closed. Once a channel is closed, all the information pertaining to that
-// channel within the openChannelBucket is deleted, and a compact summary is
-// put in place instead.
-type ChannelCloseSummary struct {
- // ChanPoint is the outpoint for this channel's funding transaction,
- // and is used as a unique identifier for the channel.
- ChanPoint wire.OutPoint
-
- // ShortChanID encodes the exact location in the chain in which the
- // channel was initially confirmed. This includes: the block height,
- // transaction index, and the output within the target transaction.
- ShortChanID lnwire.ShortChannelID
-
- // ChainHash is the hash of the genesis block that this channel resides
- // within.
- ChainHash chainhash.Hash
-
- // ClosingTXID is the txid of the transaction which ultimately closed
- // this channel.
- ClosingTXID chainhash.Hash
-
- // RemotePub is the public key of the remote peer that we formerly had
- // a channel with.
- RemotePub *btcec.PublicKey
-
- // Capacity was the total capacity of the channel.
- Capacity btcutil.Amount
-
- // CloseHeight is the height at which the funding transaction was
- // spent.
- CloseHeight uint32
-
- // SettledBalance is our total balance settled balance at the time of
- // channel closure. This _does not_ include the sum of any outputs that
- // have been time-locked as a result of the unilateral channel closure.
- SettledBalance btcutil.Amount
-
- // TimeLockedBalance is the sum of all the time-locked outputs at the
- // time of channel closure. If we triggered the force closure of this
- // channel, then this value will be non-zero if our settled output is
- // above the dust limit. If we were on the receiving side of a channel
- // force closure, then this value will be non-zero if we had any
- // outstanding outgoing HTLC's at the time of channel closure.
- TimeLockedBalance btcutil.Amount
-
- // CloseType details exactly _how_ the channel was closed. Five closure
- // types are possible: cooperative, local force, remote force, breach
- // and funding canceled.
- CloseType ClosureType
-
- // IsPending indicates whether this channel is in the 'pending close'
- // state, which means the channel closing transaction has been
- // confirmed, but not yet been fully resolved. In the case of a channel
- // that has been cooperatively closed, it will go straight into the
- // fully resolved state as soon as the closing transaction has been
- // confirmed. However, for channels that have been force closed, they'll
- // stay marked as "pending" until _all_ the pending funds have been
- // swept.
- IsPending bool
-
- // RemoteCurrentRevocation is the current revocation for their
- // commitment transaction. However, since this is the derived public key,
- // we don't yet have the private key so we aren't yet able to verify
- // that it's actually in the hash chain.
- RemoteCurrentRevocation *btcec.PublicKey
-
- // RemoteNextRevocation is the revocation key to be used for the *next*
- // commitment transaction we create for the local node. Within the
- // specification, this value is referred to as the
- // per-commitment-point.
- RemoteNextRevocation *btcec.PublicKey
-
- // LocalChanConfig is the channel configuration for the local node.
- LocalChanConfig ChannelConfig
-
- // LastChanSyncMsg is the ChannelReestablish message for this channel
- // for the state at the point where it was closed.
- LastChanSyncMsg *lnwire.ChannelReestablish
-}
+// was closed.
+type ChannelCloseSummary = cstate.ChannelCloseSummary
// CloseChannel closes a previously active Lightning channel. Closing a
// channel entails persisting a record of the close while either purging the
diff --git a/channeldb/chanstate_assertions.go b/channeldb/chanstate_assertions.go
new file mode 100644
index 0000000..0398e62
--- /dev/null
+++ b/channeldb/chanstate_assertions.go
@@ -0,0 +1,7 @@
+package channeldb
+
+import "github.com/lightningnetwork/lnd/chanstate"
+
+// Compile-time assertions that ChannelStateDB satisfies the channel-state
+// store contracts while the KV implementation still lives in channeldb.
+var _ chanstate.Store[*OpenChannel] = (*ChannelStateDB)(nil)
diff --git a/channeldb/db.go b/channeldb/db.go
index 894f9fa..a516242 100644
--- a/channeldb/db.go
+++ b/channeldb/db.go
@@ -32,6 +32,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb/migration34"
"github.com/lightningnetwork/lnd/channeldb/migration35"
"github.com/lightningnetwork/lnd/channeldb/migration_01_to_11"
+ "github.com/lightningnetwork/lnd/chanstate"
"github.com/lightningnetwork/lnd/clock"
graphdb "github.com/lightningnetwork/lnd/graph/db"
"github.com/lightningnetwork/lnd/invoices"
@@ -777,10 +778,7 @@ func (c *ChannelStateDB) FetchChannelByID(id lnwire.ChannelID) (*OpenChannel,
}
// ChanCount is used by the server in determining access control.
-type ChanCount struct {
- HasOpenOrClosedChan bool
- PendingOpenCount uint64
-}
+type ChanCount = chanstate.ChanCount
// FetchPermAndTempPeers returns a map where the key is the remote node's
// public key and the value is a struct that has a tally of the pending-open
@@ -1678,17 +1676,8 @@ func (c *ChannelStateDB) RepairLinkNodes(network wire.BitcoinNet) error {
}
// ChannelShell is a shell of a channel that is meant to be used for channel
-// recovery purposes. It contains a minimal OpenChannel instance along with
-// addresses for that target node.
-type ChannelShell struct {
- // NodeAddrs the set of addresses that this node has known to be
- // reachable at in the past.
- NodeAddrs []net.Addr
-
- // Chan is a shell of an OpenChannel, it contains only the items
- // required to restore the channel on disk.
- Chan *OpenChannel
-}
+// recovery purposes.
+type ChannelShell = chanstate.ChannelShell[*OpenChannel]
// RestoreChannelShells is a method that allows the caller to reconstruct the
// state of an OpenChannel from the ChannelShell. We'll attempt to write the
diff --git a/channelnotifier/channelnotifier.go b/channelnotifier/channelnotifier.go
index 7332421..fdfadc0 100644
--- a/channelnotifier/channelnotifier.go
+++ b/channelnotifier/channelnotifier.go
@@ -18,7 +18,7 @@ type ChannelNotifier struct {
ntfnServer *subscribe.Server
- chanDB chanstate.Store
+ chanDB chanstate.Store[*channeldb.OpenChannel]
}
// PendingOpenChannelEvent represents a new event where a new channel has
@@ -98,7 +98,7 @@ type FundingTimeoutEvent struct {
// New creates a new channel notifier. The ChannelNotifier gets channel
// events from peers and from the chain arbitrator, and dispatches them to
// its clients.
-func New(chanDB chanstate.Store) *ChannelNotifier {
+func New(chanDB chanstate.Store[*channeldb.OpenChannel]) *ChannelNotifier {
return &ChannelNotifier{
ntfnServer: subscribe.NewServer(),
chanDB: chanDB,
diff --git a/chanrestore.go b/chanrestore.go
index d97e50f..e8da9c9 100644
--- a/chanrestore.go
+++ b/chanrestore.go
@@ -36,7 +36,7 @@ const (
// need the secret key chain in order obtain the prior shachain root so we can
// verify the DLP protocol as initiated by the remote node.
type chanDBRestorer struct {
- db chanstate.OpenChannelStore
+ db chanstate.OpenChannelStore[*channeldb.OpenChannel]
secretKeys keychain.SecretKeyRing
diff --git a/chanstate/channel.go b/chanstate/channel.go
new file mode 100644
index 0000000..2389b9a
--- /dev/null
+++ b/chanstate/channel.go
@@ -0,0 +1,32 @@
+package chanstate
+
+import "net"
+
+// ChanCount is used by the server in determining access control.
+type ChanCount struct {
+ HasOpenOrClosedChan bool
+ PendingOpenCount uint64
+}
+
+// FinalHtlcInfo contains information about the final outcome of an htlc.
+type FinalHtlcInfo struct {
+ // Settled is true is the htlc was settled. If false, the htlc was
+ // failed.
+ Settled bool
+
+ // Offchain indicates whether the htlc was resolved off-chain or
+ // on-chain.
+ Offchain bool
+}
+
+// ChannelShell contains the minimal channel state and peer addresses needed to
+// restore a channel during recovery.
+type ChannelShell[Channel any] struct {
+ // NodeAddrs is the set of addresses that this node has known to be
+ // reachable at in the past.
+ NodeAddrs []net.Addr
+
+ // Chan is the minimal channel state required to restore the channel on
+ // disk.
+ Chan Channel
+}
diff --git a/chanstate/channel_status.go b/chanstate/channel_status.go
new file mode 100644
index 0000000..b19fe36
--- /dev/null
+++ b/chanstate/channel_status.go
@@ -0,0 +1,110 @@
+package chanstate
+
+import (
+ "strconv"
+ "strings"
+)
+
+// ChannelStatus is a bit vector used to indicate whether an OpenChannel is in
+// the default usable state, or a state where it shouldn't be used.
+type ChannelStatus uint64
+
+var (
+ // ChanStatusDefault is the normal state of an open channel.
+ ChanStatusDefault ChannelStatus
+
+ // ChanStatusBorked indicates that the channel has entered an
+ // irreconcilable state, triggered by a state desynchronization or
+ // channel breach. Channels in this state should never be added to the
+ // htlc switch.
+ ChanStatusBorked ChannelStatus = 1
+
+ // ChanStatusCommitBroadcasted indicates that a commitment for this
+ // channel has been broadcasted.
+ ChanStatusCommitBroadcasted ChannelStatus = 1 << 1
+
+ // ChanStatusLocalDataLoss indicates that we have lost channel state
+ // for this channel, and broadcasting our latest commitment might be
+ // considered a breach.
+ //
+ // TODO(halseh): actually enforce that we are not force closing such a
+ // channel.
+ ChanStatusLocalDataLoss ChannelStatus = 1 << 2
+
+ // ChanStatusRestored is a status flag that signals that the channel
+ // has been restored, and doesn't have all the fields a typical channel
+ // will have.
+ ChanStatusRestored ChannelStatus = 1 << 3
+
+ // ChanStatusCoopBroadcasted indicates that a cooperative close for
+ // this channel has been broadcasted. Older cooperatively closed
+ // channels will only have this status set. Newer ones will also have
+ // close initiator information stored using the local/remote initiator
+ // status. This status is set in conjunction with the initiator status
+ // so that we do not need to check multiple channel statues for
+ // cooperative closes.
+ ChanStatusCoopBroadcasted ChannelStatus = 1 << 4
+
+ // ChanStatusLocalCloseInitiator indicates that we initiated closing
+ // the channel.
+ ChanStatusLocalCloseInitiator ChannelStatus = 1 << 5
+
+ // ChanStatusRemoteCloseInitiator indicates that the remote node
+ // initiated closing the channel.
+ ChanStatusRemoteCloseInitiator ChannelStatus = 1 << 6
+)
+
+// chanStatusStrings maps a ChannelStatus to a human friendly string that
+// describes that status.
+var chanStatusStrings = map[ChannelStatus]string{
+ ChanStatusDefault: "ChanStatusDefault",
+ ChanStatusBorked: "ChanStatusBorked",
+ ChanStatusCommitBroadcasted: "ChanStatusCommitBroadcasted",
+ ChanStatusLocalDataLoss: "ChanStatusLocalDataLoss",
+ ChanStatusRestored: "ChanStatusRestored",
+ ChanStatusCoopBroadcasted: "ChanStatusCoopBroadcasted",
+ ChanStatusLocalCloseInitiator: "ChanStatusLocalCloseInitiator",
+ ChanStatusRemoteCloseInitiator: "ChanStatusRemoteCloseInitiator",
+}
+
+// orderedChanStatusFlags is an in-order list of all that channel status flags.
+var orderedChanStatusFlags = []ChannelStatus{
+ ChanStatusBorked,
+ ChanStatusCommitBroadcasted,
+ ChanStatusLocalDataLoss,
+ ChanStatusRestored,
+ ChanStatusCoopBroadcasted,
+ ChanStatusLocalCloseInitiator,
+ ChanStatusRemoteCloseInitiator,
+}
+
+// String returns a human-readable representation of the ChannelStatus.
+func (c ChannelStatus) String() string {
+ // If no flags are set, then this is the default case.
+ if c == ChanStatusDefault {
+ return chanStatusStrings[ChanStatusDefault]
+ }
+
+ // Add individual bit flags.
+ statusStr := ""
+ for _, flag := range orderedChanStatusFlags {
+ if c&flag == flag {
+ statusStr += chanStatusStrings[flag] + "|"
+ c -= flag
+ }
+ }
+
+ // Remove anything to the right of the final bar, including it as well.
+ statusStr = strings.TrimRight(statusStr, "|")
+
+ // Add any remaining flags which aren't accounted for as hex.
+ if c != 0 {
+ statusStr += "|0x" + strconv.FormatUint(uint64(c), 16)
+ }
+
+ // If this was purely an unknown flag, then remove the extra bar at the
+ // start of the string.
+ statusStr = strings.TrimLeft(statusStr, "|")
+
+ return statusStr
+}
diff --git a/chanstate/close_summary.go b/chanstate/close_summary.go
new file mode 100644
index 0000000..e582545
--- /dev/null
+++ b/chanstate/close_summary.go
@@ -0,0 +1,126 @@
+package chanstate
+
+import (
+ "github.com/btcsuite/btcd/btcec/v2"
+ "github.com/btcsuite/btcd/btcutil/v2"
+ "github.com/btcsuite/btcd/chainhash/v2"
+ "github.com/btcsuite/btcd/wire/v2"
+ "github.com/lightningnetwork/lnd/lnwire"
+)
+
+// ClosureType is an enum like structure that details exactly _how_ a channel
+// was closed. Three closure types are currently possible: none, cooperative,
+// local force close, remote force close, and (remote) breach.
+type ClosureType uint8
+
+const (
+ // CooperativeClose indicates that a channel has been closed
+ // cooperatively. This means that both channel peers were online and
+ // signed a new transaction paying out the settled balance of the
+ // contract.
+ CooperativeClose ClosureType = 0
+
+ // LocalForceClose indicates that we have unilaterally broadcast our
+ // current commitment state on-chain.
+ LocalForceClose ClosureType = 1
+
+ // RemoteForceClose indicates that the remote peer has unilaterally
+ // broadcast their current commitment state on-chain.
+ RemoteForceClose ClosureType = 4
+
+ // BreachClose indicates that the remote peer attempted to broadcast a
+ // prior _revoked_ channel state.
+ BreachClose ClosureType = 2
+
+ // FundingCanceled indicates that the channel never was fully opened
+ // before it was marked as closed in the database. This can happen if
+ // we or the remote fail at some point during the opening workflow, or
+ // we timeout waiting for the funding transaction to be confirmed.
+ FundingCanceled ClosureType = 3
+
+ // Abandoned indicates that the channel state was removed without
+ // any further actions. This is intended to clean up unusable
+ // channels during development.
+ Abandoned ClosureType = 5
+)
+
+// ChannelCloseSummary contains the final state of a channel at the point it
+// was closed. Once a channel is closed, all the information pertaining to that
+// channel within the openChannelBucket is deleted, and a compact summary is
+// put in place instead.
+type ChannelCloseSummary struct {
+ // ChanPoint is the outpoint for this channel's funding transaction,
+ // and is used as a unique identifier for the channel.
+ ChanPoint wire.OutPoint
+
+ // ShortChanID encodes the exact location in the chain in which the
+ // channel was initially confirmed. This includes: the block height,
+ // transaction index, and the output within the target transaction.
+ ShortChanID lnwire.ShortChannelID
+
+ // ChainHash is the hash of the genesis block that this channel resides
+ // within.
+ ChainHash chainhash.Hash
+
+ // ClosingTXID is the txid of the transaction which ultimately closed
+ // this channel.
+ ClosingTXID chainhash.Hash
+
+ // RemotePub is the public key of the remote peer that we formerly had
+ // a channel with.
+ RemotePub *btcec.PublicKey
+
+ // Capacity was the total capacity of the channel.
+ Capacity btcutil.Amount
+
+ // CloseHeight is the height at which the funding transaction was
+ // spent.
+ CloseHeight uint32
+
+ // SettledBalance is our total balance settled balance at the time of
+ // channel closure. This _does not_ include the sum of any outputs that
+ // have been time-locked as a result of the unilateral channel closure.
+ SettledBalance btcutil.Amount
+
+ // TimeLockedBalance is the sum of all the time-locked outputs at the
+ // time of channel closure. If we triggered the force closure of this
+ // channel, then this value will be non-zero if our settled output is
+ // above the dust limit. If we were on the receiving side of a channel
+ // force closure, then this value will be non-zero if we had any
+ // outstanding outgoing HTLC's at the time of channel closure.
+ TimeLockedBalance btcutil.Amount
+
+ // CloseType details exactly _how_ the channel was closed. Five closure
+ // types are possible: cooperative, local force, remote force, breach
+ // and funding canceled.
+ CloseType ClosureType
+
+ // IsPending indicates whether this channel is in the 'pending close'
+ // state, which means the channel closing transaction has been
+ // confirmed, but not yet been fully resolved. In the case of a channel
+ // that has been cooperatively closed, it will go straight into the
+ // fully resolved state as soon as the closing transaction has been
+ // confirmed. However, for channels that have been force closed, they'll
+ // stay marked as "pending" until _all_ the pending funds have been
+ // swept.
+ IsPending bool
+
+ // RemoteCurrentRevocation is the current revocation for their
+ // commitment transaction. However, since this is the derived public
+ // key, we don't yet have the private key so we aren't yet able to
+ // verify that it's actually in the hash chain.
+ RemoteCurrentRevocation *btcec.PublicKey
+
+ // RemoteNextRevocation is the revocation key to be used for the *next*
+ // commitment transaction we create for the local node. Within the
+ // specification, this value is referred to as the
+ // per-commitment-point.
+ RemoteNextRevocation *btcec.PublicKey
+
+ // LocalChanConfig is the channel configuration for the local node.
+ LocalChanConfig ChannelConfig
+
+ // LastChanSyncMsg is the ChannelReestablish message for this channel
+ // for the state at the point where it was closed.
+ LastChanSyncMsg *lnwire.ChannelReestablish
+}
diff --git a/chanstate/config.go b/chanstate/config.go
new file mode 100644
index 0000000..e9adecf
--- /dev/null
+++ b/chanstate/config.go
@@ -0,0 +1,108 @@
+package chanstate
+
+import (
+ "github.com/btcsuite/btcd/btcutil/v2"
+ "github.com/lightningnetwork/lnd/keychain"
+ "github.com/lightningnetwork/lnd/lnwire"
+)
+
+// ChannelStateBounds are the parameters from OpenChannel and AcceptChannel
+// that are responsible for providing bounds on the state space of the abstract
+// channel state. These values must be remembered for normal channel operation
+// but they do not impact how we compute the commitment transactions themselves.
+type ChannelStateBounds struct {
+ // ChanReserve is an absolute reservation on the channel for the
+ // owner of this set of constraints. This means that the current
+ // settled balance for this node CANNOT dip below the reservation
+ // amount. This acts as a defense against costless attacks when
+ // either side no longer has any skin in the game.
+ ChanReserve btcutil.Amount
+
+ // MaxPendingAmount is the maximum pending HTLC value that the
+ // owner of these constraints can offer the remote node at a
+ // particular time.
+ MaxPendingAmount lnwire.MilliSatoshi
+
+ // MinHTLC is the minimum HTLC value that the owner of these
+ // constraints can offer the remote node. If any HTLCs below this
+ // amount are offered, then the HTLC will be rejected. This, in
+ // tandem with the dust limit allows a node to regulate the
+ // smallest HTLC that it deems economically relevant.
+ MinHTLC lnwire.MilliSatoshi
+
+ // MaxAcceptedHtlcs is the maximum number of HTLCs that the owner of
+ // this set of constraints can offer the remote node. This allows each
+ // node to limit their over all exposure to HTLCs that may need to be
+ // acted upon in the case of a unilateral channel closure or a contract
+ // breach.
+ MaxAcceptedHtlcs uint16
+}
+
+// CommitmentParams are the parameters from OpenChannel and
+// AcceptChannel that are required to render an abstract channel state to a
+// concrete commitment transaction. These values are necessary to (re)compute
+// the commitment transaction. We treat these differently than the state space
+// bounds because their history needs to be stored in order to properly handle
+// chain resolution.
+type CommitmentParams struct {
+ // DustLimit is the threshold (in satoshis) below which any outputs
+ // should be trimmed. When an output is trimmed, it isn't materialized
+ // as an actual output, but is instead burned to miner's fees.
+ DustLimit btcutil.Amount
+
+ // CsvDelay is the relative time lock delay expressed in blocks. Any
+ // settled outputs that pay to the owner of this channel configuration
+ // MUST ensure that the delay branch uses this value as the relative
+ // time lock. Similarly, any HTLC's offered by this node should use
+ // this value as well.
+ CsvDelay uint16
+}
+
+// ChannelConfig is a struct that houses the various configuration opens for
+// channels. Each side maintains an instance of this configuration file as it
+// governs: how the funding and commitment transaction to be created, the
+// nature of HTLC's allotted, the keys to be used for delivery, and relative
+// time lock parameters.
+type ChannelConfig struct {
+ // ChannelStateBounds is the set of constraints that must be
+ // upheld for the duration of the channel for the owner of this channel
+ // configuration. Constraints govern a number of flow control related
+ // parameters, also including the smallest HTLC that will be accepted
+ // by a participant.
+ ChannelStateBounds
+
+ // CommitmentParams is an embedding of the parameters
+ // required to render an abstract channel state into a concrete
+ // commitment transaction.
+ CommitmentParams
+
+ // MultiSigKey is the key to be used within the 2-of-2 output script
+ // for the owner of this channel config.
+ MultiSigKey keychain.KeyDescriptor
+
+ // RevocationBasePoint is the base public key to be used when deriving
+ // revocation keys for the remote node's commitment transaction. This
+ // will be combined along with a per commitment secret to derive a
+ // unique revocation key for each state.
+ RevocationBasePoint keychain.KeyDescriptor
+
+ // PaymentBasePoint is the base public key to be used when deriving
+ // the key used within the non-delayed pay-to-self output on the
+ // commitment transaction for a node. This will be combined with a
+ // tweak derived from the per-commitment point to ensure unique keys
+ // for each commitment transaction.
+ PaymentBasePoint keychain.KeyDescriptor
+
+ // DelayBasePoint is the base public key to be used when deriving the
+ // key used within the delayed pay-to-self output on the commitment
+ // transaction for a node. This will be combined with a tweak derived
+ // from the per-commitment point to ensure unique keys for each
+ // commitment transaction.
+ DelayBasePoint keychain.KeyDescriptor
+
+ // HtlcBasePoint is the base public key to be used when deriving the
+ // local HTLC key. The derived key (combined with the tweak derived
+ // from the per-commitment point) is used within the "to self" clause
+ // within any HTLC output scripts.
+ HtlcBasePoint keychain.KeyDescriptor
+}
diff --git a/chanstate/interface.go b/chanstate/interface.go
index 038cdc9..0db90f7 100644
--- a/chanstate/interface.go
+++ b/chanstate/interface.go
@@ -3,7 +3,6 @@ package chanstate
import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/wire/v2"
- "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/graph/db/models"
"github.com/lightningnetwork/lnd/lnwire"
)
@@ -17,16 +16,16 @@ import (
// concrete channeldb.ChannelStateDB type during the migration. Once the channel
// state implementation moves into this package and the old concrete type is no
// longer part of consumer-facing code, this name can be revisited.
-type Store interface {
+type Store[Channel any] interface {
// OpenChannelStore owns open-channel records.
- OpenChannelStore
+ OpenChannelStore[Channel]
// HistoricalChannelStore owns the post-close historical channel view.
- HistoricalChannelStore
+ HistoricalChannelStore[Channel]
// ClosedChannelStore owns closed-channel summaries and lifecycle
// mutations.
- ClosedChannelStore
+ ClosedChannelStore[Channel]
// FinalHTLCStore owns final HTLC outcome data.
FinalHTLCStore
@@ -41,54 +40,52 @@ type Store interface {
}
// OpenChannelStore owns open-channel records.
-type OpenChannelStore interface {
+type OpenChannelStore[Channel any] interface {
// FetchOpenChannels starts a new database transaction and returns
// all stored currently active/open channels associated with the
// target nodeID. In the case that no active channels are known to
// have been created with this node, then a zero-length slice is
// returned.
- FetchOpenChannels(nodeID *btcec.PublicKey) (
- []*channeldb.OpenChannel, error)
+ FetchOpenChannels(nodeID *btcec.PublicKey) ([]Channel, error)
// FetchChannel attempts to locate a channel specified by the passed
// channel point. If the channel cannot be found, then an error will
// be returned.
- FetchChannel(chanPoint wire.OutPoint) (*channeldb.OpenChannel, error)
+ FetchChannel(chanPoint wire.OutPoint) (Channel, error)
// FetchChannelByID attempts to locate a channel specified by the
// passed channel ID. If the channel cannot be found, then an error
// will be returned.
- FetchChannelByID(id lnwire.ChannelID) (*channeldb.OpenChannel, error)
+ FetchChannelByID(id lnwire.ChannelID) (Channel, error)
// FetchAllChannels attempts to retrieve all open channels currently
// stored within the database, including pending open, fully open and
// channels waiting for a closing transaction to confirm.
- FetchAllChannels() ([]*channeldb.OpenChannel, error)
+ FetchAllChannels() ([]Channel, error)
// FetchAllOpenChannels will return all channels that have the
// funding transaction confirmed, and is not waiting for a closing
// transaction to be confirmed.
- FetchAllOpenChannels() ([]*channeldb.OpenChannel, error)
+ FetchAllOpenChannels() ([]Channel, error)
// FetchPendingChannels will return channels that have completed the
// process of generating and broadcasting funding transactions, but
// whose funding transactions have yet to be confirmed on the
// blockchain.
- FetchPendingChannels() ([]*channeldb.OpenChannel, error)
+ FetchPendingChannels() ([]Channel, error)
// FetchWaitingCloseChannels will return all channels that have been
// opened, but are now waiting for a closing transaction to be
// confirmed.
//
// NOTE: This includes channels that are also pending to be opened.
- FetchWaitingCloseChannels() ([]*channeldb.OpenChannel, error)
+ FetchWaitingCloseChannels() ([]Channel, error)
// FetchPermAndTempPeers returns a map where the key is the remote
// node's public key and the value is a struct that has a tally of
// the pending-open channels and whether the peer has an open or
// closed channel with us.
- FetchPermAndTempPeers(chainHash []byte) (
- map[string]channeldb.ChanCount, error)
+ FetchPermAndTempPeers(chainHash []byte) (map[string]ChanCount, error)
// RestoreChannelShells reconstructs the state of an OpenChannel from
// the ChannelShell. We'll attempt to write the new channel to disk,
@@ -96,19 +93,18 @@ type OpenChannelStore interface {
// finally create an edge within the graph for the channel as well.
// This method is idempotent, so repeated calls with the same set of
// channel shells won't modify the database after the initial call.
- RestoreChannelShells(channelShells ...*channeldb.ChannelShell) error
+ RestoreChannelShells(channelShells ...*ChannelShell[Channel]) error
}
// HistoricalChannelStore owns the post-close historical channel view.
-type HistoricalChannelStore interface {
+type HistoricalChannelStore[Channel any] interface {
// FetchHistoricalChannel fetches open channel data from the
// historical channel bucket.
- FetchHistoricalChannel(outPoint *wire.OutPoint) (
- *channeldb.OpenChannel, error)
+ FetchHistoricalChannel(outPoint *wire.OutPoint) (Channel, error)
}
// ClosedChannelStore owns closed-channel summaries and lifecycle mutations.
-type ClosedChannelStore interface {
+type ClosedChannelStore[Channel any] interface {
// FetchClosedChannels attempts to fetch all closed channels from the
// database. The pendingOnly bool toggles if channels that aren't yet
// fully closed should be returned in the response or not. When a
@@ -117,17 +113,17 @@ type ClosedChannelStore interface {
// become fully closed after _all_ the pending funds (if any) have
// been swept.
FetchClosedChannels(pendingOnly bool) (
- []*channeldb.ChannelCloseSummary, error)
+ []*ChannelCloseSummary, error)
// FetchClosedChannel queries for a channel close summary using the
// channel point of the channel in question.
FetchClosedChannel(chanID *wire.OutPoint) (
- *channeldb.ChannelCloseSummary, error)
+ *ChannelCloseSummary, error)
// FetchClosedChannelForID queries for a channel close summary using
// the channel ID of the channel in question.
FetchClosedChannelForID(cid lnwire.ChannelID) (
- *channeldb.ChannelCloseSummary, error)
+ *ChannelCloseSummary, error)
// MarkChanFullyClosed marks a channel as fully closed within the
// database. A channel should be marked as fully closed if the
@@ -142,9 +138,8 @@ type ClosedChannelStore interface {
// FetchClosedChannel and FetchClosedChannelForID. Any ChannelStatus
// values are merged into the archived summary. Returns
// ErrChannelCloseSummaryNil if summary is nil.
- CloseChannel(channel *channeldb.OpenChannel,
- summary *channeldb.ChannelCloseSummary,
- statuses ...channeldb.ChannelStatus) error
+ CloseChannel(channel Channel, summary *ChannelCloseSummary,
+ statuses ...ChannelStatus) error
// AbandonChannel attempts to remove the target channel from the open
// channel database. If the channel was already removed (has a closed
@@ -159,7 +154,7 @@ type FinalHTLCStore interface {
// database. If the htlc has no final resolution yet, ErrHtlcUnknown
// is returned.
LookupFinalHtlc(chanID lnwire.ShortChannelID,
- htlcIndex uint64) (*channeldb.FinalHtlcInfo, error)
+ htlcIndex uint64) (*FinalHtlcInfo, error)
// PutOnchainFinalHtlcOutcome stores the final on-chain outcome of an
// htlc in the database.
@@ -211,18 +206,3 @@ type LinkNodeMaintainer interface {
// called on startup to ensure that our database is consistent.
RepairLinkNodes(network wire.BitcoinNet) error
}
-
-// Compile-time assertion that channeldb.ChannelStateDB satisfies the Store
-// contract. If a method signature drifts on the concrete type,
-// this assertion will fail to build before any consumer migration.
-//
-// NOTE: This assertion lives in the interface file as a temporary exception to
-// the established pattern (see invoices/sql_store.go, payments/db/kv_store.go,
-// graph/db/kv_store.go), where each implementation asserts itself in its own
-// file. The implementation still lives in channeldb/, and channeldb must not
-// import chanstate to avoid a cycle, so the assertion has no local
-// implementation file to live in yet. When the KV implementation moves into
-// this package (chanstate/kv_store.go), this assertion MUST be removed from
-// here and re-stated next to the local implementation, matching the precedent
-// packages.
-var _ Store = (*channeldb.ChannelStateDB)(nil)
diff --git a/contractcourt/breach_arbitrator.go b/contractcourt/breach_arbitrator.go
index 7b839e6..4b23bdb 100644
--- a/contractcourt/breach_arbitrator.go
+++ b/contractcourt/breach_arbitrator.go
@@ -14,6 +14,7 @@ import (
"github.com/btcsuite/btcd/txscript/v2"
"github.com/btcsuite/btcd/wire/v2"
"github.com/lightningnetwork/lnd/chainntnfs"
+ "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/chanstate"
"github.com/lightningnetwork/lnd/fn/v2"
graphdb "github.com/lightningnetwork/lnd/graph/db"
@@ -142,7 +143,7 @@ type BreachConfig struct {
// DB provides access to the user's closed channels, allowing the breach
// arbiter to determine how it should respond to channel closure.
- DB chanstate.ClosedChannelStore
+ DB chanstate.ClosedChannelStore[*channeldb.OpenChannel]
// Estimator is used by the breach arbiter to determine an appropriate
// fee level when generating, signing, and broadcasting sweep
diff --git a/funding/manager.go b/funding/manager.go
index 4efbb10..5b9ab81 100644
--- a/funding/manager.go
+++ b/funding/manager.go
@@ -387,7 +387,7 @@ type Config struct {
// ChannelDB is the database that keeps track of channel state used by
// the funding flow.
- ChannelDB chanstate.Store
+ ChannelDB chanstate.Store[*channeldb.OpenChannel]
// SignMessage signs an arbitrary message with a given public key. The
// actual digest signed is the double sha-256 of the message. In the
diff --git a/lnrpc/invoicesrpc/addinvoice.go b/lnrpc/invoicesrpc/addinvoice.go
index 7610552..5f3357a 100644
--- a/lnrpc/invoicesrpc/addinvoice.go
+++ b/lnrpc/invoicesrpc/addinvoice.go
@@ -72,7 +72,7 @@ type AddInvoiceConfig struct {
DefaultCLTVExpiry uint32
// ChanDB is used to access open channel state.
- ChanDB chanstate.OpenChannelStore
+ ChanDB chanstate.OpenChannelStore[*channeldb.OpenChannel]
// Graph gives the invoice server access to various graph related
// queries.
diff --git a/lnrpc/invoicesrpc/config_active.go b/lnrpc/invoicesrpc/config_active.go
index 3a162bf..f0f0a35 100644
--- a/lnrpc/invoicesrpc/config_active.go
+++ b/lnrpc/invoicesrpc/config_active.go
@@ -5,6 +5,7 @@ package invoicesrpc
import (
"github.com/btcsuite/btcd/chaincfg/v2"
+ "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/chanstate"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/lnwire"
@@ -57,7 +58,7 @@ type Config struct {
// ChanStateDB is a possibly replicated db instance which contains open
// channel state.
- ChanStateDB chanstate.OpenChannelStore
+ ChanStateDB chanstate.OpenChannelStore[*channeldb.OpenChannel]
// GenInvoiceFeatures returns a feature containing feature bits that
// should be advertised on freshly generated invoices.
diff --git a/lnrpc/walletrpc/config_active.go b/lnrpc/walletrpc/config_active.go
index 33917b1..3a16ac4 100644
--- a/lnrpc/walletrpc/config_active.go
+++ b/lnrpc/walletrpc/config_active.go
@@ -6,6 +6,7 @@ package walletrpc
import (
"github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcwallet/wallet"
+ "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/chanstate"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwallet"
@@ -79,5 +80,5 @@ type Config struct {
CoinSelectionStrategy wallet.CoinSelectionStrategy
// ChanStateDB is the reference to the open channel store.
- ChanStateDB chanstate.OpenChannelStore
+ ChanStateDB chanstate.OpenChannelStore[*channeldb.OpenChannel]
}
diff --git a/peer/brontide.go b/peer/brontide.go
index 0a22005..e701798 100644
--- a/peer/brontide.go
+++ b/peer/brontide.go
@@ -261,7 +261,7 @@ type Config struct {
InterceptSwitch *htlcswitch.InterceptableSwitch
// ChannelDB is used to fetch channel state needed by the peer.
- ChannelDB chanstate.Store
+ ChannelDB chanstate.Store[*channeldb.OpenChannel]
// ChannelGraph is a pointer to the channel graph which is used to
// query information about the set of known active channels.
diff --git a/server.go b/server.go
index bb6743e..2575f5c 100644
--- a/server.go
+++ b/server.go
@@ -326,7 +326,7 @@ type server struct {
graphDB *graphdb.ChannelGraph
v1Graph *graphdb.VersionedGraph
- chanStateDB chanstate.Store
+ chanStateDB chanstate.Store[*channeldb.OpenChannel]
linkNodeDB *channeldb.LinkNodeDB
addrSource channeldb.AddrSource
diff --git a/subrpcserver_config.go b/subrpcserver_config.go
index 8bd4b02..f7f80bf 100644
--- a/subrpcserver_config.go
+++ b/subrpcserver_config.go
@@ -11,6 +11,7 @@ import (
"github.com/lightningnetwork/lnd/aliasmgr"
"github.com/lightningnetwork/lnd/autopilot"
"github.com/lightningnetwork/lnd/chainreg"
+ "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/chanstate"
"github.com/lightningnetwork/lnd/fn/v2"
graphdb "github.com/lightningnetwork/lnd/graph/db"
@@ -115,7 +116,7 @@ func (s *subRPCServerConfigs) PopulateDependencies(cfg *Config,
routerBackend *routerrpc.RouterBackend,
nodeSigner *netann.NodeSigner,
graphDB *graphdb.ChannelGraph,
- chanStateDB chanstate.Store,
+ chanStateDB chanstate.Store[*channeldb.OpenChannel],
sweeper *sweep.UtxoSweeper,
tower *watchtower.Standalone,
towerClientMgr *wtclient.Manager,
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.