Merge pull request #1583
2a72d45
JSON-RPC method: prioritisetransaction <txid> <priority delta> <priority tx fee> (Luke Dashjr)
This commit is contained in:
commit
ffb32acfab
8 changed files with 74 additions and 3 deletions
10
src/main.cpp
10
src/main.cpp
|
@ -789,6 +789,16 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
|
||||||
|
|
||||||
int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode)
|
int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
LOCK(mempool.cs);
|
||||||
|
uint256 hash = tx.GetHash();
|
||||||
|
double dPriorityDelta = 0;
|
||||||
|
int64_t nFeeDelta = 0;
|
||||||
|
mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
|
||||||
|
if (dPriorityDelta > 0 || nFeeDelta > 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Base fee is either minTxFee or minRelayTxFee
|
// Base fee is either minTxFee or minRelayTxFee
|
||||||
CFeeRate baseFeeRate = (mode == GMF_RELAY) ? tx.minRelayTxFee : tx.minTxFee;
|
CFeeRate baseFeeRate = (mode == GMF_RELAY) ? tx.minRelayTxFee : tx.minTxFee;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
@ -186,6 +188,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
dPriority = tx.ComputePriority(dPriority, nTxSize);
|
dPriority = tx.ComputePriority(dPriority, nTxSize);
|
||||||
|
|
||||||
|
uint256 hash = tx.GetHash();
|
||||||
|
mempool.ApplyDeltas(hash, dPriority, nTotalIn);
|
||||||
|
|
||||||
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
|
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
|
||||||
|
|
||||||
if (porphan)
|
if (porphan)
|
||||||
|
@ -227,10 +232,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Skip free transactions if we're past the minimum block size:
|
// Skip free transactions if we're past the minimum block size:
|
||||||
if (fSortedByFee && (feeRate < CTransaction::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
|
const uint256& hash = tx.GetHash();
|
||||||
|
double dPriorityDelta = 0;
|
||||||
|
int64_t nFeeDelta = 0;
|
||||||
|
mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
|
||||||
|
if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < CTransaction::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Prioritize by fee once past the priority size or we run out of high-priority
|
// Prioritise by fee once past the priority size or we run out of high-priority
|
||||||
// transactions:
|
// transactions:
|
||||||
if (!fSortedByFee &&
|
if (!fSortedByFee &&
|
||||||
((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
|
((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
|
||||||
|
@ -257,7 +266,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CTxUndo txundo;
|
CTxUndo txundo;
|
||||||
const uint256& hash = tx.GetHash();
|
|
||||||
UpdateCoins(tx, state, view, txundo, pindexPrev->nHeight+1);
|
UpdateCoins(tx, state, view, txundo, pindexPrev->nHeight+1);
|
||||||
|
|
||||||
// Added
|
// Added
|
||||||
|
|
|
@ -72,6 +72,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
||||||
if (strMethod == "listtransactions" && n > 2) ConvertTo<int64_t>(params[2]);
|
if (strMethod == "listtransactions" && n > 2) ConvertTo<int64_t>(params[2]);
|
||||||
if (strMethod == "listaccounts" && n > 0) ConvertTo<int64_t>(params[0]);
|
if (strMethod == "listaccounts" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||||
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<int64_t>(params[1]);
|
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||||
|
if (strMethod == "prioritisetransaction" && n > 1) ConvertTo<double>(params[1]);
|
||||||
|
if (strMethod == "prioritisetransaction" && n > 2) ConvertTo<int64_t>(params[2]);
|
||||||
if (strMethod == "getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
|
if (strMethod == "getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
|
||||||
if (strMethod == "listsinceblock" && n > 1) ConvertTo<int64_t>(params[1]);
|
if (strMethod == "listsinceblock" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||||
if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
|
if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
|
||||||
|
|
|
@ -247,6 +247,20 @@ Value getmininginfo(const Array& params, bool fHelp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Value prioritisetransaction(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() != 3)
|
||||||
|
throw runtime_error(
|
||||||
|
"prioritisetransaction <txid> <priority delta> <fee delta>\n"
|
||||||
|
"Accepts the transaction into mined blocks at a higher (or lower) priority");
|
||||||
|
|
||||||
|
uint256 hash;
|
||||||
|
hash.SetHex(params[0].get_str());
|
||||||
|
mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), params[2].get_int64());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value getblocktemplate(const Array& params, bool fHelp)
|
Value getblocktemplate(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() > 1)
|
if (fHelp || params.size() > 1)
|
||||||
|
|
|
@ -254,6 +254,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||||
{ "getblocktemplate", &getblocktemplate, true, false, false },
|
{ "getblocktemplate", &getblocktemplate, true, false, false },
|
||||||
{ "getmininginfo", &getmininginfo, true, false, false },
|
{ "getmininginfo", &getmininginfo, true, false, false },
|
||||||
{ "getnetworkhashps", &getnetworkhashps, true, false, false },
|
{ "getnetworkhashps", &getnetworkhashps, true, false, false },
|
||||||
|
{ "prioritisetransaction", &prioritisetransaction, true, false, false },
|
||||||
{ "submitblock", &submitblock, false, true, false },
|
{ "submitblock", &submitblock, false, true, false },
|
||||||
|
|
||||||
/* Raw transactions */
|
/* Raw transactions */
|
||||||
|
|
|
@ -130,6 +130,7 @@ extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHe
|
||||||
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
|
||||||
|
extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
|
||||||
|
|
|
@ -447,6 +447,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
|
||||||
std::list<CTransaction> dummy;
|
std::list<CTransaction> dummy;
|
||||||
remove(tx, dummy, false);
|
remove(tx, dummy, false);
|
||||||
removeConflicts(tx, conflicts);
|
removeConflicts(tx, conflicts);
|
||||||
|
ClearPrioritisation(tx.GetHash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,6 +565,34 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, int64_t nFeeDelta)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
std::pair<double, int64_t> &deltas = mapDeltas[hash];
|
||||||
|
deltas.first += dPriorityDelta;
|
||||||
|
deltas.second += nFeeDelta;
|
||||||
|
}
|
||||||
|
LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash.c_str(), dPriorityDelta, nFeeDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
std::map<uint256, std::pair<double, int64_t> >::iterator pos = mapDeltas.find(hash);
|
||||||
|
if (pos == mapDeltas.end())
|
||||||
|
return;
|
||||||
|
const std::pair<double, int64_t> &deltas = pos->second;
|
||||||
|
dPriorityDelta += deltas.first;
|
||||||
|
nFeeDelta += deltas.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTxMemPool::ClearPrioritisation(const uint256 hash)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
mapDeltas.erase(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
|
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ public:
|
||||||
mutable CCriticalSection cs;
|
mutable CCriticalSection cs;
|
||||||
std::map<uint256, CTxMemPoolEntry> mapTx;
|
std::map<uint256, CTxMemPoolEntry> mapTx;
|
||||||
std::map<COutPoint, CInPoint> mapNextTx;
|
std::map<COutPoint, CInPoint> mapNextTx;
|
||||||
|
std::map<uint256, std::pair<double, int64_t> > mapDeltas;
|
||||||
|
|
||||||
CTxMemPool();
|
CTxMemPool();
|
||||||
~CTxMemPool();
|
~CTxMemPool();
|
||||||
|
@ -95,6 +96,11 @@ public:
|
||||||
unsigned int GetTransactionsUpdated() const;
|
unsigned int GetTransactionsUpdated() const;
|
||||||
void AddTransactionsUpdated(unsigned int n);
|
void AddTransactionsUpdated(unsigned int n);
|
||||||
|
|
||||||
|
/** Affect CreateNewBlock prioritisation of transactions */
|
||||||
|
void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, int64_t nFeeDelta);
|
||||||
|
void ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta);
|
||||||
|
void ClearPrioritisation(const uint256 hash);
|
||||||
|
|
||||||
unsigned long size()
|
unsigned long size()
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
|
|
Loading…
Reference in a new issue