Skip to content

Commit 3bb4d6d

Browse files
authored
Merge pull request #9036 from Roasbeef/0-18-3-branch
release: bump version to v0.18.3 rc2
2 parents 8f25de0 + d111d8d commit 3bb4d6d

25 files changed

+1279
-197
lines changed

build/version.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const (
4747

4848
// AppPreRelease MUST only contain characters from semanticAlphabet per
4949
// the semantic versioning spec.
50-
AppPreRelease = "beta.rc1"
50+
AppPreRelease = "beta.rc2"
5151
)
5252

5353
func init() {

channeldb/error.go

+4
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

+97-3
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
@@ -2143,6 +2152,21 @@ func (c *ChannelGraph) FilterKnownChanIDs(chansInfo []ChannelUpdateInfo,
21432152
zombieIndex, scid,
21442153
)
21452154

2155+
// TODO(ziggie): Make sure that for the strict
2156+
// pruning case we compare the pubkeys and
2157+
// whether the right timestamp is not older than
2158+
// the `ChannelPruneExpiry`.
2159+
//
2160+
// NOTE: The timestamp data has no verification
2161+
// attached to it in the `ReplyChannelRange` msg
2162+
// so we are trusting this data at this point.
2163+
// However it is not critical because we are
2164+
// just removing the channel from the db when
2165+
// the timestamps are more recent. During the
2166+
// querying of the gossip msg verification
2167+
// happens as usual.
2168+
// However we should start punishing peers when
2169+
// they don't provide us honest data ?
21462170
isStillZombie := isZombieChan(
21472171
info.Node1UpdateTimestamp,
21482172
info.Node2UpdateTimestamp,
@@ -2211,6 +2235,29 @@ type ChannelUpdateInfo struct {
22112235
Node2UpdateTimestamp time.Time
22122236
}
22132237

2238+
// NewChannelUpdateInfo is a constructor which makes sure we initialize the
2239+
// timestamps with zero seconds unix timestamp which equals
2240+
// `January 1, 1970, 00:00:00 UTC` in case the value is `time.Time{}`.
2241+
func NewChannelUpdateInfo(scid lnwire.ShortChannelID, node1Timestamp,
2242+
node2Timestamp time.Time) ChannelUpdateInfo {
2243+
2244+
chanInfo := ChannelUpdateInfo{
2245+
ShortChannelID: scid,
2246+
Node1UpdateTimestamp: node1Timestamp,
2247+
Node2UpdateTimestamp: node2Timestamp,
2248+
}
2249+
2250+
if node1Timestamp.IsZero() {
2251+
chanInfo.Node1UpdateTimestamp = time.Unix(0, 0)
2252+
}
2253+
2254+
if node2Timestamp.IsZero() {
2255+
chanInfo.Node2UpdateTimestamp = time.Unix(0, 0)
2256+
}
2257+
2258+
return chanInfo
2259+
}
2260+
22142261
// BlockChannelRange represents a range of channels for a given block height.
22152262
type BlockChannelRange struct {
22162263
// Height is the height of the block all of the channels below were
@@ -2284,9 +2331,9 @@ func (c *ChannelGraph) FilterChannelRange(startHeight,
22842331
rawCid := byteOrder.Uint64(k)
22852332
cid := lnwire.NewShortChanIDFromInt(rawCid)
22862333

2287-
chanInfo := ChannelUpdateInfo{
2288-
ShortChannelID: cid,
2289-
}
2334+
chanInfo := NewChannelUpdateInfo(
2335+
cid, time.Time{}, time.Time{},
2336+
)
22902337

22912338
if !withTimestamps {
22922339
channelsPerBlock[cid.BlockHeight] = append(
@@ -3846,6 +3893,53 @@ func (c *ChannelGraph) NumZombies() (uint64, error) {
38463893
return numZombies, nil
38473894
}
38483895

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+
38493943
func putLightningNode(nodeBucket kvdb.RwBucket, aliasBucket kvdb.RwBucket, // nolint:dupl
38503944
updateIndex kvdb.RwBucket, node *LightningNode) error {
38513945

channeldb/graph_test.go

+64-29
Original file line numberDiff line numberDiff line change
@@ -1980,9 +1980,9 @@ func TestFilterKnownChanIDs(t *testing.T) {
19801980
t.Fatalf("unable to create channel edge: %v", err)
19811981
}
19821982

1983-
chanIDs = append(chanIDs, ChannelUpdateInfo{
1984-
ShortChannelID: chanID,
1985-
})
1983+
chanIDs = append(chanIDs, NewChannelUpdateInfo(
1984+
chanID, time.Time{}, time.Time{},
1985+
))
19861986
}
19871987

19881988
const numZombies = 5
@@ -2024,20 +2024,28 @@ func TestFilterKnownChanIDs(t *testing.T) {
20242024
// should get the same set back.
20252025
{
20262026
queryIDs: []ChannelUpdateInfo{
2027-
{ShortChannelID: lnwire.ShortChannelID{
2028-
BlockHeight: 99,
2029-
}},
2030-
{ShortChannelID: lnwire.ShortChannelID{
2031-
BlockHeight: 100,
2032-
}},
2027+
{
2028+
ShortChannelID: lnwire.ShortChannelID{
2029+
BlockHeight: 99,
2030+
},
2031+
},
2032+
{
2033+
ShortChannelID: lnwire.ShortChannelID{
2034+
BlockHeight: 100,
2035+
},
2036+
},
20332037
},
20342038
resp: []ChannelUpdateInfo{
2035-
{ShortChannelID: lnwire.ShortChannelID{
2036-
BlockHeight: 99,
2037-
}},
2038-
{ShortChannelID: lnwire.ShortChannelID{
2039-
BlockHeight: 100,
2040-
}},
2039+
{
2040+
ShortChannelID: lnwire.ShortChannelID{
2041+
BlockHeight: 99,
2042+
},
2043+
},
2044+
{
2045+
ShortChannelID: lnwire.ShortChannelID{
2046+
BlockHeight: 100,
2047+
},
2048+
},
20412049
},
20422050
},
20432051

@@ -2419,7 +2427,7 @@ func TestFilterChannelRange(t *testing.T) {
24192427
)
24202428
)
24212429

2422-
updateTimeSeed := int64(1)
2430+
updateTimeSeed := time.Now().Unix()
24232431
maybeAddPolicy := func(chanID uint64, node *LightningNode,
24242432
node2 bool) time.Time {
24252433

@@ -2428,7 +2436,7 @@ func TestFilterChannelRange(t *testing.T) {
24282436
chanFlags = lnwire.ChanUpdateDirection
24292437
}
24302438

2431-
var updateTime time.Time
2439+
var updateTime = time.Unix(0, 0)
24322440
if rand.Int31n(2) == 0 {
24332441
updateTime = time.Unix(updateTimeSeed, 0)
24342442
err = graph.UpdateEdgePolicy(&models.ChannelEdgePolicy{
@@ -2456,11 +2464,16 @@ func TestFilterChannelRange(t *testing.T) {
24562464
)
24572465
require.NoError(t, graph.AddChannelEdge(&channel2))
24582466

2467+
chanInfo1 := NewChannelUpdateInfo(
2468+
chanID1, time.Time{}, time.Time{},
2469+
)
2470+
chanInfo2 := NewChannelUpdateInfo(
2471+
chanID2, time.Time{}, time.Time{},
2472+
)
24592473
channelRanges = append(channelRanges, BlockChannelRange{
24602474
Height: chanHeight,
24612475
Channels: []ChannelUpdateInfo{
2462-
{ShortChannelID: chanID1},
2463-
{ShortChannelID: chanID2},
2476+
chanInfo1, chanInfo2,
24642477
},
24652478
})
24662479

@@ -2471,20 +2484,17 @@ func TestFilterChannelRange(t *testing.T) {
24712484
time4 = maybeAddPolicy(channel2.ChannelID, node2, true)
24722485
)
24732486

2487+
chanInfo1 = NewChannelUpdateInfo(
2488+
chanID1, time1, time2,
2489+
)
2490+
chanInfo2 = NewChannelUpdateInfo(
2491+
chanID2, time3, time4,
2492+
)
24742493
channelRangesWithTimestamps = append(
24752494
channelRangesWithTimestamps, BlockChannelRange{
24762495
Height: chanHeight,
24772496
Channels: []ChannelUpdateInfo{
2478-
{
2479-
ShortChannelID: chanID1,
2480-
Node1UpdateTimestamp: time1,
2481-
Node2UpdateTimestamp: time2,
2482-
},
2483-
{
2484-
ShortChannelID: chanID2,
2485-
Node1UpdateTimestamp: time3,
2486-
Node2UpdateTimestamp: time4,
2487-
},
2497+
chanInfo1, chanInfo2,
24882498
},
24892499
},
24902500
)
@@ -4027,3 +4037,28 @@ func TestGraphLoading(t *testing.T) {
40274037
graphReloaded.graphCache.nodeFeatures,
40284038
)
40294039
}
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)