mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-18 21:35:24 +01:00
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.
This commit is contained in:
parent
8939a217c3
commit
199e83d3f2
@ -43,6 +43,10 @@ var (
|
||||
// created.
|
||||
ErrMetaNotFound = fmt.Errorf("unable to locate meta information")
|
||||
|
||||
// ErrClosedScidsNotFound is returned when the closed scid bucket
|
||||
// hasn't been created.
|
||||
ErrClosedScidsNotFound = fmt.Errorf("closed scid bucket doesn't exist")
|
||||
|
||||
// ErrGraphNotFound is returned when at least one of the components of
|
||||
// graph doesn't exist.
|
||||
ErrGraphNotFound = fmt.Errorf("graph bucket not initialized")
|
||||
|
@ -153,6 +153,14 @@ var (
|
||||
// case we'll remove all entries from the prune log with a block height
|
||||
// that no longer exists.
|
||||
pruneLogBucket = []byte("prune-log")
|
||||
|
||||
// closedScidBucket is a top-level bucket that stores scids for
|
||||
// channels that we know to be closed. This is used so that we don't
|
||||
// need to perform expensive validation checks if we receive a channel
|
||||
// announcement for the channel again.
|
||||
//
|
||||
// maps: scid -> []byte{}
|
||||
closedScidBucket = []byte("closed-scid")
|
||||
)
|
||||
|
||||
const (
|
||||
@ -318,6 +326,7 @@ var graphTopLevelBuckets = [][]byte{
|
||||
nodeBucket,
|
||||
edgeBucket,
|
||||
graphMetaBucket,
|
||||
closedScidBucket,
|
||||
}
|
||||
|
||||
// Wipe completely deletes all saved state within all used buckets within the
|
||||
@ -3884,6 +3893,53 @@ func (c *ChannelGraph) NumZombies() (uint64, error) {
|
||||
return numZombies, nil
|
||||
}
|
||||
|
||||
// PutClosedScid stores a SCID for a closed channel in the database. This is so
|
||||
// that we can ignore channel announcements that we know to be closed without
|
||||
// having to validate them and fetch a block.
|
||||
func (c *ChannelGraph) PutClosedScid(scid lnwire.ShortChannelID) error {
|
||||
return kvdb.Update(c.db, func(tx kvdb.RwTx) error {
|
||||
closedScids, err := tx.CreateTopLevelBucket(closedScidBucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var k [8]byte
|
||||
byteOrder.PutUint64(k[:], scid.ToUint64())
|
||||
|
||||
return closedScids.Put(k[:], []byte{})
|
||||
}, func() {})
|
||||
}
|
||||
|
||||
// IsClosedScid checks whether a channel identified by the passed in scid is
|
||||
// closed. This helps avoid having to perform expensive validation checks.
|
||||
// TODO: Add an LRU cache to cut down on disc reads.
|
||||
func (c *ChannelGraph) IsClosedScid(scid lnwire.ShortChannelID) (bool, error) {
|
||||
var isClosed bool
|
||||
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
|
||||
closedScids := tx.ReadBucket(closedScidBucket)
|
||||
if closedScids == nil {
|
||||
return ErrClosedScidsNotFound
|
||||
}
|
||||
|
||||
var k [8]byte
|
||||
byteOrder.PutUint64(k[:], scid.ToUint64())
|
||||
|
||||
if closedScids.Get(k[:]) != nil {
|
||||
isClosed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func() {
|
||||
isClosed = false
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return isClosed, nil
|
||||
}
|
||||
|
||||
func putLightningNode(nodeBucket kvdb.RwBucket, aliasBucket kvdb.RwBucket, // nolint:dupl
|
||||
updateIndex kvdb.RwBucket, node *LightningNode) error {
|
||||
|
||||
|
@ -4037,3 +4037,28 @@ func TestGraphLoading(t *testing.T) {
|
||||
graphReloaded.graphCache.nodeFeatures,
|
||||
)
|
||||
}
|
||||
|
||||
// TestClosedScid tests that we can correctly insert a SCID into the index of
|
||||
// closed short channel ids.
|
||||
func TestClosedScid(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
graph, err := MakeTestGraph(t)
|
||||
require.Nil(t, err)
|
||||
|
||||
scid := lnwire.ShortChannelID{}
|
||||
|
||||
// The scid should not exist in the closedScidBucket.
|
||||
exists, err := graph.IsClosedScid(scid)
|
||||
require.Nil(t, err)
|
||||
require.False(t, exists)
|
||||
|
||||
// After we call PutClosedScid, the call to IsClosedScid should return
|
||||
// true.
|
||||
err = graph.PutClosedScid(scid)
|
||||
require.Nil(t, err)
|
||||
|
||||
exists, err = graph.IsClosedScid(scid)
|
||||
require.Nil(t, err)
|
||||
require.True(t, exists)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user