Skip to content

Commit b491a1a

Browse files
committed
channeldb: add encoding for ChannelEdgePolicy2
Similarly to the previous commit, here we add the encoding for the new ChannelEdgePolicy2. This is done in the same was as for ChannelEdgeInfo2: - a 0xff prefix - followed by a type-byte - followed by the TLV encoding of the ChannelEdgePolicy2.
1 parent fb12e7a commit b491a1a

File tree

3 files changed

+395
-10
lines changed

3 files changed

+395
-10
lines changed

channeldb/edge_policy.go

Lines changed: 198 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package channeldb
22

33
import (
4+
"bufio"
45
"bytes"
56
"encoding/binary"
67
"errors"
@@ -12,6 +13,30 @@ import (
1213
"github.com/lightningnetwork/lnd/channeldb/models"
1314
"github.com/lightningnetwork/lnd/kvdb"
1415
"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
1540
)
1641

1742
func putChanEdgePolicy(edges kvdb.RwBucket, edge *models.ChannelEdgePolicy1,
@@ -63,7 +88,14 @@ func putChanEdgePolicy(edges kvdb.RwBucket, edge *models.ChannelEdgePolicy1,
6388
return err
6489
}
6590

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())
6799

68100
var oldIndexKey [8 + 8]byte
69101
byteOrder.PutUint64(oldIndexKey[:8], oldUpdateTime)
@@ -169,7 +201,13 @@ func fetchChanEdgePolicy(edges kvdb.RBucket, chanID []byte,
169201
return nil, err
170202
}
171203

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
173211
}
174212

175213
func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket,
@@ -201,8 +239,56 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket,
201239
return edge1, edge2, nil
202240
}
203241

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 {
206292

207293
err := wire.WriteVarBytes(w, 0, edge.SigBytes)
208294
if err != nil {
@@ -241,7 +327,7 @@ func serializeChanEdgePolicy(w io.Writer, edge *models.ChannelEdgePolicy1,
241327
return err
242328
}
243329

244-
if _, err := w.Write(to); err != nil {
330+
if _, err := w.Write(edge.ToNode[:]); err != nil {
245331
return err
246332
}
247333

@@ -271,7 +357,36 @@ func serializeChanEdgePolicy(w io.Writer, edge *models.ChannelEdgePolicy1,
271357
return nil
272358
}
273359

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+
275390
// Deserialize the policy. Note that in case an optional field is not
276391
// found, both an error and a populated policy object are returned.
277392
edge, deserializeErr := deserializeChanEdgePolicyRaw(r)
@@ -284,7 +399,45 @@ func deserializeChanEdgePolicy(r io.Reader) (*models.ChannelEdgePolicy1, error)
284399
return edge, deserializeErr
285400
}
286401

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,
288441
error) {
289442

290443
edge := &models.ChannelEdgePolicy1{}
@@ -370,3 +523,41 @@ func deserializeChanEdgePolicyRaw(r io.Reader) (*models.ChannelEdgePolicy1,
370523

371524
return edge, nil
372525
}
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

Comments
 (0)