Skip to content

Commit a91f13f

Browse files
committed
chanstate: introduce ChannelStore interface
Add a new chanstate package containing the ChannelStore interface plus a package logger. The interface mirrors the public surface of *channeldb.ChannelStateDB so the compile-time assertion var _ ChannelStore = (*channeldb.ChannelStateDB)(nil) passes today. Subsequent consumer migration is a mechanical type swap from *channeldb.ChannelStateDB to chanstate.ChannelStore with no further interface design churn. The interface deliberately excludes: - GetParentDB: documented as a test-only escape hatch. - LinkNodeDB: belongs to a separate peer/node-metadata domain that gets its own decomposition later. No kvdb types appear in the interface, matching the precedent set by invoices/, payments/db/, and graph/db/. The chanstate -> channeldb import direction is one-way; channeldb does not import chanstate. No consumer migrates in this commit.
1 parent 8315b71 commit a91f13f

2 files changed

Lines changed: 184 additions & 0 deletions

File tree

chanstate/interface.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package chanstate
2+
3+
import (
4+
"github.com/btcsuite/btcd/btcec/v2"
5+
"github.com/btcsuite/btcd/wire"
6+
"github.com/lightningnetwork/lnd/channeldb"
7+
"github.com/lightningnetwork/lnd/lnwire"
8+
)
9+
10+
// ChannelStore is the persistence contract for the channel-state subsystem.
11+
// Consumers depend on this interface rather than the concrete
12+
// channeldb.ChannelStateDB so the underlying storage can be swapped without
13+
// touching call sites.
14+
type ChannelStore interface {
15+
// FetchOpenChannels starts a new database transaction and returns
16+
// all stored currently active/open channels associated with the
17+
// target nodeID. In the case that no active channels are known to
18+
// have been created with this node, then a zero-length slice is
19+
// returned.
20+
FetchOpenChannels(nodeID *btcec.PublicKey) (
21+
[]*channeldb.OpenChannel, error)
22+
23+
// FetchChannel attempts to locate a channel specified by the passed
24+
// channel point. If the channel cannot be found, then an error will
25+
// be returned.
26+
FetchChannel(chanPoint wire.OutPoint) (*channeldb.OpenChannel, error)
27+
28+
// FetchChannelByID attempts to locate a channel specified by the
29+
// passed channel ID. If the channel cannot be found, then an error
30+
// will be returned.
31+
FetchChannelByID(id lnwire.ChannelID) (*channeldb.OpenChannel, error)
32+
33+
// FetchHistoricalChannel fetches open channel data from the
34+
// historical channel bucket.
35+
FetchHistoricalChannel(outPoint *wire.OutPoint) (
36+
*channeldb.OpenChannel, error)
37+
38+
// FetchAllChannels attempts to retrieve all open channels currently
39+
// stored within the database, including pending open, fully open and
40+
// channels waiting for a closing transaction to confirm.
41+
FetchAllChannels() ([]*channeldb.OpenChannel, error)
42+
43+
// FetchAllOpenChannels will return all channels that have the
44+
// funding transaction confirmed, and is not waiting for a closing
45+
// transaction to be confirmed.
46+
FetchAllOpenChannels() ([]*channeldb.OpenChannel, error)
47+
48+
// FetchPendingChannels will return channels that have completed the
49+
// process of generating and broadcasting funding transactions, but
50+
// whose funding transactions have yet to be confirmed on the
51+
// blockchain.
52+
FetchPendingChannels() ([]*channeldb.OpenChannel, error)
53+
54+
// FetchWaitingCloseChannels will return all channels that have been
55+
// opened, but are now waiting for a closing transaction to be
56+
// confirmed.
57+
//
58+
// NOTE: This includes channels that are also pending to be opened.
59+
FetchWaitingCloseChannels() ([]*channeldb.OpenChannel, error)
60+
61+
// FetchClosedChannels attempts to fetch all closed channels from the
62+
// database. The pendingOnly bool toggles if channels that aren't yet
63+
// fully closed should be returned in the response or not. When a
64+
// channel was cooperatively closed, it becomes fully closed after a
65+
// single confirmation. When a channel was forcibly closed, it will
66+
// become fully closed after _all_ the pending funds (if any) have
67+
// been swept.
68+
FetchClosedChannels(pendingOnly bool) (
69+
[]*channeldb.ChannelCloseSummary, error)
70+
71+
// FetchClosedChannel queries for a channel close summary using the
72+
// channel point of the channel in question.
73+
FetchClosedChannel(chanID *wire.OutPoint) (
74+
*channeldb.ChannelCloseSummary, error)
75+
76+
// FetchClosedChannelForID queries for a channel close summary using
77+
// the channel ID of the channel in question.
78+
FetchClosedChannelForID(cid lnwire.ChannelID) (
79+
*channeldb.ChannelCloseSummary, error)
80+
81+
// FetchPermAndTempPeers returns a map where the key is the remote
82+
// node's public key and the value is a struct that has a tally of
83+
// the pending-open channels and whether the peer has an open or
84+
// closed channel with us.
85+
FetchPermAndTempPeers(chainHash []byte) (
86+
map[string]channeldb.ChanCount, error)
87+
88+
// MarkChanFullyClosed marks a channel as fully closed within the
89+
// database. A channel should be marked as fully closed if the
90+
// channel was initially cooperatively closed and it's reached a
91+
// single confirmation, or after all the pending funds in a channel
92+
// that has been forcibly closed have been swept.
93+
MarkChanFullyClosed(chanPoint *wire.OutPoint) error
94+
95+
// CloseChannel marks the given channel as closed: the open-channel
96+
// record is removed and the supplied ChannelCloseSummary is
97+
// archived so the channel becomes retrievable via
98+
// FetchClosedChannel and FetchClosedChannelForID. Any ChannelStatus
99+
// values are merged into the archived summary. Returns
100+
// ErrChannelCloseSummaryNil if summary is nil.
101+
CloseChannel(channel *channeldb.OpenChannel,
102+
summary *channeldb.ChannelCloseSummary,
103+
statuses ...channeldb.ChannelStatus) error
104+
105+
// AbandonChannel attempts to remove the target channel from the open
106+
// channel database. If the channel was already removed (has a closed
107+
// channel entry), then we'll return a nil error. Otherwise, we'll
108+
// insert a new close summary into the database.
109+
AbandonChannel(chanPoint *wire.OutPoint, bestHeight uint32) error
110+
111+
// RestoreChannelShells reconstructs the state of an OpenChannel from
112+
// the ChannelShell. We'll attempt to write the new channel to disk,
113+
// create a LinkNode instance with the passed node addresses, and
114+
// finally create an edge within the graph for the channel as well.
115+
// This method is idempotent, so repeated calls with the same set of
116+
// channel shells won't modify the database after the initial call.
117+
RestoreChannelShells(channelShells ...*channeldb.ChannelShell) error
118+
119+
// SaveChannelOpeningState saves the serialized channel state for the
120+
// provided chanPoint to the channelOpeningStateBucket.
121+
SaveChannelOpeningState(outPoint, serializedState []byte) error
122+
123+
// GetChannelOpeningState fetches the serialized channel state for
124+
// the provided outPoint from the database, or returns
125+
// ErrChannelNotFound if the channel is not found.
126+
GetChannelOpeningState(outPoint []byte) ([]byte, error)
127+
128+
// DeleteChannelOpeningState removes any state for outPoint from the
129+
// database.
130+
DeleteChannelOpeningState(outPoint []byte) error
131+
132+
// LookupFinalHtlc retrieves a final htlc resolution from the
133+
// database. If the htlc has no final resolution yet, ErrHtlcUnknown
134+
// is returned.
135+
LookupFinalHtlc(chanID lnwire.ShortChannelID,
136+
htlcIndex uint64) (*channeldb.FinalHtlcInfo, error)
137+
138+
// PutOnchainFinalHtlcOutcome stores the final on-chain outcome of an
139+
// htlc in the database.
140+
PutOnchainFinalHtlcOutcome(chanID lnwire.ShortChannelID,
141+
htlcID uint64, settled bool) error
142+
143+
// PruneLinkNodes attempts to prune all link nodes found within the
144+
// database with whom we no longer have any open channels with.
145+
PruneLinkNodes() error
146+
147+
// RepairLinkNodes scans all channels in the database and ensures
148+
// that a link node exists for each remote peer. This should be
149+
// called on startup to ensure that our database is consistent.
150+
RepairLinkNodes(network wire.BitcoinNet) error
151+
}
152+
153+
// Compile-time assertion that channeldb.ChannelStateDB satisfies the
154+
// ChannelStore contract. If a method signature drifts on the concrete type,
155+
// this assertion will fail to build before any consumer migration.
156+
var _ ChannelStore = (*channeldb.ChannelStateDB)(nil)

chanstate/log.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package chanstate
2+
3+
import (
4+
"github.com/btcsuite/btclog/v2"
5+
"github.com/lightningnetwork/lnd/build"
6+
)
7+
8+
// log is a logger that is initialized with no output filters. This means the
9+
// package will not perform any logging by default until the caller requests
10+
// it.
11+
var log btclog.Logger
12+
13+
func init() {
14+
UseLogger(build.NewSubLogger("CHST", nil))
15+
}
16+
17+
// DisableLog disables all library log output. Logging output is disabled by
18+
// default until UseLogger is called.
19+
func DisableLog() {
20+
UseLogger(btclog.Disabled)
21+
}
22+
23+
// UseLogger uses a specified Logger to output package logging info. This
24+
// should be used in preference to SetLogWriter if the caller is also using
25+
// btclog.
26+
func UseLogger(logger btclog.Logger) {
27+
log = logger
28+
}

0 commit comments

Comments
 (0)