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

lightningnetwork / lnd / 13536249039

26 Feb 2025 03:42AM UTC coverage: 57.462% (-1.4%) from 58.835%
13536249039

Pull #8453

github

Roasbeef
peer: update chooseDeliveryScript to gen script if needed

In this commit, we update `chooseDeliveryScript` to generate a new
script if needed. This allows us to fold in a few other lines that
always followed this function into this expanded function.

The tests have been updated accordingly.
Pull Request #8453: [4/4] - multi: integrate new rbf coop close FSM into the existing peer flow

275 of 1318 new or added lines in 22 files covered. (20.86%)

19521 existing lines in 257 files now uncovered.

103858 of 180741 relevant lines covered (57.46%)

24750.23 hits per line

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

73.98
/htlcswitch/circuit.go
1
package htlcswitch
2

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

7
        "github.com/lightningnetwork/lnd/channeldb"
8
        "github.com/lightningnetwork/lnd/graph/db/models"
9
        "github.com/lightningnetwork/lnd/htlcswitch/hop"
10
        "github.com/lightningnetwork/lnd/lnwire"
11
)
12

13
// EmptyCircuitKey is a default value for an outgoing circuit key returned when
14
// a circuit's keystone has not been set. Note that this value is invalid for
15
// use as a keystone, since the outgoing channel id can never be equal to
16
// sourceHop.
17
var EmptyCircuitKey CircuitKey
18

19
// CircuitKey is a tuple of channel ID and HTLC ID, used to uniquely identify
20
// HTLCs in a circuit. Circuits are identified primarily by the circuit key of
21
// the incoming HTLC. However, a circuit may also be referenced by its outgoing
22
// circuit key after the HTLC has been forwarded via the outgoing link.
23
type CircuitKey = models.CircuitKey
24

25
// PaymentCircuit is used by the switch as placeholder between when the
26
// switch makes a forwarding decision and the outgoing link determines the
27
// proper HTLC ID for the local log. After the outgoing HTLC ID has been
28
// determined, the half circuit will be converted into a full PaymentCircuit.
29
type PaymentCircuit struct {
30
        // AddRef is the forward reference of the Add update in the incoming
31
        // link's forwarding package. This value is set on the htlcPacket of the
32
        // returned settle/fail so that it can be removed from disk.
33
        AddRef channeldb.AddRef
34

35
        // Incoming is the circuit key identifying the incoming channel and htlc
36
        // index from which this ADD originates.
37
        Incoming CircuitKey
38

39
        // Outgoing is the circuit key identifying the outgoing channel, and the
40
        // HTLC index that was used to forward the ADD. It will be nil if this
41
        // circuit's keystone has not been set.
42
        Outgoing *CircuitKey
43

44
        // PaymentHash used as unique identifier of payment.
45
        PaymentHash [32]byte
46

47
        // IncomingAmount is the value of the HTLC from the incoming link.
48
        IncomingAmount lnwire.MilliSatoshi
49

50
        // OutgoingAmount specifies the value of the HTLC leaving the switch,
51
        // either as a payment or forwarded amount.
52
        OutgoingAmount lnwire.MilliSatoshi
53

54
        // ErrorEncrypter is used to re-encrypt the onion failure before
55
        // sending it back to the originator of the payment.
56
        ErrorEncrypter hop.ErrorEncrypter
57

58
        // LoadedFromDisk is set true for any circuits loaded after the circuit
59
        // map is reloaded from disk.
60
        //
61
        // NOTE: This value is determined implicitly during a restart. It is not
62
        // persisted, and should never be set outside the circuit map.
63
        LoadedFromDisk bool
64
}
65

66
// HasKeystone returns true if an outgoing link has assigned this circuit's
67
// outgoing circuit key.
68
func (c *PaymentCircuit) HasKeystone() bool {
798✔
69
        return c.Outgoing != nil
798✔
70
}
798✔
71

72
// newPaymentCircuit initializes a payment circuit on the heap using the payment
73
// hash and an in-memory htlc packet.
74
func newPaymentCircuit(hash *[32]byte, pkt *htlcPacket) *PaymentCircuit {
498✔
75
        var addRef channeldb.AddRef
498✔
76
        if pkt.sourceRef != nil {
534✔
77
                addRef = *pkt.sourceRef
36✔
78
        }
36✔
79

80
        return &PaymentCircuit{
498✔
81
                AddRef: addRef,
498✔
82
                Incoming: CircuitKey{
498✔
83
                        ChanID: pkt.incomingChanID,
498✔
84
                        HtlcID: pkt.incomingHTLCID,
498✔
85
                },
498✔
86
                PaymentHash:    *hash,
498✔
87
                IncomingAmount: pkt.incomingAmount,
498✔
88
                OutgoingAmount: pkt.amount,
498✔
89
                ErrorEncrypter: pkt.obfuscator,
498✔
90
        }
498✔
91
}
92

93
// makePaymentCircuit initializes a payment circuit on the stack using the
94
// payment hash and an in-memory htlc packet.
95
func makePaymentCircuit(hash *[32]byte, pkt *htlcPacket) PaymentCircuit {
15✔
96
        var addRef channeldb.AddRef
15✔
97
        if pkt.sourceRef != nil {
15✔
98
                addRef = *pkt.sourceRef
×
99
        }
×
100

101
        return PaymentCircuit{
15✔
102
                AddRef: addRef,
15✔
103
                Incoming: CircuitKey{
15✔
104
                        ChanID: pkt.incomingChanID,
15✔
105
                        HtlcID: pkt.incomingHTLCID,
15✔
106
                },
15✔
107
                PaymentHash:    *hash,
15✔
108
                IncomingAmount: pkt.incomingAmount,
15✔
109
                OutgoingAmount: pkt.amount,
15✔
110
                ErrorEncrypter: pkt.obfuscator,
15✔
111
        }
15✔
112
}
113

