Bitcoin Core  31.0.0
P2P Digital Currency
txgraph.h
Go to the documentation of this file.
1 // Copyright (c) The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <compare>
6 #include <cstdint>
7 #include <functional>
8 #include <memory>
9 #include <optional>
10 #include <utility>
11 #include <vector>
12 
13 #include <util/feefrac.h>
14 
15 #ifndef BITCOIN_TXGRAPH_H
16 #define BITCOIN_TXGRAPH_H
17 
18 static constexpr unsigned MAX_CLUSTER_COUNT_LIMIT{64};
19 
47 class TxGraph
48 {
49 public:
51  using GraphIndex = uint32_t;
52 
62  class Ref;
63 
64  enum class Level {
65  TOP,
66  MAIN
67  };
68 
70  virtual ~TxGraph() = default;
78  virtual void AddTransaction(Ref& arg, const FeePerWeight& feerate) noexcept = 0;
93  virtual void RemoveTransaction(const Ref& arg) noexcept = 0;
98  virtual void AddDependency(const Ref& parent, const Ref& child) noexcept = 0;
102  virtual void SetTransactionFee(const Ref& arg, int64_t fee) noexcept = 0;
103 
108  virtual bool DoWork(uint64_t max_cost) noexcept = 0;
109 
114  virtual void StartStaging() noexcept = 0;
116  virtual void AbortStaging() noexcept = 0;
118  virtual void CommitStaging() noexcept = 0;
120  virtual bool HaveStaging() const noexcept = 0;
121 
127  virtual bool IsOversized(Level level) noexcept = 0;
130  virtual bool Exists(const Ref& arg, Level level) noexcept = 0;
134  virtual FeePerWeight GetIndividualFeerate(const Ref& arg) noexcept = 0;
138  virtual FeePerWeight GetMainChunkFeerate(const Ref& arg) noexcept = 0;
142  virtual std::vector<Ref*> GetCluster(const Ref& arg, Level level) noexcept = 0;
146  virtual std::vector<Ref*> GetAncestors(const Ref& arg, Level level) noexcept = 0;
150  virtual std::vector<Ref*> GetDescendants(const Ref& arg, Level level) noexcept = 0;
154  virtual std::vector<Ref*> GetAncestorsUnion(std::span<const Ref* const> args, Level level) noexcept = 0;
158  virtual std::vector<Ref*> GetDescendantsUnion(std::span<const Ref* const> args, Level level) noexcept = 0;
161  virtual GraphIndex GetTransactionCount(Level level) noexcept = 0;
164  virtual std::strong_ordering CompareMainOrder(const Ref& a, const Ref& b) noexcept = 0;
168  virtual GraphIndex CountDistinctClusters(std::span<const Ref* const>, Level level) noexcept = 0;
173  virtual std::pair<std::vector<FeeFrac>, std::vector<FeeFrac>> GetMainStagingDiagrams() noexcept = 0;
178  virtual std::vector<Ref*> Trim() noexcept = 0;
179 
182  {
183  protected:
185  BlockBuilder() noexcept = default;
186  public:
188  virtual ~BlockBuilder() = default;
190  virtual std::optional<std::pair<std::vector<Ref*>, FeePerWeight>> GetCurrentChunk() noexcept = 0;
192  virtual void Include() noexcept = 0;
195  virtual void Skip() noexcept = 0;
196  };
197 
201  virtual std::unique_ptr<BlockBuilder> GetBlockBuilder() noexcept = 0;
206  virtual std::pair<std::vector<Ref*>, FeePerWeight> GetWorstMainChunk() noexcept = 0;
207 
213  virtual size_t GetMainMemoryUsage() noexcept = 0;
214 
216  virtual void SanityCheck() const = 0;
217 
218 protected:
219  // Allow TxGraph::Ref to call UpdateRef and UnlinkRef.
220  friend class TxGraph::Ref;
222  virtual void UpdateRef(GraphIndex index, Ref& new_location) noexcept = 0;
224  virtual void UnlinkRef(GraphIndex index) noexcept = 0;
225  // Allow TxGraph implementations (inheriting from it) to access Ref internals.
226  static TxGraph*& GetRefGraph(Ref& arg) noexcept { return arg.m_graph; }
227  static TxGraph* GetRefGraph(const Ref& arg) noexcept { return arg.m_graph; }
228  static GraphIndex& GetRefIndex(Ref& arg) noexcept { return arg.m_index; }
229  static GraphIndex GetRefIndex(const Ref& arg) noexcept { return arg.m_index; }
230 
231 public:
232  class Ref
233  {
234  // Allow TxGraph's GetRefGraph and GetRefIndex to access internals.
235  friend class TxGraph;
237  TxGraph* m_graph = nullptr;
240  public:
242  Ref() noexcept = default;
245  virtual ~Ref();
246  // Support move-constructing a Ref.
247  Ref& operator=(Ref&& other) noexcept = delete;
248  Ref(Ref&& other) noexcept;
249  // Do not permit copy constructing or copy assignment. A TxGraph entry can have at most one
250  // Ref pointing to it.
251  Ref& operator=(const Ref&) = delete;
252  Ref(const Ref&) = delete;
253  };
254 };
255 
266 std::unique_ptr<TxGraph> MakeTxGraph(
267  unsigned max_cluster_count,
268  uint64_t max_cluster_size,
269  uint64_t acceptable_cost,
270  const std::function<std::strong_ordering(const TxGraph::Ref&, const TxGraph::Ref&)>& fallback_order
271 ) noexcept;
272 
273 #endif // BITCOIN_TXGRAPH_H
Always refers to the main graph, whether staging is present or not.
static constexpr unsigned MAX_CLUSTER_COUNT_LIMIT
Definition: txgraph.h:18
static GraphIndex & GetRefIndex(Ref &arg) noexcept
Definition: txgraph.h:228
virtual void UnlinkRef(GraphIndex index) noexcept=0
Inform the TxGraph implementation that a TxGraph::Ref was destroyed.
virtual void AbortStaging() noexcept=0
Discard the existing active staging graph (which must exist).
static TxGraph *& GetRefGraph(Ref &arg) noexcept
Definition: txgraph.h:226
virtual std::strong_ordering CompareMainOrder(const Ref &a, const Ref &b) noexcept=0
Compare two transactions according to their order in the main graph.
virtual std::unique_ptr< BlockBuilder > GetBlockBuilder() noexcept=0
Construct a block builder, drawing chunks in order, from the main graph, which cannot be oversized...
Definition: common.h:29
GraphIndex m_index
Index into the Graph&#39;s m_entries.
Definition: txgraph.h:239
virtual std::vector< Ref * > GetDescendantsUnion(std::span< const Ref *const > args, Level level) noexcept=0
Like GetDescendants, but return the Refs for all transactions in the union of the provided arguments&#39;...
virtual size_t GetMainMemoryUsage() noexcept=0
Get the approximate memory usage for this object, just counting the main graph.
Tagged wrapper around FeeFrac to avoid unit confusion.
Definition: feefrac.h:238
virtual void UpdateRef(GraphIndex index, Ref &new_location) noexcept=0
Inform the TxGraph implementation that a TxGraph::Ref has moved.
virtual void AddTransaction(Ref &arg, const FeePerWeight &feerate) noexcept=0
Initialize arg (which must be an empty Ref) to refer to a new transaction in this graph with the spec...
virtual void SetTransactionFee(const Ref &arg, int64_t fee) noexcept=0
Modify the fee of the specified transaction, in both the main graph and the staging graph if it exist...
TxGraph * m_graph
Which Graph the Entry lives in.
Definition: txgraph.h:237
Data structure to encapsulate fees, sizes, and dependencies for a set of transactions.
Definition: txgraph.h:47
Interface returned by GetBlockBuilder.
Definition: txgraph.h:181
virtual void CommitStaging() noexcept=0
Replace the main graph with the staging graph (which must exist).
ArgsManager & args
Definition: bitcoind.cpp:277
Ref() noexcept=default
Construct an empty Ref.
virtual FeePerWeight GetIndividualFeerate(const Ref &arg) noexcept=0
Get the individual transaction feerate of transaction arg.
virtual ~TxGraph()=default
Virtual destructor, so inheriting is safe.
virtual std::pair< std::vector< Ref * >, FeePerWeight > GetWorstMainChunk() noexcept=0
Get the last chunk in the main graph, i.e., the last chunk that would be returned by a BlockBuilder c...
virtual std::vector< Ref * > Trim() noexcept=0
Remove transactions (including their own descendants) according to a fast but best-effort strategy su...
uint32_t GraphIndex
Internal identifier for a transaction within a TxGraph.
Definition: txgraph.h:51
virtual void RemoveTransaction(const Ref &arg) noexcept=0
Remove the specified transaction.
virtual bool DoWork(uint64_t max_cost) noexcept=0
TxGraph is internally lazy, and will not compute many things until they are needed.
virtual void SanityCheck() const =0
Perform an internal consistency check on this object.
virtual std::pair< std::vector< FeeFrac >, std::vector< FeeFrac > > GetMainStagingDiagrams() noexcept=0
For both main and staging (which must both exist and not be oversized), return the combined respectiv...
static TxGraph * GetRefGraph(const Ref &arg) noexcept
Definition: txgraph.h:227
virtual std::vector< Ref * > GetDescendants(const Ref &arg, Level level) noexcept=0
Get pointers to all descendants of the specified transaction (including the transaction itself)...
virtual FeePerWeight GetMainChunkFeerate(const Ref &arg) noexcept=0
Get the feerate of the chunk which transaction arg is in, in the main graph.
Data structure storing a fee and size, ordered by increasing fee/size.
Definition: feefrac.h:39
virtual void StartStaging() noexcept=0
Create a staging graph (which cannot exist already).
virtual GraphIndex CountDistinctClusters(std::span< const Ref *const >, Level level) noexcept=0
Count the number of distinct clusters that the specified transactions belong to.
virtual std::vector< Ref * > GetAncestors(const Ref &arg, Level level) noexcept=0
Get pointers to all ancestors of the specified transaction (including the transaction itself)...
virtual bool IsOversized(Level level) noexcept=0
Determine whether the graph is oversized (contains a connected component of more than the configured ...
virtual GraphIndex GetTransactionCount(Level level) noexcept=0
Get the total number of transactions in the graph.
virtual void AddDependency(const Ref &parent, const Ref &child) noexcept=0
Add a dependency between two specified transactions.
virtual bool Exists(const Ref &arg, Level level) noexcept=0
Determine whether arg exists in the graph (i.e., was not removed).
virtual std::vector< Ref * > GetCluster(const Ref &arg, Level level) noexcept=0
Get pointers to all transactions in the cluster which arg is in.
std::unique_ptr< TxGraph > MakeTxGraph(unsigned max_cluster_count, uint64_t max_cluster_size, uint64_t acceptable_cost, const std::function< std::strong_ordering(const TxGraph::Ref &, const TxGraph::Ref &)> &fallback_order) noexcept
Construct a new TxGraph with the specified limit on the number of transactions within a cluster...
Definition: txgraph.cpp:3570
virtual std::vector< Ref * > GetAncestorsUnion(std::span< const Ref *const > args, Level level) noexcept=0
Like GetAncestors, but return the Refs for all transactions in the union of the provided arguments&#39; a...
Refers to staging if it exists, main otherwise.
virtual bool HaveStaging() const noexcept=0
Check whether a staging graph exists.
uint64_t fee
static GraphIndex GetRefIndex(const Ref &arg) noexcept
Definition: txgraph.h:229