From d807ff23d24444d6c11894a42b31ab38a8352a53 Mon Sep 17 00:00:00 2001 From: eugene Date: Thu, 5 Jan 2023 17:38:59 -0500 Subject: [PATCH] channeldb: fix DisconnectBlockAtHeight bug for zero-conf channels When a block is disconnected due to a reorg, DisconnectBlockAtHeight is called for the block height. Prior to this patch, it would delete every SCID in the graph with a block height greater than the disconnected height. This meant that a reorg would delete every zero-conf channel edge from the graph. The fix simply iterates up until the StartingAlias and deletes every SCID between the disconnected height and the StartingAlias height. --- channeldb/graph.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index 957c0b828..1e6dbf8d6 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -20,6 +20,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" + "github.com/lightningnetwork/lnd/aliasmgr" "github.com/lightningnetwork/lnd/batch" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnwire" @@ -1525,12 +1526,10 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf BlockHeight: height, } - // Delete everything after this height from the db. - endShortChanID := lnwire.ShortChannelID{ - BlockHeight: math.MaxUint32 & 0x00ffffff, - TxIndex: math.MaxUint32 & 0x00ffffff, - TxPosition: math.MaxUint16, - } + // Delete everything after this height from the db up until the + // SCID alias range. + endShortChanID := aliasmgr.StartingAlias + // The block height will be the 3 first bytes of the channel IDs. var chanIDStart [8]byte byteOrder.PutUint64(chanIDStart[:], startShortChanID.ToUint64()) @@ -1569,11 +1568,14 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf // found edge. // NOTE: we must delete the edges after the cursor loop, since // modifying the bucket while traversing is not safe. + // NOTE: We use a < comparison in bytes.Compare instead of <= + // so that the StartingAlias itself isn't deleted. var keys [][]byte cursor := edgeIndex.ReadWriteCursor() - for k, v := cursor.Seek(chanIDStart[:]); k != nil && - bytes.Compare(k, chanIDEnd[:]) <= 0; k, v = cursor.Next() { + //nolint:lll + for k, v := cursor.Seek(chanIDStart[:]); k != nil && + bytes.Compare(k, chanIDEnd[:]) < 0; k, v = cursor.Next() { edgeInfoReader := bytes.NewReader(v) edgeInfo, err := deserializeChanEdgeInfo(edgeInfoReader) if err != nil {