114
// Encode writes a PaymentCircuit to the provided io.Writer.
115
func (c *PaymentCircuit) Encode(w io.Writer) error {
583✔
116
        if err := c.AddRef.Encode(w); err != nil {
583✔
117
                return err
×
118
        }
×
119

120
        if err := c.Incoming.Encode(w); err != nil {
583✔
121
                return err
×
122
        }
×
123

124
        if _, err := w.Write(c.PaymentHash[:]); err != nil {
583✔
125
                return err
×
126
        }
×
127

128
        var scratch [8]byte
583✔
129

583✔
130
        binary.BigEndian.PutUint64(scratch[:], uint64(c.IncomingAmount))
583✔
131
        if _, err := w.Write(scratch[:]); err != nil {
583✔
132
                return err
×
133
        }
×
134

135
        binary.BigEndian.PutUint64(scratch[:], uint64(c.OutgoingAmount))
583✔
136
        if _, err := w.Write(scratch[:]); err != nil {
583✔
137
                return err
×
138
        }
×
139

140
        // Defaults to EncrypterTypeNone.
141
        var encrypterType hop.EncrypterType
583✔
142
        if c.ErrorEncrypter != nil {
724✔
143
                encrypterType = c.ErrorEncrypter.Type()
141✔
144
        }
141✔
145

146
        err := binary.Write(w, binary.BigEndian, encrypterType)
583✔
147
        if err != nil {
583✔
148
                return err
×
149
        }
×
150

151
        // Skip encoding of error encrypter if this half add does not have one.
152
        if encrypterType == hop.EncrypterTypeNone {
1,025✔
153
                return nil
442✔
154
        }
442✔
155

156
        return c.ErrorEncrypter.Encode(w)
141✔
157
}
158

159
// Decode reads a PaymentCircuit from the provided io.Reader.
160
func (c *PaymentCircuit) Decode(r io.Reader) error {
102✔
161
        if err := c.AddRef.Decode(r); err != nil {
102✔
162
                return err
×
163
        }
×
164

165
        if err := c.Incoming.Decode(r); err != nil {
102✔
166
                return err
×
167
        }
×
168

169
        if _, err := io.ReadFull(r, c.PaymentHash[:]); err != nil {
102✔
170
                return err
×
171
        }
×
172

173
        var scratch [8]byte
102✔
174

102✔
175
        if _, err := io.ReadFull(r, scratch[:]); err != nil {
102✔
176
                return err
×
177
        }
×
178
        c.IncomingAmount = lnwire.MilliSatoshi(
102✔
179
                binary.BigEndian.Uint64(scratch[:]))
102✔
180

102✔
181
        if _, err := io.ReadFull(r, scratch[:]); err != nil {
102✔
182
                return err
×
183
        }
×
184
        c.OutgoingAmount = lnwire.MilliSatoshi(
102✔
185
                binary.BigEndian.Uint64(scratch[:]))
102✔
186

102✔
187
        // Read the encrypter type used for this circuit.
102✔
188
        var encrypterType hop.EncrypterType
102✔
189
        err := binary.Read(r, binary.BigEndian, &encrypterType)
102✔
190
        if err != nil {
102✔
191
                return err
×
192
        }
×
193

194
        switch encrypterType {
102✔
195
        case hop.EncrypterTypeNone:
4✔
196
                // No encrypter was provided, such as when the payment is
4✔
197
                // locally initiated.
4✔
198
                return nil
4✔
199

200
        case hop.EncrypterTypeSphinx:
32✔
201
                // Sphinx encrypter was used as this is a forwarded HTLC.
32✔
202
                c.ErrorEncrypter = hop.NewSphinxErrorEncrypter()
32✔
203

204
        case hop.EncrypterTypeMock:
66✔
205
                // Test encrypter.
66✔
206
                c.ErrorEncrypter = NewMockObfuscator()
66✔
207

UNCOV
208
        case hop.EncrypterTypeIntroduction:
×
UNCOV
209
                c.ErrorEncrypter = hop.NewIntroductionErrorEncrypter()
×
210

211
        case hop.EncrypterTypeRelaying:
×
212
                c.ErrorEncrypter = hop.NewRelayingErrorEncrypter()
×
213

214
        default:
×
215
                return UnknownEncrypterType(encrypterType)
×
216
        }
217

218
        return c.ErrorEncrypter.Decode(r)
98✔
219
}
220

221
// InKey returns the primary identifier for the circuit corresponding to the
222
// incoming HTLC.
223
func (c *PaymentCircuit) InKey() CircuitKey {
1,549✔
224
        return c.Incoming
1,549✔
225
}
1,549✔
226

227
// OutKey returns the keystone identifying the outgoing link and HTLC ID. If the
228
// circuit hasn't been completed, this method returns an EmptyKeystone, which is
229
// an invalid outgoing circuit key. Only call this method if HasKeystone returns
230
// true.
231
func (c *PaymentCircuit) OutKey() CircuitKey {
1,631✔
232
        if c.Outgoing != nil {
3,243✔
233
                return *c.Outgoing
1,612✔
234
        }
1,612✔
235

236
        return EmptyCircuitKey
19✔
237
}
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