mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-10-10 23:22:48 +02:00
multi: extract and pass through IsZombieChannel method
This commit is contained in:
@@ -335,6 +335,11 @@ type Config struct {
|
|||||||
// to without iterating over the entire set of open channels.
|
// to without iterating over the entire set of open channels.
|
||||||
FindChannel func(node *btcec.PublicKey, chanID lnwire.ChannelID) (
|
FindChannel func(node *btcec.PublicKey, chanID lnwire.ChannelID) (
|
||||||
*channeldb.OpenChannel, error)
|
*channeldb.OpenChannel, error)
|
||||||
|
|
||||||
|
// IsStillZombieChannel takes the timestamps of the latest channel
|
||||||
|
// updates for a channel and returns true if the channel should be
|
||||||
|
// considered a zombie based on these timestamps.
|
||||||
|
IsStillZombieChannel func(time.Time, time.Time) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// processedNetworkMsg is a wrapper around networkMsg and a boolean. It is
|
// processedNetworkMsg is a wrapper around networkMsg and a boolean. It is
|
||||||
@@ -519,6 +524,7 @@ func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper
|
|||||||
IgnoreHistoricalFilters: cfg.IgnoreHistoricalFilters,
|
IgnoreHistoricalFilters: cfg.IgnoreHistoricalFilters,
|
||||||
BestHeight: gossiper.latestHeight,
|
BestHeight: gossiper.latestHeight,
|
||||||
PinnedSyncers: cfg.PinnedSyncers,
|
PinnedSyncers: cfg.PinnedSyncers,
|
||||||
|
IsStillZombieChannel: cfg.IsStillZombieChannel,
|
||||||
})
|
})
|
||||||
|
|
||||||
gossiper.reliableSender = newReliableSender(&reliableSenderCfg{
|
gossiper.reliableSender = newReliableSender(&reliableSenderCfg{
|
||||||
|
@@ -102,6 +102,11 @@ type SyncManagerCfg struct {
|
|||||||
// ActiveSync upon connection. These peers will never transition to
|
// ActiveSync upon connection. These peers will never transition to
|
||||||
// PassiveSync.
|
// PassiveSync.
|
||||||
PinnedSyncers PinnedSyncers
|
PinnedSyncers PinnedSyncers
|
||||||
|
|
||||||
|
// IsStillZombieChannel takes the timestamps of the latest channel
|
||||||
|
// updates for a channel and returns true if the channel should be
|
||||||
|
// considered a zombie based on these timestamps.
|
||||||
|
IsStillZombieChannel func(time.Time, time.Time) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// SyncManager is a subsystem of the gossiper that manages the gossip syncers
|
// SyncManager is a subsystem of the gossiper that manages the gossip syncers
|
||||||
@@ -501,6 +506,7 @@ func (m *SyncManager) createGossipSyncer(peer lnpeer.Peer) *GossipSyncer {
|
|||||||
markGraphSynced: m.markGraphSynced,
|
markGraphSynced: m.markGraphSynced,
|
||||||
maxQueryChanRangeReplies: maxQueryChanRangeReplies,
|
maxQueryChanRangeReplies: maxQueryChanRangeReplies,
|
||||||
noTimestampQueryOption: m.cfg.NoTimestampQueries,
|
noTimestampQueryOption: m.cfg.NoTimestampQueries,
|
||||||
|
isStillZombieChannel: m.cfg.IsStillZombieChannel,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Gossip syncers are initialized by default in a PassiveSync type
|
// Gossip syncers are initialized by default in a PassiveSync type
|
||||||
|
@@ -293,6 +293,11 @@ type gossipSyncerCfg struct {
|
|||||||
// maxQueryChanRangeReplies is the maximum number of replies we'll allow
|
// maxQueryChanRangeReplies is the maximum number of replies we'll allow
|
||||||
// for a single QueryChannelRange request.
|
// for a single QueryChannelRange request.
|
||||||
maxQueryChanRangeReplies uint32
|
maxQueryChanRangeReplies uint32
|
||||||
|
|
||||||
|
// isStillZombieChannel takes the timestamps of the latest channel
|
||||||
|
// updates for a channel and returns true if the channel should be
|
||||||
|
// considered a zombie based on these timestamps.
|
||||||
|
isStillZombieChannel func(time.Time, time.Time) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// GossipSyncer is a struct that handles synchronizing the channel graph state
|
// GossipSyncer is a struct that handles synchronizing the channel graph state
|
||||||
|
@@ -888,6 +888,55 @@ func (r *ChannelRouter) syncGraphWithChain() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isZombieChannel takes two edge policy updates and determines if the
|
||||||
|
// corresponding channel should be considered a zombie. The first boolean is
|
||||||
|
// true if the policy update from node 1 is considered a zombie, the second
|
||||||
|
// boolean is that of node 2, and the final boolean is true if the channel
|
||||||
|
// is considered a zombie.
|
||||||
|
func (r *ChannelRouter) isZombieChannel(e1,
|
||||||
|
e2 *models.ChannelEdgePolicy) (bool, bool, bool) {
|
||||||
|
|
||||||
|
chanExpiry := r.cfg.ChannelPruneExpiry
|
||||||
|
|
||||||
|
e1Zombie := e1 == nil || time.Since(e1.LastUpdate) >= chanExpiry
|
||||||
|
e2Zombie := e2 == nil || time.Since(e2.LastUpdate) >= chanExpiry
|
||||||
|
|
||||||
|
var e1Time, e2Time time.Time
|
||||||
|
if e1 != nil {
|
||||||
|
e1Time = e1.LastUpdate
|
||||||
|
}
|
||||||
|
if e2 != nil {
|
||||||
|
e2Time = e2.LastUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
return e1Zombie, e2Zombie, r.IsZombieChannel(e1Time, e2Time)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsZombieChannel takes the timestamps of the latest channel updates for a
|
||||||
|
// channel and returns true if the channel should be considered a zombie based
|
||||||
|
// on these timestamps.
|
||||||
|
func (r *ChannelRouter) IsZombieChannel(updateTime1,
|
||||||
|
updateTime2 time.Time) bool {
|
||||||
|
|
||||||
|
chanExpiry := r.cfg.ChannelPruneExpiry
|
||||||
|
|
||||||
|
e1Zombie := updateTime1.IsZero() ||
|
||||||
|
time.Since(updateTime1) >= chanExpiry
|
||||||
|
|
||||||
|
e2Zombie := updateTime2.IsZero() ||
|
||||||
|
time.Since(updateTime2) >= chanExpiry
|
||||||
|
|
||||||
|
// If we're using strict zombie pruning, then a channel is only
|
||||||
|
// considered live if both edges have a recent update we know of.
|
||||||
|
if r.cfg.StrictZombiePruning {
|
||||||
|
return e1Zombie || e2Zombie
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, if we're using the less strict variant, then a channel is
|
||||||
|
// considered live if either of the edges have a recent update.
|
||||||
|
return e1Zombie && e2Zombie
|
||||||
|
}
|
||||||
|
|
||||||
// pruneZombieChans is a method that will be called periodically to prune out
|
// pruneZombieChans is a method that will be called periodically to prune out
|
||||||
// any "zombie" channels. We consider channels zombies if *both* edges haven't
|
// any "zombie" channels. We consider channels zombies if *both* edges haven't
|
||||||
// been updated since our zombie horizon. If AssumeChannelValid is present,
|
// been updated since our zombie horizon. If AssumeChannelValid is present,
|
||||||
@@ -911,8 +960,10 @@ func (r *ChannelRouter) pruneZombieChans() error {
|
|||||||
filterPruneChans := func(info *models.ChannelEdgeInfo,
|
filterPruneChans := func(info *models.ChannelEdgeInfo,
|
||||||
e1, e2 *models.ChannelEdgePolicy) error {
|
e1, e2 *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
// Exit early in case this channel is already marked to be pruned
|
// Exit early in case this channel is already marked to be
|
||||||
if _, markedToPrune := chansToPrune[info.ChannelID]; markedToPrune {
|
// pruned
|
||||||
|
_, markedToPrune := chansToPrune[info.ChannelID]
|
||||||
|
if markedToPrune {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -923,39 +974,22 @@ func (r *ChannelRouter) pruneZombieChans() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If either edge hasn't been updated for a period of
|
e1Zombie, e2Zombie, isZombieChan := r.isZombieChannel(e1, e2)
|
||||||
// chanExpiry, then we'll mark the channel itself as eligible
|
|
||||||
// for graph pruning.
|
|
||||||
e1Zombie := e1 == nil || time.Since(e1.LastUpdate) >= chanExpiry
|
|
||||||
e2Zombie := e2 == nil || time.Since(e2.LastUpdate) >= chanExpiry
|
|
||||||
|
|
||||||
if e1Zombie {
|
if e1Zombie {
|
||||||
log.Tracef("Node1 pubkey=%x of chan_id=%v is zombie",
|
log.Tracef("Node1 pubkey=%x of chan_id=%v is zombie",
|
||||||
info.NodeKey1Bytes, info.ChannelID)
|
info.NodeKey1Bytes, info.ChannelID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if e2Zombie {
|
if e2Zombie {
|
||||||
log.Tracef("Node2 pubkey=%x of chan_id=%v is zombie",
|
log.Tracef("Node2 pubkey=%x of chan_id=%v is zombie",
|
||||||
info.NodeKey2Bytes, info.ChannelID)
|
info.NodeKey2Bytes, info.ChannelID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're using strict zombie pruning, then a channel is only
|
// If either edge hasn't been updated for a period of
|
||||||
// considered live if both edges have a recent update we know
|
// chanExpiry, then we'll mark the channel itself as eligible
|
||||||
// of.
|
// for graph pruning.
|
||||||
var channelIsLive bool
|
if !isZombieChan {
|
||||||
switch {
|
|
||||||
case r.cfg.StrictZombiePruning:
|
|
||||||
channelIsLive = !e1Zombie && !e2Zombie
|
|
||||||
|
|
||||||
// Otherwise, if we're using the less strict variant, then a
|
|
||||||
// channel is considered live if either of the edges have a
|
|
||||||
// recent update.
|
|
||||||
default:
|
|
||||||
channelIsLive = !e1Zombie || !e2Zombie
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return early if the channel is still considered to be live
|
|
||||||
// with the current set of configuration parameters.
|
|
||||||
if channelIsLive {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1030,6 +1030,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
FindBaseByAlias: s.aliasMgr.FindBaseSCID,
|
FindBaseByAlias: s.aliasMgr.FindBaseSCID,
|
||||||
GetAlias: s.aliasMgr.GetPeerAlias,
|
GetAlias: s.aliasMgr.GetPeerAlias,
|
||||||
FindChannel: s.findChannel,
|
FindChannel: s.findChannel,
|
||||||
|
IsStillZombieChannel: s.chanRouter.IsZombieChannel,
|
||||||
}, nodeKeyDesc)
|
}, nodeKeyDesc)
|
||||||
|
|
||||||
s.localChanMgr = &localchans.Manager{
|
s.localChanMgr = &localchans.Manager{
|
||||||
|
Reference in New Issue
Block a user