• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 21754201310

06 Feb 2026 02:33PM UTC coverage: 65.063%. First build
21754201310

Pull #10542

github

web-flow
Merge d37a5b58c into 509913ebd
Pull Request #10542: [g175] graph/db: add v2 gossip support for channel policies

138 of 562 new or added lines in 14 files covered. (24.56%)

138940 of 213546 relevant lines covered (65.06%)

20579.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.73
/graph/db/reject_cache.go
1
package graphdb
2

3
import (
4
        "time"
5

6
        "github.com/lightningnetwork/lnd/lnwire"
7
)
8

9
// rejectFlags is a compact representation of various metadata stored by the
10
// reject cache about a particular channel.
11
type rejectFlags uint8
12

13
const (
14
        // rejectFlagExists is a flag indicating whether the channel exists,
15
        // i.e. the channel is open and has a recent channel update. If this
16
        // flag is not set, the channel is either a zombie or unknown.
17
        rejectFlagExists rejectFlags = 1 << iota
18

19
        // rejectFlagZombie is a flag indicating whether the channel is a
20
        // zombie, i.e. the channel is open but has no recent channel updates.
21
        rejectFlagZombie
22
)
23

24
// packRejectFlags computes the rejectFlags corresponding to the passed boolean
25
// values indicating whether the edge exists or is a zombie.
26
func packRejectFlags(exists, isZombie bool) rejectFlags {
640✔
27
        var flags rejectFlags
640✔
28
        if exists {
945✔
29
                flags |= rejectFlagExists
305✔
30
        }
305✔
31
        if isZombie {
842✔
32
                flags |= rejectFlagZombie
202✔
33
        }
202✔
34

35
        return flags
640✔
36
}
37

38
// unpack returns the booleans packed into the rejectFlags. The first indicates
39
// if the edge exists in our graph, the second indicates if the edge is a
40
// zombie.
41
func (f rejectFlags) unpack() (bool, bool) {
75✔
42
        return f&rejectFlagExists == rejectFlagExists,
75✔
43
                f&rejectFlagZombie == rejectFlagZombie
75✔
44
}
75✔
45

46
// rejectCacheEntry caches frequently accessed information about a channel,
47
// including the timestamps of its latest edge policies and whether or not the
48
// channel exists in the graph.
49
type rejectCacheEntry struct {
50
        // upd{1,2}Time are Unix timestamps for v1 policies.
51
        upd1Time int64
52
        upd2Time int64
53

54
        // upd{1,2}BlockHeight are the last known block heights for v2
55
        // policies.
56
        upd1BlockHeight int64
57
        upd2BlockHeight int64
58

59
        flags rejectFlags
60
}
61

62
func newRejectCacheEntryV1(upd1, upd2 time.Time, exists,
NEW
63
        isZombie bool) rejectCacheEntry {
×
NEW
64

×
NEW
65
        return rejectCacheEntry{
×
NEW
66
                upd1Time: upd1.Unix(),
×
NEW
67
                upd2Time: upd2.Unix(),
×
NEW
68
                flags:    packRejectFlags(exists, isZombie),
×
NEW
69
        }
×
NEW
70
}
×
71

72
func newRejectCacheEntryV2(upd1, upd2 uint32, exists,
NEW
73
        isZombie bool) rejectCacheEntry {
×
NEW
74

×
NEW
75
        return rejectCacheEntry{
×
NEW
76
                upd1BlockHeight: int64(upd1),
×
NEW
77
                upd2BlockHeight: int64(upd2),
×
NEW
78
                flags:           packRejectFlags(exists, isZombie),
×
NEW
79
        }
×
NEW
80
}
×
81

82
func updateRejectCacheEntryV1(entry *rejectCacheEntry, isUpdate1 bool,
NEW
83
        lastUpdate time.Time) {
×
NEW
84

×
NEW
85
        if isUpdate1 {
×
NEW
86
                entry.upd1Time = lastUpdate.Unix()
×
NEW
87
        } else {
×
NEW
88
                entry.upd2Time = lastUpdate.Unix()
×
NEW
89
        }
×
90
}
91

92
func updateRejectCacheEntryV2(entry *rejectCacheEntry, isUpdate1 bool,
NEW
93
        blockHeight uint32) {
×
NEW
94

×
NEW
95
        blockHeight64 := int64(blockHeight)
×
NEW
96
        if isUpdate1 {
×
NEW
97
                entry.upd1BlockHeight = blockHeight64
×
NEW
98
        } else {
×
NEW
99
                entry.upd2BlockHeight = blockHeight64
×
NEW
100
        }
×
101
}
102

103
// rejectCacheKey uniquely identifies a channel entry in the reject cache by
104
// gossip version and channel ID.
105
type rejectCacheKey struct {
106
        version lnwire.GossipVersion
107
        chanID  uint64
108
}
109

110
// rejectCache is an in-memory cache used to improve the performance of
111
// HasChannelEdge. It caches information about the whether or channel exists, as
112
// well as the most recent timestamps for each policy (if they exists).
113
type rejectCache struct {
114
        n     int
115
        edges map[rejectCacheKey]rejectCacheEntry
116
}
117

118
// newRejectCache creates a new rejectCache with maximum capacity of n entries.
119
func newRejectCache(n int) *rejectCache {
187✔
120
        return &rejectCache{
187✔
121
                n:     n,
187✔
122
                edges: make(map[rejectCacheKey]rejectCacheEntry, n),
187✔
123
        }
187✔
124
}
187✔
125

126
// get returns the entry from the cache for chanid, if it exists.
127
func (c *rejectCache) get(version lnwire.GossipVersion, chanid uint64) (
128
        rejectCacheEntry, bool) {
3,624✔
129

3,624✔
130
        entry, ok := c.edges[rejectCacheKey{
3,624✔
131
                version: version,
3,624✔
132
                chanID:  chanid,
3,624✔
133
        }]
3,624✔
134
        return entry, ok
3,624✔
135
}
3,624✔
136

137
// insert adds the entry to the reject cache. If an entry for chanid already
138
// exists, it will be replaced with the new entry. If the entry doesn't exists,
139
// it will be inserted to the cache, performing a random eviction if the cache
140
// is at capacity.
141
func (c *rejectCache) insert(version lnwire.GossipVersion, chanid uint64,
142
        entry rejectCacheEntry) {
345✔
143

345✔
144
        key := rejectCacheKey{
345✔
145
                version: version,
345✔
146
                chanID:  chanid,
345✔
147
        }
345✔
148

345✔
149
        // If entry exists, replace it.
345✔
150
        if _, ok := c.edges[key]; ok {
453✔
151
                c.edges[key] = entry
108✔
152
                return
108✔
153
        }
108✔
154

155
        // Otherwise, evict an entry at random and insert.
156
        if len(c.edges) == c.n {
241✔
157
                for id := range c.edges {
2✔
158
                        delete(c.edges, id)
1✔
159
                        break
1✔
160
                }
161
        }
162
        c.edges[key] = entry
240✔
163
}
164

165
// remove deletes an entry for chanid from the cache, if it exists.
166
func (c *rejectCache) remove(version lnwire.GossipVersion, chanid uint64) {
1,875✔
167
        delete(c.edges, rejectCacheKey{
1,875✔
168
                version: version,
1,875✔
169
                chanID:  chanid,
1,875✔
170
        })
1,875✔
171
}
1,875✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc