channeldb: extend DeleteChannelEdge to mark edge as zombie
We mark the edges as zombies when pruning them to ensure we don't attempt to reprocess them later on. This also applies to channels that have been removed from the graph due to being stale.
This commit is contained in:
parent
b780dfacdb
commit
e98f4d6d9d
@ -728,6 +728,10 @@ func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint,
|
|||||||
if nodes == nil {
|
if nodes == nil {
|
||||||
return ErrSourceNodeNotSet
|
return ErrSourceNodeNotSet
|
||||||
}
|
}
|
||||||
|
zombieIndex, err := edges.CreateBucketIfNotExists(zombieBucket)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// For each of the outpoints that have been spent within the
|
// For each of the outpoints that have been spent within the
|
||||||
// block, we attempt to delete them from the graph as if that
|
// block, we attempt to delete them from the graph as if that
|
||||||
@ -761,7 +765,8 @@ func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint,
|
|||||||
// a channel. If no error is returned, then a channel
|
// a channel. If no error is returned, then a channel
|
||||||
// was successfully pruned.
|
// was successfully pruned.
|
||||||
err = delChannelByEdge(
|
err = delChannelByEdge(
|
||||||
edges, edgeIndex, chanIndex, nodes, chanPoint,
|
edges, edgeIndex, chanIndex, zombieIndex, nodes,
|
||||||
|
chanPoint, false,
|
||||||
)
|
)
|
||||||
if err != nil && err != ErrEdgeNotFound {
|
if err != nil && err != ErrEdgeNotFound {
|
||||||
return err
|
return err
|
||||||
@ -971,6 +976,10 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
zombieIndex, err := edges.CreateBucketIfNotExists(zombieBucket)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
nodes, err := tx.CreateBucketIfNotExists(nodeBucket)
|
nodes, err := tx.CreateBucketIfNotExists(nodeBucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -988,7 +997,8 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = delChannelByEdge(
|
err = delChannelByEdge(
|
||||||
edges, edgeIndex, chanIndex, nodes, &edgeInfo.ChannelPoint,
|
edges, edgeIndex, chanIndex, zombieIndex, nodes,
|
||||||
|
&edgeInfo.ChannelPoint, false,
|
||||||
)
|
)
|
||||||
if err != nil && err != ErrEdgeNotFound {
|
if err != nil && err != ErrEdgeNotFound {
|
||||||
return err
|
return err
|
||||||
@ -1075,8 +1085,9 @@ func (c *ChannelGraph) PruneTip() (*chainhash.Hash, uint32, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeleteChannelEdge removes an edge from the database as identified by its
|
// DeleteChannelEdge removes an edge from the database as identified by its
|
||||||
// funding outpoint. If the edge does not exist within the database, then
|
// funding outpoint and also marks it as a zombie. This ensures that we're
|
||||||
// ErrEdgeNotFound will be returned.
|
// unable to re-add this to our database once again. If the edge does not exist
|
||||||
|
// within the database, then ErrEdgeNotFound will be returned.
|
||||||
func (c *ChannelGraph) DeleteChannelEdge(chanPoint *wire.OutPoint) error {
|
func (c *ChannelGraph) DeleteChannelEdge(chanPoint *wire.OutPoint) error {
|
||||||
// TODO(roasbeef): possibly delete from node bucket if node has no more
|
// TODO(roasbeef): possibly delete from node bucket if node has no more
|
||||||
// channels
|
// channels
|
||||||
@ -1096,19 +1107,22 @@ func (c *ChannelGraph) DeleteChannelEdge(chanPoint *wire.OutPoint) error {
|
|||||||
if edgeIndex == nil {
|
if edgeIndex == nil {
|
||||||
return ErrEdgeNotFound
|
return ErrEdgeNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
chanIndex := edges.Bucket(channelPointBucket)
|
chanIndex := edges.Bucket(channelPointBucket)
|
||||||
if chanIndex == nil {
|
if chanIndex == nil {
|
||||||
return ErrEdgeNotFound
|
return ErrEdgeNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes := tx.Bucket(nodeBucket)
|
nodes := tx.Bucket(nodeBucket)
|
||||||
if nodes == nil {
|
if nodes == nil {
|
||||||
return ErrGraphNodeNotFound
|
return ErrGraphNodeNotFound
|
||||||
}
|
}
|
||||||
|
zombieIndex, err := edges.CreateBucketIfNotExists(zombieBucket)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return delChannelByEdge(
|
return delChannelByEdge(
|
||||||
edges, edgeIndex, chanIndex, nodes, chanPoint,
|
edges, edgeIndex, chanIndex, zombieIndex, nodes,
|
||||||
|
chanPoint, true,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1579,8 +1593,9 @@ func delEdgeUpdateIndexEntry(edgesBucket *bbolt.Bucket, chanID uint64,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func delChannelByEdge(edges *bbolt.Bucket, edgeIndex *bbolt.Bucket,
|
func delChannelByEdge(edges, edgeIndex, chanIndex, zombieIndex,
|
||||||
chanIndex *bbolt.Bucket, nodes *bbolt.Bucket, chanPoint *wire.OutPoint) error {
|
nodes *bbolt.Bucket, chanPoint *wire.OutPoint, isZombie bool) error {
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
if err := writeOutpoint(&b, chanPoint); err != nil {
|
if err := writeOutpoint(&b, chanPoint); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1638,12 +1653,29 @@ func delChannelByEdge(edges *bbolt.Bucket, edgeIndex *bbolt.Bucket,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, with the edge data deleted, we can purge the information
|
// With the edge data deleted, we can purge the information from the two
|
||||||
// from the two edge indexes.
|
// edge indexes.
|
||||||
if err := edgeIndex.Delete(chanID); err != nil {
|
if err := edgeIndex.Delete(chanID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return chanIndex.Delete(b.Bytes())
|
if err := chanIndex.Delete(b.Bytes()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, we'll mark the edge as a zombie within our index if it's
|
||||||
|
// being removed due to the channel becoming a zombie. We do this to
|
||||||
|
// ensure we don't store unnecessary data for spent channels.
|
||||||
|
if !isZombie {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var pubKey1, pubKey2 [33]byte
|
||||||
|
copy(pubKey1[:], nodeKeys[:33])
|
||||||
|
copy(pubKey2[:], nodeKeys[33:])
|
||||||
|
|
||||||
|
return markEdgeZombie(
|
||||||
|
zombieIndex, byteOrder.Uint64(chanID), pubKey1, pubKey2,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateEdgePolicy updates the edge routing policy for a single directed edge
|
// UpdateEdgePolicy updates the edge routing policy for a single directed edge
|
||||||
|
@ -374,6 +374,10 @@ func TestEdgeInsertionDeletion(t *testing.T) {
|
|||||||
if _, _, _, err := graph.FetchChannelEdgesByID(chanID); err == nil {
|
if _, _, _, err := graph.FetchChannelEdgesByID(chanID); err == nil {
|
||||||
t.Fatalf("channel edge not deleted")
|
t.Fatalf("channel edge not deleted")
|
||||||
}
|
}
|
||||||
|
isZombie, _, _ := graph.IsZombieEdge(chanID)
|
||||||
|
if !isZombie {
|
||||||
|
t.Fatal("channel edge not marked as zombie")
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, attempt to delete a (now) non-existent edge within the
|
// Finally, attempt to delete a (now) non-existent edge within the
|
||||||
// database, this should result in an error.
|
// database, this should result in an error.
|
||||||
|
Loading…
Reference in New Issue
Block a user