v31.1-roots.1 · Commit 3: [PATCH 03/17] feat(policy): preserve cluster accounting and repair dynamic dust
src/txmempool.cpp
Before: src/txmempool.cpp · After: src/txmempool.cpp
File metadata
index bfff181683277273582787bd40b1700fae115ae8..e9456994b4cb2985a490596e2a444b04a1f513a3 100644
Download original patch · Release notes
Diff rows 1–236 of 236. 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/txmempool.cpp
CHANGED
|
@@ -37,6 +37,14 @@
|
|
| 37 |
TRACEPOINT_SEMAPHORE(mempool, added);
|
| 38 |
TRACEPOINT_SEMAPHORE(mempool, removed);
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp)
|
| 41 |
{
|
| 42 |
AssertLockHeld(cs_main);
|
|
@@ -174,7 +182,7 @@ static CTxMemPool::Options&& Flatten(CTxMemPool::Options&& opts, bilingual_str&
|
|
| 174 |
}
|
| 175 |
|
| 176 |
CTxMemPool::CTxMemPool(Options opts, bilingual_str& error)
|
| 177 |
-
: m_opts{Flatten(std::move(opts), error)}
|
| 178 |
{
|
| 179 |
m_txgraph = MakeTxGraph(
|
| 180 |
/*max_cluster_count=*/m_opts.limits.cluster_count,
|
|
@@ -187,6 +195,43 @@ CTxMemPool::CTxMemPool(Options opts, bilingual_str& error)
|
|
| 187 |
});
|
| 188 |
}
|
| 189 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
bool CTxMemPool::isSpent(const COutPoint& outpoint) const
|
| 191 |
{
|
| 192 |
LOCK(cs);
|
|
@@ -246,9 +291,17 @@ void CTxMemPool::addNewTransaction(CTxMemPool::txiter newit)
|
|
| 246 |
// In that case, our disconnect block logic will call UpdateTransactionsFromBlock
|
| 247 |
// to clean up the mess we're leaving here.
|
| 248 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
nTransactionsUpdated++;
|
| 250 |
totalTxSize += entry.GetTxSize();
|
| 251 |
m_total_fee += entry.GetFee();
|
|
|
|
|
|
|
| 252 |
|
| 253 |
txns_randomized.emplace_back(tx.GetWitnessHash(), newit);
|
| 254 |
newit->idx_randomized = txns_randomized.size() - 1;
|
|
@@ -298,8 +351,17 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
|
|
| 298 |
txns_randomized.clear();
|
| 299 |
}
|
| 300 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 301 |
totalTxSize -= it->GetTxSize();
|
| 302 |
m_total_fee -= it->GetFee();
|
|
|
|
|
|
|
| 303 |
cachedInnerUsage -= it->DynamicMemoryUsage();
|
| 304 |
mapTx.erase(it);
|
| 305 |
nTransactionsUpdated++;
|
|
@@ -442,6 +504,8 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
|
|
| 442 |
|
| 443 |
uint64_t checkTotal = 0;
|
| 444 |
CAmount check_total_fee{0};
|
|
|
|
|
|
|
| 445 |
CAmount check_total_modified_fee{0};
|
| 446 |
int64_t check_total_adjusted_weight{0};
|
| 447 |
uint64_t innerUsage = 0;
|
|
@@ -477,6 +541,11 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
|
|
| 477 |
check_total_adjusted_weight += it->GetAdjustedWeight();
|
| 478 |
check_total_fee += it->GetFee();
|
| 479 |
check_total_modified_fee += it->GetModifiedFee();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 480 |
innerUsage += it->DynamicMemoryUsage();
|
| 481 |
const CTransaction& tx = it->GetTx();
|
| 482 |
|
|
@@ -548,6 +617,9 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
|
|
| 548 |
|
| 549 |
assert(totalTxSize == checkTotal);
|
| 550 |
assert(m_total_fee == check_total_fee);
|
|
|
|
|
|
|
|
|
|
| 551 |
assert(diagram.back().fee == check_total_modified_fee);
|
| 552 |
assert(diagram.back().size == check_total_adjusted_weight);
|
| 553 |
assert(innerUsage == cachedInnerUsage);
|
|
@@ -627,13 +699,43 @@ CTransactionRef CTxMemPool::get(const Txid& hash) const
|
|
| 627 |
return i->GetSharedTx();
|
| 628 |
}
|
| 629 |
|
| 630 |
-
void CTxMemPool::PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 631 |
{
|
| 632 |
{
|
| 633 |
LOCK(cs);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 634 |
CAmount &delta = mapDeltas[hash];
|
| 635 |
delta = SaturatingAdd(delta, nFeeDelta);
|
| 636 |
-
txiter it = mapTx.find(hash);
|
| 637 |
if (it != mapTx.end()) {
|
| 638 |
// PrioritiseTransaction calls stack on previous ones. Set the new
|
| 639 |
// transaction fee to be current modified fee + feedelta.
|
|
@@ -652,6 +754,7 @@ void CTxMemPool::PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelt
|
|
| 652 |
FormatMoney(delta));
|
| 653 |
}
|
| 654 |
}
|
|
|
|
| 655 |
}
|
| 656 |
|
| 657 |
void CTxMemPool::ApplyDelta(const Txid& hash, CAmount &nFeeDelta) const
|
|
@@ -661,7 +764,7 @@ void CTxMemPool::ApplyDelta(const Txid& hash, CAmount &nFeeDelta) const
|
|
| 661 |
if (pos == mapDeltas.end())
|
| 662 |
return;
|
| 663 |
const CAmount &delta = pos->second;
|
| 664 |
-
nFeeDelta += delta;
|
| 665 |
}
|
| 666 |
|
| 667 |
void CTxMemPool::ClearPrioritisation(const Txid& hash)
|
|
@@ -778,7 +881,11 @@ void CCoinsViewMemPool::Reset()
|
|
| 778 |
size_t CTxMemPool::DynamicMemoryUsage() const {
|
| 779 |
LOCK(cs);
|
| 780 |
// Estimate the overhead of mapTx to be 9 pointers (3 pointers per index) + an allocation, as no exact formula for boost::multi_index_contained is implemented.
|
| 781 |
-
return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 9 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(txns_randomized) + m_txgraph->GetMainMemoryUsage() + cachedInnerUsage;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 782 |
}
|
| 783 |
|
| 784 |
void CTxMemPool::RemoveUnbroadcastTx(const Txid& txid, const bool unchecked) {
|
|
@@ -1002,7 +1109,7 @@ util::Result<std::pair<std::vector<FeeFrac>, std::vector<FeeFrac>>> CTxMemPool::
|
|
| 1002 |
return m_pool->m_txgraph->GetMainStagingDiagrams();
|
| 1003 |
}
|
| 1004 |
|
| 1005 |
-
CTxMemPool::ChangeSet::TxHandle CTxMemPool::ChangeSet::StageAddition(const CTransactionRef& tx, const CAmount fee, int64_t time, unsigned int entry_height, uint64_t entry_sequence, bool spends_coinbase, int64_t sigops_cost, LockPoints lp)
|
| 1006 |
{
|
| 1007 |
LOCK(m_pool->cs);
|
| 1008 |
Assume(m_to_add.find(tx->GetHash()) == m_to_add.end());
|
|
@@ -1014,13 +1121,15 @@ CTxMemPool::ChangeSet::TxHandle CTxMemPool::ChangeSet::StageAddition(const CTran
|
|
| 1014 |
CAmount delta{0};
|
| 1015 |
m_pool->ApplyDelta(tx->GetHash(), delta);
|
| 1016 |
|
| 1017 |
-
FeePerWeight feerate(fee, GetSigOpsAdjustedWeight(GetTransactionWeight(*tx), sigops_cost, ::nBytesPerSigOp));
|
| 1018 |
-
auto newit = m_to_add.emplace(tx, fee, time, entry_height, entry_sequence, spends_coinbase, sigops_cost, lp).first;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1019 |
m_pool->m_txgraph->AddTransaction(const_cast<CTxMemPoolEntry&>(*newit), feerate);
|
| 1020 |
-
if (delta) {
|
| 1021 |
-
newit->UpdateModifiedFee(delta);
|
| 1022 |
-
m_pool->m_txgraph->SetTransactionFee(*newit, newit->GetModifiedFee());
|
| 1023 |
-
}
|
| 1024 |
|
| 1025 |
m_entry_vec.push_back(newit);
|
| 1026 |
|
|
@@ -1043,6 +1152,8 @@ void CTxMemPool::ChangeSet::Apply()
|
|
| 1043 |
m_pool->Apply(this);
|
| 1044 |
m_to_add.clear();
|
| 1045 |
m_to_remove.clear();
|
|
|
|
|
|
|
| 1046 |
m_entry_vec.clear();
|
| 1047 |
m_ancestors.clear();
|
| 1048 |
}
|
|
|
|
| 37 |
TRACEPOINT_SEMAPHORE(mempool, added);
|
| 38 |
TRACEPOINT_SEMAPHORE(mempool, removed);
|
| 39 |
|
| 40 |
+
namespace {
|
| 41 |
+
uint64_t AbsoluteFee(CAmount fee)
|
| 42 |
+
{
|
| 43 |
+
// Avoid negating INT64_MIN.
|
| 44 |
+
return fee < 0 ? static_cast<uint64_t>(-(fee + 1)) + 1 : static_cast<uint64_t>(fee);
|
| 45 |
+
}
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp)
|
| 49 |
{
|
| 50 |
AssertLockHeld(cs_main);
|
|
|
|
| 182 |
}
|
| 183 |
|
| 184 |
CTxMemPool::CTxMemPool(Options opts, bilingual_str& error)
|
| 185 |
+
: m_dust_relay_feerate{opts.dust_relay_feerate}, m_opts{Flatten(std::move(opts), error)}
|
| 186 |
{
|
| 187 |
m_txgraph = MakeTxGraph(
|
| 188 |
/*max_cluster_count=*/m_opts.limits.cluster_count,
|
|
|
|
| 195 |
});
|
| 196 |
}
|
| 197 |
|
| 198 |
+
CFeeRate CTxMemPool::GetDustRelayFee() const
|
| 199 |
+
{
|
| 200 |
+
LOCK(cs);
|
| 201 |
+
return m_dust_relay_feerate;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
StandardnessOptions CTxMemPool::GetStandardnessOptions() const
|
| 205 |
+
{
|
| 206 |
+
LOCK(cs);
|
| 207 |
+
StandardnessOptions options{m_opts};
|
| 208 |
+
options.dust_relay_feerate = m_dust_relay_feerate;
|
| 209 |
+
return options;
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
std::optional<CFeeRate> CTxMemPool::EstimateDustFromMempool(int32_t target_kvb) const
|
| 213 |
+
{
|
| 214 |
+
Assume(target_kvb > 0);
|
| 215 |
+
int64_t remaining{int64_t{target_kvb} * 1000};
|
| 216 |
+
LOCK(cs);
|
| 217 |
+
for (const auto& entry : GetSortedScoreWithTopology()) {
|
| 218 |
+
remaining -= entry->GetTxSize();
|
| 219 |
+
if (remaining <= 0) return CFeeRate{entry->GetFee(), static_cast<int32_t>(entry->GetTxSize())};
|
| 220 |
+
}
|
| 221 |
+
return std::nullopt;
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
void CTxMemPool::UpdateDynamicDustFee(std::optional<CFeeRate> estimate)
|
| 225 |
+
{
|
| 226 |
+
if (m_opts.dust_relay_target == 0) return;
|
| 227 |
+
const CFeeRate fee{estimate ? std::max(ScaleDustFee(*estimate, m_opts.dust_relay_multiplier), m_opts.dust_relay_feerate) : m_opts.dust_relay_feerate};
|
| 228 |
+
LOCK(cs);
|
| 229 |
+
if (m_dust_relay_feerate != fee) {
|
| 230 |
+
LogDebug(BCLog::MEMPOOL, "Updating dust feerate to %s\n", fee.ToString(FeeRateFormat::SAT_VB));
|
| 231 |
+
m_dust_relay_feerate = fee;
|
| 232 |
+
}
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
bool CTxMemPool::isSpent(const COutPoint& outpoint) const
|
| 236 |
{
|
| 237 |
LOCK(cs);
|
|
|
|
| 291 |
// In that case, our disconnect block logic will call UpdateTransactionsFromBlock
|
| 292 |
// to clean up the mess we're leaving here.
|
| 293 |
|
| 294 |
+
for (const auto& [script, claims] : entry.m_script_claims) {
|
| 295 |
+
auto& [created, spent] = m_used_scripts[script];
|
| 296 |
+
if (claims & 2) created.insert(tx.GetHash());
|
| 297 |
+
if (claims & 1) spent.insert(tx.GetHash());
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
nTransactionsUpdated++;
|
| 301 |
totalTxSize += entry.GetTxSize();
|
| 302 |
m_total_fee += entry.GetFee();
|
| 303 |
+
m_modified_fee_usage += AbsoluteFee(entry.GetModifiedFee());
|
| 304 |
+
m_policy_weight_usage += entry.GetAdjustedWeight();
|
| 305 |
|
| 306 |
txns_randomized.emplace_back(tx.GetWitnessHash(), newit);
|
| 307 |
newit->idx_randomized = txns_randomized.size() - 1;
|
|
|
|
| 351 |
txns_randomized.clear();
|
| 352 |
}
|
| 353 |
|
| 354 |
+
for (const auto& [script, claims] : it->m_script_claims) {
|
| 355 |
+
auto used = m_used_scripts.find(script);
|
| 356 |
+
Assume(used != m_used_scripts.end());
|
| 357 |
+
used->second.first.erase(it->GetTx().GetHash());
|
| 358 |
+
used->second.second.erase(it->GetTx().GetHash());
|
| 359 |
+
if (used->second.first.empty() && used->second.second.empty()) m_used_scripts.erase(used);
|
| 360 |
+
}
|
| 361 |
totalTxSize -= it->GetTxSize();
|
| 362 |
m_total_fee -= it->GetFee();
|
| 363 |
+
m_modified_fee_usage -= AbsoluteFee(it->GetModifiedFee());
|
| 364 |
+
m_policy_weight_usage -= it->GetAdjustedWeight();
|
| 365 |
cachedInnerUsage -= it->DynamicMemoryUsage();
|
| 366 |
mapTx.erase(it);
|
| 367 |
nTransactionsUpdated++;
|
|
|
|
| 504 |
|
| 505 |
uint64_t checkTotal = 0;
|
| 506 |
CAmount check_total_fee{0};
|
| 507 |
+
uint64_t check_absolute_fee{0};
|
| 508 |
+
std::map<CScript, std::pair<std::set<Txid>, std::set<Txid>>> check_scripts;
|
| 509 |
CAmount check_total_modified_fee{0};
|
| 510 |
int64_t check_total_adjusted_weight{0};
|
| 511 |
uint64_t innerUsage = 0;
|
|
|
|
| 541 |
check_total_adjusted_weight += it->GetAdjustedWeight();
|
| 542 |
check_total_fee += it->GetFee();
|
| 543 |
check_total_modified_fee += it->GetModifiedFee();
|
| 544 |
+
check_absolute_fee += AbsoluteFee(it->GetModifiedFee());
|
| 545 |
+
for (const auto& [script, claims] : it->m_script_claims) {
|
| 546 |
+
if (claims & 2) check_scripts[script].first.insert(it->GetTx().GetHash());
|
| 547 |
+
if (claims & 1) check_scripts[script].second.insert(it->GetTx().GetHash());
|
| 548 |
+
}
|
| 549 |
innerUsage += it->DynamicMemoryUsage();
|
| 550 |
const CTransaction& tx = it->GetTx();
|
| 551 |
|
|
|
|
| 617 |
|
| 618 |
assert(totalTxSize == checkTotal);
|
| 619 |
assert(m_total_fee == check_total_fee);
|
| 620 |
+
assert(m_modified_fee_usage == check_absolute_fee);
|
| 621 |
+
assert(m_policy_weight_usage == static_cast<uint64_t>(check_total_adjusted_weight));
|
| 622 |
+
assert(m_used_scripts == check_scripts);
|
| 623 |
assert(diagram.back().fee == check_total_modified_fee);
|
| 624 |
assert(diagram.back().size == check_total_adjusted_weight);
|
| 625 |
assert(innerUsage == cachedInnerUsage);
|
|
|
|
| 699 |
return i->GetSharedTx();
|
| 700 |
}
|
| 701 |
|
| 702 |
+
std::set<Txid> CTxMemPool::GetScriptConflicts(const CScript& script, bool creating) const
|
| 703 |
+
{
|
| 704 |
+
AssertLockHeld(cs);
|
| 705 |
+
std::set<Txid> conflicts;
|
| 706 |
+
const auto it = m_used_scripts.find(script);
|
| 707 |
+
if (it != m_used_scripts.end()) {
|
| 708 |
+
conflicts = it->second.second;
|
| 709 |
+
if (creating) conflicts.insert(it->second.first.begin(), it->second.first.end());
|
| 710 |
+
}
|
| 711 |
+
return conflicts;
|
| 712 |
+
}
|
| 713 |
+
|
| 714 |
+
bool CTxMemPool::CanAddPolicyWeight(int64_t weight) const
|
| 715 |
+
{
|
| 716 |
+
AssertLockHeld(cs);
|
| 717 |
+
return weight > 0 && static_cast<uint64_t>(weight) <= uint64_t{INT32_MAX} - m_policy_weight_usage - m_staged_weight_usage;
|
| 718 |
+
}
|
| 719 |
+
|
| 720 |
+
bool CTxMemPool::CanAddModifiedFee(CAmount fee) const
|
| 721 |
+
{
|
| 722 |
+
AssertLockHeld(cs);
|
| 723 |
+
return AbsoluteFee(fee) <= uint64_t{INT64_MAX} - m_modified_fee_usage - m_staged_fee_usage;
|
| 724 |
+
}
|
| 725 |
+
|
| 726 |
+
bool CTxMemPool::PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta)
|
| 727 |
{
|
| 728 |
{
|
| 729 |
LOCK(cs);
|
| 730 |
+
txiter it = mapTx.find(hash);
|
| 731 |
+
if (it != mapTx.end()) {
|
| 732 |
+
const auto new_fee = SaturatingAdd(it->GetModifiedFee(), nFeeDelta);
|
| 733 |
+
const auto other_usage = m_modified_fee_usage - AbsoluteFee(it->GetModifiedFee()) + m_staged_fee_usage;
|
| 734 |
+
if (AbsoluteFee(new_fee) > uint64_t{INT64_MAX} - other_usage) return false;
|
| 735 |
+
m_modified_fee_usage = m_modified_fee_usage - AbsoluteFee(it->GetModifiedFee()) + AbsoluteFee(new_fee);
|
| 736 |
+
}
|
| 737 |
CAmount &delta = mapDeltas[hash];
|
| 738 |
delta = SaturatingAdd(delta, nFeeDelta);
|
|
|
|
| 739 |
if (it != mapTx.end()) {
|
| 740 |
// PrioritiseTransaction calls stack on previous ones. Set the new
|
| 741 |
// transaction fee to be current modified fee + feedelta.
|
|
|
|
| 754 |
FormatMoney(delta));
|
| 755 |
}
|
| 756 |
}
|
| 757 |
+
return true;
|
| 758 |
}
|
| 759 |
|
| 760 |
void CTxMemPool::ApplyDelta(const Txid& hash, CAmount &nFeeDelta) const
|
|
|
|
| 764 |
if (pos == mapDeltas.end())
|
| 765 |
return;
|
| 766 |
const CAmount &delta = pos->second;
|
| 767 |
+
nFeeDelta = SaturatingAdd(nFeeDelta, delta);
|
| 768 |
}
|
| 769 |
|
| 770 |
void CTxMemPool::ClearPrioritisation(const Txid& hash)
|
|
|
|
| 881 |
size_t CTxMemPool::DynamicMemoryUsage() const {
|
| 882 |
LOCK(cs);
|
| 883 |
// Estimate the overhead of mapTx to be 9 pointers (3 pointers per index) + an allocation, as no exact formula for boost::multi_index_contained is implemented.
|
| 884 |
+
size_t script_usage{memusage::DynamicUsage(m_used_scripts)};
|
| 885 |
+
for (const auto& [script, claims] : m_used_scripts) {
|
| 886 |
+
script_usage += RecursiveDynamicUsage(script) + memusage::DynamicUsage(claims.first) + memusage::DynamicUsage(claims.second);
|
| 887 |
+
}
|
| 888 |
+
return script_usage + memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 9 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(txns_randomized) + m_txgraph->GetMainMemoryUsage() + cachedInnerUsage;
|
| 889 |
}
|
| 890 |
|
| 891 |
void CTxMemPool::RemoveUnbroadcastTx(const Txid& txid, const bool unchecked) {
|
|
|
|
| 1109 |
return m_pool->m_txgraph->GetMainStagingDiagrams();
|
| 1110 |
}
|
| 1111 |
|
| 1112 |
+
CTxMemPool::ChangeSet::TxHandle CTxMemPool::ChangeSet::StageAddition(const CTransactionRef& tx, const CAmount fee, int64_t time, unsigned int entry_height, uint64_t entry_sequence, bool spends_coinbase, int64_t sigops_cost, LockPoints lp, int32_t extra_weight, CAmount dust_penalty, std::map<CScript, unsigned> script_claims)
|
| 1113 |
{
|
| 1114 |
LOCK(m_pool->cs);
|
| 1115 |
Assume(m_to_add.find(tx->GetHash()) == m_to_add.end());
|
|
|
|
| 1121 |
CAmount delta{0};
|
| 1122 |
m_pool->ApplyDelta(tx->GetHash(), delta);
|
| 1123 |
|
| 1124 |
+
auto newit = m_to_add.emplace(tx, fee, time, entry_height, entry_sequence, spends_coinbase, sigops_cost, lp, extra_weight, dust_penalty, std::move(script_claims)).first;
|
| 1125 |
+
newit->UpdateModifiedFee(delta);
|
| 1126 |
+
newit->UpdateModifiedFee(-dust_penalty);
|
| 1127 |
+
Assume(m_pool->CanAddPolicyWeight(newit->GetAdjustedWeight()));
|
| 1128 |
+
m_pool->m_staged_weight_usage += newit->GetAdjustedWeight();
|
| 1129 |
+
Assume(m_pool->CanAddModifiedFee(newit->GetModifiedFee()));
|
| 1130 |
+
m_pool->m_staged_fee_usage += AbsoluteFee(newit->GetModifiedFee());
|
| 1131 |
+
const FeePerWeight feerate{newit->GetModifiedFee(), static_cast<int32_t>(newit->GetAdjustedWeight())};
|
| 1132 |
m_pool->m_txgraph->AddTransaction(const_cast<CTxMemPoolEntry&>(*newit), feerate);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1133 |
|
| 1134 |
m_entry_vec.push_back(newit);
|
| 1135 |
|
|
|
|
| 1152 |
m_pool->Apply(this);
|
| 1153 |
m_to_add.clear();
|
| 1154 |
m_to_remove.clear();
|
| 1155 |
+
m_pool->m_staged_fee_usage = 0;
|
| 1156 |
+
m_pool->m_staged_weight_usage = 0;
|
| 1157 |
m_entry_vec.clear();
|
| 1158 |
m_ancestors.clear();
|
| 1159 |
}
|