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

lightningnetwork / lnd / 12312390362

13 Dec 2024 08:44AM UTC coverage: 57.458% (+8.5%) from 48.92%
12312390362

Pull #9343

github

ellemouton
fn: rework the ContextGuard and add tests

In this commit, the ContextGuard struct is re-worked such that the
context that its new main WithCtx method provides is cancelled in sync
with a parent context being cancelled or with it's quit channel being
cancelled. Tests are added to assert the behaviour. In order for the
close of the quit channel to be consistent with the cancelling of the
derived context, the quit channel _must_ be contained internal to the
ContextGuard so that callers are only able to close the channel via the
exposed Quit method which will then take care to first cancel any
derived context that depend on the quit channel before returning.
Pull Request #9343: fn: expand the ContextGuard and add tests

101853 of 177264 relevant lines covered (57.46%)

24972.93 hits per line

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

86.15
/watchtower/wtdb/client_session.go
1
package wtdb
2

3
import (
4
        "fmt"
5
        "io"
6

7
        "github.com/lightningnetwork/lnd/lnwire"
8
        "github.com/lightningnetwork/lnd/watchtower/blob"
9
        "github.com/lightningnetwork/lnd/watchtower/wtpolicy"
10
)
11

12
// CSessionStatus is a bit-field representing the possible statuses of
13
// ClientSessions.
14
type CSessionStatus uint8
15

16
const (
17
        // CSessionActive indicates that the ClientSession is active and can be
18
        // used for backups.
19
        CSessionActive CSessionStatus = 0
20

21
        // CSessionTerminal indicates that the ClientSession is in a terminal
22
        // state and cannot be used for backups.
23
        CSessionTerminal CSessionStatus = 1
24
)
25

26
// ClientSession encapsulates a SessionInfo returned from a successful
27
// session negotiation, and also records the tower and ephemeral secret used for
28
// communicating with the tower.
29
type ClientSession struct {
30
        // ID is the client's public key used when authenticating with the
31
        // tower.
32
        //
33
        // NOTE: This value is not serialized with the body of the struct, it
34
        // should be set and recovered as the ClientSession's key.
35
        ID SessionID
36

37
        ClientSessionBody
38
}
39

40
// ClientSessionBody represents the primary components of a ClientSession that
41
// are serialized together within the database. The CommittedUpdates and
42
// AckedUpdates are serialized in buckets separate from the body.
43
type ClientSessionBody struct {
44
        // SeqNum is the next unallocated sequence number that can be sent to
45
        // the tower.
46
        SeqNum uint16
47

48
        // TowerLastApplied the last last-applied the tower has echoed back.
49
        TowerLastApplied uint16
50

51
        // TowerID is the unique, db-assigned identifier that references the
52
        // Tower with which the session is negotiated.
53
        TowerID TowerID
54

55
        // KeyIndex is the index of key locator used to derive the client's
56
        // session key so that it can authenticate with the tower to update its
57
        // session. In order to rederive the private key, the key locator should
58
        // use the keychain.KeyFamilyTowerSession key family.
59
        KeyIndex uint32
60

61
        // Policy holds the negotiated session parameters.
62
        Policy wtpolicy.Policy
63

64
        // Status indicates the current state of the ClientSession.
65
        Status CSessionStatus
66

67
        // RewardPkScript is the pkscript that the tower's reward will be
68
        // deposited to if a sweep transaction confirms and the sessions
69
        // specifies a reward output.
70
        RewardPkScript []byte
71
}
72

73
// Encode writes a ClientSessionBody to the passed io.Writer.
74
func (s *ClientSessionBody) Encode(w io.Writer) error {
1,256✔
75
        return WriteElements(w,
1,256✔
76
                s.SeqNum,
1,256✔
77
                s.TowerLastApplied,
1,256✔
78
                uint64(s.TowerID),
1,256✔
79
                s.KeyIndex,
1,256✔
80
                uint8(s.Status),
1,256✔
81
                s.Policy,
1,256✔
82
                s.RewardPkScript,
1,256✔
83
        )
1,256✔
84
}
1,256✔
85

