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

lightningnetwork / lnd / 13566028875

27 Feb 2025 12:09PM UTC coverage: 49.396% (-9.4%) from 58.748%
13566028875

Pull #9555

github

ellemouton
graph/db: populate the graph cache in Start instead of during construction

In this commit, we move the graph cache population logic out of the
ChannelGraph constructor and into its Start method instead.
Pull Request #9555: graph: extract cache from CRUD [6]

34 of 54 new or added lines in 4 files covered. (62.96%)

27464 existing lines in 436 files now uncovered.

101095 of 204664 relevant lines covered (49.4%)

1.54 hits per line

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

66.67
/watchtower/wtdb/tower.go
1
package wtdb
2

3
import (
4
        "encoding/hex"
5
        "fmt"
6
        "io"
7
        "net"
8

9
        "github.com/btcsuite/btcd/btcec/v2"
10
        "github.com/lightningnetwork/lnd/tlv"
11
)
12

13
// TowerStatus represents the state of the tower as set by the tower client.
14
type TowerStatus uint8
15

16
const (
17
        // TowerStatusActive is the default state of the tower, and it indicates
18
        // that this tower should be used to attempt session creation.
19
        TowerStatusActive TowerStatus = 0
20

21
        // TowerStatusInactive indicates that the tower should not be used to
22
        // attempt session creation.
23
        TowerStatusInactive TowerStatus = 1
24
)
25

26
const (
27
        // TowerStatusTLVType is the TLV type number that will be used to store
28
        // the tower's status.
29
        TowerStatusTLVType = tlv.Type(0)
30
)
31

32
// TowerID is a unique 64-bit identifier allocated to each unique watchtower.
33
// This allows the client to conserve on-disk space by not needing to always
34
// reference towers by their pubkey.
35
type TowerID uint64
36

37
// TowerIDFromBytes constructs a TowerID from the provided byte slice. The
38
// argument must have at least 8 bytes, and should contain the TowerID in
39
// big-endian byte order.
40
func TowerIDFromBytes(towerIDBytes []byte) TowerID {
3✔
41
        return TowerID(byteOrder.Uint64(towerIDBytes))
3✔
42
}
3✔
43

44
// Bytes encodes a TowerID into an 8-byte slice in big-endian byte order.
45
func (id TowerID) Bytes() []byte {
3✔
46
        var buf [8]byte
3✔
47
        byteOrder.PutUint64(buf[:], uint64(id))
3✔
48
        return buf[:]
3✔
49
}
3✔
50

51
// Tower holds the necessary components required to connect to a remote tower.
52
// Communication is handled by brontide, and requires both a public key and an
53
// address.
54
type Tower struct {
55
        // ID is a unique ID for this record assigned by the database.
56
        ID TowerID
57

58
        // IdentityKey is the public key of the remote node, used to
59
        // authenticate the brontide transport.
60
        IdentityKey *btcec.PublicKey
61

62
        // Addresses is a list of possible addresses to reach the tower.
63
        Addresses []net.Addr
64

65
        // Status is the status of this tower as set by the client.
66
        Status TowerStatus
67
}
68

69
// AddAddress adds the given address to the tower's in-memory list of addresses.
70
// If the address's string is already present, the Tower will be left
71
// unmodified. Otherwise, the address is prepended to the beginning of the
72
// Tower's addresses, on the assumption that it is fresher than the others.
73
//
74
// NOTE: This method is NOT safe for concurrent use.
75
func (t *Tower) AddAddress(addr net.Addr) {
3✔
76
        // Ensure we don't add a duplicate address.
3✔
77
        addrStr := addr.String()
3✔
78
        for _, existingAddr := range t.Addresses {
6✔
79
                if existingAddr.String() == addrStr {
6✔
80
                        return
3✔
81
                }
3✔
82
        }
83

84
        // Add this address to the front of the list, on the assumption that it
85
        // is a fresher address and will be tried first.
UNCOV
86
        t.Addresses = append([]net.Addr{addr}, t.Addresses...)
×
87
}
88

89
// RemoveAddress removes the given address from the tower's in-memory list of
90
// addresses. If the address doesn't exist, then this will act as a NOP.
UNCOV
91
func (t *Tower) RemoveAddress(addr net.Addr) {
×
UNCOV
92
        addrStr := addr.String()
×
UNCOV
93
        for i, address := range t.Addresses {
×
UNCOV
94
                if address.String() != addrStr {
×
UNCOV
95
                        continue
×
96
                }
UNCOV
97
                t.Addresses = append(t.Addresses[:i], t.Addresses[i+1:]...)
×
UNCOV
98
                return
×
99
        }
100
}
101

102
// String returns a user-friendly identifier of the tower.
103
func (t *Tower) String() string {
×
104
        pubKey := hex.EncodeToString(t.IdentityKey.SerializeCompressed())
×
105
        if len(t.Addresses) == 0 {
×
106
                return pubKey
×
107
        }
×
108
        return fmt.Sprintf("%v@%v", pubKey, t.Addresses[0])
×
109
}
110

111
// Encode writes the Tower to the passed io.Writer. The TowerID is not
112
// serialized, since it acts as the key.
113
func (t *Tower) Encode(w io.Writer) error {
3✔
114
        err := WriteElements(w,
3✔
115
                t.IdentityKey,
3✔
116
                t.Addresses,
3✔
117
        )
3✔
118
        if err != nil {
3✔
119
                return err
×
120
        }
×
121

122
        status := uint8(t.Status)
3✔
123
        tlvRecords := []tlv.Record{
3✔
124
                tlv.MakePrimitiveRecord(TowerStatusTLVType, &status),
3✔
125
        }
3✔
126

3✔
127
        tlvStream, err := tlv.NewStream(tlvRecords...)
3✔
128
        if err != nil {
3✔
129
                return err
×
130
        }
×
131

132
        return tlvStream.Encode(w)
3✔
133
}
134

135
// Decode reads a Tower from the passed io.Reader. The TowerID is meant to be
136
// decoded from the key.
137
func (t *Tower) Decode(r io.Reader) error {
3✔
138
        err := ReadElements(r,
3✔
139
                &t.IdentityKey,
3✔
140
                &t.Addresses,
3✔
141
        )
3✔
142
        if err != nil {
3✔
143
                return err
×
144
        }
×
145

146
        var status uint8
3✔
147
        tlvRecords := []tlv.Record{
3✔
148
                tlv.MakePrimitiveRecord(TowerStatusTLVType, &status),
3✔
149
        }
3✔
150

3✔
151
        tlvStream, err := tlv.NewStream(tlvRecords...)
3✔
152
        if err != nil {
3✔
153
                return err
×
154
        }
×
155

156
        typeMap, err := tlvStream.DecodeWithParsedTypes(r)
3✔
157
        if err != nil {
3✔
158
                return err
×
159
        }
×
160

161
        if _, ok := typeMap[TowerStatusTLVType]; ok {
6✔
162
                t.Status = TowerStatus(status)
3✔
163
        }
3✔
164

165
        return nil
3✔
166
}
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

© 2025 Coveralls, Inc