mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-06-03 16:02:34 +02:00
Enable prioritisetransaction with priority delta
This commit is contained in:
parent
cdfbda5f20
commit
b532312c29
@ -154,7 +154,9 @@ bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path, FopenFn mock
|
||||
{
|
||||
LOCK(pool.cs);
|
||||
for (const auto &i : pool.mapDeltas) {
|
||||
mapDeltas[i.first] = i.second;
|
||||
if (i.second.second) { // fee delta
|
||||
mapDeltas[i.first] = i.second.second;
|
||||
}
|
||||
}
|
||||
vinfo = pool.infoAll();
|
||||
unbroadcast_txids = pool.GetUnbroadcastTxs();
|
||||
|
@ -262,7 +262,7 @@ bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& packa
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
|
||||
void BlockAssembler::AddToBlock(const CTxMemPool& mempool, CTxMemPool::txiter iter)
|
||||
{
|
||||
pblocktemplate->block.vtx.emplace_back(iter->GetSharedTx());
|
||||
pblocktemplate->vTxFees.push_back(iter->GetFee());
|
||||
@ -279,6 +279,8 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
|
||||
bool fPrintPriority = gArgs.GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY);
|
||||
if (fPrintPriority) {
|
||||
double dPriority = iter->GetPriority(nHeight);
|
||||
CAmount dummy;
|
||||
mempool.ApplyDeltas(iter->GetTx().GetHash(), dPriority, dummy);
|
||||
LogPrintf("priority %.1f fee rate %s txid %s\n",
|
||||
dPriority,
|
||||
CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(),
|
||||
@ -477,7 +479,7 @@ void BlockAssembler::addPackageTxs(const CTxMemPool& mempool, int& nPackagesSele
|
||||
SortForBlock(ancestors, sortedEntries);
|
||||
|
||||
for (size_t i = 0; i < sortedEntries.size(); ++i) {
|
||||
AddToBlock(sortedEntries[i]);
|
||||
AddToBlock(mempool, sortedEntries[i]);
|
||||
// Erase from the modified set, if present
|
||||
mapModifiedTx.erase(sortedEntries[i]);
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ private:
|
||||
/** Clear the block's state and prepare for assembling a new block */
|
||||
void resetBlock();
|
||||
/** Add a tx to the block */
|
||||
void AddToBlock(CTxMemPool::txiter iter);
|
||||
void AddToBlock(const CTxMemPool& mempool, CTxMemPool::txiter iter) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
|
||||
|
||||
// Methods for how to add transactions to a block.
|
||||
/** Add transactions based on tx "priority" */
|
||||
|
@ -199,6 +199,8 @@ void BlockAssembler::addPriorityTxs(const CTxMemPool& mempool, int &nPackagesSel
|
||||
vecPriority.reserve(mempool.mapTx.size());
|
||||
for (auto mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) {
|
||||
double dPriority = mi->GetPriority(nHeight);
|
||||
CAmount dummy;
|
||||
mempool.ApplyDeltas(mi->GetTx().GetHash(), dPriority, dummy);
|
||||
vecPriority.emplace_back(dPriority, mi);
|
||||
}
|
||||
std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
|
||||
@ -225,7 +227,7 @@ void BlockAssembler::addPriorityTxs(const CTxMemPool& mempool, int &nPackagesSel
|
||||
|
||||
// If this tx fits in the block add it, otherwise keep looping
|
||||
if (TestForBlock(iter)) {
|
||||
AddToBlock(iter);
|
||||
AddToBlock(mempool, iter);
|
||||
|
||||
++nPackagesSelected;
|
||||
|
||||
|
@ -253,7 +253,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "estimatesmartfee", 0, "conf_target" },
|
||||
{ "estimaterawfee", 0, "conf_target" },
|
||||
{ "estimaterawfee", 1, "threshold" },
|
||||
{ "prioritisetransaction", 1, "dummy" },
|
||||
{ "prioritisetransaction", 1, "priority_delta" },
|
||||
{ "prioritisetransaction", 2, "fee_delta" },
|
||||
{ "setban", 2, "bantime" },
|
||||
{ "setban", 3, "absolute" },
|
||||
|
@ -452,9 +452,10 @@ static RPCHelpMan prioritisetransaction()
|
||||
"Accepts the transaction into mined blocks at a higher (or lower) priority\n",
|
||||
{
|
||||
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id."},
|
||||
{"dummy", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "API-Compatibility for previous API. Must be zero or null.\n"
|
||||
" DEPRECATED. For forward compatibility use named arguments and omit this parameter."},
|
||||
{"fee_delta", RPCArg::Type::NUM, RPCArg::Optional::NO, "The fee value (in satoshis) to add (or subtract, if negative).\n"
|
||||
{"priority_delta", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The priority to add or subtract.\n"
|
||||
" The transaction selection algorithm considers the tx as it would have a higher priority.\n"
|
||||
" (priority of a transaction is calculated: coinage * value_in_satoshis / txsize)\n"},
|
||||
{"fee_delta", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The fee value (in satoshis) to add (or subtract, if negative).\n"
|
||||
" Note, that this value is not a fee rate. It is a value to modify absolute fee of the TX.\n"
|
||||
" The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
|
||||
" considers the transaction as it would have paid a higher (or lower) fee."},
|
||||
@ -470,14 +471,17 @@ static RPCHelpMan prioritisetransaction()
|
||||
LOCK(cs_main);
|
||||
|
||||
uint256 hash(ParseHashV(request.params[0], "txid"));
|
||||
const auto dummy{self.MaybeArg<double>(1)};
|
||||
CAmount nAmount = request.params[2].getInt<int64_t>();
|
||||
double priority_delta = 0;
|
||||
CAmount nAmount = 0;
|
||||
|
||||
if (dummy && *dummy != 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is no longer supported, dummy argument to prioritisetransaction must be 0.");
|
||||
if (!request.params[1].isNull()) {
|
||||
priority_delta = request.params[1].get_real();
|
||||
}
|
||||
if (!request.params[2].isNull()) {
|
||||
nAmount = request.params[2].getInt<int64_t>();
|
||||
}
|
||||
|
||||
EnsureAnyMemPool(request.context).PrioritiseTransaction(hash, nAmount);
|
||||
EnsureAnyMemPool(request.context).PrioritiseTransaction(hash, priority_delta, nAmount);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@ -846,6 +850,9 @@ static RPCHelpMan getblocktemplate()
|
||||
}
|
||||
entry.pushKV("sigops", nTxSigOps);
|
||||
entry.pushKV("weight", GetTransactionWeight(tx));
|
||||
if (index_in_template && !pblocktemplate->vTxPriorities.empty()) {
|
||||
entry.pushKV("priority", pblocktemplate->vTxPriorities[index_in_template]);
|
||||
}
|
||||
|
||||
transactions.push_back(entry);
|
||||
}
|
||||
|
@ -441,8 +441,10 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
|
||||
indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
|
||||
|
||||
// Update transaction for any feeDelta created by PrioritiseTransaction
|
||||
double priority_delta{0.};
|
||||
CAmount delta{0};
|
||||
ApplyDelta(entry.GetTx().GetHash(), delta);
|
||||
ApplyDeltas(entry.GetTx().GetHash(), priority_delta, delta);
|
||||
// NOTE: priority_delta is handled in addPriorityTxs
|
||||
// The following call to UpdateModifiedFee assumes no previous fee modifications
|
||||
Assume(entry.GetFee() == entry.GetModifiedFee());
|
||||
if (delta) {
|
||||
@ -900,15 +902,17 @@ TxMempoolInfo CTxMemPool::info_for_relay(const GenTxid& gtxid, uint64_t last_seq
|
||||
}
|
||||
}
|
||||
|
||||
void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta)
|
||||
void CTxMemPool::PrioritiseTransaction(const uint256& hash, double dPriorityDelta, const CAmount& nFeeDelta)
|
||||
{
|
||||
{
|
||||
LOCK(cs);
|
||||
CAmount &delta = mapDeltas[hash];
|
||||
delta = SaturatingAdd(delta, nFeeDelta);
|
||||
std::pair<double, CAmount> &deltas = mapDeltas[hash];
|
||||
deltas.first += dPriorityDelta;
|
||||
deltas.second = SaturatingAdd(deltas.second, nFeeDelta);
|
||||
txiter it = mapTx.find(hash);
|
||||
if (it != mapTx.end()) {
|
||||
mapTx.modify(it, [&nFeeDelta](CTxMemPoolEntry& e) { e.UpdateModifiedFee(nFeeDelta); });
|
||||
|
||||
// Now update all ancestors' modified fees with descendants
|
||||
auto ancestors{AssumeCalculateMemPoolAncestors(__func__, *it, Limits::NoLimits(), /*fSearchForParents=*/false)};
|
||||
for (txiter ancestorIt : ancestors) {
|
||||
@ -923,27 +927,29 @@ void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeD
|
||||
}
|
||||
++nTransactionsUpdated;
|
||||
}
|
||||
if (delta == 0) {
|
||||
if (deltas.first == 0. && deltas.second == 0) {
|
||||
mapDeltas.erase(hash);
|
||||
LogPrintf("PrioritiseTransaction: %s (%sin mempool) delta cleared\n", hash.ToString(), it == mapTx.end() ? "not " : "");
|
||||
} else {
|
||||
LogPrintf("PrioritiseTransaction: %s (%sin mempool) fee += %s, new delta=%s\n",
|
||||
LogPrintf("PrioritiseTransaction: %s (%sin mempool) priority += %f, fee += %s, new delta=%s\n",
|
||||
hash.ToString(),
|
||||
it == mapTx.end() ? "not " : "",
|
||||
dPriorityDelta,
|
||||
FormatMoney(nFeeDelta),
|
||||
FormatMoney(delta));
|
||||
FormatMoney(deltas.second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTxMemPool::ApplyDelta(const uint256& hash, CAmount &nFeeDelta) const
|
||||
void CTxMemPool::ApplyDeltas(const uint256& hash, double &dPriorityDelta, CAmount &nFeeDelta) const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(hash);
|
||||
std::map<uint256, std::pair<double, CAmount> >::const_iterator pos = mapDeltas.find(hash);
|
||||
if (pos == mapDeltas.end())
|
||||
return;
|
||||
const CAmount &delta = pos->second;
|
||||
nFeeDelta += delta;
|
||||
const std::pair<double, CAmount> &deltas = pos->second;
|
||||
dPriorityDelta += deltas.first;
|
||||
nFeeDelta += deltas.second;
|
||||
}
|
||||
|
||||
void CTxMemPool::ClearPrioritisation(const uint256& hash)
|
||||
@ -963,7 +969,7 @@ std::vector<CTxMemPool::delta_info> CTxMemPool::GetPrioritisedTransactions() con
|
||||
const bool in_mempool{iter != mapTx.end()};
|
||||
std::optional<CAmount> modified_fee;
|
||||
if (in_mempool) modified_fee = iter->GetModifiedFee();
|
||||
result.emplace_back(delta_info{in_mempool, delta, modified_fee, txid});
|
||||
result.emplace_back(delta_info{in_mempool, delta.second, modified_fee, txid});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ private:
|
||||
|
||||
public:
|
||||
indirectmap<COutPoint, const CTransaction*> mapNextTx GUARDED_BY(cs);
|
||||
std::map<uint256, CAmount> mapDeltas GUARDED_BY(cs);
|
||||
std::map<uint256, std::pair<double, CAmount> > mapDeltas GUARDED_BY(cs);
|
||||
|
||||
using Options = kernel::MemPoolOptions;
|
||||
|
||||
@ -504,8 +504,9 @@ public:
|
||||
void UpdateDependentPriorities(const CTransaction &tx, unsigned int nBlockHeight, bool addToChain);
|
||||
|
||||
/** Affect CreateNewBlock prioritisation of transactions */
|
||||
void PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta);
|
||||
void ApplyDelta(const uint256& hash, CAmount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
void PrioritiseTransaction(const uint256& hash, double dPriorityDelta, const CAmount& nFeeDelta);
|
||||
void PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta) { PrioritiseTransaction(hash, 0., nFeeDelta); }
|
||||
void ApplyDeltas(const uint256& hash, double &dPriorityDelta, CAmount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
void ClearPrioritisation(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
struct delta_info {
|
||||
|
@ -855,7 +855,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
||||
|
||||
// ws.m_modified_fees includes any fee deltas from PrioritiseTransaction
|
||||
ws.m_modified_fees = ws.m_base_fees;
|
||||
m_pool.ApplyDelta(hash, ws.m_modified_fees);
|
||||
double nPriorityDummy{0};
|
||||
m_pool.ApplyDeltas(hash, nPriorityDummy, ws.m_modified_fees);
|
||||
|
||||
CAmount inChainInputValue;
|
||||
// Since entries arrive *after* the tip's height, their priority is for the height+1
|
||||
|
Loading…
Reference in New Issue
Block a user