Merge pull request #8171 from ellemouton/zombieChansUseCorrectChanID
channeldb+discovery: pass correct SCID to `MarkEdgeLive`
This commit is contained in:
5 files changed
+47
-32
No files matched your search
@@ -75,6 +75,10 @@ var (
|
|||||||
// but it is marked as a zombie within the zombie index.
|
// but it is marked as a zombie within the zombie index.
|
||||||
ErrZombieEdge = errors.New("edge marked as zombie")
|
ErrZombieEdge = errors.New("edge marked as zombie")
|
||||||
|
|
||||||
|
// ErrZombieEdgeNotFound is an error returned when we attempt to find an
|
||||||
|
// edge in the zombie index which is not there.
|
||||||
|
ErrZombieEdgeNotFound = errors.New("edge not found in zombie index")
|
||||||
|
|
||||||
// ErrEdgeAlreadyExist is returned when edge with specific
|
// ErrEdgeAlreadyExist is returned when edge with specific
|
||||||
// channel id can't be added because it already exist.
|
// channel id can't be added because it already exist.
|
||||||
ErrEdgeAlreadyExist = fmt.Errorf("edge already exist")
|
ErrEdgeAlreadyExist = fmt.Errorf("edge already exist")
|
||||||
|
|||||||
@@ -3512,6 +3512,11 @@ func (c *ChannelGraph) MarkEdgeLive(chanID uint64) error {
|
|||||||
|
|
||||||
var k [8]byte
|
var k [8]byte
|
||||||
byteOrder.PutUint64(k[:], chanID)
|
byteOrder.PutUint64(k[:], chanID)
|
||||||
|
|
||||||
|
if len(zombieIndex.Get(k[:])) == 0 {
|
||||||
|
return ErrZombieEdgeNotFound
|
||||||
|
}
|
||||||
|
|
||||||
return zombieIndex.Delete(k[:])
|
return zombieIndex.Delete(k[:])
|
||||||
}, func() {})
|
}, func() {})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+17
-26
@@ -3067,16 +3067,12 @@ func TestGraphZombieIndex(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
edge, _, _ := createChannelEdge(graph.db, node1, node2)
|
edge, _, _ := createChannelEdge(graph.db, node1, node2)
|
||||||
if err := graph.AddChannelEdge(edge); err != nil {
|
require.NoError(t, graph.AddChannelEdge(edge))
|
||||||
t.Fatalf("unable to create channel edge: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since the edge is known the graph and it isn't a zombie, IsZombieEdge
|
// Since the edge is known the graph and it isn't a zombie, IsZombieEdge
|
||||||
// should not report the channel as a zombie.
|
// should not report the channel as a zombie.
|
||||||
isZombie, _, _ := graph.IsZombieEdge(edge.ChannelID)
|
isZombie, _, _ := graph.IsZombieEdge(edge.ChannelID)
|
||||||
if isZombie {
|
require.False(t, isZombie)
|
||||||
t.Fatal("expected edge to not be marked as zombie")
|
|
||||||
}
|
|
||||||
assertNumZombies(t, graph, 0)
|
assertNumZombies(t, graph, 0)
|
||||||
|
|
||||||
// If we delete the edge and mark it as a zombie, then we should expect
|
// If we delete the edge and mark it as a zombie, then we should expect
|
||||||
@@ -3084,28 +3080,24 @@ func TestGraphZombieIndex(t *testing.T) {
|
|||||||
err = graph.DeleteChannelEdges(false, true, edge.ChannelID)
|
err = graph.DeleteChannelEdges(false, true, edge.ChannelID)
|
||||||
require.NoError(t, err, "unable to mark edge as zombie")
|
require.NoError(t, err, "unable to mark edge as zombie")
|
||||||
isZombie, pubKey1, pubKey2 := graph.IsZombieEdge(edge.ChannelID)
|
isZombie, pubKey1, pubKey2 := graph.IsZombieEdge(edge.ChannelID)
|
||||||
if !isZombie {
|
require.True(t, isZombie)
|
||||||
t.Fatal("expected edge to be marked as zombie")
|
require.Equal(t, node1.PubKeyBytes, pubKey1)
|
||||||
}
|
require.Equal(t, node2.PubKeyBytes, pubKey2)
|
||||||
if pubKey1 != node1.PubKeyBytes {
|
|
||||||
t.Fatalf("expected pubKey1 %x, got %x", node1.PubKeyBytes,
|
|
||||||
pubKey1)
|
|
||||||
}
|
|
||||||
if pubKey2 != node2.PubKeyBytes {
|
|
||||||
t.Fatalf("expected pubKey2 %x, got %x", node2.PubKeyBytes,
|
|
||||||
pubKey2)
|
|
||||||
}
|
|
||||||
assertNumZombies(t, graph, 1)
|
assertNumZombies(t, graph, 1)
|
||||||
|
|
||||||
// Similarly, if we mark the same edge as live, we should no longer see
|
// Similarly, if we mark the same edge as live, we should no longer see
|
||||||
// it within the index.
|
// it within the index.
|
||||||
if err := graph.MarkEdgeLive(edge.ChannelID); err != nil {
|
require.NoError(t, graph.MarkEdgeLive(edge.ChannelID))
|
||||||
t.Fatalf("unable to mark edge as live: %v", err)
|
|
||||||
}
|
// Attempting to mark the edge as live again now that it is no longer
|
||||||
|
// in the zombie index should fail.
|
||||||
|
require.ErrorIs(
|
||||||
|
t, graph.MarkEdgeLive(edge.ChannelID), ErrZombieEdgeNotFound,
|
||||||
|
)
|
||||||
|
|
||||||
isZombie, _, _ = graph.IsZombieEdge(edge.ChannelID)
|
isZombie, _, _ = graph.IsZombieEdge(edge.ChannelID)
|
||||||
if isZombie {
|
require.False(t, isZombie)
|
||||||
t.Fatal("expected edge to not be marked as zombie")
|
|
||||||
}
|
|
||||||
assertNumZombies(t, graph, 0)
|
assertNumZombies(t, graph, 0)
|
||||||
|
|
||||||
// If we mark the edge as a zombie manually, then it should show up as
|
// If we mark the edge as a zombie manually, then it should show up as
|
||||||
@@ -3114,10 +3106,9 @@ func TestGraphZombieIndex(t *testing.T) {
|
|||||||
edge.ChannelID, node1.PubKeyBytes, node2.PubKeyBytes,
|
edge.ChannelID, node1.PubKeyBytes, node2.PubKeyBytes,
|
||||||
)
|
)
|
||||||
require.NoError(t, err, "unable to mark edge as zombie")
|
require.NoError(t, err, "unable to mark edge as zombie")
|
||||||
|
|
||||||
isZombie, _, _ = graph.IsZombieEdge(edge.ChannelID)
|
isZombie, _, _ = graph.IsZombieEdge(edge.ChannelID)
|
||||||
if !isZombie {
|
require.True(t, isZombie)
|
||||||
t.Fatal("expected edge to be marked as zombie")
|
|
||||||
}
|
|
||||||
assertNumZombies(t, graph, 1)
|
assertNumZombies(t, graph, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
-6
@@ -2022,8 +2022,12 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
|||||||
|
|
||||||
// processZombieUpdate determines whether the provided channel update should
|
// processZombieUpdate determines whether the provided channel update should
|
||||||
// resurrect a given zombie edge.
|
// resurrect a given zombie edge.
|
||||||
|
//
|
||||||
|
// NOTE: only the NodeKey1Bytes and NodeKey2Bytes members of the ChannelEdgeInfo
|
||||||
|
// should be inspected.
|
||||||
func (d *AuthenticatedGossiper) processZombieUpdate(
|
func (d *AuthenticatedGossiper) processZombieUpdate(
|
||||||
chanInfo *models.ChannelEdgeInfo, msg *lnwire.ChannelUpdate) error {
|
chanInfo *models.ChannelEdgeInfo, scid lnwire.ShortChannelID,
|
||||||
|
msg *lnwire.ChannelUpdate) error {
|
||||||
|
|
||||||
// The least-significant bit in the flag on the channel update tells us
|
// The least-significant bit in the flag on the channel update tells us
|
||||||
// which edge is being updated.
|
// which edge is being updated.
|
||||||
@@ -2031,7 +2035,7 @@ func (d *AuthenticatedGossiper) processZombieUpdate(
|
|||||||
|
|
||||||
// Since we've deemed the update as not stale above, before marking it
|
// Since we've deemed the update as not stale above, before marking it
|
||||||
// live, we'll make sure it has been signed by the correct party. If we
|
// live, we'll make sure it has been signed by the correct party. If we
|
||||||
// have both pubkeys, either party can resurect the channel. If we've
|
// have both pubkeys, either party can resurrect the channel. If we've
|
||||||
// already marked this with the stricter, single-sided resurrection we
|
// already marked this with the stricter, single-sided resurrection we
|
||||||
// will only have the pubkey of the node with the oldest timestamp.
|
// will only have the pubkey of the node with the oldest timestamp.
|
||||||
var pubKey *btcec.PublicKey
|
var pubKey *btcec.PublicKey
|
||||||
@@ -2055,12 +2059,20 @@ func (d *AuthenticatedGossiper) processZombieUpdate(
|
|||||||
// With the signature valid, we'll proceed to mark the
|
// With the signature valid, we'll proceed to mark the
|
||||||
// edge as live and wait for the channel announcement to
|
// edge as live and wait for the channel announcement to
|
||||||
// come through again.
|
// come through again.
|
||||||
baseScid := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID)
|
err = d.cfg.Router.MarkEdgeLive(scid)
|
||||||
err = d.cfg.Router.MarkEdgeLive(baseScid)
|
switch {
|
||||||
if err != nil {
|
case errors.Is(err, channeldb.ErrZombieEdgeNotFound):
|
||||||
|
log.Errorf("edge with chan_id=%v was not found in the "+
|
||||||
|
"zombie index: %v", err)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case err != nil:
|
||||||
return fmt.Errorf("unable to remove edge with "+
|
return fmt.Errorf("unable to remove edge with "+
|
||||||
"chan_id=%v from zombie index: %v",
|
"chan_id=%v from zombie index: %v",
|
||||||
msg.ShortChannelID, err)
|
msg.ShortChannelID, err)
|
||||||
|
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Removed edge with chan_id=%v from zombie "+
|
log.Debugf("Removed edge with chan_id=%v from zombie "+
|
||||||
@@ -2731,7 +2743,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
|
|||||||
break
|
break
|
||||||
|
|
||||||
case channeldb.ErrZombieEdge:
|
case channeldb.ErrZombieEdge:
|
||||||
err = d.processZombieUpdate(chanInfo, upd)
|
err = d.processZombieUpdate(chanInfo, graphScid, upd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug(err)
|
log.Debug(err)
|
||||||
nMsg.err <- err
|
nMsg.err <- err
|
||||||
|
|||||||
@@ -39,6 +39,9 @@
|
|||||||
|
|
||||||
* [Fixed a case](https://github.com/lightningnetwork/lnd/pull/7503) where it's
|
* [Fixed a case](https://github.com/lightningnetwork/lnd/pull/7503) where it's
|
||||||
possible a failed payment might be stuck in pending.
|
possible a failed payment might be stuck in pending.
|
||||||
|
|
||||||
|
* [Ensure that a valid SCID](https://github.com/lightningnetwork/lnd/pull/8171)
|
||||||
|
is used when marking a zombie edge as live.
|
||||||
|
|
||||||
# New Features
|
# New Features
|
||||||
## Functional Enhancements
|
## Functional Enhancements
|
||||||
|
|||||||
Reference in new issue
Block a user