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

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

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

0.0
/watchtower/wtdb/migration1/codec.go
1
package migration1
2

3
import (
4
        "encoding/binary"
5
        "io"
6

7
        "github.com/lightningnetwork/lnd/channeldb"
8
        "github.com/lightningnetwork/lnd/lnwallet/chainfee"
9
        "github.com/lightningnetwork/lnd/watchtower/blob"
10
        "github.com/lightningnetwork/lnd/watchtower/wtpolicy"
11
)
12

13
// SessionIDSize is 33-bytes; it is a serialized, compressed public key.
14
const SessionIDSize = 33
15

16
// UnknownElementType is an alias for channeldb.UnknownElementType.
17
type UnknownElementType = channeldb.UnknownElementType
18

19
// SessionID is created from the remote public key of a client, and serves as a
20
// unique identifier and authentication for sending state updates.
21
type SessionID [SessionIDSize]byte
22

23
// TowerID is a unique 64-bit identifier allocated to each unique watchtower.
24
// This allows the client to conserve on-disk space by not needing to always
25
// reference towers by their pubkey.
26
type TowerID uint64
27

28
// Bytes encodes a TowerID into an 8-byte slice in big-endian byte order.
UNCOV
29
func (id TowerID) Bytes() []byte {
×
UNCOV
30
        var buf [8]byte
×
UNCOV
31
        binary.BigEndian.PutUint64(buf[:], uint64(id))
×
UNCOV
32
        return buf[:]
×
UNCOV
33
}
×
34

35
// ClientSession encapsulates a SessionInfo returned from a successful
36
// session negotiation, and also records the tower and ephemeral secret used for
37
// communicating with the tower.
38
type ClientSession struct {
39
        // ID is the client's public key used when authenticating with the
40
        // tower.
41
        ID SessionID
42
        ClientSessionBody
43
}
44

45
// CSessionStatus is a bit-field representing the possible statuses of
46
// ClientSessions.
47
type CSessionStatus uint8
48

49
type ClientSessionBody struct {
50
        // SeqNum is the next unallocated sequence number that can be sent to
51
        // the tower.
52
        SeqNum uint16
53

54
        // TowerLastApplied the last last-applied the tower has echoed back.
55
        TowerLastApplied uint16
56

57
        // TowerID is the unique, db-assigned identifier that references the
58
        // Tower with which the session is negotiated.
59
        TowerID TowerID
60

61
        // KeyIndex is the index of key locator used to derive the client's
62
        // session key so that it can authenticate with the tower to update its
63
        // session. In order to rederive the private key, the key locator should
64
        // use the keychain.KeyFamilyTowerSession key family.
65
        KeyIndex uint32
66

67
        // Policy holds the negotiated session parameters.
68
        Policy wtpolicy.Policy
69

70
        // Status indicates the current state of the ClientSession.
71
        Status CSessionStatus
72

73
        // RewardPkScript is the pkscript that the tower's reward will be
74
        // deposited to if a sweep transaction confirms and the sessions
75
        // specifies a reward output.
76
        RewardPkScript []byte
77
}
78

79
// Encode writes a ClientSessionBody to the passed io.Writer.
UNCOV
80
func (s *ClientSessionBody) Encode(w io.Writer) error {
×
UNCOV
81
        return WriteElements(w,
×
UNCOV
82
                s.SeqNum,
×
UNCOV
83
                s.TowerLastApplied,
×
UNCOV
84
                uint64(s.TowerID),
×
UNCOV
85
                s.KeyIndex,
×
UNCOV
86
                uint8(s.Status),
×
UNCOV
87
                s.Policy,
×
UNCOV
88
                s.RewardPkScript,
×
UNCOV
89
        )
×
UNCOV
90
}
×
91

92
// Decode reads a ClientSessionBody from the passed io.Reader.
UNCOV
93
func (s *ClientSessionBody) Decode(r io.Reader) error {
×
UNCOV
94
        var (
×
UNCOV
95
                towerID uint64
×
UNCOV
96
                status  uint8
×
UNCOV
97
        )
×
UNCOV
98
        err := ReadElements(r,
×
UNCOV
99
                &s.SeqNum,
×
UNCOV
100
                &s.TowerLastApplied,
×
UNCOV
101
                &towerID,
×
UNCOV
102
                &s.KeyIndex,
×
UNCOV
103
                &status,
×
UNCOV
104
                &s.Policy,
×
UNCOV
105
                &s.RewardPkScript,
×
UNCOV
106
        )
×
UNCOV
107
        if err != nil {
×
108
                return err
×
109
        }
×
110

UNCOV
111
        s.TowerID = TowerID(towerID)
×
UNCOV
112
        s.Status = CSessionStatus(status)
×
UNCOV
113

×
UNCOV
114
        return nil
×
115
}
116

