graph+routing: address linter errors

This is done in a separate commit so as to keep the original code-move
commit mostly a pure code move.
This commit is contained in:
Elle Mouton committed 2024-07-15 15:56:33 +02:00
1 parent 743502f99d
commit fe34d62eb1
10 files changed
+163 -139

No files matched your search

+3 -1
View File
@@ -2200,7 +2200,9 @@ func (d *AuthenticatedGossiper) updateChannel(info *models.ChannelEdgeInfo,
// To ensure that our signature is valid, we'll verify it ourself // To ensure that our signature is valid, we'll verify it ourself
// before committing it to the slice returned. // before committing it to the slice returned.
err = graph.ValidateChannelUpdateAnn(d.selfKey, info.Capacity, chanUpdate) err = graph.ValidateChannelUpdateAnn(
d.selfKey, info.Capacity, chanUpdate,
)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("generated invalid channel "+ return nil, nil, fmt.Errorf("generated invalid channel "+
"update sig: %v", err) "update sig: %v", err)
+63 -34
View File
@@ -222,7 +222,7 @@ func (b *Builder) Start() error {
// channels from the graph based on their spentness, but whether they // channels from the graph based on their spentness, but whether they
// are considered zombies or not. We will start zombie pruning after a // are considered zombies or not. We will start zombie pruning after a
// small delay, to avoid slowing down startup of lnd. // small delay, to avoid slowing down startup of lnd.
if b.cfg.AssumeChannelValid { if b.cfg.AssumeChannelValid { //nolint:nestif
time.AfterFunc(b.cfg.FirstTimePruneDelay, func() { time.AfterFunc(b.cfg.FirstTimePruneDelay, func() {
select { select {
case <-b.quit: case <-b.quit:
@@ -256,6 +256,7 @@ func (b *Builder) Start() error {
if err != nil && !errors.Is( if err != nil && !errors.Is(
err, channeldb.ErrGraphNoEdgesFound, err, channeldb.ErrGraphNoEdgesFound,
) { ) {
return err return err
} }
@@ -290,7 +291,9 @@ func (b *Builder) Start() error {
// from the graph in order to ensure we maintain a tight graph // from the graph in order to ensure we maintain a tight graph
// of "useful" nodes. // of "useful" nodes.
err = b.cfg.Graph.PruneGraphNodes() err = b.cfg.Graph.PruneGraphNodes()
if err != nil && err != channeldb.ErrGraphNodesNotFound { if err != nil &&
!errors.Is(err, channeldb.ErrGraphNodesNotFound) {
return err return err
} }
} }
@@ -344,8 +347,8 @@ func (b *Builder) syncGraphWithChain() error {
switch { switch {
// If the graph has never been pruned, or hasn't fully been // If the graph has never been pruned, or hasn't fully been
// created yet, then we don't treat this as an explicit error. // created yet, then we don't treat this as an explicit error.
case err == channeldb.ErrGraphNeverPruned: case errors.Is(err, channeldb.ErrGraphNeverPruned):
case err == channeldb.ErrGraphNotFound: case errors.Is(err, channeldb.ErrGraphNotFound):
default: default:
return err return err
} }
@@ -355,7 +358,6 @@ func (b *Builder) syncGraphWithChain() error {
pruneHeight, pruneHash) pruneHeight, pruneHash)
switch { switch {
// If the graph has never been pruned, then we can exit early as this // If the graph has never been pruned, then we can exit early as this
// entails it's being created for the first time and hasn't seen any // entails it's being created for the first time and hasn't seen any
// block or created channels. // block or created channels.
@@ -388,34 +390,40 @@ func (b *Builder) syncGraphWithChain() error {
} }
pruneHash, pruneHeight, err = b.cfg.Graph.PruneTip() pruneHash, pruneHeight, err = b.cfg.Graph.PruneTip()
if err != nil {
switch { switch {
// If at this point the graph has never been pruned, we // If at this point the graph has never been pruned, we can exit
// can exit as this entails we are back to the point // as this entails we are back to the point where it hasn't seen
// where it hasn't seen any block or created channels, // any block or created channels, alas there's nothing left to
// alas there's nothing left to prune. // prune.
case err == channeldb.ErrGraphNeverPruned: case errors.Is(err, channeldb.ErrGraphNeverPruned):
return nil return nil
case err == channeldb.ErrGraphNotFound:
case errors.Is(err, channeldb.ErrGraphNotFound):
return nil return nil
default:
case err != nil:
return err return err
default:
} }
}
mainBlockHash, err = b.cfg.Chain.GetBlockHash(int64(pruneHeight)) mainBlockHash, err = b.cfg.Chain.GetBlockHash(
int64(pruneHeight),
)
if err != nil { if err != nil {
return err return err
} }
} }
log.Infof("Syncing channel graph from height=%v (hash=%v) to height=%v "+ log.Infof("Syncing channel graph from height=%v (hash=%v) to "+
"(hash=%v)", pruneHeight, pruneHash, bestHeight, bestHash) "height=%v (hash=%v)", pruneHeight, pruneHash, bestHeight,
bestHash)
// If we're not yet caught up, then we'll walk forward in the chain // If we're not yet caught up, then we'll walk forward in the chain
// pruning the channel graph with each new block that hasn't yet been // pruning the channel graph with each new block that hasn't yet been
// consumed by the channel graph. // consumed by the channel graph.
var spentOutputs []*wire.OutPoint var spentOutputs []*wire.OutPoint
for nextHeight := pruneHeight + 1; nextHeight <= uint32(bestHeight); nextHeight++ { for nextHeight := pruneHeight + 1; nextHeight <= uint32(bestHeight); nextHeight++ { //nolint:lll
// Break out of the rescan early if a shutdown has been // Break out of the rescan early if a shutdown has been
// requested, otherwise long rescans will block the daemon from // requested, otherwise long rescans will block the daemon from
// shutting down promptly. // shutting down promptly.
@@ -462,6 +470,7 @@ func (b *Builder) syncGraphWithChain() error {
log.Infof("Graph pruning complete: %v channels were closed since "+ log.Infof("Graph pruning complete: %v channels were closed since "+
"height %v", len(closedChans), pruneHeight) "height %v", len(closedChans), pruneHeight)
return nil return nil
} }
@@ -615,7 +624,11 @@ func (b *Builder) pruneZombieChans() error {
} }
for _, u := range oldEdges { for _, u := range oldEdges {
filterPruneChans(u.Info, u.Policy1, u.Policy2) err = filterPruneChans(u.Info, u.Policy1, u.Policy2)
if err != nil {
return fmt.Errorf("error filtering channels to "+
"prune: %w", err)
}
} }
log.Infof("Pruning %v zombie channels", len(chansToPrune)) log.Infof("Pruning %v zombie channels", len(chansToPrune))
@@ -640,7 +653,7 @@ func (b *Builder) pruneZombieChans() error {
// With the channels pruned, we'll also attempt to prune any nodes that // With the channels pruned, we'll also attempt to prune any nodes that
// were a part of them. // were a part of them.
err = b.cfg.Graph.PruneGraphNodes() err = b.cfg.Graph.PruneGraphNodes()
if err != nil && err != channeldb.ErrGraphNodesNotFound { if err != nil && !errors.Is(err, channeldb.ErrGraphNodesNotFound) {
return fmt.Errorf("unable to prune graph nodes: %w", err) return fmt.Errorf("unable to prune graph nodes: %w", err)
} }
@@ -761,7 +774,6 @@ func (b *Builder) networkHandler() {
} }
for { for {
// If there are stats, resume the statTicker. // If there are stats, resume the statTicker.
if !b.stats.Empty() { if !b.stats.Empty() {
b.statTicker.Resume() b.statTicker.Resume()
@@ -793,12 +805,14 @@ func (b *Builder) networkHandler() {
// Since this block is stale, we update our best height // Since this block is stale, we update our best height
// to the previous block. // to the previous block.
blockHeight := uint32(chainUpdate.Height) blockHeight := chainUpdate.Height
atomic.StoreUint32(&b.bestHeight, blockHeight-1) atomic.StoreUint32(&b.bestHeight, blockHeight-1)
// Update the channel graph to reflect that this block // Update the channel graph to reflect that this block
// was disconnected. // was disconnected.
_, err := b.cfg.Graph.DisconnectBlockAtHeight(blockHeight) _, err := b.cfg.Graph.DisconnectBlockAtHeight(
blockHeight,
)
if err != nil { if err != nil {
log.Errorf("unable to prune graph with stale "+ log.Errorf("unable to prune graph with stale "+
"block: %v", err) "block: %v", err)
@@ -836,7 +850,9 @@ func (b *Builder) networkHandler() {
"height=%v, got height=%v", "height=%v, got height=%v",
currentHeight+1, chainUpdate.Height) currentHeight+1, chainUpdate.Height)
err := b.getMissingBlocks(currentHeight, chainUpdate) err := b.getMissingBlocks(
currentHeight, chainUpdate,
)
if err != nil { if err != nil {
log.Errorf("unable to retrieve missing"+ log.Errorf("unable to retrieve missing"+
"blocks: %v", err) "blocks: %v", err)
@@ -1136,6 +1152,8 @@ func makeFundingScript(bitcoinKey1, bitcoinKey2 []byte,
// channel/edge update network update. If the update didn't affect the internal // channel/edge update network update. If the update didn't affect the internal
// state of the draft due to either being out of date, invalid, or redundant, // state of the draft due to either being out of date, invalid, or redundant,
// then error is returned. // then error is returned.
//
//nolint:funlen
func (b *Builder) processUpdate(msg interface{}, func (b *Builder) processUpdate(msg interface{},
op ...batch.SchedulerOption) error { op ...batch.SchedulerOption) error {
@@ -1166,7 +1184,9 @@ func (b *Builder) processUpdate(msg interface{},
_, _, exists, isZombie, err := b.cfg.Graph.HasChannelEdge( _, _, exists, isZombie, err := b.cfg.Graph.HasChannelEdge(
msg.ChannelID, msg.ChannelID,
) )
if err != nil && err != channeldb.ErrGraphNoEdgesFound { if err != nil &&
!errors.Is(err, channeldb.ErrGraphNoEdgesFound) {
return errors.Errorf("unable to check for edge "+ return errors.Errorf("unable to check for edge "+
"existence: %v", err) "existence: %v", err)
} }
@@ -1188,7 +1208,8 @@ func (b *Builder) processUpdate(msg interface{},
// ChannelAnnouncement from the gossiper. // ChannelAnnouncement from the gossiper.
scid := lnwire.NewShortChanIDFromInt(msg.ChannelID) scid := lnwire.NewShortChanIDFromInt(msg.ChannelID)
if b.cfg.AssumeChannelValid || b.cfg.IsAlias(scid) { if b.cfg.AssumeChannelValid || b.cfg.IsAlias(scid) {
if err := b.cfg.Graph.AddChannelEdge(msg, op...); err != nil { err := b.cfg.Graph.AddChannelEdge(msg, op...)
if err != nil {
return fmt.Errorf("unable to add edge: %w", err) return fmt.Errorf("unable to add edge: %w", err)
} }
log.Tracef("New channel discovered! Link "+ log.Tracef("New channel discovered! Link "+
@@ -1206,6 +1227,8 @@ func (b *Builder) processUpdate(msg interface{},
channelID := lnwire.NewShortChanIDFromInt(msg.ChannelID) channelID := lnwire.NewShortChanIDFromInt(msg.ChannelID)
fundingTx, err := b.fetchFundingTxWrapper(&channelID) fundingTx, err := b.fetchFundingTxWrapper(&channelID)
if err != nil { if err != nil {
//nolint:lll
//
// In order to ensure we don't erroneously mark a // In order to ensure we don't erroneously mark a
// channel as a zombie due to an RPC failure, we'll // channel as a zombie due to an RPC failure, we'll
// attempt to string match for the relevant errors. // attempt to string match for the relevant errors.
@@ -1253,13 +1276,15 @@ func (b *Builder) processUpdate(msg interface{},
// formed. If this check fails, then this channel either // formed. If this check fails, then this channel either
// doesn't exist, or isn't the one that was meant to be created // doesn't exist, or isn't the one that was meant to be created
// according to the passed channel proofs. // according to the passed channel proofs.
fundingPoint, err := chanvalidate.Validate(&chanvalidate.Context{ fundingPoint, err := chanvalidate.Validate(
&chanvalidate.Context{
Locator: &chanvalidate.ShortChanIDChanLocator{ Locator: &chanvalidate.ShortChanIDChanLocator{
ID: channelID, ID: channelID,
}, },
MultiSigPkScript: fundingPkScript, MultiSigPkScript: fundingPkScript,
FundingTx: fundingTx, FundingTx: fundingTx,
}) },
)
if err != nil { if err != nil {
// Mark the edge as a zombie so we won't try to // Mark the edge as a zombie so we won't try to
// re-validate it on start up. // re-validate it on start up.
@@ -1336,16 +1361,20 @@ func (b *Builder) processUpdate(msg interface{},
edge1Timestamp, edge2Timestamp, exists, isZombie, err := edge1Timestamp, edge2Timestamp, exists, isZombie, err :=
b.cfg.Graph.HasChannelEdge(msg.ChannelID) b.cfg.Graph.HasChannelEdge(msg.ChannelID)
if err != nil && err != channeldb.ErrGraphNoEdgesFound { if err != nil && !errors.Is(
err, channeldb.ErrGraphNoEdgesFound,
) {
return errors.Errorf("unable to check for edge "+ return errors.Errorf("unable to check for edge "+
"existence: %v", err) "existence: %v", err)
} }
// If the channel is marked as a zombie in our database, and // If the channel is marked as a zombie in our database, and
// we consider this a stale update, then we should not apply the // we consider this a stale update, then we should not apply the
// policy. // policy.
isStaleUpdate := time.Since(msg.LastUpdate) > b.cfg.ChannelPruneExpiry isStaleUpdate := time.Since(msg.LastUpdate) >
b.cfg.ChannelPruneExpiry
if isZombie && isStaleUpdate { if isZombie && isStaleUpdate {
return newErrf(ErrIgnored, "ignoring stale update "+ return newErrf(ErrIgnored, "ignoring stale update "+
"(flags=%v|%v) for zombie chan_id=%v", "(flags=%v|%v) for zombie chan_id=%v",
@@ -1368,7 +1397,6 @@ func (b *Builder) processUpdate(msg interface{},
// that edge. If this message has a timestamp not strictly // that edge. If this message has a timestamp not strictly
// newer than what we already know of we can exit early. // newer than what we already know of we can exit early.
switch { switch {
// A flag set of 0 indicates this is an announcement for the // A flag set of 0 indicates this is an announcement for the
// "first" node in the channel. // "first" node in the channel.
case msg.ChannelFlags&lnwire.ChanUpdateDirection == 0: case msg.ChannelFlags&lnwire.ChanUpdateDirection == 0:
@@ -1448,7 +1476,7 @@ func (b *Builder) fetchFundingTxWrapper(chanID *lnwire.ShortChannelID) (
// short channel ID. // short channel ID.
// //
// TODO(roasbeef): replace with call to GetBlockTransaction? (would allow to // TODO(roasbeef): replace with call to GetBlockTransaction? (would allow to
// later use getblocktxn) // later use getblocktxn).
func (b *Builder) fetchFundingTx( func (b *Builder) fetchFundingTx(
chanID *lnwire.ShortChannelID) (*wire.MsgTx, error) { chanID *lnwire.ShortChannelID) (*wire.MsgTx, error) {
@@ -1702,6 +1730,7 @@ func (b *Builder) AddProof(chanID lnwire.ShortChannelID,
} }
info.AuthProof = proof info.AuthProof = proof
return b.cfg.Graph.UpdateChannelEdge(info) return b.cfg.Graph.UpdateChannelEdge(info)
} }
@@ -1739,6 +1768,7 @@ func (b *Builder) IsKnownEdge(chanID lnwire.ShortChannelID) bool {
_, _, exists, isZombie, _ := b.cfg.Graph.HasChannelEdge( _, _, exists, isZombie, _ := b.cfg.Graph.HasChannelEdge(
chanID.ToUint64(), chanID.ToUint64(),
) )
return exists || isZombie return exists || isZombie
} }
@@ -1754,7 +1784,6 @@ func (b *Builder) IsStaleEdgePolicy(chanID lnwire.ShortChannelID,
if err != nil { if err != nil {
log.Debugf("Check stale edge policy got error: %v", err) log.Debugf("Check stale edge policy got error: %v", err)
return false return false
} }
// If we know of the edge as a zombie, then we'll make some additional // If we know of the edge as a zombie, then we'll make some additional
+52 -27
View File
@@ -182,7 +182,7 @@ func TestIgnoreChannelEdgePolicyForUnknownChannel(t *testing.T) {
} }
// TestWakeUpOnStaleBranch tests that upon startup of the ChannelRouter, if the // TestWakeUpOnStaleBranch tests that upon startup of the ChannelRouter, if the
// the chain previously reflected in the channel graph is stale (overtaken by a // chain previously reflected in the channel graph is stale (overtaken by a
// longer chain), the channel router will prune the graph for any channels // longer chain), the channel router will prune the graph for any channels
// confirmed on the stale chain, and resync to the main chain. // confirmed on the stale chain, and resync to the main chain.
func TestWakeUpOnStaleBranch(t *testing.T) { func TestWakeUpOnStaleBranch(t *testing.T) {
@@ -216,7 +216,6 @@ func TestWakeUpOnStaleBranch(t *testing.T) {
block.Transactions = append(block.Transactions, block.Transactions = append(block.Transactions,
fundingTx) fundingTx)
chanID1 = chanID.ToUint64() chanID1 = chanID.ToUint64()
} }
ctx.chain.addBlock(block, height, rand.Uint32()) ctx.chain.addBlock(block, height, rand.Uint32())
ctx.chain.setBestBlock(int32(height)) ctx.chain.setBestBlock(int32(height))
@@ -418,7 +417,6 @@ func TestDisconnectedBlocks(t *testing.T) {
block.Transactions = append(block.Transactions, block.Transactions = append(block.Transactions,
fundingTx) fundingTx)
chanID1 = chanID.ToUint64() chanID1 = chanID.ToUint64()
} }
ctx.chain.addBlock(block, height, rand.Uint32()) ctx.chain.addBlock(block, height, rand.Uint32())
ctx.chain.setBestBlock(int32(height)) ctx.chain.setBestBlock(int32(height))
@@ -633,7 +631,9 @@ func TestRouterChansClosedOfflinePruneGraph(t *testing.T) {
} }
// The router should now be aware of the channel we created above. // The router should now be aware of the channel we created above.
_, _, hasChan, isZombie, err := ctx.graph.HasChannelEdge(chanID1.ToUint64()) _, _, hasChan, isZombie, err := ctx.graph.HasChannelEdge(
chanID1.ToUint64(),
)
if err != nil { if err != nil {
t.Fatalf("error looking for edge: %v", chanID1) t.Fatalf("error looking for edge: %v", chanID1)
} }
@@ -713,7 +713,9 @@ func TestRouterChansClosedOfflinePruneGraph(t *testing.T) {
// At this point, the channel that was pruned should no longer be known // At this point, the channel that was pruned should no longer be known
// by the router. // by the router.
_, _, hasChan, isZombie, err = ctx.graph.HasChannelEdge(chanID1.ToUint64()) _, _, hasChan, isZombie, err = ctx.graph.HasChannelEdge(
chanID1.ToUint64(),
)
if err != nil { if err != nil {
t.Fatalf("error looking for edge: %v", chanID1) t.Fatalf("error looking for edge: %v", chanID1)
} }
@@ -833,20 +835,23 @@ func TestPruneChannelGraphStaleEdges(t *testing.T) {
// All of the channels should exist before pruning them. // All of the channels should exist before pruning them.
assertChannelsPruned(t, ctx.graph, testChannels) assertChannelsPruned(t, ctx.graph, testChannels)
// Proceed to prune the channels - only the last one should be pruned. // Proceed to prune the channels - only the last one should be
// pruned.
if err := ctx.builder.pruneZombieChans(); err != nil { if err := ctx.builder.pruneZombieChans(); err != nil {
t.Fatalf("unable to prune zombie channels: %v", err) t.Fatalf("unable to prune zombie channels: %v", err)
} }
// We expect channels that have either both edges stale, or one edge // We expect channels that have either both edges stale, or one
// stale with both known. // edge stale with both known.
var prunedChannels []uint64 var prunedChannels []uint64
if strictPruning { if strictPruning {
prunedChannels = []uint64{2, 5, 7} prunedChannels = []uint64{2, 5, 7}
} else { } else {
prunedChannels = []uint64{2, 7} prunedChannels = []uint64{2, 7}
} }
assertChannelsPruned(t, ctx.graph, testChannels, prunedChannels...) assertChannelsPruned(
t, ctx.graph, testChannels, prunedChannels...,
)
} }
} }
@@ -1387,7 +1392,9 @@ func TestBlockDifferenceFix(t *testing.T) {
err := wait.NoError(func() error { err := wait.NoError(func() error {
// Then router height should be updated to the latest block. // Then router height should be updated to the latest block.
if atomic.LoadUint32(&ctx.builder.bestHeight) != newBlockHeight { if atomic.LoadUint32(&ctx.builder.bestHeight) !=
newBlockHeight {
return fmt.Errorf("height should have been updated "+ return fmt.Errorf("height should have been updated "+
"to %v, instead got %v", newBlockHeight, "to %v, instead got %v", newBlockHeight,
ctx.builder.bestHeight) ctx.builder.bestHeight)
@@ -1589,7 +1596,10 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
} }
err = graph.AddChannelEdge(&edgeInfo) err = graph.AddChannelEdge(&edgeInfo)
if err != nil && err != channeldb.ErrEdgeAlreadyExist { if err != nil && !errors.Is(
err, channeldb.ErrEdgeAlreadyExist,
) {
return nil, err return nil, err
} }
@@ -1602,15 +1612,25 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
edgePolicy := &models.ChannelEdgePolicy{ edgePolicy := &models.ChannelEdgePolicy{
SigBytes: testSig.Serialize(), SigBytes: testSig.Serialize(),
MessageFlags: lnwire.ChanUpdateMsgFlags(edge.MessageFlags), MessageFlags: lnwire.ChanUpdateMsgFlags(
edge.MessageFlags,
),
ChannelFlags: channelFlags, ChannelFlags: channelFlags,
ChannelID: edge.ChannelID, ChannelID: edge.ChannelID,
LastUpdate: testTime, LastUpdate: testTime,
TimeLockDelta: edge.Expiry, TimeLockDelta: edge.Expiry,
MinHTLC: lnwire.MilliSatoshi(edge.MinHTLC), MinHTLC: lnwire.MilliSatoshi(
MaxHTLC: lnwire.MilliSatoshi(edge.MaxHTLC), edge.MinHTLC,
FeeBaseMSat: lnwire.MilliSatoshi(edge.FeeBaseMsat), ),
FeeProportionalMillionths: lnwire.MilliSatoshi(edge.FeeRate), MaxHTLC: lnwire.MilliSatoshi(
edge.MaxHTLC,
),
FeeBaseMSat: lnwire.MilliSatoshi(
edge.FeeBaseMsat,
),
FeeProportionalMillionths: lnwire.MilliSatoshi(
edge.FeeRate,
),
ToNode: targetNode, ToNode: targetNode,
} }
if err := graph.UpdateEdgePolicy(edgePolicy); err != nil { if err := graph.UpdateEdgePolicy(edgePolicy); err != nil {
@@ -1652,7 +1672,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
// testGraph is the struct which corresponds to the JSON format used to encode // testGraph is the struct which corresponds to the JSON format used to encode
// graphs within the files in the testdata directory. // graphs within the files in the testdata directory.
// //
// TODO(roasbeef): add test graph auto-generator // TODO(roasbeef): add test graph auto-generator.
type testGraph struct { type testGraph struct {
Info []string `json:"info"` Info []string `json:"info"`
Nodes []testNode `json:"nodes"` Nodes []testNode `json:"nodes"`
@@ -1788,13 +1808,14 @@ type testChannelPolicy struct {
Features *lnwire.FeatureVector Features *lnwire.FeatureVector
} }
// createTestGraphFromChannels returns a fully populated ChannelGraph based on a set of // createTestGraphFromChannels returns a fully populated ChannelGraph based on a
// test channels. Additional required information like keys are derived in // set of test channels. Additional required information like keys are derived
// a deterministic way and added to the channel graph. A list of nodes is // in a deterministic way and added to the channel graph. A list of nodes is not
// not required and derived from the channel data. The goal is to keep // required and derived from the channel data. The goal is to keep instantiating
// instantiating a test channel graph as light weight as possible. // a test channel graph as light weight as possible.
func createTestGraphFromChannels(t *testing.T, useCache bool, func createTestGraphFromChannels(t *testing.T, useCache bool,
testChannels []*testChannel, source string) (*testGraphInstance, error) { testChannels []*testChannel, source string) (*testGraphInstance,
error) {
// We'll use this fake address for the IP address of all the nodes in // We'll use this fake address for the IP address of all the nodes in
// our tests. This value isn't needed for path finding so it doesn't // our tests. This value isn't needed for path finding so it doesn't
@@ -1940,7 +1961,9 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
} }
err = graph.AddChannelEdge(&edgeInfo) err = graph.AddChannelEdge(&edgeInfo)
if err != nil && err != channeldb.ErrEdgeAlreadyExist { if err != nil &&
!errors.Is(err, channeldb.ErrEdgeAlreadyExist) {
return nil, err return nil, err
} }
@@ -1981,7 +2004,8 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
ToNode: node2Vertex, ToNode: node2Vertex,
ExtraOpaqueData: getExtraData(node1), ExtraOpaqueData: getExtraData(node1),
} }
if err := graph.UpdateEdgePolicy(edgePolicy); err != nil { err := graph.UpdateEdgePolicy(edgePolicy)
if err != nil {
return nil, err return nil, err
} }
} }
@@ -2011,12 +2035,13 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
ToNode: node1Vertex, ToNode: node1Vertex,
ExtraOpaqueData: getExtraData(node2), ExtraOpaqueData: getExtraData(node2),
} }
if err := graph.UpdateEdgePolicy(edgePolicy); err != nil { err := graph.UpdateEdgePolicy(edgePolicy)
if err != nil {
return nil, err return nil, err
} }
} }
channelID++ channelID++ //nolint:ineffassign
} }
return &testGraphInstance{ return &testGraphInstance{
+1 -1
View File
@@ -18,7 +18,7 @@ func init() {
} }
// DisableLog disables all library log output. Logging output is disabled by // DisableLog disables all library log output. Logging output is disabled by
// by default until UseLogger is called. // default until UseLogger is called.
func DisableLog() { func DisableLog() {
UseLogger(btclog.Disabled) UseLogger(btclog.Disabled)
} }
-1
View File
@@ -117,7 +117,6 @@ type topologyClient struct {
// notifyTopologyChange notifies all registered clients of a new change in // notifyTopologyChange notifies all registered clients of a new change in
// graph topology in a non-blocking. // graph topology in a non-blocking.
func (b *Builder) notifyTopologyChange(topologyDiff *TopologyChange) { func (b *Builder) notifyTopologyChange(topologyDiff *TopologyChange) {
// notifyClient is a helper closure that will send topology updates to // notifyClient is a helper closure that will send topology updates to
// the given client. // the given client.
notifyClient := func(clientID uint64, client *topologyClient) bool { notifyClient := func(clientID uint64, client *topologyClient) bool {
+11 -21
View File
@@ -55,8 +55,14 @@ var (
timeout = time.Second * 5 timeout = time.Second * 5
testRBytes, _ = hex.DecodeString("8ce2bc69281ce27da07e6683571319d18e949ddfa2965fb6caa1bf0314f882d7") testRBytes, _ = hex.DecodeString(
testSBytes, _ = hex.DecodeString("299105481d63e0f4bc2a88121167221b6700d72a0ead154c03be696a292d24ae") "8ce2bc69281ce27da07e6683571319d18e949ddfa2965fb6caa1bf03" +
"14f882d7",
)
testSBytes, _ = hex.DecodeString(
"299105481d63e0f4bc2a88121167221b6700d72a0ead154c03be696a2" +
"92d24ae",
)
testRScalar = new(btcec.ModNScalar) testRScalar = new(btcec.ModNScalar)
testSScalar = new(btcec.ModNScalar) testSScalar = new(btcec.ModNScalar)
_ = testRScalar.SetByteSlice(testRBytes) _ = testRScalar.SetByteSlice(testRBytes)
@@ -1027,22 +1033,6 @@ type testCtx struct {
notifier *lnmock.ChainNotifier notifier *lnmock.ChainNotifier
} }
func (c *testCtx) getChannelIDFromAlias(t *testing.T, a, b string) uint64 {
vertexA, ok := c.aliases[a]
require.True(t, ok, "cannot find aliases for %s", a)
vertexB, ok := c.aliases[b]
require.True(t, ok, "cannot find aliases for %s", b)
channelIDMap, ok := c.channelIDs[vertexA]
require.True(t, ok, "cannot find channelID map %s(%s)", vertexA, a)
channelID, ok := channelIDMap[vertexB]
require.True(t, ok, "cannot find channelID using %s(%s)", vertexB, b)
return channelID
}
func createTestCtxSingleNode(t *testing.T, func createTestCtxSingleNode(t *testing.T,
startingHeight uint32) *testCtx { startingHeight uint32) *testCtx {
@@ -1127,8 +1117,8 @@ type testGraphInstance struct {
graphBackend kvdb.Backend graphBackend kvdb.Backend
// aliasMap is a map from a node's alias to its public key. This type is // aliasMap is a map from a node's alias to its public key. This type is
// provided in order to allow easily look up from the human memorable alias // provided in order to allow easily look up from the human memorable
// to an exact node's public key. // alias to an exact node's public key.
aliasMap map[string]route.Vertex aliasMap map[string]route.Vertex
// privKeyMap maps a node alias to its private key. This is used to be // privKeyMap maps a node alias to its private key. This is used to be
@@ -1201,7 +1191,7 @@ func createTestCtxFromGraphInstanceAssumeValid(t *testing.T,
} }
t.Cleanup(func() { t.Cleanup(func() {
graphBuilder.Stop() require.NoError(t, graphBuilder.Stop())
}) })
return ctx return ctx
+4 -2
View File
@@ -2288,7 +2288,8 @@ func TestPathFindSpecExample(t *testing.T) {
// parameters. // parameters.
lastHop := route.Hops[1] lastHop := route.Hops[1]
require.EqualValues(t, amt, lastHop.AmtToForward) require.EqualValues(t, amt, lastHop.AmtToForward)
require.EqualValues(t, startingHeight+MinCLTVDelta, lastHop.OutgoingTimeLock) require.EqualValues(t, startingHeight+MinCLTVDelta,
lastHop.OutgoingTimeLock)
} }
func assertExpectedPath(t *testing.T, aliasMap map[string]route.Vertex, func assertExpectedPath(t *testing.T, aliasMap map[string]route.Vertex,
@@ -2297,7 +2298,8 @@ func assertExpectedPath(t *testing.T, aliasMap map[string]route.Vertex,
require.Len(t, path, len(nodeAliases)) require.Len(t, path, len(nodeAliases))
for i, hop := range path { for i, hop := range path {
require.Equal(t, aliasMap[nodeAliases[i]], hop.policy.ToNodePubKey()) require.Equal(t, aliasMap[nodeAliases[i]],
hop.policy.ToNodePubKey())
} }
} }
+23 -50
View File
@@ -59,8 +59,6 @@ var (
priv2, _ = btcec.NewPrivateKey() priv2, _ = btcec.NewPrivateKey()
bitcoinKey2 = priv2.PubKey() bitcoinKey2 = priv2.PubKey()
timeout = time.Second * 5
) )
type testCtx struct { type testCtx struct {
@@ -194,7 +192,7 @@ func createTestNode() (*channeldb.LightningNode, error) {
LastUpdate: time.Unix(updateTime, 0), LastUpdate: time.Unix(updateTime, 0),
Addresses: testAddrs, Addresses: testAddrs,
Color: color.RGBA{1, 2, 3, 0}, Color: color.RGBA{1, 2, 3, 0},
Alias: "kek" + string(pub[:]), Alias: "kek" + string(pub),
AuthSigBytes: testSig.Serialize(), AuthSigBytes: testSig.Serialize(),
Features: testFeatures, Features: testFeatures,
} }
@@ -308,7 +306,6 @@ func TestSendPaymentRouteFailureFallback(t *testing.T) {
// the more costly path (through pham nuwen). // the more costly path (through pham nuwen).
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcherOld).setPaymentResult( ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcherOld).setPaymentResult(
func(firstHop lnwire.ShortChannelID) ([32]byte, error) { func(firstHop lnwire.ShortChannelID) ([32]byte, error) {
if firstHop == roasbeefSongoku { if firstHop == roasbeefSongoku {
return [32]byte{}, htlcswitch.NewForwardingError( return [32]byte{}, htlcswitch.NewForwardingError(
// TODO(roasbeef): temp node failure // TODO(roasbeef): temp node failure
@@ -607,8 +604,11 @@ func TestSendPaymentErrorRepeatedFeeInsufficient(t *testing.T) {
// We'll now modify the SendToSwitch method to return an error for the // We'll now modify the SendToSwitch method to return an error for the
// outgoing channel to Son goku. This will be a fee related error, so // outgoing channel to Son goku. This will be a fee related error, so
// it should only cause the edge to be pruned after the second attempt. // it should only cause the edge to be pruned after the second attempt.
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcherOld).setPaymentResult( dispatcher, ok := ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcherOld) //nolint:lll
func(firstHop lnwire.ShortChannelID) ([32]byte, error) { require.True(t, ok)
dispatcher.setPaymentResult(func(firstHop lnwire.ShortChannelID) (
[32]byte, error) {
roasbeefSongoku := lnwire.NewShortChanIDFromInt( roasbeefSongoku := lnwire.NewShortChanIDFromInt(
roasbeefSongokuChanID, roasbeefSongokuChanID,
@@ -1211,12 +1211,8 @@ func TestFindPathFeeWeighting(t *testing.T) {
// The route that was chosen should be exactly one hop, and should be // The route that was chosen should be exactly one hop, and should be
// directly to luoji. // directly to luoji.
if len(path) != 1 { require.Len(t, path, 1)
t.Fatalf("expected path length of 1, instead was: %v", len(path)) require.Equal(t, ctx.aliases["luoji"], path[0].policy.ToNodePubKey())
}
if path[0].policy.ToNodePubKey() != ctx.aliases["luoji"] {
t.Fatalf("wrong node: %v", path[0].policy.ToNodePubKey())
}
} }
// TestEmptyRoutesGenerateSphinxPacket tests that the generateSphinxPacket // TestEmptyRoutesGenerateSphinxPacket tests that the generateSphinxPacket
@@ -1228,9 +1224,7 @@ func TestEmptyRoutesGenerateSphinxPacket(t *testing.T) {
sessionKey, _ := btcec.NewPrivateKey() sessionKey, _ := btcec.NewPrivateKey()
emptyRoute := &route.Route{} emptyRoute := &route.Route{}
_, _, err := generateSphinxPacket(emptyRoute, testHash[:], sessionKey) _, _, err := generateSphinxPacket(emptyRoute, testHash[:], sessionKey)
if err != route.ErrNoRouteHopsProvided { require.ErrorIs(t, err, route.ErrNoRouteHopsProvided)
t.Fatalf("expected empty hops error: instead got: %v", err)
}
} }
// TestUnknownErrorSource tests that if the source of an error is unknown, all // TestUnknownErrorSource tests that if the source of an error is unknown, all
@@ -1270,7 +1264,9 @@ func TestUnknownErrorSource(t *testing.T) {
}, 4), }, 4),
} }
testGraph, err := createTestGraphFromChannels(t, true, testChannels, "a") testGraph, err := createTestGraphFromChannels(
t, true, testChannels, "a",
)
require.NoError(t, err, "unable to create graph") require.NoError(t, err, "unable to create graph")
const startingBlockHeight = 101 const startingBlockHeight = 101
@@ -1284,8 +1280,11 @@ func TestUnknownErrorSource(t *testing.T) {
// We'll modify the SendToSwitch method so that it simulates hop b as a // We'll modify the SendToSwitch method so that it simulates hop b as a
// node that returns an unparsable failure if approached via the a->b // node that returns an unparsable failure if approached via the a->b
// channel. // channel.
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcherOld).setPaymentResult( dispatcher, ok := ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcherOld) //nolint:lll
func(firstHop lnwire.ShortChannelID) ([32]byte, error) { require.True(t, ok)
dispatcher.setPaymentResult(func(firstHop lnwire.ShortChannelID) (
[32]byte, error) {
// If channel a->b is used, return an error without // If channel a->b is used, return an error without
// source and message. The sender won't know the origin // source and message. The sender won't know the origin
@@ -1308,8 +1307,11 @@ func TestUnknownErrorSource(t *testing.T) {
payment.paymentHash) payment.paymentHash)
// Next we modify payment result to return an unknown failure. // Next we modify payment result to return an unknown failure.
ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcherOld).setPaymentResult( dispatcher, ok = ctx.router.cfg.Payer.(*mockPaymentAttemptDispatcherOld) //nolint:lll
func(firstHop lnwire.ShortChannelID) ([32]byte, error) { require.True(t, ok)
dispatcher.setPaymentResult(func(firstHop lnwire.ShortChannelID) (
[32]byte, error) {
// If channel a->b is used, simulate that the failure // If channel a->b is used, simulate that the failure
// couldn't be decoded (FailureMessage is nil). // couldn't be decoded (FailureMessage is nil).
@@ -2353,7 +2355,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
) )
node1Bytes := priv1.PubKey().SerializeCompressed() node1Bytes := priv1.PubKey().SerializeCompressed()
node2Bytes := connectNode node2Bytes := connectNode
if bytes.Compare(node1Bytes[:], node2Bytes[:]) == -1 { if bytes.Compare(node1Bytes, node2Bytes[:]) == -1 {
pubKey1 = priv1.PubKey() pubKey1 = priv1.PubKey()
pubKey2 = connectNodeKey pubKey2 = connectNodeKey
} else { } else {
@@ -2558,35 +2560,6 @@ func (m *mockChain) GetBestBlock() (*chainhash.Hash, int32, error) {
return &blockHash, m.bestHeight, nil return &blockHash, m.bestHeight, nil
} }
func (m *mockChain) setBestBlock(height int32) {
m.Lock()
defer m.Unlock()
m.bestHeight = height
}
func (m *mockChain) addUtxo(op wire.OutPoint, out *wire.TxOut) {
m.Lock()
m.utxos[op] = *out
m.Unlock()
}
func (m *mockChain) delUtxo(op wire.OutPoint) {
m.Lock()
delete(m.utxos, op)
m.Unlock()
}
func (m *mockChain) addBlock(block *wire.MsgBlock, height uint32, nonce uint32) {
m.Lock()
block.Header.Nonce = nonce
hash := block.Header.BlockHash()
m.blocks[hash] = block
m.blockIndex[height] = hash
m.blockHeightIndex[hash] = height
m.Unlock()
}
func createChannelEdge(bitcoinKey1, bitcoinKey2 []byte, func createChannelEdge(bitcoinKey1, bitcoinKey2 []byte,
chanValue btcutil.Amount, fundingHeight uint32) (*wire.MsgTx, chanValue btcutil.Amount, fundingHeight uint32) (*wire.MsgTx,
*wire.OutPoint, *lnwire.ShortChannelID, error) { *wire.OutPoint, *lnwire.ShortChannelID, error) {
+5 -2
View File
@@ -6666,7 +6666,8 @@ func (r *rpcServer) SubscribeChannelGraph(req *lnrpc.GraphTopologySubscription,
// marshallTopologyChange performs a mapping from the topology change struct // marshallTopologyChange performs a mapping from the topology change struct
// returned by the router to the form of notifications expected by the current // returned by the router to the form of notifications expected by the current
// gRPC service. // gRPC service.
func marshallTopologyChange(topChange *graph.TopologyChange) *lnrpc.GraphTopologyUpdate { func marshallTopologyChange(
topChange *graph.TopologyChange) *lnrpc.GraphTopologyUpdate {
// encodeKey is a simple helper function that converts a live public // encodeKey is a simple helper function that converts a live public
// key into a hex-encoded version of the compressed serialization for // key into a hex-encoded version of the compressed serialization for
@@ -6677,7 +6678,9 @@ func marshallTopologyChange(topChange *graph.TopologyChange) *lnrpc.GraphTopolog
nodeUpdates := make([]*lnrpc.NodeUpdate, len(topChange.NodeUpdates)) nodeUpdates := make([]*lnrpc.NodeUpdate, len(topChange.NodeUpdates))
for i, nodeUpdate := range topChange.NodeUpdates { for i, nodeUpdate := range topChange.NodeUpdates {
nodeAddrs := make([]*lnrpc.NodeAddress, 0, len(nodeUpdate.Addresses)) nodeAddrs := make(
[]*lnrpc.NodeAddress, 0, len(nodeUpdate.Addresses),
)
for _, addr := range nodeUpdate.Addresses { for _, addr := range nodeUpdate.Addresses {
nodeAddr := &lnrpc.NodeAddress{ nodeAddr := &lnrpc.NodeAddress{
Network: addr.Network(), Network: addr.Network(),
+1
View File
@@ -1060,6 +1060,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
IsStillZombieChannel: s.graphBuilder.IsZombieChannel, IsStillZombieChannel: s.graphBuilder.IsZombieChannel,
}, nodeKeyDesc) }, nodeKeyDesc)
//nolint:lll
s.localChanMgr = &localchans.Manager{ s.localChanMgr = &localchans.Manager{
ForAllOutgoingChannels: s.graphBuilder.ForAllOutgoingChannels, ForAllOutgoingChannels: s.graphBuilder.ForAllOutgoingChannels,
PropagateChanPolicyUpdate: s.authGossiper.PropagateChanPolicyUpdate, PropagateChanPolicyUpdate: s.authGossiper.PropagateChanPolicyUpdate,