1
1
package channeldb
2
2
3
3
import (
4
+ "bufio"
4
5
"bytes"
5
6
"encoding/binary"
6
7
"errors"
@@ -12,6 +13,30 @@ import (
12
13
"github.com/lightningnetwork/lnd/channeldb/models"
13
14
"github.com/lightningnetwork/lnd/kvdb"
14
15
"github.com/lightningnetwork/lnd/lnwire"
16
+ "github.com/lightningnetwork/lnd/tlv"
17
+ )
18
+
19
+ const (
20
+ EdgePolicy2MsgType = tlv .Type (0 )
21
+ EdgePolicy2ToNode = tlv .Type (1 )
22
+
23
+ // chanEdgePolicyNewEncodingPrefix is a byte used in the channel edge
24
+ // policy encoding to signal that the new style encoding which is
25
+ // prefixed with a type byte is being used instead of the legacy
26
+ // encoding which would start with 0x02 due to the fact that the
27
+ // encoding would start with a DER encoded ecdsa signature.
28
+ chanEdgePolicyNewEncodingPrefix = 0xff
29
+ )
30
+
31
+ // edgePolicyEncoding indicates how the bytes for a channel edge policy have
32
+ // been serialised.
33
+ type edgePolicyEncodingType uint8
34
+
35
+ const (
36
+ // edgePolicy2EncodingType will be used as a prefix for edge policies
37
+ // advertised using the ChannelUpdate2 message. The type indicates how
38
+ // the bytes following should be deserialized.
39
+ edgePolicy2EncodingType edgePolicyEncodingType = 0
15
40
)
16
41
17
42
func putChanEdgePolicy (edges kvdb.RwBucket , edge * models.ChannelEdgePolicy1 ,
@@ -63,7 +88,14 @@ func putChanEdgePolicy(edges kvdb.RwBucket, edge *models.ChannelEdgePolicy1,
63
88
return err
64
89
}
65
90
66
- oldUpdateTime := uint64 (oldEdgePolicy .LastUpdate .Unix ())
91
+ oldPol , ok := oldEdgePolicy .(* models.ChannelEdgePolicy1 )
92
+ if ! ok {
93
+ return fmt .Errorf ("expected " +
94
+ "*models.ChannelEdgePolicy1, got: %T" ,
95
+ oldEdgePolicy )
96
+ }
97
+
98
+ oldUpdateTime := uint64 (oldPol .LastUpdate .Unix ())
67
99
68
100
var oldIndexKey [8 + 8 ]byte
69
101
byteOrder .PutUint64 (oldIndexKey [:8 ], oldUpdateTime )
@@ -169,7 +201,13 @@ func fetchChanEdgePolicy(edges kvdb.RBucket, chanID []byte,
169
201
return nil , err
170
202
}
171
203
172
- return ep , nil
204
+ pol , ok := ep .(* models.ChannelEdgePolicy1 )
205
+ if ! ok {
206
+ return nil , fmt .Errorf ("expected *models.ChannelEdgePolicy1, " +
207
+ "got: %T" , ep )
208
+ }
209
+
210
+ return pol , nil
173
211
}
174
212
175
213
func fetchChanEdgePolicies (edgeIndex kvdb.RBucket , edges kvdb.RBucket ,
@@ -201,8 +239,56 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket,
201
239
return edge1 , edge2 , nil
202
240
}
203
241
204
- func serializeChanEdgePolicy (w io.Writer , edge * models.ChannelEdgePolicy1 ,
205
- to []byte ) error {
242
+ func serializeChanEdgePolicy (w io.Writer ,
243
+ edgePolicy models.ChannelEdgePolicy , toNode []byte ) error {
244
+
245
+ var (
246
+ withTypeByte bool
247
+ typeByte edgePolicyEncodingType
248
+ serialize func (w io.Writer ) error
249
+ )
250
+
251
+ switch policy := edgePolicy .(type ) {
252
+ case * models.ChannelEdgePolicy1 :
253
+ serialize = func (w io.Writer ) error {
254
+ copy (policy .ToNode [:], toNode )
255
+
256
+ return serializeChanEdgePolicy1 (w , policy )
257
+ }
258
+ case * models.ChannelEdgePolicy2 :
259
+ withTypeByte = true
260
+ typeByte = edgePolicy2EncodingType
261
+
262
+ serialize = func (w io.Writer ) error {
263
+ copy (policy .ToNode [:], toNode )
264
+
265
+ return serializeChanEdgePolicy2 (w , policy )
266
+ }
267
+ default :
268
+ return fmt .Errorf ("unhandled implementation of " +
269
+ "ChannelEdgePolicy: %T" , edgePolicy )
270
+ }
271
+
272
+ if withTypeByte {
273
+ // First, write the identifying encoding byte to signal that
274
+ // this is not using the legacy encoding.
275
+ _ , err := w .Write ([]byte {chanEdgePolicyNewEncodingPrefix })
276
+ if err != nil {
277
+ return err
278
+ }
279
+
280
+ // Now, write the encoding type.
281
+ _ , err = w .Write ([]byte {byte (typeByte )})
282
+ if err != nil {
283
+ return err
284
+ }
285
+ }
286
+
287
+ return serialize (w )
288
+ }
289
+
290
+ func serializeChanEdgePolicy1 (w io.Writer ,
291
+ edge * models.ChannelEdgePolicy1 ) error {
206
292
207
293
err := wire .WriteVarBytes (w , 0 , edge .SigBytes )
208
294
if err != nil {
@@ -241,7 +327,7 @@ func serializeChanEdgePolicy(w io.Writer, edge *models.ChannelEdgePolicy1,
241
327
return err
242
328
}
243
329
244
- if _ , err := w .Write (to ); err != nil {
330
+ if _ , err := w .Write (edge . ToNode [:] ); err != nil {
245
331
return err
246
332
}
247
333
@@ -271,7 +357,36 @@ func serializeChanEdgePolicy(w io.Writer, edge *models.ChannelEdgePolicy1,
271
357
return nil
272
358
}
273
359
274
- func deserializeChanEdgePolicy (r io.Reader ) (* models.ChannelEdgePolicy1 , error ) {
360
+ func serializeChanEdgePolicy2 (w io.Writer ,
361
+ edge * models.ChannelEdgePolicy2 ) error {
362
+
363
+ if len (edge .ExtraOpaqueData ) > MaxAllowedExtraOpaqueBytes {
364
+ return ErrTooManyExtraOpaqueBytes (len (edge .ExtraOpaqueData ))
365
+ }
366
+
367
+ var b bytes.Buffer
368
+ if err := edge .Encode (& b , 0 ); err != nil {
369
+ return err
370
+ }
371
+
372
+ msg := b .Bytes ()
373
+
374
+ records := []tlv.Record {
375
+ tlv .MakePrimitiveRecord (EdgePolicy2MsgType , & msg ),
376
+ tlv .MakePrimitiveRecord (EdgePolicy2ToNode , & edge .ToNode ),
377
+ }
378
+
379
+ stream , err := tlv .NewStream (records ... )
380
+ if err != nil {
381
+ return err
382
+ }
383
+
384
+ return stream .Encode (w )
385
+ }
386
+
387
+ func deserializeChanEdgePolicy (r io.Reader ) (models.ChannelEdgePolicy ,
388
+ error ) {
389
+
275
390
// Deserialize the policy. Note that in case an optional field is not
276
391
// found, both an error and a populated policy object are returned.
277
392
edge , deserializeErr := deserializeChanEdgePolicyRaw (r )
@@ -284,7 +399,45 @@ func deserializeChanEdgePolicy(r io.Reader) (*models.ChannelEdgePolicy1, error)
284
399
return edge , deserializeErr
285
400
}
286
401
287
- func deserializeChanEdgePolicyRaw (r io.Reader ) (* models.ChannelEdgePolicy1 ,
402
+ func deserializeChanEdgePolicyRaw (reader io.Reader ) (models.ChannelEdgePolicy ,
403
+ error ) {
404
+
405
+ // Wrap the io.Reader in a bufio.Reader so that we can peak the first
406
+ // byte of the stream without actually consuming from the stream.
407
+ r := bufio .NewReader (reader )
408
+
409
+ firstByte , err := r .Peek (1 )
410
+ if err != nil {
411
+ return nil , err
412
+ }
413
+
414
+ if firstByte [0 ] != chanEdgePolicyNewEncodingPrefix {
415
+ return deserializeChanEdgePolicy1Raw (r )
416
+ }
417
+
418
+ // Pop the encoding type byte.
419
+ var scratch [1 ]byte
420
+ if _ , err = r .Read (scratch [:]); err != nil {
421
+ return nil , err
422
+ }
423
+
424
+ // Now, read the encoding type byte.
425
+ if _ , err = r .Read (scratch [:]); err != nil {
426
+ return nil , err
427
+ }
428
+
429
+ encoding := edgePolicyEncodingType (scratch [0 ])
430
+ switch encoding {
431
+ case edgePolicy2EncodingType :
432
+ return deserializeChanEdgePolicy2Raw (r )
433
+
434
+ default :
435
+ return nil , fmt .Errorf ("unknown edge policy encoding type: %d" ,
436
+ encoding )
437
+ }
438
+ }
439
+
440
+ func deserializeChanEdgePolicy1Raw (r io.Reader ) (* models.ChannelEdgePolicy1 ,
288
441
error ) {
289
442
290
443
edge := & models.ChannelEdgePolicy1 {}
@@ -370,3 +523,41 @@ func deserializeChanEdgePolicyRaw(r io.Reader) (*models.ChannelEdgePolicy1,
370
523
371
524
return edge , nil
372
525
}
526
+
527
+ func deserializeChanEdgePolicy2Raw (r io.Reader ) (* models.ChannelEdgePolicy2 ,
528
+ error ) {
529
+
530
+ var (
531
+ msgBytes []byte
532
+ toNode [33 ]byte
533
+ )
534
+
535
+ records := []tlv.Record {
536
+ tlv .MakePrimitiveRecord (EdgePolicy2MsgType , & msgBytes ),
537
+ tlv .MakePrimitiveRecord (EdgePolicy2ToNode , & toNode ),
538
+ }
539
+
540
+ stream , err := tlv .NewStream (records ... )
541
+ if err != nil {
542
+ return nil , err
543
+ }
544
+
545
+ err = stream .Decode (r )
546
+ if err != nil {
547
+ return nil , err
548
+ }
549
+
550
+ var (
551
+ chanUpdate lnwire.ChannelUpdate2
552
+ reader = bytes .NewReader (msgBytes )
553
+ )
554
+ err = chanUpdate .Decode (reader , 0 )
555
+ if err != nil {
556
+ return nil , err
557
+ }
558
+
559
+ return & models.ChannelEdgePolicy2 {
560
+ ChannelUpdate2 : chanUpdate ,
561
+ ToNode : toNode ,
562
+ }, nil
563
+ }
0 commit comments