Merge pull request #8171 from ellemouton/zombieChansUseCorrectChanID

channeldb+discovery: pass correct SCID to `MarkEdgeLive`
This commit is contained in:
Elle 2023-11-14 11:05:57 +02:00 committed by GitHub
commit 5e369a02bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 32 deletions

View File

@ -75,6 +75,10 @@ var (
// but it is marked as a zombie within the zombie index.
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
// channel id can't be added because it already exist.
ErrEdgeAlreadyExist = fmt.Errorf("edge already exist")

View File

@ -3512,6 +3512,11 @@ func (c *ChannelGraph) MarkEdgeLive(chanID uint64) error {
var k [8]byte
byteOrder.PutUint64(k[:], chanID)
if len(zombieIndex.Get(k[:])) == 0 {
return ErrZombieEdgeNotFound
}
return zombieIndex.Delete(k[:])
}, func() {})
if err != nil {

View File

@ -3067,16 +3067,12 @@ func TestGraphZombieIndex(t *testing.T) {
}
edge, _, _ := createChannelEdge(graph.db, node1, node2)
if err := graph.AddChannelEdge(edge); err != nil {
t.Fatalf("unable to create channel edge: %v", err)
}
require.NoError(t, graph.AddChannelEdge(edge))
// Since the edge is known the graph and it isn't a zombie, IsZombieEdge
// should not report the channel as a zombie.
isZombie, _, _ := graph.IsZombieEdge(edge.ChannelID)
if isZombie {
t.Fatal("expected edge to not be marked as zombie")
}
require.False(t, isZombie)
assertNumZombies(t, graph, 0)
// 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)
require.NoError(t, err, "unable to mark edge as zombie")
isZombie, pubKey1, pubKey2 := graph.IsZombieEdge(edge.ChannelID)
if !isZombie {
t.Fatal("expected edge to be marked as zombie")
}
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)
}
require.True(t, isZombie)
require.Equal(t, node1.PubKeyBytes, pubKey1)
require.Equal(t, node2.PubKeyBytes, pubKey2)
assertNumZombies(t, graph, 1)
// Similarly, if we mark the same edge as live, we should no longer see
// it within the index.
if err := graph.MarkEdgeLive(edge.ChannelID); err != nil {
t.Fatalf("unable to mark edge as live: %v", err)
}
require.NoError(t, graph.MarkEdgeLive(edge.ChannelID))
// 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)
if isZombie {
t.Fatal("expected edge to not be marked as zombie")
}
require.False(t, isZombie)
assertNumZombies(t, graph, 0)
// 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,
)
require.NoError(t, err, "unable to mark edge as zombie")
isZombie, _, _ = graph.IsZombieEdge(edge.ChannelID)
if !isZombie {
t.Fatal("expected edge to be marked as zombie")
}
require.True(t, isZombie)
assertNumZombies(t, graph, 1)
}

View File

@ -2022,8 +2022,12 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
// processZombieUpdate determines whether the provided channel update should
// resurrect a given zombie edge.
//
// NOTE: only the NodeKey1Bytes and NodeKey2Bytes members of the ChannelEdgeInfo
// should be inspected.
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
// 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
// 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
// will only have the pubkey of the node with the oldest timestamp.
var pubKey *btcec.PublicKey
@ -2055,12 +2059,20 @@ func (d *AuthenticatedGossiper) processZombieUpdate(
// With the signature valid, we'll proceed to mark the
// edge as live and wait for the channel announcement to
// come through again.
baseScid := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID)
err = d.cfg.Router.MarkEdgeLive(baseScid)
if err != nil {
err = d.cfg.Router.MarkEdgeLive(scid)
switch {
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 "+
"chan_id=%v from zombie index: %v",
msg.ShortChannelID, err)
default:
}
log.Debugf("Removed edge with chan_id=%v from zombie "+
@ -2731,7 +2743,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
break
case channeldb.ErrZombieEdge:
err = d.processZombieUpdate(chanInfo, upd)
err = d.processZombieUpdate(chanInfo, graphScid, upd)
if err != nil {
log.Debug(err)
nMsg.err <- err

View File

@ -39,6 +39,9 @@
* [Fixed a case](https://github.com/lightningnetwork/lnd/pull/7503) where it's
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
## Functional Enhancements