86
// Decode reads a ClientSessionBody from the passed io.Reader.
87
func (s *ClientSessionBody) Decode(r io.Reader) error {
1,518✔
88
        var (
1,518✔
89
                towerID uint64
1,518✔
90
                status  uint8
1,518✔
91
        )
1,518✔
92
        err := ReadElements(r,
1,518✔
93
                &s.SeqNum,
1,518✔
94
                &s.TowerLastApplied,
1,518✔
95
                &towerID,
1,518✔
96
                &s.KeyIndex,
1,518✔
97
                &status,
1,518✔
98
                &s.Policy,
1,518✔
99
                &s.RewardPkScript,
1,518✔
100
        )
1,518✔
101
        if err != nil {
1,518✔
102
                return err
×
103
        }
×
104

105
        s.TowerID = TowerID(towerID)
1,518✔
106
        s.Status = CSessionStatus(status)
1,518✔
107

1,518✔
108
        return nil
1,518✔
109
}
110

111
// BackupID identifies a particular revoked, remote commitment by channel id and
112
// commitment height.
113
type BackupID struct {
114
        // ChanID is the channel id of the revoked commitment.
115
        ChanID lnwire.ChannelID
116

117
        // CommitHeight is the commitment height of the revoked commitment.
118
        CommitHeight uint64
119
}
120

121
// Encode writes the BackupID from the passed io.Writer.
122
func (b *BackupID) Encode(w io.Writer) error {
171,769✔
123
        return WriteElements(w,
171,769✔
124
                b.ChanID,
171,769✔
125
                b.CommitHeight,
171,769✔
126
        )
171,769✔
127
}
171,769✔
128

129
// Decode reads a BackupID from the passed io.Reader.
130
func (b *BackupID) Decode(r io.Reader) error {
172,008✔
131
        return ReadElements(r,
172,008✔
132
                &b.ChanID,
172,008✔
133
                &b.CommitHeight,
172,008✔
134
        )
172,008✔
135
}
172,008✔
136

137
// String returns a human-readable encoding of a BackupID.
138
func (b BackupID) String() string {
×
139
        return fmt.Sprintf("backup(%v, %d)", b.ChanID, b.CommitHeight)
×
140
}
×
141

142
// CommittedUpdate holds a state update sent by a client along with its
143
// allocated sequence number and the exact remote commitment the encrypted
144
// justice transaction can rectify.
145
type CommittedUpdate struct {
146
        // SeqNum is the unique sequence number allocated by the session to this
147
        // update.
148
        SeqNum uint16
149

150
        CommittedUpdateBody
151
}
152

153
// CommittedUpdateBody represents the primary components of a CommittedUpdate.
154
// On disk, this is stored under the sequence number, which acts as its key.
155
type CommittedUpdateBody struct {
156
        // BackupID identifies the breached commitment that the encrypted blob
157
        // can spend from.
158
        BackupID BackupID
159

160
        // Hint is the 16-byte prefix of the revoked commitment transaction ID.
161
        Hint blob.BreachHint
162

163
        // EncryptedBlob is a ciphertext containing the sweep information for
164
        // exacting justice if the commitment transaction matching the breach
165
        // hint is broadcast.
166
        EncryptedBlob []byte
167
}
168

169
// Encode writes the CommittedUpdateBody to the passed io.Writer.
170
func (u *CommittedUpdateBody) Encode(w io.Writer) error {
624✔
171
        err := u.BackupID.Encode(w)
624✔
172
        if err != nil {
624✔
173
                return err
×
174
        }
×
175

176
        return WriteElements(w,
624✔
177
                u.Hint,
624✔
178
                u.EncryptedBlob,
624✔
179
        )
624✔
180
}
181

182
// Decode reads a CommittedUpdateBody from the passed io.Reader.
183
func (u *CommittedUpdateBody) Decode(r io.Reader) error {
863✔
184
        err := u.BackupID.Decode(r)
863✔
185
        if err != nil {
863✔
186
                return err
×
187
        }
×
188

189
        return ReadElements(r,
863✔
190
                &u.Hint,
863✔
191
                &u.EncryptedBlob,
863✔
192
        )
863✔
193
}
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