aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuke Dashjr <luke-jr+git@utopios.org>2012-07-11 18:52:41 +0000
committerLuke Dashjr <luke-jr+git@utopios.org>2014-06-26 11:49:46 +0000
commit2a72d4591f5adf25fcb4d0433b390ba6c37f57a9 (patch)
treeb46f8cc4f0529ca6d1faebdb5690ba3353044fc1 /src
parent343feecf562a39e7d898ece2fd745fcb9d4c90e9 (diff)
downloadbitcoin-2a72d4591f5adf25fcb4d0433b390ba6c37f57a9.tar.xz
JSON-RPC method: prioritisetransaction <txid> <priority delta> <priority tx fee>
Accepts the transaction into mined blocks at a higher (or lower) priority
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp10
-rw-r--r--src/miner.cpp14
-rw-r--r--src/rpcclient.cpp2
-rw-r--r--src/rpcmining.cpp14
-rw-r--r--src/rpcserver.cpp1
-rw-r--r--src/rpcserver.h1
-rw-r--r--src/txmempool.cpp29
-rw-r--r--src/txmempool.h6
8 files changed, 74 insertions, 3 deletions
diff --git a/src/main.cpp b/src/main.cpp
index ea47601081..e06c519ee2 100644
--- a/src/main.cpp
+++ b/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)
{
+ {
+ 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
CFeeRate baseFeeRate = (mode == GMF_RELAY) ? tx.minRelayTxFee : tx.minTxFee;
diff --git a/src/miner.cpp b/src/miner.cpp
index 19b4694357..69e53756e0 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -3,6 +3,8 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <inttypes.h>
+
#include "miner.h"
#include "core.h"
@@ -186,6 +188,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
dPriority = tx.ComputePriority(dPriority, nTxSize);
+ uint256 hash = tx.GetHash();
+ mempool.ApplyDeltas(hash, dPriority, nTotalIn);
+
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
if (porphan)
@@ -227,10 +232,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
continue;
// 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;
- // 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:
if (!fSortedByFee &&
((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
@@ -257,7 +266,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
continue;
CTxUndo txundo;
- const uint256& hash = tx.GetHash();
UpdateCoins(tx, state, view, txundo, pindexPrev->nHeight+1);
// Added
diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp
index 3a06e33016..30881b9b1a 100644
--- a/src/rpcclient.cpp
+++ b/src/rpcclient.cpp
@@ -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 == "listaccounts" && n > 0) ConvertTo<int64_t>(params[0]);
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 == "listsinceblock" && n > 1) ConvertTo<int64_t>(params[1]);
if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 0072557f87..98caf704ee 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -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)
{
if (fHelp || params.size() > 1)
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index c5d09cf577..6552de8c49 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -254,6 +254,7 @@ static const CRPCCommand vRPCCommands[] =
{ "getblocktemplate", &getblocktemplate, true, false, false },
{ "getmininginfo", &getmininginfo, true, false, false },
{ "getnetworkhashps", &getnetworkhashps, true, false, false },
+ { "prioritisetransaction", &prioritisetransaction, true, false, false },
{ "submitblock", &submitblock, false, true, false },
/* Raw transactions */
diff --git a/src/rpcserver.h b/src/rpcserver.h
index 5271542385..1966a65b50 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -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 gethashespersec(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 submitblock(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 4bf01d4848..52f82ef040 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -447,6 +447,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
std::list<CTransaction> dummy;
remove(tx, dummy, false);
removeConflicts(tx, conflicts);
+ ClearPrioritisation(tx.GetHash());
}
}
@@ -564,6 +565,34 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
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) { }
diff --git a/src/txmempool.h b/src/txmempool.h
index b2915aa842..f7dbb126a0 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -71,6 +71,7 @@ public:
mutable CCriticalSection cs;
std::map<uint256, CTxMemPoolEntry> mapTx;
std::map<COutPoint, CInPoint> mapNextTx;
+ std::map<uint256, std::pair<double, int64_t> > mapDeltas;
CTxMemPool();
~CTxMemPool();
@@ -95,6 +96,11 @@ public:
unsigned int GetTransactionsUpdated() const;
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()
{
LOCK(cs);