graph -> discovery: move ValidationBarrier to discovery

This commit is contained in:
Eugene Siegel committed 2025-01-23 13:04:39 -05:00
1 parent e0e4073bcd
commit 323b633895
4 files changed
+50 -38

No files matched your search

+4 -11
View File
@@ -518,7 +518,7 @@ type AuthenticatedGossiper struct {
chanUpdateRateLimiter map[uint64][2]*rate.Limiter chanUpdateRateLimiter map[uint64][2]*rate.Limiter
// vb is used to enforce job dependency ordering of gossip messages. // vb is used to enforce job dependency ordering of gossip messages.
vb *graph.ValidationBarrier vb *ValidationBarrier
sync.Mutex sync.Mutex
} }
@@ -545,7 +545,7 @@ func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper
banman: newBanman(), banman: newBanman(),
} }
gossiper.vb = graph.NewValidationBarrier(1000, gossiper.quit) gossiper.vb = NewValidationBarrier(1000, gossiper.quit)
gossiper.syncMgr = newSyncManager(&SyncManagerCfg{ gossiper.syncMgr = newSyncManager(&SyncManagerCfg{
ChainHash: cfg.ChainHash, ChainHash: cfg.ChainHash,
@@ -1543,7 +1543,7 @@ func (d *AuthenticatedGossiper) networkHandler() {
// //
// NOTE: must be run as a goroutine. // NOTE: must be run as a goroutine.
func (d *AuthenticatedGossiper) handleNetworkMessages(nMsg *networkMsg, func (d *AuthenticatedGossiper) handleNetworkMessages(nMsg *networkMsg,
deDuped *deDupedAnnouncements, jobID graph.JobID) { deDuped *deDupedAnnouncements, jobID JobID) {
defer d.wg.Done() defer d.wg.Done()
defer d.vb.CompleteJob() defer d.vb.CompleteJob()
@@ -1559,12 +1559,7 @@ func (d *AuthenticatedGossiper) handleNetworkMessages(nMsg *networkMsg,
log.Debugf("Validating network message %s got err: %v", log.Debugf("Validating network message %s got err: %v",
nMsg.msg.MsgType(), err) nMsg.msg.MsgType(), err)
if !graph.IsError( if errors.Is(err, ErrVBarrierShuttingDown) {
err,
graph.ErrVBarrierShuttingDown,
graph.ErrParentValidationFailed,
) {
log.Warnf("unexpected error during validation "+ log.Warnf("unexpected error during validation "+
"barrier shutdown: %v", err) "barrier shutdown: %v", err)
} }
@@ -2423,7 +2418,6 @@ func (d *AuthenticatedGossiper) handleNodeAnnouncement(nMsg *networkMsg,
err, err,
graph.ErrOutdated, graph.ErrOutdated,
graph.ErrIgnored, graph.ErrIgnored,
graph.ErrVBarrierShuttingDown,
) { ) {
log.Error(err) log.Error(err)
@@ -3164,7 +3158,6 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
if graph.IsError( if graph.IsError(
err, graph.ErrOutdated, err, graph.ErrOutdated,
graph.ErrIgnored, graph.ErrIgnored,
graph.ErrVBarrierShuttingDown,
) { ) {
log.Debugf("Update edge for short_chan_id(%v) got: %v", log.Debugf("Update edge for short_chan_id(%v) got: %v",
@@ -1,4 +1,4 @@
package graph package discovery
import ( import (
"fmt" "fmt"
@@ -11,6 +11,13 @@ import (
"github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/routing/route"
) )
var (
// ErrVBarrierShuttingDown signals that the barrier has been requested
// to shutdown, and that the caller should not treat the wait condition
// as fulfilled.
ErrVBarrierShuttingDown = errors.New("ValidationBarrier shutting down")
)
// JobID identifies an active job in the validation barrier. It is large so // JobID identifies an active job in the validation barrier. It is large so
// that we don't need to worry about overflows. // that we don't need to worry about overflows.
type JobID uint64 type JobID uint64
@@ -88,7 +95,7 @@ func NewValidationBarrier(numActiveReqs int,
} }
// InitJobDependencies will wait for a new job slot to become open, and then // InitJobDependencies will wait for a new job slot to become open, and then
// sets up any dependent signals/trigger for the new job // sets up any dependent signals/trigger for the new job.
func (v *ValidationBarrier) InitJobDependencies(job interface{}) (JobID, func (v *ValidationBarrier) InitJobDependencies(job interface{}) (JobID,
error) { error) {
@@ -296,8 +303,7 @@ func (v *ValidationBarrier) WaitForParents(childJobID JobID,
for { for {
select { select {
case <-v.quit: case <-v.quit:
return NewErrf(ErrVBarrierShuttingDown, return ErrVBarrierShuttingDown
"validation barrier shutting down")
case <-jobChan: case <-jobChan:
// Every time this is sent on or if it's closed, a // Every time this is sent on or if it's closed, a
@@ -1,11 +1,12 @@
package graph_test package discovery
import ( import (
"encoding/binary" "encoding/binary"
"errors"
"sync"
"testing" "testing"
"time" "time"
"github.com/lightningnetwork/lnd/graph"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -22,18 +23,38 @@ func TestValidationBarrierSemaphore(t *testing.T) {
) )
quit := make(chan struct{}) quit := make(chan struct{})
barrier := graph.NewValidationBarrier(numTasks, quit) barrier := NewValidationBarrier(numTasks, quit)
var scidMtx sync.RWMutex
currentScid := lnwire.ShortChannelID{}
// Saturate the semaphore with jobs. // Saturate the semaphore with jobs.
for i := 0; i < numTasks; i++ { for i := 0; i < numTasks; i++ {
barrier.InitJobDependencies(nil) scidMtx.Lock()
dummyUpdate := &lnwire.ChannelUpdate1{
ShortChannelID: currentScid,
}
currentScid.TxIndex++
scidMtx.Unlock()
_, err := barrier.InitJobDependencies(dummyUpdate)
require.NoError(t, err)
} }
// Spawn additional tasks that will signal completion when added. // Spawn additional tasks that will signal completion when added.
jobAdded := make(chan struct{}) jobAdded := make(chan struct{})
for i := 0; i < numPendingTasks; i++ { for i := 0; i < numPendingTasks; i++ {
go func() { go func() {
barrier.InitJobDependencies(nil) scidMtx.Lock()
dummyUpdate := &lnwire.ChannelUpdate1{
ShortChannelID: currentScid,
}
currentScid.TxIndex++
scidMtx.Unlock()
_, err := barrier.InitJobDependencies(dummyUpdate)
require.NoError(t, err)
jobAdded <- struct{}{} jobAdded <- struct{}{}
}() }()
} }
@@ -70,12 +91,12 @@ func TestValidationBarrierQuit(t *testing.T) {
) )
quit := make(chan struct{}) quit := make(chan struct{})
barrier := graph.NewValidationBarrier(2*numTasks, quit) barrier := NewValidationBarrier(2*numTasks, quit)
// Create a set of unique channel announcements that we will prep for // Create a set of unique channel announcements that we will prep for
// validation. // validation.
anns := make([]*lnwire.ChannelAnnouncement1, 0, numTasks) anns := make([]*lnwire.ChannelAnnouncement1, 0, numTasks)
parentJobIDs := make([]graph.JobID, 0, numTasks) parentJobIDs := make([]JobID, 0, numTasks)
for i := 0; i < numTasks; i++ { for i := 0; i < numTasks; i++ {
anns = append(anns, &lnwire.ChannelAnnouncement1{ anns = append(anns, &lnwire.ChannelAnnouncement1{
ShortChannelID: lnwire.NewShortChanIDFromInt(uint64(i)), ShortChannelID: lnwire.NewShortChanIDFromInt(uint64(i)),
@@ -91,7 +112,7 @@ func TestValidationBarrierQuit(t *testing.T) {
// Create a set of channel updates, that must wait until their // Create a set of channel updates, that must wait until their
// associated channel announcement has been verified. // associated channel announcement has been verified.
chanUpds := make([]*lnwire.ChannelUpdate1, 0, numTasks) chanUpds := make([]*lnwire.ChannelUpdate1, 0, numTasks)
childJobIDs := make([]graph.JobID, 0, numTasks) childJobIDs := make([]JobID, 0, numTasks)
for i := 0; i < numTasks; i++ { for i := 0; i < numTasks; i++ {
chanUpds = append(chanUpds, &lnwire.ChannelUpdate1{ chanUpds = append(chanUpds, &lnwire.ChannelUpdate1{
ShortChannelID: lnwire.NewShortChanIDFromInt(uint64(i)), ShortChannelID: lnwire.NewShortChanIDFromInt(uint64(i)),
@@ -154,11 +175,12 @@ func TestValidationBarrierQuit(t *testing.T) {
t.Fatalf("unexpected failure while waiting: %v", err) t.Fatalf("unexpected failure while waiting: %v", err)
// Last half should return the shutdown error. // Last half should return the shutdown error.
case i >= numTasks/2 && !graph.IsError( case i >= numTasks/2 && !errors.Is(
err, graph.ErrVBarrierShuttingDown, err, ErrVBarrierShuttingDown,
): ):
t.Fatalf("expected failure after quitting: want %v, "+ t.Fatalf("expected failure after quitting: want %v, "+
"got %v", graph.ErrVBarrierShuttingDown, err) "got %v", ErrVBarrierShuttingDown, err)
} }
} }
} }
@@ -175,7 +197,7 @@ func TestValidationBarrierParentJobsClear(t *testing.T) {
) )
quit := make(chan struct{}) quit := make(chan struct{})
barrier := graph.NewValidationBarrier(numTasks, quit) barrier := NewValidationBarrier(numTasks, quit)
sharedScid := lnwire.NewShortChanIDFromInt(0) sharedScid := lnwire.NewShortChanIDFromInt(0)
sharedNodeID := nodeIDFromInt(0) sharedNodeID := nodeIDFromInt(0)
@@ -221,8 +243,8 @@ func TestValidationBarrierParentJobsClear(t *testing.T) {
childID2, err := barrier.InitJobDependencies(node1) childID2, err := barrier.InitJobDependencies(node1)
require.NoError(t, err) require.NoError(t, err)
run := func(vb *graph.ValidationBarrier, childJobID graph.JobID, run := func(vb *ValidationBarrier, childJobID JobID, job interface{},
job interface{}, resp chan error, start chan error) { resp chan error, start chan error) {
close(start) close(start)
-9
View File
@@ -28,15 +28,6 @@ const (
// ErrInvalidFundingOutput is returned if the channel funding output // ErrInvalidFundingOutput is returned if the channel funding output
// fails validation. // fails validation.
ErrInvalidFundingOutput ErrInvalidFundingOutput
// ErrVBarrierShuttingDown signals that the barrier has been requested
// to shutdown, and that the caller should not treat the wait condition
// as fulfilled.
ErrVBarrierShuttingDown
// ErrParentValidationFailed signals that the validation of a
// dependent's parent failed, so the dependent must not be processed.
ErrParentValidationFailed
) )
// Error is a structure that represent the error inside the graph package, // Error is a structure that represent the error inside the graph package,