v30.3-roots.1 · Commit 3: [PATCH 03/68] feat(policy): preserve Roots relay and network controls on Core 30.3
src/kernel/mempool_entry.h
Before: src/kernel/mempool_entry.h · After: src/kernel/mempool_entry.h
File metadata
index 51a1f26642f48f18de71026ccd598b505a1b399e..ee0f360e3c183e5e58e9b143d7bcf25434f1aa00 100644
Download original patch · Release notes
Diff rows 1–166 of 166. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/kernel/mempool_entry.h
CHANGED
|
@@ -8,12 +8,14 @@
|
|
| 8 |
#include <consensus/amount.h>
|
| 9 |
#include <consensus/validation.h>
|
| 10 |
#include <core_memusage.h>
|
|
|
|
| 11 |
#include <policy/policy.h>
|
| 12 |
#include <policy/settings.h>
|
| 13 |
#include <primitives/transaction.h>
|
| 14 |
#include <util/epochguard.h>
|
| 15 |
#include <util/overflow.h>
|
| 16 |
|
|
|
|
| 17 |
#include <chrono>
|
| 18 |
#include <cstddef>
|
| 19 |
#include <cstdint>
|
|
@@ -35,6 +37,15 @@ struct LockPoints {
|
|
| 35 |
CBlockIndex* maxInputBlock{nullptr};
|
| 36 |
};
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
struct CompareIteratorByHash {
|
| 39 |
// SFINAE for T where T is either a pointer type (e.g., a txiter) or a reference_wrapper<T>
|
| 40 |
// (e.g. a wrapped CTxMemPoolEntry&)
|
|
@@ -84,9 +95,15 @@ private:
|
|
| 84 |
const size_t nUsageSize; //!< ... and total memory usage
|
| 85 |
const int64_t nTime; //!< Local time when entering the mempool
|
| 86 |
const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
const unsigned int entryHeight; //!< Chain height when entering the mempool
|
|
|
|
|
|
|
|
|
|
| 88 |
const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase
|
| 89 |
-
const int64_t sigOpCost; //!< Total sigop cost
|
| 90 |
CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block
|
| 91 |
mutable LockPoints lockPoints; //!< Track the height and time at which tx was final
|
| 92 |
|
|
@@ -108,7 +125,9 @@ private:
|
|
| 108 |
public:
|
| 109 |
CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
|
| 110 |
int64_t time, unsigned int entry_height, uint64_t entry_sequence,
|
|
|
|
| 111 |
bool spends_coinbase,
|
|
|
|
| 112 |
int64_t sigops_cost, LockPoints lp)
|
| 113 |
: tx{tx},
|
| 114 |
nFee{fee},
|
|
@@ -116,16 +135,32 @@ public:
|
|
| 116 |
nUsageSize{RecursiveDynamicUsage(tx)},
|
| 117 |
nTime{time},
|
| 118 |
entry_sequence{entry_sequence},
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
entryHeight{entry_height},
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
spendsCoinbase{spends_coinbase},
|
| 121 |
-
sigOpCost{sigops_cost},
|
| 122 |
m_modified_fee{nFee},
|
| 123 |
lockPoints{lp},
|
| 124 |
nSizeWithDescendants{GetTxSize()},
|
| 125 |
nModFeesWithDescendants{nFee},
|
| 126 |
nSizeWithAncestors{GetTxSize()},
|
| 127 |
nModFeesWithAncestors{nFee},
|
| 128 |
-
nSigOpCostWithAncestors{sigOpCost} {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
CTxMemPoolEntry(ExplicitCopyTag, const CTxMemPoolEntry& entry) : CTxMemPoolEntry(entry) {}
|
| 131 |
CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
|
|
@@ -136,18 +171,36 @@ public:
|
|
| 136 |
|
| 137 |
const CTransaction& GetTx() const { return *this->tx; }
|
| 138 |
CTransactionRef GetSharedTx() const { return this->tx; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
const CAmount& GetFee() const { return nFee; }
|
| 140 |
int32_t GetTxSize() const
|
| 141 |
{
|
| 142 |
-
return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
|
| 143 |
}
|
| 144 |
int32_t GetTxWeight() const { return nTxWeight; }
|
| 145 |
std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
|
| 146 |
unsigned int GetHeight() const { return entryHeight; }
|
| 147 |
uint64_t GetSequence() const { return entry_sequence; }
|
|
|
|
| 148 |
int64_t GetSigOpCost() const { return sigOpCost; }
|
| 149 |
CAmount GetModifiedFee() const { return m_modified_fee; }
|
| 150 |
-
size_t DynamicMemoryUsage() const { return nUsageSize; }
|
| 151 |
const LockPoints& GetLockPoints() const { return lockPoints; }
|
| 152 |
|
| 153 |
// Adjusts the descendant state.
|
|
@@ -186,6 +239,8 @@ public:
|
|
| 186 |
|
| 187 |
mutable size_t idx_randomized; //!< Index in mempool's txns_randomized
|
| 188 |
mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms
|
|
|
|
|
|
|
| 189 |
};
|
| 190 |
|
| 191 |
using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
|
|
@@ -226,7 +281,7 @@ struct NewMempoolTransactionInfo {
|
|
| 226 |
* This boolean indicates whether the transaction was added
|
| 227 |
* without enforcing mempool fee limits.
|
| 228 |
*/
|
| 229 |
-
const bool m_mempool_limit_bypassed;
|
| 230 |
/* This boolean indicates whether the transaction is part of a package. */
|
| 231 |
const bool m_submitted_in_package;
|
| 232 |
/*
|
|
@@ -239,14 +294,22 @@ struct NewMempoolTransactionInfo {
|
|
| 239 |
|
| 240 |
explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
|
| 241 |
const int64_t vsize, const unsigned int height,
|
| 242 |
-
const bool mempool_limit_bypassed, const bool submitted_in_package,
|
| 243 |
const bool chainstate_is_current,
|
| 244 |
const bool has_no_mempool_parents)
|
| 245 |
: info{tx, fee, vsize, height},
|
| 246 |
-
m_mempool_limit_bypassed{mempool_limit_bypassed},
|
| 247 |
m_submitted_in_package{submitted_in_package},
|
| 248 |
m_chainstate_is_current{chainstate_is_current},
|
| 249 |
m_has_no_mempool_parents{has_no_mempool_parents} {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
};
|
| 251 |
|
| 252 |
#endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H
|
|
|
|
| 8 |
#include <consensus/amount.h>
|
| 9 |
#include <consensus/validation.h>
|
| 10 |
#include <core_memusage.h>
|
| 11 |
+
#include <policy/coin_age_priority.h>
|
| 12 |
#include <policy/policy.h>
|
| 13 |
#include <policy/settings.h>
|
| 14 |
#include <primitives/transaction.h>
|
| 15 |
#include <util/epochguard.h>
|
| 16 |
#include <util/overflow.h>
|
| 17 |
|
| 18 |
+
#include <cassert>
|
| 19 |
#include <chrono>
|
| 20 |
#include <cstddef>
|
| 21 |
#include <cstdint>
|
|
|
|
| 37 |
CBlockIndex* maxInputBlock{nullptr};
|
| 38 |
};
|
| 39 |
|
| 40 |
+
enum MemPool_SPK_State {
|
| 41 |
+
MSS_UNSEEN = 0,
|
| 42 |
+
MSS_SPENT = 1, // .second
|
| 43 |
+
MSS_CREATED = 2, // .first
|
| 44 |
+
MSS_BOTH = 3,
|
| 45 |
+
};
|
| 46 |
+
|
| 47 |
+
typedef std::map<uint160, enum MemPool_SPK_State> SPKStates_t;
|
| 48 |
+
|
| 49 |
struct CompareIteratorByHash {
|
| 50 |
// SFINAE for T where T is either a pointer type (e.g., a txiter) or a reference_wrapper<T>
|
| 51 |
// (e.g. a wrapped CTxMemPoolEntry&)
|
|
|
|
| 95 |
const size_t nUsageSize; //!< ... and total memory usage
|
| 96 |
const int64_t nTime; //!< Local time when entering the mempool
|
| 97 |
const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay
|
| 98 |
+
const int64_t sigOpCost; //!< Total sigop cost
|
| 99 |
+
const int32_t m_extra_weight; //!< Policy-only additional transaction weight beyond nTxWeight
|
| 100 |
+
const size_t nModSize; //!< Cached modified size for priority
|
| 101 |
+
const double entryPriority; //!< Priority when entering the mempool
|
| 102 |
const unsigned int entryHeight; //!< Chain height when entering the mempool
|
| 103 |
+
double cachedPriority; //!< Last calculated priority
|
| 104 |
+
unsigned int cachedHeight; //!< Height at which priority was last calculated
|
| 105 |
+
CAmount inChainInputValue; //!< Sum of all txin values that are already in blockchain
|
| 106 |
const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase
|
|
|
|
| 107 |
CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block
|
| 108 |
mutable LockPoints lockPoints; //!< Track the height and time at which tx was final
|
| 109 |
|
|
|
|
| 125 |
public:
|
| 126 |
CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
|
| 127 |
int64_t time, unsigned int entry_height, uint64_t entry_sequence,
|
| 128 |
+
CoinAgeCache coin_age_cache,
|
| 129 |
bool spends_coinbase,
|
| 130 |
+
int32_t extra_weight,
|
| 131 |
int64_t sigops_cost, LockPoints lp)
|
| 132 |
: tx{tx},
|
| 133 |
nFee{fee},
|
|
|
|
| 135 |
nUsageSize{RecursiveDynamicUsage(tx)},
|
| 136 |
nTime{time},
|
| 137 |
entry_sequence{entry_sequence},
|
| 138 |
+
sigOpCost{sigops_cost},
|
| 139 |
+
m_extra_weight{extra_weight},
|
| 140 |
+
nModSize{CalculateModifiedSize(*tx, GetTxSize())},
|
| 141 |
+
entryPriority{ComputePriority2(coin_age_cache.inputs_coin_age, nModSize)},
|
| 142 |
entryHeight{entry_height},
|
| 143 |
+
cachedPriority{entryPriority},
|
| 144 |
+
// Since entries arrive *after* the tip's height, their entry priority is for the height+1
|
| 145 |
+
cachedHeight{entry_height + 1},
|
| 146 |
+
inChainInputValue{coin_age_cache.in_chain_input_value},
|
| 147 |
spendsCoinbase{spends_coinbase},
|
|
|
|
| 148 |
m_modified_fee{nFee},
|
| 149 |
lockPoints{lp},
|
| 150 |
nSizeWithDescendants{GetTxSize()},
|
| 151 |
nModFeesWithDescendants{nFee},
|
| 152 |
nSizeWithAncestors{GetTxSize()},
|
| 153 |
nModFeesWithAncestors{nFee},
|
| 154 |
+
nSigOpCostWithAncestors{sigOpCost} {
|
| 155 |
+
CAmount nValueIn = tx->GetValueOut() + nFee;
|
| 156 |
+
assert(inChainInputValue <= nValueIn);
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
|
| 160 |
+
int64_t time, unsigned int entry_height, uint64_t entry_sequence,
|
| 161 |
+
bool spends_coinbase, int64_t sigops_cost, LockPoints lp)
|
| 162 |
+
: CTxMemPoolEntry(tx, fee, time, entry_height, entry_sequence, COIN_AGE_CACHE_ZERO,
|
| 163 |
+
spends_coinbase, /*extra_weight=*/0, sigops_cost, lp) {}
|
| 164 |
|
| 165 |
CTxMemPoolEntry(ExplicitCopyTag, const CTxMemPoolEntry& entry) : CTxMemPoolEntry(entry) {}
|
| 166 |
CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
|
|
|
|
| 171 |
|
| 172 |
const CTransaction& GetTx() const { return *this->tx; }
|
| 173 |
CTransactionRef GetSharedTx() const { return this->tx; }
|
| 174 |
+
double GetStartingPriority() const {return entryPriority; }
|
| 175 |
+
CoinAgeCache GetInternalCoinAgeCache() const {
|
| 176 |
+
return {
|
| 177 |
+
.inputs_coin_age = ReversePriority2(cachedPriority, nModSize),
|
| 178 |
+
.in_chain_input_value = inChainInputValue,
|
| 179 |
+
};
|
| 180 |
+
}
|
| 181 |
+
/**
|
| 182 |
+
* Fast calculation of priority as update from cached value, but only valid if
|
| 183 |
+
* currentHeight is greater than last height it was recalculated.
|
| 184 |
+
*/
|
| 185 |
+
double GetPriority(unsigned int currentHeight) const;
|
| 186 |
+
/**
|
| 187 |
+
* Recalculate the cached priority as of currentHeight and adjust inChainInputValue by
|
| 188 |
+
* valueInCurrentBlock which represents input that was just added to or removed from the blockchain.
|
| 189 |
+
*/
|
| 190 |
+
void UpdateCachedPriority(unsigned int currentHeight, CAmount valueInCurrentBlock);
|
| 191 |
const CAmount& GetFee() const { return nFee; }
|
| 192 |
int32_t GetTxSize() const
|
| 193 |
{
|
| 194 |
+
return GetVirtualTransactionSize(nTxWeight + m_extra_weight, sigOpCost, ::nBytesPerSigOp);
|
| 195 |
}
|
| 196 |
int32_t GetTxWeight() const { return nTxWeight; }
|
| 197 |
std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
|
| 198 |
unsigned int GetHeight() const { return entryHeight; }
|
| 199 |
uint64_t GetSequence() const { return entry_sequence; }
|
| 200 |
+
int32_t GetExtraWeight() const { return m_extra_weight; }
|
| 201 |
int64_t GetSigOpCost() const { return sigOpCost; }
|
| 202 |
CAmount GetModifiedFee() const { return m_modified_fee; }
|
| 203 |
+
size_t DynamicMemoryUsage() const { return nUsageSize + memusage::DynamicUsage(mapSPK); }
|
| 204 |
const LockPoints& GetLockPoints() const { return lockPoints; }
|
| 205 |
|
| 206 |
// Adjusts the descendant state.
|
|
|
|
| 239 |
|
| 240 |
mutable size_t idx_randomized; //!< Index in mempool's txns_randomized
|
| 241 |
mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms
|
| 242 |
+
|
| 243 |
+
SPKStates_t mapSPK;
|
| 244 |
};
|
| 245 |
|
| 246 |
using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
|
|
|
|
| 281 |
* This boolean indicates whether the transaction was added
|
| 282 |
* without enforcing mempool fee limits.
|
| 283 |
*/
|
| 284 |
+
const ignore_rejects_type m_ignore_rejects;
|
| 285 |
/* This boolean indicates whether the transaction is part of a package. */
|
| 286 |
const bool m_submitted_in_package;
|
| 287 |
/*
|
|
|
|
| 294 |
|
| 295 |
explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
|
| 296 |
const int64_t vsize, const unsigned int height,
|
| 297 |
+
const ignore_rejects_type& ignore_rejects, const bool submitted_in_package,
|
| 298 |
const bool chainstate_is_current,
|
| 299 |
const bool has_no_mempool_parents)
|
| 300 |
: info{tx, fee, vsize, height},
|
| 301 |
+
m_ignore_rejects{ignore_rejects},
|
| 302 |
m_submitted_in_package{submitted_in_package},
|
| 303 |
m_chainstate_is_current{chainstate_is_current},
|
| 304 |
m_has_no_mempool_parents{has_no_mempool_parents} {}
|
| 305 |
+
|
| 306 |
+
NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
|
| 307 |
+
const int64_t vsize, const unsigned int height,
|
| 308 |
+
const bool mempool_limit_bypassed, const bool submitted_in_package,
|
| 309 |
+
const bool chainstate_is_current, const bool has_no_mempool_parents)
|
| 310 |
+
: NewMempoolTransactionInfo(tx, fee, vsize, height,
|
| 311 |
+
empty_ignore_rejects,
|
| 312 |
+
submitted_in_package, chainstate_is_current, has_no_mempool_parents) {}
|
| 313 |
};
|
| 314 |
|
| 315 |
#endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H
|