Skip to content

Commit 4558eb0

Browse files
Crypt-iQRoasbeef
authored andcommitted
channeldb: add PutClosedScid and IsClosedScid
This commit adds the ability to store closed channels by scid in the database. This will allow the gossiper to ignore channel announcements for closed channels without having to do any expensive validation.
1 parent e431e5b commit 4558eb0

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

channeldb/error.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ var (
4343
// created.
4444
ErrMetaNotFound = fmt.Errorf("unable to locate meta information")
4545

46+
// ErrClosedScidsNotFound is returned when the closed scid bucket
47+
// hasn't been created.
48+
ErrClosedScidsNotFound = fmt.Errorf("closed scid bucket doesn't exist")
49+
4650
// ErrGraphNotFound is returned when at least one of the components of
4751
// graph doesn't exist.
4852
ErrGraphNotFound = fmt.Errorf("graph bucket not initialized")

channeldb/graph.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ var (
153153
// case we'll remove all entries from the prune log with a block height
154154
// that no longer exists.
155155
pruneLogBucket = []byte("prune-log")
156+
157+
// closedScidBucket is a top-level bucket that stores scids for
158+
// channels that we know to be closed. This is used so that we don't
159+
// need to perform expensive validation checks if we receive a channel
160+
// announcement for the channel again.
161+
//
162+
// maps: scid -> []byte{}
163+
closedScidBucket = []byte("closed-scid")
156164
)
157165

158166
const (
@@ -318,6 +326,7 @@ var graphTopLevelBuckets = [][]byte{
318326
nodeBucket,
319327
edgeBucket,
320328
graphMetaBucket,
329+
closedScidBucket,
321330
}
322331

323332
// Wipe completely deletes all saved state within all used buckets within the
@@ -3884,6 +3893,53 @@ func (c *ChannelGraph) NumZombies() (uint64, error) {
38843893
return numZombies, nil
38853894
}
38863895

3896+
// PutClosedScid stores a SCID for a closed channel in the database. This is so
3897+
// that we can ignore channel announcements that we know to be closed without
3898+
// having to validate them and fetch a block.
3899+
func (c *ChannelGraph) PutClosedScid(scid lnwire.ShortChannelID) error {
3900+
return kvdb.Update(c.db, func(tx kvdb.RwTx) error {
3901+
closedScids, err := tx.CreateTopLevelBucket(closedScidBucket)
3902+
if err != nil {
3903+
return err
3904+
}
3905+
3906+
var k [8]byte
3907+
byteOrder.PutUint64(k[:], scid.ToUint64())
3908+
3909+
return closedScids.Put(k[:], []byte{})
3910+
}, func() {})
3911+
}
3912+
3913+
// IsClosedScid checks whether a channel identified by the passed in scid is
3914+
// closed. This helps avoid having to perform expensive validation checks.
3915+
// TODO: Add an LRU cache to cut down on disc reads.
3916+
func (c *ChannelGraph) IsClosedScid(scid lnwire.ShortChannelID) (bool, error) {
3917+
var isClosed bool
3918+
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
3919+
closedScids := tx.ReadBucket(closedScidBucket)
3920+
if closedScids == nil {
3921+
return ErrClosedScidsNotFound
3922+
}
3923+
3924+
var k [8]byte
3925+
byteOrder.PutUint64(k[:], scid.ToUint64())
3926+
3927+
if closedScids.Get(k[:]) != nil {
3928+
isClosed = true
3929+
return nil
3930+
}
3931+
3932+
return nil
3933+
}, func() {
3934+
isClosed = false
3935+
})
3936+
if err != nil {
3937+
return false, err
3938+
}
3939+
3940+
return isClosed, nil
3941+
}
3942+
38873943
func putLightningNode(nodeBucket kvdb.RwBucket, aliasBucket kvdb.RwBucket, // nolint:dupl
38883944
updateIndex kvdb.RwBucket, node *LightningNode) error {
38893945

channeldb/graph_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4037,3 +4037,28 @@ func TestGraphLoading(t *testing.T) {
40374037
graphReloaded.graphCache.nodeFeatures,
40384038
)
40394039
}
4040+
4041+
// TestClosedScid tests that we can correctly insert a SCID into the index of
4042+
// closed short channel ids.
4043+
func TestClosedScid(t *testing.T) {
4044+
t.Parallel()
4045+
4046+
graph, err := MakeTestGraph(t)
4047+
require.Nil(t, err)
4048+
4049+
scid := lnwire.ShortChannelID{}
4050+
4051+
// The scid should not exist in the closedScidBucket.
4052+
exists, err := graph.IsClosedScid(scid)
4053+
require.Nil(t, err)
4054+
require.False(t, exists)
4055+
4056+
// After we call PutClosedScid, the call to IsClosedScid should return
4057+
// true.
4058+
err = graph.PutClosedScid(scid)
4059+
require.Nil(t, err)
4060+
4061+
exists, err = graph.IsClosedScid(scid)
4062+
require.Nil(t, err)
4063+
require.True(t, exists)
4064+
}

0 commit comments

Comments
 (0)