@@ -17,6 +17,7 @@ import (
1717
1818 "github.com/btcsuite/btcd/btcec/v2"
1919 "github.com/btcsuite/btcd/btcec/v2/ecdsa"
20+ "github.com/btcsuite/btcd/btcec/v2/schnorr"
2021 "github.com/btcsuite/btcd/btcutil"
2122 "github.com/btcsuite/btcd/chaincfg"
2223 "github.com/btcsuite/btcd/chaincfg/chainhash"
@@ -214,6 +215,22 @@ var versionedTests = []versionedTest{
214215 name : "channel view taproot v1 round trip" ,
215216 test : testChannelViewTaprootV1RoundTrip ,
216217 },
218+ {
219+ name : "node pruning update index deletion" ,
220+ test : testNodePruningUpdateIndexDeletion ,
221+ },
222+ {
223+ name : "lightning node sig verification" ,
224+ test : testLightningNodeSigVerification ,
225+ },
226+ {
227+ name : "graph zombie index" ,
228+ test : testGraphZombieIndex ,
229+ },
230+ {
231+ name : "disconnect block at height" ,
232+ test : testDisconnectBlockAtHeight ,
233+ },
217234}
218235
219236// TestVersionedDBs runs various tests against both v1 and v2 versioned
@@ -853,21 +870,21 @@ func createEdge(version lnwire.GossipVersion, height, txIndex uint32,
853870 return edgeInfo , shortChanID
854871}
855872
856- // TestDisconnectBlockAtHeight checks that the pruned state of the channel
873+ // testDisconnectBlockAtHeight checks that the pruned state of the channel
857874// database is what we expect after calling DisconnectBlockAtHeight.
858- func TestDisconnectBlockAtHeight (t * testing.T ) {
875+ func testDisconnectBlockAtHeight (t * testing.T , v lnwire. GossipVersion ) {
859876 t .Parallel ()
860877 ctx := t .Context ()
861878
862879 graph := MakeTestGraph (t , WithSyncGraphCachePopulation ())
863880
864- sourceNode := createTestVertex (t , lnwire . GossipVersion1 )
881+ sourceNode := createTestVertex (t , v )
865882 require .NoError (t , graph .SetSourceNode (ctx , sourceNode ))
866883
867884 // We'd like to test the insertion/deletion of edges, so we create two
868885 // vertexes to connect.
869- node1 := createTestVertex (t , lnwire . GossipVersion1 )
870- node2 := createTestVertex (t , lnwire . GossipVersion1 )
886+ node1 := createTestVertex (t , v )
887+ node2 := createTestVertex (t , v )
871888
872889 // In addition to the fake vertexes we create some fake channel
873890 // identifiers.
@@ -885,29 +902,20 @@ func TestDisconnectBlockAtHeight(t *testing.T) {
885902 _ , err = graph .PruneGraph (ctx , spendOutputs , & blockHash2 , 156 )
886903 require .NoError (t , err , "unable to prune graph" )
887904
888- // We'll create 3 almost identical edges, so first create a helper
889- // method containing all logic for doing so.
890-
891905 // Create an edge which has its block height at 156.
892906 height := uint32 (156 )
893- edgeInfo , _ := createEdge (
894- lnwire .GossipVersion1 , height , 0 , 0 , 0 , node1 , node2 ,
895- )
907+ edgeInfo , _ := createEdge (v , height , 0 , 0 , 0 , node1 , node2 )
896908
897- // Create an edge with block height 157. We give it
898- // maximum values for tx index and position, to make
899- // sure our database range scan get edges from the
900- // entire range.
909+ // Create an edge with block height 157. We give it maximum values for
910+ // tx index and position, to make sure our database range scan gets
911+ // edges from the entire range.
901912 edgeInfo2 , _ := createEdge (
902- lnwire .GossipVersion1 , height + 1 ,
903- math .MaxUint32 & 0x00ffffff , math .MaxUint16 , 1 , node1 ,
904- node2 ,
913+ v , height + 1 , math .MaxUint32 & 0x00ffffff , math .MaxUint16 ,
914+ 1 , node1 , node2 ,
905915 )
906916
907917 // Create a third edge, this with a block height of 155.
908- edgeInfo3 , _ := createEdge (
909- lnwire .GossipVersion1 , height - 1 , 0 , 0 , 2 , node1 , node2 ,
910- )
918+ edgeInfo3 , _ := createEdge (v , height - 1 , 0 , 0 , 2 , node1 , node2 )
911919
912920 // Now add all these new edges to the database.
913921 require .NoError (t , graph .AddChannelEdge (ctx , edgeInfo ))
@@ -932,21 +940,21 @@ func TestDisconnectBlockAtHeight(t *testing.T) {
932940
933941 // The two first edges should be removed from the db.
934942 has , isZombie , err := graph .HasChannelEdge (
935- ctx , lnwire . GossipVersion1 , edgeInfo .ChannelID ,
943+ ctx , v , edgeInfo .ChannelID ,
936944 )
937945 require .NoError (t , err , "unable to query for edge" )
938946 require .False (t , has )
939947 require .False (t , isZombie )
940948 has , isZombie , err = graph .HasChannelEdge (
941- ctx , lnwire . GossipVersion1 , edgeInfo2 .ChannelID ,
949+ ctx , v , edgeInfo2 .ChannelID ,
942950 )
943951 require .NoError (t , err , "unable to query for edge" )
944952 require .False (t , has )
945953 require .False (t , isZombie )
946954
947955 // Edge 3 should not be removed.
948956 has , isZombie , err = graph .HasChannelEdge (
949- ctx , lnwire . GossipVersion1 , edgeInfo3 .ChannelID ,
957+ ctx , v , edgeInfo3 .ChannelID ,
950958 )
951959 require .NoError (t , err , "unable to query for edge" )
952960 require .True (t , has )
@@ -4395,14 +4403,18 @@ func TestFilterChannelRangeVersionGuard(t *testing.T) {
43954403
43964404 store := NewTestDB (t )
43974405
4398- _ , err := store .FilterChannelRange (
4406+ resp , err := store .FilterChannelRange (
43994407 ctx , lnwire .GossipVersion2 , 0 , 1000 , false ,
44004408 )
44014409
4402- // The KV store does not support v2 and must return the sentinel error.
4403- // The SQL store accepts any known version (returning empty results
4404- // since no v2 channels have been added).
4405- if err != nil {
4410+ if isSQLDB {
4411+ // The SQL store accepts any known version and returns empty
4412+ // results since no v2 channels have been added.
4413+ require .NoError (t , err )
4414+ require .Empty (t , resp )
4415+ } else {
4416+ // The KV store does not support v2 and must return the
4417+ // sentinel error.
44064418 require .ErrorIs (t , err , ErrVersionNotSupportedForKVDB )
44074419 }
44084420}
@@ -4915,27 +4927,45 @@ func testAddChannelEdgeShellNodes(t *testing.T, v lnwire.GossipVersion) {
49154927// TestNodePruningUpdateIndexDeletion tests that once a node has been removed
49164928// from the channel graph, we also remove the entry from the update index as
49174929// well.
4918- func TestNodePruningUpdateIndexDeletion (t * testing.T ) {
4930+ // testNodePruningUpdateIndexDeletion verifies that deleting a node also removes
4931+ // it from the update index used by NodeUpdatesInHorizon.
4932+ func testNodePruningUpdateIndexDeletion (t * testing.T ,
4933+ v lnwire.GossipVersion ) {
4934+
49194935 t .Parallel ()
49204936 ctx := t .Context ()
49214937
4922- graph := NewVersionedGraph (MakeTestGraph (t ), lnwire . GossipVersion1 )
4938+ graph := NewVersionedGraph (MakeTestGraph (t ), v )
49234939
49244940 // We'll first populate our graph with a single node that will be
49254941 // removed shortly.
4926- node1 := createTestVertex (t , lnwire . GossipVersion1 )
4942+ node1 := createTestVertex (t , v )
49274943 require .NoError (t , graph .AddNode (ctx , node1 ))
49284944
4945+ // Build a NodeUpdateRange that covers the node we just inserted. V1
4946+ // uses time-based ranges, v2 uses block-height-based ranges.
4947+ var updateRange NodeUpdateRange
4948+ switch v {
4949+ case lnwire .GossipVersion1 :
4950+ updateRange = NodeUpdateRange {
4951+ StartTime : fn .Some (time .Unix (9 , 0 )),
4952+ EndTime : fn .Some (
4953+ node1 .LastUpdate .Add (time .Minute ),
4954+ ),
4955+ }
4956+ case lnwire .GossipVersion2 :
4957+ updateRange = NodeUpdateRange {
4958+ StartHeight : fn .Some (uint32 (0 )),
4959+ EndHeight : fn .Some (
4960+ node1 .LastBlockHeight + 1 ,
4961+ ),
4962+ }
4963+ }
4964+
49294965 // We'll confirm that we can retrieve the node using
4930- // NodeUpdatesInHorizon, using a time that's slightly beyond the last
4931- // update time of our test node.
4932- startTime := time .Unix (9 , 0 )
4933- endTime := node1 .LastUpdate .Add (time .Minute )
4966+ // NodeUpdatesInHorizon.
49344967 nodesInHorizonIter := graph .NodeUpdatesInHorizon (
4935- ctx , NodeUpdateRange {
4936- StartTime : fn .Some (startTime ),
4937- EndTime : fn .Some (endTime ),
4938- },
4968+ ctx , updateRange ,
49394969 )
49404970
49414971 // We should only have a single node, and that node should exactly
@@ -4953,10 +4983,7 @@ func TestNodePruningUpdateIndexDeletion(t *testing.T) {
49534983 // Now that the node has been deleted, we'll again query the nodes in
49544984 // the horizon. This time we should have no nodes at all.
49554985 nodesInHorizonIter = graph .NodeUpdatesInHorizon (
4956- ctx , NodeUpdateRange {
4957- StartTime : fn .Some (startTime ),
4958- EndTime : fn .Some (endTime ),
4959- },
4986+ ctx , updateRange ,
49604987 )
49614988 nodesInHorizon , err = fn .CollectErr (nodesInHorizonIter )
49624989 require .NoError (t , err , "unable to fetch nodes in horizon" )
@@ -5373,95 +5400,91 @@ func putSerializedPolicy(t *testing.T, db kvdb.Backend, from []byte,
53735400 require .NoError (t , err , "error writing db" )
53745401}
53755402
5376- // assertNumZombies queries the provided ChannelGraph for NumZombies, and
5377- // asserts that the returned number is equal to expZombies.
5378- func assertNumZombies (t * testing.T , graph * ChannelGraph , expZombies uint64 ) {
5403+ // assertNumZombies queries the provided ChannelGraph for NumZombies for the
5404+ // given gossip version and asserts that the result equals the expected count.
5405+ func assertNumZombies (t * testing.T , graph * ChannelGraph ,
5406+ v lnwire.GossipVersion , expZombies uint64 ) {
5407+
53795408 t .Helper ()
53805409
5381- v1Graph := NewVersionedGraph (graph , lnwire . GossipVersion1 )
5382- numZombies , err := v1Graph .NumZombies (t .Context ())
5410+ vGraph := NewVersionedGraph (graph , v )
5411+ numZombies , err := vGraph .NumZombies (t .Context ())
53835412 require .NoError (t , err , "unable to query number of zombies" )
53845413 require .Equal (t , expZombies , numZombies )
53855414}
53865415
5387- // TestGraphZombieIndex ensures that we can mark edges correctly as zombie/live.
5388- func TestGraphZombieIndex (t * testing.T ) {
5416+ // testGraphZombieIndex ensures that we can mark edges correctly as zombie/live.
5417+ func testGraphZombieIndex (t * testing.T , v lnwire. GossipVersion ) {
53895418 t .Parallel ()
53905419 ctx := t .Context ()
53915420
53925421 // We'll start by creating our test graph along with a test edge.
53935422 graph := MakeTestGraph (t )
53945423
5395- node1 := createTestVertex (t , lnwire . GossipVersion1 )
5396- node2 := createTestVertex (t , lnwire . GossipVersion1 )
5424+ node1 := createTestVertex (t , v )
5425+ node2 := createTestVertex (t , v )
53975426
53985427 // Swap the nodes if the second's pubkey is smaller than the first.
53995428 // Without this, the comparisons at the end will fail probabilistically.
54005429 if bytes .Compare (node2 .PubKeyBytes [:], node1 .PubKeyBytes [:]) < 0 {
54015430 node1 , node2 = node2 , node1
54025431 }
54035432
5404- edge , _ , _ := createChannelEdge (
5405- node1 , node2 , lnwire .GossipVersion1 ,
5406- )
5433+ edge , _ , _ := createChannelEdge (node1 , node2 , v )
54075434 require .NoError (t , graph .AddChannelEdge (ctx , edge ))
54085435
5409- v1Graph := NewVersionedGraph (graph , lnwire . GossipVersion1 )
5436+ vGraph := NewVersionedGraph (graph , v )
54105437
54115438 // Since the edge is known the graph and it isn't a zombie, IsZombieEdge
54125439 // should not report the channel as a zombie.
5413- isZombie , _ , _ , err := v1Graph .IsZombieEdge (ctx , edge .ChannelID )
5440+ isZombie , _ , _ , err := vGraph .IsZombieEdge (ctx , edge .ChannelID )
54145441 require .NoError (t , err )
54155442 require .False (t , isZombie )
5416- assertNumZombies (t , graph , 0 )
5443+ assertNumZombies (t , graph , v , 0 )
54175444
54185445 // If we delete the edge and mark it as a zombie, then we should expect
54195446 // to see it within the index.
5420- err = graph .DeleteChannelEdges (
5421- ctx , lnwire .GossipVersion1 , false , true , edge .ChannelID ,
5422- )
5447+ err = graph .DeleteChannelEdges (ctx , v , false , true , edge .ChannelID )
54235448 require .NoError (t , err , "unable to mark edge as zombie" )
5424- isZombie , pubKey1 , pubKey2 , err := v1Graph .IsZombieEdge (
5449+ isZombie , pubKey1 , pubKey2 , err := vGraph .IsZombieEdge (
54255450 ctx , edge .ChannelID ,
54265451 )
54275452 require .NoError (t , err )
54285453 require .True (t , isZombie )
54295454 require .Equal (t , node1 .PubKeyBytes , pubKey1 )
54305455 require .Equal (t , node2 .PubKeyBytes , pubKey2 )
5431- assertNumZombies (t , graph , 1 )
5456+ assertNumZombies (t , graph , v , 1 )
54325457
54335458 // Similarly, if we mark the same edge as live, we should no longer see
54345459 // it within the index.
5435- err = graph .MarkEdgeLive (ctx , lnwire . GossipVersion1 , edge .ChannelID )
5460+ err = graph .MarkEdgeLive (ctx , v , edge .ChannelID )
54365461 require .NoError (t , err )
54375462
54385463 // Attempting to mark the edge as live again now that it is no longer
54395464 // in the zombie index should fail.
54405465 require .ErrorIs (
5441- t , graph .MarkEdgeLive (
5442- ctx , lnwire .GossipVersion1 , edge .ChannelID ,
5443- ),
5466+ t , graph .MarkEdgeLive (ctx , v , edge .ChannelID ),
54445467 ErrZombieEdgeNotFound ,
54455468 )
54465469
5447- isZombie , _ , _ , err = v1Graph .IsZombieEdge (ctx , edge .ChannelID )
5470+ isZombie , _ , _ , err = vGraph .IsZombieEdge (ctx , edge .ChannelID )
54485471 require .NoError (t , err )
54495472 require .False (t , isZombie )
54505473
5451- assertNumZombies (t , graph , 0 )
5474+ assertNumZombies (t , graph , v , 0 )
54525475
54535476 // If we mark the edge as a zombie manually, then it should show up as
54545477 // being a zombie once again.
54555478 err = graph .MarkEdgeZombie (
5456- ctx , lnwire . GossipVersion1 , edge .ChannelID ,
5479+ ctx , v , edge .ChannelID ,
54575480 node1 .PubKeyBytes , node2 .PubKeyBytes ,
54585481 )
54595482 require .NoError (t , err , "unable to mark edge as zombie" )
54605483
5461- isZombie , _ , _ , err = v1Graph .IsZombieEdge (ctx , edge .ChannelID )
5484+ isZombie , _ , _ , err = vGraph .IsZombieEdge (ctx , edge .ChannelID )
54625485 require .NoError (t , err )
54635486 require .True (t , isZombie )
5464- assertNumZombies (t , graph , 1 )
5487+ assertNumZombies (t , graph , v , 1 )
54655488}
54665489
54675490// compareNodes is used to compare two Nodes.
@@ -5522,33 +5545,50 @@ func compareEdgePolicies(t testing.TB, a, b *models.ChannelEdgePolicy) {
55225545 require .Equal (t , normalizedA , normalizedB )
55235546}
55245547
5525- // TestLightningNodeSigVerification checks that we can use the Node's
5526- // pubkey to verify signatures.
5527- func TestLightningNodeSigVerification (t * testing.T ) {
5548+ // testLightningNodeSigVerification checks that we can use the Node's pubkey to
5549+ // verify signatures. For v1 this exercises ECDSA, for v2 Schnorr.
5550+ func testLightningNodeSigVerification (t * testing.T ,
5551+ v lnwire.GossipVersion ) {
5552+
55285553 t .Parallel ()
55295554
55305555 // Create some dummy data to sign.
55315556 var data [32 ]byte
55325557 _ , err := prand .Read (data [:])
55335558 require .NoError (t , err )
55345559
5535- // Create private key and sign the data with it .
5560+ // Create private key.
55365561 priv , err := btcec .NewPrivateKey ()
5537- require .NoError (t , err , "unable to crete priv key" )
5538-
5539- sign := ecdsa .Sign (priv , data [:])
5540-
5541- // Sanity check that the signature checks out.
5542- require .True (t , sign .Verify (data [:], priv .PubKey ()))
5562+ require .NoError (t , err , "unable to create priv key" )
55435563
55445564 // Create a Node from the same private key.
5545- node := createNode (t , lnwire . GossipVersion1 , priv )
5565+ node := createNode (t , v , priv )
55465566
5547- // And finally check that we can verify the same signature from the
5548- // pubkey returned from the lightning node .
5567+ // Retrieve the public key from the node and verify a signature
5568+ // produced by the same private key .
55495569 nodePub , err := node .PubKey ()
55505570 require .NoError (t , err , "unable to get pubkey" )
5551- require .True (t , sign .Verify (data [:], nodePub ))
5571+
5572+ // Sign the data using the appropriate scheme for the gossip version.
5573+ // V1 uses ECDSA, v2 uses Schnorr.
5574+ type verifiable interface {
5575+ Verify (hash []byte , pubKey * btcec.PublicKey ) bool
5576+ }
5577+
5578+ var sig verifiable
5579+ switch v {
5580+ case lnwire .GossipVersion1 :
5581+ sig = ecdsa .Sign (priv , data [:])
5582+ case lnwire .GossipVersion2 :
5583+ schnorrSig , sErr := schnorr .Sign (priv , data [:])
5584+ require .NoError (t , sErr )
5585+ sig = schnorrSig
5586+ }
5587+
5588+ // Verify against the raw private key's pubkey, then against the
5589+ // pubkey extracted from the Node.
5590+ require .True (t , sig .Verify (data [:], priv .PubKey ()))
5591+ require .True (t , sig .Verify (data [:], nodePub ))
55525592}
55535593
55545594// TestComputeFee tests fee calculation based on the outgoing amt.
0 commit comments