117
// WriteElements serializes a variadic list of elements into the given
118
// io.Writer.
UNCOV
119
func WriteElements(w io.Writer, elements ...interface{}) error {
×
UNCOV
120
        for _, element := range elements {
×
UNCOV
121
                if err := WriteElement(w, element); err != nil {
×
122
                        return err
×
123
                }
×
124
        }
125

UNCOV
126
        return nil
×
127
}
128

129
// WriteElement serializes a single element into the provided io.Writer.
UNCOV
130
func WriteElement(w io.Writer, element interface{}) error {
×
UNCOV
131
        err := channeldb.WriteElement(w, element)
×
UNCOV
132
        switch {
×
133
        // Known to channeldb codec.
UNCOV
134
        case err == nil:
×
UNCOV
135
                return nil
×
136

137
        // Fail if error is not UnknownElementType.
UNCOV
138
        default:
×
UNCOV
139
                if _, ok := err.(UnknownElementType); !ok {
×
140
                        return err
×
141
                }
×
142
        }
143

144
        // Process any wtdb-specific extensions to the codec.
UNCOV
145
        switch e := element.(type) {
×
146
        case SessionID:
×
147
                if _, err := w.Write(e[:]); err != nil {
×
148
                        return err
×
149
                }
×
150

151
        case blob.BreachHint:
×
152
                if _, err := w.Write(e[:]); err != nil {
×
153
                        return err
×
154
                }
×
155

UNCOV
156
        case wtpolicy.Policy:
×
UNCOV
157
                return channeldb.WriteElements(w,
×
UNCOV
158
                        uint16(e.BlobType),
×
UNCOV
159
                        e.MaxUpdates,
×
UNCOV
160
                        e.RewardBase,
×
UNCOV
161
                        e.RewardRate,
×
UNCOV
162
                        uint64(e.SweepFeeRate),
×
UNCOV
163
                )
×
164

165
        // Type is still unknown to wtdb extensions, fail.
166
        default:
×
167
                return channeldb.NewUnknownElementType(
×
168
                        "WriteElement", element,
×
169
                )
×
170
        }
171

172
        return nil
×
173
}
174

175
// ReadElements deserializes the provided io.Reader into a variadic list of
176
// target elements.
UNCOV
177
func ReadElements(r io.Reader, elements ...interface{}) error {
×
UNCOV
178
        for _, element := range elements {
×
UNCOV
179
                if err := ReadElement(r, element); err != nil {
×
180
                        return err
×
181
                }
×
182
        }
183

UNCOV
184
        return nil
×
185
}
186

187
// ReadElement deserializes a single element from the provided io.Reader.
UNCOV
188
func ReadElement(r io.Reader, element interface{}) error {
×
UNCOV
189
        err := channeldb.ReadElement(r, element)
×
UNCOV
190
        switch {
×
191
        // Known to channeldb codec.
UNCOV
192
        case err == nil:
×
UNCOV
193
                return nil
×
194

195
        // Fail if error is not UnknownElementType.
UNCOV
196
        default:
×
UNCOV
197
                if _, ok := err.(UnknownElementType); !ok {
×
198
                        return err
×
199
                }
×
200
        }
201

202
        // Process any wtdb-specific extensions to the codec.
UNCOV
203
        switch e := element.(type) {
×
204
        case *SessionID:
×
205
                if _, err := io.ReadFull(r, e[:]); err != nil {
×
206
                        return err
×
207
                }
×
208

209
        case *blob.BreachHint:
×
210
                if _, err := io.ReadFull(r, e[:]); err != nil {
×
211
                        return err
×
212
                }
×
213

UNCOV
214
        case *wtpolicy.Policy:
×
UNCOV
215
                var (
×
UNCOV
216
                        blobType     uint16
×
UNCOV
217
                        sweepFeeRate uint64
×
UNCOV
218
                )
×
UNCOV
219
                err := channeldb.ReadElements(r,
×
UNCOV
220
                        &blobType,
×
UNCOV
221
                        &e.MaxUpdates,
×
UNCOV
222
                        &e.RewardBase,
×
UNCOV
223
                        &e.RewardRate,
×
UNCOV
224
                        &sweepFeeRate,
×
UNCOV
225
                )
×
UNCOV
226
                if err != nil {
×
227
                        return err
×
228
                }
×
229

UNCOV
230
                e.BlobType = blob.Type(blobType)
×
UNCOV
231
                e.SweepFeeRate = chainfee.SatPerKWeight(sweepFeeRate)
×
232

233
        // Type is still unknown to wtdb extensions, fail.
234
        default:
×
235
                return channeldb.NewUnknownElementType(
×
236
                        "ReadElement", element,
×
237
                )
×
238
        }
239

UNCOV
240
        return nil
×
241
}
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