txgraph: Destroying Ref means removing transaction (feature)

Before this commit, if a TxGraph::Ref object is destroyed, it becomes impossible
to refer to, but the actual corresponding transaction node in the TxGraph remains,
and remains indefinitely as there is no way to remove it.

Fix this by making the destruction of TxGraph::Ref trigger immediate removal of
the corresponding transaction in TxGraph, both in main and staging if it exists.
This commit is contained in:
Pieter Wuille
2024-12-03 11:25:49 -05:00
parent 6b037ceddf
commit 82fa3573e1
3 changed files with 179 additions and 71 deletions

View File

@@ -50,7 +50,8 @@ public:
/** Data type used to reference transactions within a TxGraph.
*
* Every transaction within a TxGraph has exactly one corresponding TxGraph::Ref, held by users
* of the class. Refs can only be destroyed after the transaction is removed from the graph.
* of the class. Destroying the TxGraph::Ref removes the corresponding transaction (in both the
* main and staging graphs).
*
* Users of the class can inherit from TxGraph::Ref. If all Refs are inherited this way, the
* Ref* pointers returned by TxGraph functions can be cast to, and used as, this inherited type.
@@ -104,7 +105,9 @@ public:
/** Determine whether the graph is oversized (contains a connected component of more than the
* configured maximum cluster count). If main_only is false and a staging graph exists, it is
* queried; otherwise the main graph is queried. Some of the functions below are not available
* for oversized graphs. The mutators above are always available. */
* for oversized graphs. The mutators above are always available. Removing a transaction by
* destroying its Ref while staging exists will not clear main's oversizedness until staging
* is aborted or committed. */
virtual bool IsOversized(bool main_only = false) noexcept = 0;
/** Determine whether arg exists in the graph (i.e., was not removed). If main_only is false
* and a staging graph exists, it is queried; otherwise the main graph is queried. This is
@@ -167,8 +170,8 @@ public:
/** Construct an empty Ref. Non-empty Refs can only be created using
* TxGraph::AddTransaction. */
Ref() noexcept = default;
/** Destroy this Ref. This is only allowed when it is empty, or the transaction it refers
* to does not exist in the graph (in main nor staging). */
/** Destroy this Ref. If it is not empty, the corresponding transaction is removed (in both
* main and staging, if it exists). */
virtual ~Ref();
// Support moving a Ref.
Ref& operator=(Ref&& other) noexcept;