Enable prioritisetransaction with priority delta

This commit is contained in:
Luke Dashjr 2018-03-11 03:05:30 +00:00
parent cdfbda5f20
commit b532312c29
9 changed files with 51 additions and 30 deletions

View File

@ -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();

View File

@ -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]);
}

View File

@ -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" */

View File

@ -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;

View File

@ -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" },

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 {

View File

@ -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