refactor: move various duties from ChannelRouter to graph.Builder

This commit is a large refactor that moves over various responsibilities
from the ChannelRouter to the graph.Builder. These include all graph
related tasks such as:
- graph pruning
- validation of new network updates & persisting new updates
- notifying topology update clients of any changes.

This is a large commit but:
- many of the files are purely moved from `routing` to `graph`
- the business logic put in the graph Builder is copied exactly as is
  from the ChannelRouter with one exception:
- The ChannelRouter just needs to be able to call the Builder's
  `ApplyChannelUpdate` method. So this is now exported and provided to
the ChannelRouter as a config option.
- The trickiest part was just moving over the test code since quite a
  bit had to be duplicated.
This commit is contained in:
Elle Mouton committed 2024-07-15 15:56:33 +02:00
1 parent 0b7364f54b
commit 7f1be39d45
26 files changed
+5121 -3862

No files matched your search

+3 -3
View File
@@ -5,9 +5,9 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/graph"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/netann"
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/routing/route"
)
@@ -136,7 +136,7 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
if edge1 != nil {
// We don't want to send channel updates that don't
// conform to the spec (anymore).
err := routing.ValidateChannelUpdateFields(0, edge1)
err := graph.ValidateChannelUpdateFields(0, edge1)
if err != nil {
log.Errorf("not sending invalid channel "+
"update %v: %v", edge1, err)
@@ -145,7 +145,7 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
}
}
if edge2 != nil {
err := routing.ValidateChannelUpdateFields(0, edge2)
err := graph.ValidateChannelUpdateFields(0, edge2)
if err != nil {
log.Errorf("not sending invalid channel "+
"update %v: %v", edge2, err)
+21 -22
View File
@@ -29,7 +29,6 @@ import (
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/multimutex"
"github.com/lightningnetwork/lnd/netann"
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/ticker"
"golang.org/x/time/rate"
@@ -1361,7 +1360,7 @@ func (d *AuthenticatedGossiper) networkHandler() {
// We'll use this validation to ensure that we process jobs in their
// dependency order during parallel validation.
validationBarrier := routing.NewValidationBarrier(1000, d.quit)
validationBarrier := graph.NewValidationBarrier(1000, d.quit)
for {
select {
@@ -1486,7 +1485,7 @@ func (d *AuthenticatedGossiper) networkHandler() {
//
// NOTE: must be run as a goroutine.
func (d *AuthenticatedGossiper) handleNetworkMessages(nMsg *networkMsg,
deDuped *deDupedAnnouncements, vb *routing.ValidationBarrier) {
deDuped *deDupedAnnouncements, vb *graph.ValidationBarrier) {
defer d.wg.Done()
defer vb.CompleteJob()
@@ -1502,10 +1501,10 @@ func (d *AuthenticatedGossiper) handleNetworkMessages(nMsg *networkMsg,
log.Debugf("Validating network message %s got err: %v",
nMsg.msg.MsgType(), err)
if !routing.IsError(
if !graph.IsError(
err,
routing.ErrVBarrierShuttingDown,
routing.ErrParentValidationFailed,
graph.ErrVBarrierShuttingDown,
graph.ErrParentValidationFailed,
) {
log.Warnf("unexpected error during validation "+
@@ -1861,7 +1860,7 @@ func (d *AuthenticatedGossiper) processRejectedEdge(
if err != nil {
return nil, err
}
err = routing.ValidateChannelAnn(chanAnn)
err = graph.ValidateChannelAnn(chanAnn)
if err != nil {
err := fmt.Errorf("assembled channel announcement proof "+
"for shortChanID=%v isn't valid: %v",
@@ -1910,7 +1909,7 @@ func (d *AuthenticatedGossiper) processRejectedEdge(
func (d *AuthenticatedGossiper) addNode(msg *lnwire.NodeAnnouncement,
op ...batch.SchedulerOption) error {
if err := routing.ValidateNodeAnn(msg); err != nil {
if err := graph.ValidateNodeAnn(msg); err != nil {
return fmt.Errorf("unable to validate node announcement: %w",
err)
}
@@ -2064,7 +2063,7 @@ func (d *AuthenticatedGossiper) processZombieUpdate(
"with chan_id=%v", msg.ShortChannelID)
}
err := routing.VerifyChannelUpdateSignature(msg, pubKey)
err := graph.VerifyChannelUpdateSignature(msg, pubKey)
if err != nil {
return fmt.Errorf("unable to verify channel "+
"update signature: %v", err)
@@ -2201,7 +2200,7 @@ func (d *AuthenticatedGossiper) updateChannel(info *models.ChannelEdgeInfo,
// To ensure that our signature is valid, we'll verify it ourself
// before committing it to the slice returned.
err = routing.ValidateChannelUpdateAnn(d.selfKey, info.Capacity, chanUpdate)
err = graph.ValidateChannelUpdateAnn(d.selfKey, info.Capacity, chanUpdate)
if err != nil {
return nil, nil, fmt.Errorf("generated invalid channel "+
"update sig: %v", err)
@@ -2338,11 +2337,11 @@ func (d *AuthenticatedGossiper) handleNodeAnnouncement(nMsg *networkMsg,
log.Debugf("Adding node: %x got error: %v", nodeAnn.NodeID,
err)
if !routing.IsError(
if !graph.IsError(
err,
routing.ErrOutdated,
routing.ErrIgnored,
routing.ErrVBarrierShuttingDown,
graph.ErrOutdated,
graph.ErrIgnored,
graph.ErrVBarrierShuttingDown,
) {
log.Error(err)
@@ -2457,7 +2456,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
// the signatures within the proof as it should be well formed.
var proof *models.ChannelAuthProof
if nMsg.isRemote {
if err := routing.ValidateChannelAnn(ann); err != nil {
if err := graph.ValidateChannelAnn(ann); err != nil {
err := fmt.Errorf("unable to validate announcement: "+
"%v", err)
@@ -2538,7 +2537,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
// If the edge was rejected due to already being known, then it
// may be the case that this new message has a fresh channel
// proof, so we'll check.
if routing.IsError(err, routing.ErrIgnored) {
if graph.IsError(err, graph.ErrIgnored) {
// Attempt to process the rejected message to see if we
// get any new announcements.
anns, rErr := d.processRejectedEdge(ann, proof)
@@ -2862,7 +2861,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
// Validate the channel announcement with the expected public key and
// channel capacity. In the case of an invalid channel update, we'll
// return an error to the caller and exit early.
err = routing.ValidateChannelUpdateAnn(pubKey, chanInfo.Capacity, upd)
err = graph.ValidateChannelUpdateAnn(pubKey, chanInfo.Capacity, upd)
if err != nil {
rErr := fmt.Errorf("unable to validate channel update "+
"announcement for short_chan_id=%v: %v",
@@ -2947,10 +2946,10 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
}
if err := d.cfg.Router.UpdateEdge(update, ops...); err != nil {
if routing.IsError(
err, routing.ErrOutdated,
routing.ErrIgnored,
routing.ErrVBarrierShuttingDown,
if graph.IsError(
err, graph.ErrOutdated,
graph.ErrIgnored,
graph.ErrVBarrierShuttingDown,
) {
log.Debugf("Update edge for short_chan_id(%v) got: %v",
@@ -3268,7 +3267,7 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
// With all the necessary components assembled validate the full
// channel announcement proof.
if err := routing.ValidateChannelAnn(chanAnn); err != nil {
if err := graph.ValidateChannelAnn(chanAnn); err != nil {
err := fmt.Errorf("channel announcement proof for "+
"short_chan_id=%v isn't valid: %v", shortChanID, err)
+2 -3
View File
@@ -33,7 +33,6 @@ import (
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/netann"
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/ticker"
"github.com/stretchr/testify/require"
@@ -351,7 +350,7 @@ func (r *mockGraphSource) IsStaleEdgePolicy(chanID lnwire.ShortChannelID,
// Since it exists within our zombie index, we'll check that it
// respects the router's live edge horizon to determine whether
// it is stale or not.
return time.Since(timestamp) > routing.DefaultChannelPruneExpiry
return time.Since(timestamp) > graph.DefaultChannelPruneExpiry
}
switch {
@@ -2258,7 +2257,7 @@ func TestProcessZombieEdgeNowLive(t *testing.T) {
// We'll generate a channel update with a timestamp far enough in the
// past to consider it a zombie.
zombieTimestamp := time.Now().Add(-routing.DefaultChannelPruneExpiry)
zombieTimestamp := time.Now().Add(-graph.DefaultChannelPruneExpiry)
batch.chanUpdAnn2.Timestamp = uint32(zombieTimestamp.Unix())
if err := signUpdate(remoteKeyPriv2, batch.chanUpdAnn2); err != nil {
t.Fatalf("unable to sign update with new timestamp: %v", err)