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

lightningnetwork / lnd / 15736109134

18 Jun 2025 02:46PM UTC coverage: 58.197% (-10.1%) from 68.248%
15736109134

Pull #9752

github

web-flow
Merge d2634a68c into 31c74f20f
Pull Request #9752: routerrpc: reject payment to invoice that don't have payment secret or blinded paths

6 of 13 new or added lines in 2 files covered. (46.15%)

28331 existing lines in 455 files now uncovered.

97860 of 168153 relevant lines covered (58.2%)

1.81 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