1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 #include "chainparams.h"
14 #include "rpcserver.h"
16 #include "validationinterface.h"
18 #include "wallet/db.h"
19 #include "wallet/wallet.h"
24 #include <boost/assign/list_of.hpp>
26 #include "json/json_spirit_utils.h"
27 #include "json/json_spirit_value.h"
29 using namespace json_spirit;
33 * Return average network hashes per second based on the last 'lookup' blocks,
34 * or from the last difficulty change if 'lookup' is nonpositive.
35 * If 'height' is nonnegative, compute the estimate at the time when a given block was found.
37 Value GetNetworkHashPS(int lookup, int height) {
38 CBlockIndex *pb = chainActive.Tip();
40 if (height >= 0 && height < chainActive.Height())
41 pb = chainActive[height];
43 if (pb == NULL || !pb->nHeight)
46 // If lookup is -1, then use blocks since last difficulty change.
48 lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1;
50 // If lookup is larger than chain, then set it to chain length.
51 if (lookup > pb->nHeight)
54 CBlockIndex *pb0 = pb;
55 int64_t minTime = pb0->GetBlockTime();
56 int64_t maxTime = minTime;
57 for (int i = 0; i < lookup; i++) {
59 int64_t time = pb0->GetBlockTime();
60 minTime = std::min(time, minTime);
61 maxTime = std::max(time, maxTime);
64 // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
65 if (minTime == maxTime)
68 arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
69 int64_t timeDiff = maxTime - minTime;
71 return (int64_t)(workDiff.getdouble() / timeDiff);
74 Value getnetworkhashps(const Array& params, bool fHelp)
76 if (fHelp || params.size() > 2)
78 "getnetworkhashps ( blocks height )\n"
79 "\nReturns the estimated network hashes per second based on the last n blocks.\n"
80 "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
81 "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
83 "1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change.\n"
84 "2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
86 "x (numeric) Hashes per second estimated\n"
88 + HelpExampleCli("getnetworkhashps", "")
89 + HelpExampleRpc("getnetworkhashps", "")
93 return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
97 Value getgenerate(const Array& params, bool fHelp)
99 if (fHelp || params.size() != 0)
102 "\nReturn if the server is set to generate coins or not. The default is false.\n"
103 "It is set with the command line argument -gen (or bitcoin.conf setting gen)\n"
104 "It can also be set with the setgenerate call.\n"
106 "true|false (boolean) If the server is set to generate coins or not\n"
108 + HelpExampleCli("getgenerate", "")
109 + HelpExampleRpc("getgenerate", "")
113 return GetBoolArg("-gen", false);
116 Value generate(const Array& params, bool fHelp)
118 if (fHelp || params.size() < 1 || params.size() > 1)
120 "generate numblocks\n"
121 "\nMine blocks immediately (before the RPC call returns)\n"
122 "\nNote: this function can only be used on the regtest network\n"
123 "1. numblocks (numeric) How many blocks are generated immediately.\n"
125 "[ blockhashes ] (array) hashes of blocks generated\n"
127 "\nGenerate 11 blocks\n"
128 + HelpExampleCli("generate", "11")
131 if (pwalletMain == NULL)
132 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
133 if (!Params().MineBlocksOnDemand())
134 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
136 int nHeightStart = 0;
139 int nGenerate = params[0].get_int();
140 CReserveKey reservekey(pwalletMain);
142 { // Don't keep cs_main locked
144 nHeightStart = chainActive.Height();
145 nHeight = nHeightStart;
146 nHeightEnd = nHeightStart+nGenerate;
148 unsigned int nExtraNonce = 0;
150 while (nHeight < nHeightEnd)
152 auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
153 if (!pblocktemplate.get())
154 throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
155 CBlock *pblock = &pblocktemplate->block;
158 IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);
160 while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
161 // Yes, there is a chance every nonce could fail to satisfy the -regtest
162 // target -- 1 in 2^(2^32). That ain't gonna happen.
165 CValidationState state;
166 if (!ProcessNewBlock(state, NULL, pblock))
167 throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
169 blockHashes.push_back(pblock->GetHash().GetHex());
175 Value setgenerate(const Array& params, bool fHelp)
177 if (fHelp || params.size() < 1 || params.size() > 2)
179 "setgenerate generate ( genproclimit )\n"
180 "\nSet 'generate' true or false to turn generation on or off.\n"
181 "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n"
182 "See the getgenerate call for the current setting.\n"
184 "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n"
185 "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
187 "\nSet the generation on with a limit of one processor\n"
188 + HelpExampleCli("setgenerate", "true 1") +
189 "\nCheck the setting\n"
190 + HelpExampleCli("getgenerate", "") +
191 "\nTurn off generation\n"
192 + HelpExampleCli("setgenerate", "false") +
194 + HelpExampleRpc("setgenerate", "true, 1")
197 if (pwalletMain == NULL)
198 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
200 bool fGenerate = true;
201 if (params.size() > 0)
202 fGenerate = params[0].get_bool();
204 int nGenProcLimit = -1;
205 if (params.size() > 1)
207 nGenProcLimit = params[1].get_int();
208 if (nGenProcLimit == 0)
212 mapArgs["-gen"] = (fGenerate ? "1" : "0");
213 mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
214 GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
221 Value getmininginfo(const Array& params, bool fHelp)
223 if (fHelp || params.size() != 0)
226 "\nReturns a json object containing mining-related information."
229 " \"blocks\": nnn, (numeric) The current block\n"
230 " \"currentblocksize\": nnn, (numeric) The last block size\n"
231 " \"currentblocktx\": nnn, (numeric) The last block transaction\n"
232 " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n"
233 " \"errors\": \"...\" (string) Current errors\n"
234 " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
235 " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
236 " \"pooledtx\": n (numeric) The size of the mem pool\n"
237 " \"testnet\": true|false (boolean) If using testnet or not\n"
238 " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
241 + HelpExampleCli("getmininginfo", "")
242 + HelpExampleRpc("getmininginfo", "")
249 obj.push_back(Pair("blocks", (int)chainActive.Height()));
250 obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
251 obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
252 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
253 obj.push_back(Pair("errors", GetWarnings("statusbar")));
254 obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
255 obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
256 obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
257 obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
258 obj.push_back(Pair("chain", Params().NetworkIDString()));
260 obj.push_back(Pair("generate", getgenerate(params, false)));
266 // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
267 Value prioritisetransaction(const Array& params, bool fHelp)
269 if (fHelp || params.size() != 3)
271 "prioritisetransaction <txid> <priority delta> <fee delta>\n"
272 "Accepts the transaction into mined blocks at a higher (or lower) priority\n"
274 "1. \"txid\" (string, required) The transaction id.\n"
275 "2. priority delta (numeric, required) The priority to add or subtract.\n"
276 " The transaction selection algorithm considers the tx as it would have a higher priority.\n"
277 " (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n"
278 "3. fee delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n"
279 " The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
280 " considers the transaction as it would have paid a higher (or lower) fee.\n"
282 "true (boolean) Returns true\n"
284 + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
285 + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
290 uint256 hash = ParseHashStr(params[0].get_str(), "txid");
291 CAmount nAmount = params[2].get_int64();
293 mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount);
298 // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
299 static Value BIP22ValidationResult(const CValidationState& state)
304 std::string strRejectReason = state.GetRejectReason();
306 throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason);
307 if (state.IsInvalid())
309 if (strRejectReason.empty())
311 return strRejectReason;
313 // Should be impossible
317 Value getblocktemplate(const Array& params, bool fHelp)
319 if (fHelp || params.size() > 1)
321 "getblocktemplate ( \"jsonrequestobject\" )\n"
322 "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
323 "It returns data needed to construct a block to work on.\n"
324 "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
327 "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n"
329 " \"mode\":\"template\" (string, optional) This must be set to \"template\" or omitted\n"
330 " \"capabilities\":[ (array, optional) A list of strings\n"
331 " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
339 " \"version\" : n, (numeric) The block version\n"
340 " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n"
341 " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n"
343 " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n"
344 " \"hash\" : \"xxxx\", (string) hash/id encoded in little-endian hexadecimal\n"
345 " \"depends\" : [ (array) array of numbers \n"
346 " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n"
349 " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n"
350 " \"sigops\" : n, (numeric) total number of SigOps, as counted for purposes of block limits; if key is not present, sigop count is unknown and clients MUST NOT assume there aren't any\n"
351 " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n"
355 " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n"
356 " \"flags\" : \"flags\" (string) \n"
358 " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
359 " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n"
360 " \"target\" : \"xxxx\", (string) The hash target\n"
361 " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
362 " \"mutable\" : [ (array of string) list of ways the block template may be changed \n"
363 " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n"
366 " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n"
367 " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n"
368 " \"sizelimit\" : n, (numeric) limit of block size\n"
369 " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
370 " \"bits\" : \"xxx\", (string) compressed target of next block\n"
371 " \"height\" : n (numeric) The height of the next block\n"
375 + HelpExampleCli("getblocktemplate", "")
376 + HelpExampleRpc("getblocktemplate", "")
381 std::string strMode = "template";
382 Value lpval = Value::null;
383 if (params.size() > 0)
385 const Object& oparam = params[0].get_obj();
386 const Value& modeval = find_value(oparam, "mode");
387 if (modeval.type() == str_type)
388 strMode = modeval.get_str();
389 else if (modeval.type() == null_type)
394 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
395 lpval = find_value(oparam, "longpollid");
397 if (strMode == "proposal")
399 const Value& dataval = find_value(oparam, "data");
400 if (dataval.type() != str_type)
401 throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
404 if (!DecodeHexBlk(block, dataval.get_str()))
405 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
407 uint256 hash = block.GetHash();
408 BlockMap::iterator mi = mapBlockIndex.find(hash);
409 if (mi != mapBlockIndex.end()) {
410 CBlockIndex *pindex = mi->second;
411 if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
413 if (pindex->nStatus & BLOCK_FAILED_MASK)
414 return "duplicate-invalid";
415 return "duplicate-inconclusive";
418 CBlockIndex* const pindexPrev = chainActive.Tip();
419 // TestBlockValidity only supports blocks built on the current Tip
420 if (block.hashPrevBlock != pindexPrev->GetBlockHash())
421 return "inconclusive-not-best-prevblk";
422 CValidationState state;
423 TestBlockValidity(state, block, pindexPrev, false, true);
424 return BIP22ValidationResult(state);
428 if (strMode != "template")
429 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
432 throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
434 if (IsInitialBlockDownload())
435 throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
437 static unsigned int nTransactionsUpdatedLast;
439 if (lpval.type() != null_type)
441 // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
442 uint256 hashWatchedChain;
443 boost::system_time checktxtime;
444 unsigned int nTransactionsUpdatedLastLP;
446 if (lpval.type() == str_type)
448 // Format: <hashBestChain><nTransactionsUpdatedLast>
449 std::string lpstr = lpval.get_str();
451 hashWatchedChain.SetHex(lpstr.substr(0, 64));
452 nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64));
456 // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
457 hashWatchedChain = chainActive.Tip()->GetBlockHash();
458 nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
461 // Release the wallet and main lock while waiting
462 LEAVE_CRITICAL_SECTION(cs_main);
464 checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
466 boost::unique_lock<boost::mutex> lock(csBestBlock);
467 while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && IsRPCRunning())
469 if (!cvBlockChange.timed_wait(lock, checktxtime))
471 // Timeout: Check transactions for update
472 if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
474 checktxtime += boost::posix_time::seconds(10);
478 ENTER_CRITICAL_SECTION(cs_main);
481 throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
482 // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
486 static CBlockIndex* pindexPrev;
487 static int64_t nStart;
488 static CBlockTemplate* pblocktemplate;
489 if (pindexPrev != chainActive.Tip() ||
490 (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
492 // Clear pindexPrev so future calls make a new block, despite any failures from here on
495 // Store the pindexBest used before CreateNewBlock, to avoid races
496 nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
497 CBlockIndex* pindexPrevNew = chainActive.Tip();
503 delete pblocktemplate;
504 pblocktemplate = NULL;
506 CScript scriptDummy = CScript() << OP_TRUE;
507 pblocktemplate = CreateNewBlock(scriptDummy);
509 throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
511 // Need to update only after we know CreateNewBlock succeeded
512 pindexPrev = pindexPrevNew;
514 CBlock* pblock = &pblocktemplate->block; // pointer for convenience
517 UpdateTime(pblock, pindexPrev);
520 static const Array aCaps = boost::assign::list_of("proposal");
523 map<uint256, int64_t> setTxIndex;
525 BOOST_FOREACH (CTransaction& tx, pblock->vtx)
527 uint256 txHash = tx.GetHash();
528 setTxIndex[txHash] = i++;
535 entry.push_back(Pair("data", EncodeHexTx(tx)));
537 entry.push_back(Pair("hash", txHash.GetHex()));
540 BOOST_FOREACH (const CTxIn &in, tx.vin)
542 if (setTxIndex.count(in.prevout.hash))
543 deps.push_back(setTxIndex[in.prevout.hash]);
545 entry.push_back(Pair("depends", deps));
547 int index_in_template = i - 1;
548 entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
549 entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
551 transactions.push_back(entry);
555 aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
557 arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
559 static Array aMutable;
560 if (aMutable.empty())
562 aMutable.push_back("time");
563 aMutable.push_back("transactions");
564 aMutable.push_back("prevblock");
568 result.push_back(Pair("capabilities", aCaps));
569 result.push_back(Pair("version", pblock->nVersion));
570 result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
571 result.push_back(Pair("transactions", transactions));
572 result.push_back(Pair("coinbaseaux", aux));
573 result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
574 result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
575 result.push_back(Pair("target", hashTarget.GetHex()));
576 result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
577 result.push_back(Pair("mutable", aMutable));
578 result.push_back(Pair("noncerange", "00000000ffffffff"));
579 result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
580 result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
581 result.push_back(Pair("curtime", pblock->GetBlockTime()));
582 result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
583 result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
588 class submitblock_StateCatcher : public CValidationInterface
593 CValidationState state;
595 submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {};
598 virtual void BlockChecked(const CBlock& block, const CValidationState& stateIn) {
599 if (block.GetHash() != hash)
606 Value submitblock(const Array& params, bool fHelp)
608 if (fHelp || params.size() < 1 || params.size() > 2)
610 "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
611 "\nAttempts to submit new block to network.\n"
612 "The 'jsonparametersobject' parameter is currently ignored.\n"
613 "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
616 "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n"
617 "2. \"jsonparametersobject\" (string, optional) object of optional parameters\n"
619 " \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n"
623 + HelpExampleCli("submitblock", "\"mydata\"")
624 + HelpExampleRpc("submitblock", "\"mydata\"")
628 if (!DecodeHexBlk(block, params[0].get_str()))
629 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
631 uint256 hash = block.GetHash();
632 bool fBlockPresent = false;
635 BlockMap::iterator mi = mapBlockIndex.find(hash);
636 if (mi != mapBlockIndex.end()) {
637 CBlockIndex *pindex = mi->second;
638 if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
640 if (pindex->nStatus & BLOCK_FAILED_MASK)
641 return "duplicate-invalid";
642 // Otherwise, we might only have the header - process the block before returning
643 fBlockPresent = true;
647 CValidationState state;
648 submitblock_StateCatcher sc(block.GetHash());
649 RegisterValidationInterface(&sc);
650 bool fAccepted = ProcessNewBlock(state, NULL, &block);
651 UnregisterValidationInterface(&sc);
654 if (fAccepted && !sc.found)
655 return "duplicate-inconclusive";
661 return "inconclusive";
664 return BIP22ValidationResult(state);
667 Value estimatefee(const Array& params, bool fHelp)
669 if (fHelp || params.size() != 1)
671 "estimatefee nblocks\n"
672 "\nEstimates the approximate fee per kilobyte\n"
673 "needed for a transaction to begin confirmation\n"
674 "within nblocks blocks.\n"
676 "1. nblocks (numeric)\n"
678 "n : (numeric) estimated fee-per-kilobyte\n"
680 "-1.0 is returned if not enough transactions and\n"
681 "blocks have been observed to make an estimate.\n"
683 + HelpExampleCli("estimatefee", "6")
686 RPCTypeCheck(params, boost::assign::list_of(int_type));
688 int nBlocks = params[0].get_int();
692 CFeeRate feeRate = mempool.estimateFee(nBlocks);
693 if (feeRate == CFeeRate(0))
696 return ValueFromAmount(feeRate.GetFeePerK());
699 Value estimatepriority(const Array& params, bool fHelp)
701 if (fHelp || params.size() != 1)
703 "estimatepriority nblocks\n"
704 "\nEstimates the approximate priority\n"
705 "a zero-fee transaction needs to begin confirmation\n"
706 "within nblocks blocks.\n"
708 "1. nblocks (numeric)\n"
710 "n : (numeric) estimated priority\n"
712 "-1.0 is returned if not enough transactions and\n"
713 "blocks have been observed to make an estimate.\n"
715 + HelpExampleCli("estimatepriority", "6")
718 RPCTypeCheck(params, boost::assign::list_of(int_type));
720 int nBlocks = params[0].get_int();
724 return mempool.estimatePriority(nBlocks);