Skip to content

Commit 8a03414

Browse files
authored
Merge pull request #10017 from ellemouton/strictTypeForChanFeatures
refactor+multi: use *lnwire.FeatureVector for ChannelEdgeInfo features
2 parents b5c84ea + 2f2845d commit 8a03414

14 files changed

+70
-78
lines changed

autopilot/prefattach_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ func (d *testDBGraph) addRandChannel(node1, node2 *btcec.PublicKey,
486486
edge := &models.ChannelEdgeInfo{
487487
ChannelID: chanID.ToUint64(),
488488
Capacity: capacity,
489+
Features: lnwire.EmptyFeatureVector(),
489490
}
490491
edge.AddNodeKeys(lnNode1, lnNode2, lnNode1, lnNode2)
491492
if err := d.db.AddChannelEdge(ctx, edge); err != nil {

discovery/gossiper.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2648,13 +2648,6 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(ctx context.Context,
26482648

26492649
// With the proof validated (if necessary), we can now store it within
26502650
// the database for our path finding and syncing needs.
2651-
var featureBuf bytes.Buffer
2652-
if err := ann.Features.Encode(&featureBuf); err != nil {
2653-
log.Errorf("unable to encode features: %v", err)
2654-
nMsg.err <- err
2655-
return nil, false
2656-
}
2657-
26582651
edge := &models.ChannelEdgeInfo{
26592652
ChannelID: scid.ToUint64(),
26602653
ChainHash: ann.ChainHash,
@@ -2663,8 +2656,10 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(ctx context.Context,
26632656
BitcoinKey1Bytes: ann.BitcoinKey1,
26642657
BitcoinKey2Bytes: ann.BitcoinKey2,
26652658
AuthProof: proof,
2666-
Features: featureBuf.Bytes(),
2667-
ExtraOpaqueData: ann.ExtraOpaqueData,
2659+
Features: lnwire.NewFeatureVector(
2660+
ann.Features, lnwire.Features,
2661+
),
2662+
ExtraOpaqueData: ann.ExtraOpaqueData,
26682663
}
26692664

26702665
// If there were any optional message fields provided, we'll include

graph/builder_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func TestAddProof(t *testing.T) {
7171
NodeKey1Bytes: node1.PubKeyBytes,
7272
NodeKey2Bytes: node2.PubKeyBytes,
7373
AuthProof: nil,
74+
Features: lnwire.EmptyFeatureVector(),
7475
FundingScript: fn.Some(script),
7576
}
7677
copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
@@ -158,6 +159,7 @@ func TestIgnoreChannelEdgePolicyForUnknownChannel(t *testing.T) {
158159
BitcoinKey1Bytes: pub1,
159160
BitcoinKey2Bytes: pub2,
160161
AuthProof: nil,
162+
Features: lnwire.EmptyFeatureVector(),
161163
FundingScript: fn.Some(script),
162164
}
163165
edgePolicy := &models.ChannelEdgePolicy{
@@ -281,6 +283,7 @@ func TestWakeUpOnStaleBranch(t *testing.T) {
281283
BitcoinSig1Bytes: testSig.Serialize(),
282284
BitcoinSig2Bytes: testSig.Serialize(),
283285
},
286+
Features: lnwire.EmptyFeatureVector(),
284287
FundingScript: fn.Some(fundingScript1),
285288
}
286289
copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
@@ -300,6 +303,7 @@ func TestWakeUpOnStaleBranch(t *testing.T) {
300303
BitcoinSig1Bytes: testSig.Serialize(),
301304
BitcoinSig2Bytes: testSig.Serialize(),
302305
},
306+
Features: lnwire.EmptyFeatureVector(),
303307
FundingScript: fn.Some(fundingScript2),
304308
}
305309
copy(edge2.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
@@ -491,6 +495,7 @@ func TestDisconnectedBlocks(t *testing.T) {
491495
BitcoinSig1Bytes: testSig.Serialize(),
492496
BitcoinSig2Bytes: testSig.Serialize(),
493497
},
498+
Features: lnwire.EmptyFeatureVector(),
494499
FundingScript: fn.Some([]byte{}),
495500
}
496501
copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
@@ -512,6 +517,7 @@ func TestDisconnectedBlocks(t *testing.T) {
512517
BitcoinSig1Bytes: testSig.Serialize(),
513518
BitcoinSig2Bytes: testSig.Serialize(),
514519
},
520+
Features: lnwire.EmptyFeatureVector(),
515521
FundingScript: fn.Some([]byte{}),
516522
}
517523
copy(edge2.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
@@ -645,6 +651,7 @@ func TestChansClosedOfflinePruneGraph(t *testing.T) {
645651
},
646652
ChannelPoint: *chanUTXO,
647653
Capacity: chanValue,
654+
Features: lnwire.EmptyFeatureVector(),
648655
FundingScript: fn.Some(script),
649656
}
650657
copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
@@ -1062,6 +1069,7 @@ func TestIsStaleNode(t *testing.T) {
10621069
BitcoinKey1Bytes: pub1,
10631070
BitcoinKey2Bytes: pub2,
10641071
AuthProof: nil,
1072+
Features: lnwire.EmptyFeatureVector(),
10651073
FundingScript: fn.Some(script),
10661074
}
10671075
if err := ctx.builder.AddEdge(ctxb, edge); err != nil {
@@ -1142,6 +1150,7 @@ func TestIsKnownEdge(t *testing.T) {
11421150
BitcoinKey2Bytes: pub2,
11431151
AuthProof: nil,
11441152
FundingScript: fn.Some(script),
1153+
Features: lnwire.EmptyFeatureVector(),
11451154
}
11461155
if err := ctx.builder.AddEdge(ctxb, edge); err != nil {
11471156
t.Fatalf("unable to add edge: %v", err)
@@ -1200,6 +1209,7 @@ func TestIsStaleEdgePolicy(t *testing.T) {
12001209
BitcoinKey1Bytes: pub1,
12011210
BitcoinKey2Bytes: pub2,
12021211
AuthProof: nil,
1212+
Features: lnwire.EmptyFeatureVector(),
12031213
FundingScript: fn.Some(script),
12041214
}
12051215
if err := ctx.builder.AddEdge(ctxb, edge); err != nil {
@@ -1508,6 +1518,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
15081518
AuthProof: &testAuthProof,
15091519
ChannelPoint: fundingPoint,
15101520
Capacity: btcutil.Amount(edge.Capacity),
1521+
Features: lnwire.EmptyFeatureVector(),
15111522
}
15121523

15131524
copy(edgeInfo.NodeKey1Bytes[:], node1Bytes)
@@ -1882,6 +1893,7 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
18821893
BitcoinKey1Bytes: node1Vertex,
18831894
NodeKey2Bytes: node2Vertex,
18841895
BitcoinKey2Bytes: node2Vertex,
1896+
Features: lnwire.EmptyFeatureVector(),
18851897
}
18861898

18871899
err = graph.AddChannelEdge(ctx, &edgeInfo)

graph/db/graph_test.go

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ func TestEdgeInsertionDeletion(t *testing.T) {
416416
BitcoinSig1Bytes: testSig.Serialize(),
417417
BitcoinSig2Bytes: testSig.Serialize(),
418418
},
419+
Features: lnwire.EmptyFeatureVector(),
419420
ChannelPoint: outpoint,
420421
Capacity: 9000,
421422
}
@@ -479,12 +480,6 @@ func createEdge(height, txIndex uint32, txPosition uint16, outPointIndex uint32,
479480
Index: outPointIndex,
480481
}
481482

482-
var (
483-
features = lnwire.NewRawFeatureVector()
484-
featureBuf bytes.Buffer
485-
)
486-
_ = features.Encode(&featureBuf)
487-
488483
node1Pub, _ := node1.PubKey()
489484
node2Pub, _ := node2.PubKey()
490485
edgeInfo := models.ChannelEdgeInfo{
@@ -499,7 +494,7 @@ func createEdge(height, txIndex uint32, txPosition uint16, outPointIndex uint32,
499494
ChannelPoint: outpoint,
500495
Capacity: 9000,
501496
ExtraOpaqueData: make([]byte, 0),
502-
Features: featureBuf.Bytes(),
497+
Features: lnwire.EmptyFeatureVector(),
503498
}
504499

505500
copy(edgeInfo.NodeKey1Bytes[:], node1Pub.SerializeCompressed())
@@ -663,8 +658,8 @@ func assertEdgeInfoEqual(t *testing.T, e1 *models.ChannelEdgeInfo,
663658
t.Fatalf("bitcoinkey2 doesn't match")
664659
}
665660

666-
if !bytes.Equal(e1.Features, e2.Features) {
667-
t.Fatalf("features doesn't match: %x vs %x", e1.Features,
661+
if !e1.Features.Equals(e2.Features.RawFeatureVector) {
662+
t.Fatalf("features don't match: %v vs %v", e1.Features,
668663
e2.Features)
669664
}
670665

@@ -741,12 +736,6 @@ func createChannelEdge(node1, node2 *models.LightningNode,
741736
Index: prand.Uint32(),
742737
}
743738

744-
var (
745-
features = lnwire.NewRawFeatureVector()
746-
featureBuf bytes.Buffer
747-
)
748-
_ = features.Encode(&featureBuf)
749-
750739
// Add the new edge to the database, this should proceed without any
751740
// errors.
752741
edgeInfo := &models.ChannelEdgeInfo{
@@ -759,7 +748,7 @@ func createChannelEdge(node1, node2 *models.LightningNode,
759748
2, 2, 2, 2,
760749
3, 3, 3, 3, 3,
761750
},
762-
Features: featureBuf.Bytes(),
751+
Features: lnwire.EmptyFeatureVector(),
763752
}
764753
copy(edgeInfo.NodeKey1Bytes[:], firstNode[:])
765754
copy(edgeInfo.NodeKey2Bytes[:], secondNode[:])
@@ -1617,6 +1606,7 @@ func fillTestGraph(t testing.TB, graph *ChannelGraph, numNodes,
16171606
BitcoinSig1Bytes: testSig.Serialize(),
16181607
BitcoinSig2Bytes: testSig.Serialize(),
16191608
},
1609+
Features: lnwire.EmptyFeatureVector(),
16201610
ChannelPoint: op,
16211611
Capacity: 1000,
16221612
}
@@ -1799,6 +1789,7 @@ func TestGraphPruning(t *testing.T) {
17991789
BitcoinSig1Bytes: testSig.Serialize(),
18001790
BitcoinSig2Bytes: testSig.Serialize(),
18011791
},
1792+
Features: lnwire.EmptyFeatureVector(),
18021793
ChannelPoint: op,
18031794
Capacity: 1000,
18041795
}

graph/db/kv_store.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4291,7 +4291,12 @@ func putChanEdgeInfo(edgeIndex kvdb.RwBucket,
42914291
return err
42924292
}
42934293

4294-
if err := wire.WriteVarBytes(&b, 0, edgeInfo.Features); err != nil {
4294+
var featureBuf bytes.Buffer
4295+
if err := edgeInfo.Features.Encode(&featureBuf); err != nil {
4296+
return fmt.Errorf("unable to encode features: %w", err)
4297+
}
4298+
4299+
if err := wire.WriteVarBytes(&b, 0, featureBuf.Bytes()); err != nil {
42954300
return err
42964301
}
42974302

@@ -4374,11 +4379,19 @@ func deserializeChanEdgeInfo(r io.Reader) (models.ChannelEdgeInfo, error) {
43744379
return models.ChannelEdgeInfo{}, err
43754380
}
43764381

4377-
edgeInfo.Features, err = wire.ReadVarBytes(r, 0, 900, "features")
4382+
featureBytes, err := wire.ReadVarBytes(r, 0, 900, "features")
43784383
if err != nil {
43794384
return models.ChannelEdgeInfo{}, err
43804385
}
43814386

4387+
features := lnwire.NewRawFeatureVector()
4388+
err = features.Decode(bytes.NewReader(featureBytes))
4389+
if err != nil {
4390+
return models.ChannelEdgeInfo{}, fmt.Errorf("unable to decode "+
4391+
"features: %w", err)
4392+
}
4393+
edgeInfo.Features = lnwire.NewFeatureVector(features, lnwire.Features)
4394+
43824395
proof := &models.ChannelAuthProof{}
43834396

43844397
proof.NodeSig1Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs")

graph/db/models/channel_edge_info.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/btcsuite/btcd/chaincfg/chainhash"
1010
"github.com/btcsuite/btcd/wire"
1111
"github.com/lightningnetwork/lnd/fn/v2"
12+
"github.com/lightningnetwork/lnd/lnwire"
1213
)
1314

1415
// ChannelEdgeInfo represents a fully authenticated channel along with all its
@@ -46,9 +47,9 @@ type ChannelEdgeInfo struct {
4647
BitcoinKey2Bytes [33]byte
4748
bitcoinKey2 *btcec.PublicKey
4849

49-
// Features is an opaque byte slice that encodes the set of channel
50-
// specific features that this channel edge supports.
51-
Features []byte
50+
// Features is the list of protocol features supported by this channel
51+
// edge.
52+
Features *lnwire.FeatureVector
5253

5354
// AuthProof is the authentication proof for this channel. This proof
5455
// contains a set of signatures binding four identities, which attests

graph/db/sql_store.go

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3833,26 +3833,16 @@ func insertChannel(ctx context.Context, db SQLQueries,
38333833
}
38343834

38353835
// Insert any channel features.
3836-
if len(edge.Features) != 0 {
3837-
chanFeatures := lnwire.NewRawFeatureVector()
3838-
err := chanFeatures.Decode(bytes.NewReader(edge.Features))
3836+
for feature := range edge.Features.Features() {
3837+
err = db.InsertChannelFeature(
3838+
ctx, sqlc.InsertChannelFeatureParams{
3839+
ChannelID: dbChanID,
3840+
FeatureBit: int32(feature),
3841+
},
3842+
)
38393843
if err != nil {
3840-
return nil, err
3841-
}
3842-
3843-
fv := lnwire.NewFeatureVector(chanFeatures, lnwire.Features)
3844-
for feature := range fv.Features() {
3845-
err = db.InsertChannelFeature(
3846-
ctx, sqlc.InsertChannelFeatureParams{
3847-
ChannelID: dbChanID,
3848-
FeatureBit: int32(feature),
3849-
},
3850-
)
3851-
if err != nil {
3852-
return nil, fmt.Errorf("unable to insert "+
3853-
"channel(%d) feature(%v): %w", dbChanID,
3854-
feature, err)
3855-
}
3844+
return nil, fmt.Errorf("unable to insert channel(%d) "+
3845+
"feature(%v): %w", dbChanID, feature, err)
38563846
}
38573847
}
38583848

@@ -3975,11 +3965,6 @@ func getAndBuildEdgeInfo(ctx context.Context, db SQLQueries,
39753965
return nil, err
39763966
}
39773967

3978-
var featureBuf bytes.Buffer
3979-
if err := fv.Encode(&featureBuf); err != nil {
3980-
return nil, fmt.Errorf("unable to encode features: %w", err)
3981-
}
3982-
39833968
recs, err := lnwire.CustomRecords(extras).Serialize()
39843969
if err != nil {
39853970
return nil, fmt.Errorf("unable to serialize extra signed "+
@@ -4002,7 +3987,7 @@ func getAndBuildEdgeInfo(ctx context.Context, db SQLQueries,
40023987
BitcoinKey2Bytes: btcKey2,
40033988
ChannelPoint: *op,
40043989
Capacity: btcutil.Amount(dbChan.Capacity.Int64),
4005-
Features: featureBuf.Bytes(),
3990+
Features: fv,
40063991
ExtraOpaqueData: recs,
40073992
}
40083993

graph/notifications_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ func TestEdgeUpdateNotification(t *testing.T) {
458458
BitcoinSig1Bytes: testSig.Serialize(),
459459
BitcoinSig2Bytes: testSig.Serialize(),
460460
},
461+
Features: lnwire.EmptyFeatureVector(),
461462
ChannelPoint: *chanPoint,
462463
Capacity: chanValue,
463464
FundingScript: fn.Some(script),
@@ -645,6 +646,7 @@ func TestNodeUpdateNotification(t *testing.T) {
645646
ChannelID: chanID.ToUint64(),
646647
NodeKey1Bytes: node1.PubKeyBytes,
647648
NodeKey2Bytes: node2.PubKeyBytes,
649+
Features: lnwire.EmptyFeatureVector(),
648650
AuthProof: &models.ChannelAuthProof{
649651
NodeSig1Bytes: testSig.Serialize(),
650652
NodeSig2Bytes: testSig.Serialize(),
@@ -839,6 +841,7 @@ func TestNotificationCancellation(t *testing.T) {
839841
BitcoinSig1Bytes: testSig.Serialize(),
840842
BitcoinSig2Bytes: testSig.Serialize(),
841843
},
844+
Features: lnwire.EmptyFeatureVector(),
842845
ChannelPoint: *chanPoint,
843846
Capacity: chanValue,
844847
FundingScript: fn.Some(script),
@@ -914,6 +917,7 @@ func TestChannelCloseNotification(t *testing.T) {
914917
BitcoinSig1Bytes: testSig.Serialize(),
915918
BitcoinSig2Bytes: testSig.Serialize(),
916919
},
920+
Features: lnwire.EmptyFeatureVector(),
917921
ChannelPoint: *chanUtxo,
918922
Capacity: chanValue,
919923
FundingScript: fn.Some(script),

netann/channel_announcement.go

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

33
import (
4-
"bytes"
54
"errors"
65
"fmt"
76

@@ -49,14 +48,11 @@ func CreateChanAnnouncement(chanProof *models.ChannelAuthProof,
4948
ChainHash: chanInfo.ChainHash,
5049
BitcoinKey1: chanInfo.BitcoinKey1Bytes,
5150
BitcoinKey2: chanInfo.BitcoinKey2Bytes,
52-
Features: lnwire.NewRawFeatureVector(),
51+
Features: chanInfo.Features.RawFeatureVector,
5352
ExtraOpaqueData: chanInfo.ExtraOpaqueData,
5453
}
5554

56-
err := chanAnn.Features.Decode(bytes.NewReader(chanInfo.Features))
57-
if err != nil {
58-
return nil, nil, nil, err
59-
}
55+
var err error
6056
chanAnn.BitcoinSig1, err = lnwire.NewSigFromECDSARawSignature(
6157
chanProof.BitcoinSig1Bytes,
6258
)

0 commit comments

Comments
 (0)