]> Git Repo - VerusCoin.git/blob - src/rpc/mining.cpp
Return minimum fee rate rather than -1 in estimatefee RPC API
[VerusCoin.git] / src / rpc / mining.cpp
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 https://www.opensource.org/licenses/mit-license.php .
5
6 #include "amount.h"
7 #include "chainparams.h"
8 #include "consensus/consensus.h"
9 #include "consensus/validation.h"
10 #include "core_io.h"
11 #ifdef ENABLE_MINING
12 #include "crypto/equihash.h"
13 #endif
14 #include "init.h"
15 #include "main.h"
16 #include "metrics.h"
17 #include "miner.h"
18 #include "net.h"
19 #include "pow.h"
20 #include "rpc/server.h"
21 #include "txmempool.h"
22 #include "util.h"
23 #include "validationinterface.h"
24 #ifdef ENABLE_WALLET
25 #include "wallet/wallet.h"
26 #endif
27 #include "pbaas/pbaas.h"
28 #include "pbaas/notarization.h"
29
30 #include <stdint.h>
31
32 #include <boost/assign/list_of.hpp>
33 #include <boost/shared_ptr.hpp>
34
35 #include <univalue.h>
36
37 using namespace std;
38
39 extern uint32_t ASSETCHAINS_ALGO;
40 extern int32_t ASSETCHAINS_EQUIHASH, ASSETCHAINS_LWMAPOS;
41 extern int32_t VERUS_MIN_STAKEAGE;
42 extern uint64_t ASSETCHAINS_STAKED;
43 extern int32_t KOMODO_MININGTHREADS;
44 extern bool VERUS_MINTBLOCKS;
45 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
46 arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc);
47 int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex);
48
49 /**
50  * Return average network hashes per second based on the last 'lookup' blocks,
51  * or over the difficulty averaging window if 'lookup' is nonpositive.
52  * If 'height' is nonnegative, compute the estimate at the time when a given block was found.
53  */
54 int64_t GetNetworkHashPS(int lookup, int height) {
55     CBlockIndex *pb = chainActive.LastTip();
56
57     if (height >= 0 && height < chainActive.Height())
58         pb = chainActive[height];
59
60     if (pb == NULL || !pb->GetHeight())
61         return 0;
62
63     // If lookup is nonpositive, then use difficulty averaging window.
64     if (lookup <= 0)
65         lookup = Params().GetConsensus().nPowAveragingWindow;
66
67     // If lookup is larger than chain, then set it to chain length.
68     if (lookup > pb->GetHeight())
69         lookup = pb->GetHeight();
70
71     CBlockIndex *pb0 = pb;
72     int64_t minTime = pb0->GetBlockTime();
73     int64_t maxTime = minTime;
74     for (int i = 0; i < lookup; i++) {
75         pb0 = pb0->pprev;
76         int64_t time = pb0->GetBlockTime();
77         minTime = std::min(time, minTime);
78         maxTime = std::max(time, maxTime);
79     }
80
81     // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
82     if (minTime == maxTime)
83         return 0;
84
85     arith_uint256 workDiff = pb->chainPower.chainWork - pb0->chainPower.chainWork;
86     int64_t timeDiff = maxTime - minTime;
87
88     return (int64_t)(workDiff.getdouble() / timeDiff);
89 }
90
91 UniValue getlocalsolps(const UniValue& params, bool fHelp)
92 {
93     if (fHelp)
94         throw runtime_error(
95             "getlocalsolps\n"
96             "\nReturns the average local solutions per second since this node was started.\n"
97             "This is the same information shown on the metrics screen (if enabled).\n"
98             "\nResult:\n"
99             "xxx.xxxxx     (numeric) Solutions per second average\n"
100             "\nExamples:\n"
101             + HelpExampleCli("getlocalsolps", "")
102             + HelpExampleRpc("getlocalsolps", "")
103        );
104
105     LOCK(cs_main);
106     return GetLocalSolPS();
107 }
108
109 UniValue getnetworksolps(const UniValue& params, bool fHelp)
110 {
111     if (fHelp || params.size() > 2)
112         throw runtime_error(
113             "getnetworksolps ( blocks height )\n"
114             "\nReturns the estimated network solutions per second based on the last n blocks.\n"
115             "Pass in [blocks] to override # of blocks, -1 specifies over difficulty averaging window.\n"
116             "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
117             "\nArguments:\n"
118             "1. blocks     (numeric, optional, default=120) The number of blocks, or -1 for blocks over difficulty averaging window.\n"
119             "2. height     (numeric, optional, default=-1) To estimate at the time of the given height.\n"
120             "\nResult:\n"
121             "x             (numeric) Solutions per second estimated\n"
122             "\nExamples:\n"
123             + HelpExampleCli("getnetworksolps", "")
124             + HelpExampleRpc("getnetworksolps", "")
125        );
126
127     LOCK(cs_main);
128     return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
129 }
130
131 UniValue getnetworkhashps(const UniValue& params, bool fHelp)
132 {
133     if (fHelp || params.size() > 2)
134         throw runtime_error(
135             "getnetworkhashps ( blocks height )\n"
136             "\nDEPRECATED - left for backwards-compatibility. Use getnetworksolps instead.\n"
137             "\nReturns the estimated network solutions per second based on the last n blocks.\n"
138             "Pass in [blocks] to override # of blocks, -1 specifies over difficulty averaging window.\n"
139             "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
140             "\nArguments:\n"
141             "1. blocks     (numeric, optional, default=120) The number of blocks, or -1 for blocks over difficulty averaging window.\n"
142             "2. height     (numeric, optional, default=-1) To estimate at the time of the given height.\n"
143             "\nResult:\n"
144             "x             (numeric) Solutions per second estimated\n"
145             "\nExamples:\n"
146             + HelpExampleCli("getnetworkhashps", "")
147             + HelpExampleRpc("getnetworkhashps", "")
148        );
149
150     LOCK(cs_main);
151     return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
152 }
153
154 #ifdef ENABLE_MINING
155 extern bool VERUS_MINTBLOCKS;
156 UniValue getgenerate(const UniValue& params, bool fHelp)
157 {
158     if (fHelp || params.size() != 0)
159         throw runtime_error(
160             "getgenerate\n"
161             "\nReturn if the server is set to mine and/or mint coins or not. The default is false.\n"
162             "It is set with the command line argument -gen (or komodo.conf setting gen) and -mint\n"
163             "It can also be set with the setgenerate call.\n"
164             "\nResult\n"
165             "{\n"
166             "  \"staking\": true|false      (boolean) If staking is on or off (see setgenerate)\n"
167             "  \"generate\": true|false     (boolean) If mining is on or off (see setgenerate)\n"
168             "  \"numthreads\": n            (numeric) The processor limit for mining. (see setgenerate)\n"
169             "}\n"
170             "\nExamples:\n"
171             + HelpExampleCli("getgenerate", "")
172             + HelpExampleRpc("getgenerate", "")
173         );
174
175     LOCK(cs_main);
176     UniValue obj(UniValue::VOBJ);
177     obj.push_back(Pair("staking",          VERUS_MINTBLOCKS));
178     obj.push_back(Pair("generate",         GetBoolArg("-gen", false)));
179     obj.push_back(Pair("numthreads",       (int64_t)KOMODO_MININGTHREADS));
180     return obj;
181 }
182
183 extern uint8_t NOTARY_PUBKEY33[33];
184
185 //Value generate(const Array& params, bool fHelp)
186 UniValue generate(const UniValue& params, bool fHelp)
187 {
188     if (fHelp || params.size() < 1 || params.size() > 1)
189         throw runtime_error(
190             "generate numblocks\n"
191             "\nMine blocks immediately (before the RPC call returns)\n"
192             "\nNote: this function can only be used on the regtest network\n"
193             "\nArguments:\n"
194             "1. numblocks    (numeric) How many blocks are generated immediately.\n"
195             "\nResult\n"
196             "[ blockhashes ]     (array) hashes of blocks generated\n"
197             "\nExamples:\n"
198             "\nGenerate 11 blocks\n"
199             + HelpExampleCli("generate", "11")
200         );
201
202     if (GetArg("-mineraddress", "").empty()) {
203 #ifdef ENABLE_WALLET
204         if (!pwalletMain) {
205             throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
206         }
207 #else
208         throw JSONRPCError(RPC_METHOD_NOT_FOUND, "verusd compiled without wallet and -mineraddress not set");
209 #endif
210     }
211     if (!Params().MineBlocksOnDemand())
212         throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
213
214     int nHeightStart = 0;
215     int nHeightEnd = 0;
216     int nHeight = 0;
217     int nGenerate = params[0].get_int();
218
219     CReserveKey reservekey(pwalletMain);
220     CPubKey pubKey;
221
222     //throw an error if no script was provided
223     if (!reservekey.GetReservedKey(pubKey))
224         throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet or -mineraddress)");
225
226     {   // Don't keep cs_main locked
227         LOCK(cs_main);
228         nHeightStart = chainActive.Height();
229         nHeight = nHeightStart;
230         nHeightEnd = nHeightStart+nGenerate;
231     }
232     unsigned int nExtraNonce = 0;
233     UniValue blockHashes(UniValue::VARR);
234     unsigned int n = Params().GetConsensus().EquihashN();
235     unsigned int k = Params().GetConsensus().EquihashK();
236     uint64_t lastTime = 0;
237     while (nHeight < nHeightEnd)
238     {
239         // Validation may fail if block generation is too fast
240         if (GetTime() == lastTime) MilliSleep(1001);
241         lastTime = GetTime();
242
243 #ifdef ENABLE_WALLET
244         std::unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey, nHeight, KOMODO_MAXGPUCOUNT));
245 #else
246         std::unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey());
247 #endif
248         if (!pblocktemplate.get())
249             throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
250         CBlock *pblock = &pblocktemplate->block;
251         {
252             LOCK(cs_main);
253             IncrementExtraNonce(pblock, chainActive.LastTip(), nExtraNonce);
254         }
255
256         // Hash state
257         crypto_generichash_blake2b_state eh_state;
258         EhInitialiseState(n, k, eh_state);
259
260         // I = the block header minus nonce and solution.
261         CEquihashInput I{*pblock};
262         CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
263         ss << I;
264
265         // H(I||...
266         crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size());
267
268         while (true) {
269             // Yes, there is a chance every nonce could fail to satisfy the -regtest
270             // target -- 1 in 2^(2^256). That ain't gonna happen
271             pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
272
273             // H(I||V||...
274             crypto_generichash_blake2b_state curr_state;
275             curr_state = eh_state;
276             crypto_generichash_blake2b_update(&curr_state,
277                                               pblock->nNonce.begin(),
278                                               pblock->nNonce.size());
279
280             // (x_1, x_2, ...) = A(I, V, n, k)
281             std::function<bool(std::vector<unsigned char>)> validBlock =
282                     [&pblock](std::vector<unsigned char> soln)
283             {
284                 LOCK(cs_main);
285                 pblock->nSolution = soln;
286                 solutionTargetChecks.increment();
287                 return CheckProofOfWork(*pblock,NOTARY_PUBKEY33,chainActive.Height(),Params().GetConsensus());
288             };
289             bool found = EhBasicSolveUncancellable(n, k, curr_state, validBlock);
290             ehSolverRuns.increment();
291             if (found) {
292                 goto endloop;
293             }
294         }
295 endloop:
296         CValidationState state;
297         if (!ProcessNewBlock(1, chainActive.LastTip()->GetHeight()+1, state, Params(), NULL, pblock, true, NULL))
298             throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
299         ++nHeight;
300         blockHashes.push_back(pblock->GetHash().GetHex());
301
302         //mark script as important because it was used at least for one coinbase output
303         reservekey.KeepKey();
304     }
305     return blockHashes;
306 }
307
308 UniValue setgenerate(const UniValue& params, bool fHelp)
309 {
310     if (fHelp || params.size() < 1 || params.size() > 2)
311         throw runtime_error(
312             "setgenerate generate ( genproclimit )\n"
313             "\nSet 'generate' true to turn either mining/generation or minting/staking on and false to turn both off.\n"
314             "Mining is limited to 'genproclimit' processors, -1 is unlimited, setgenerate true with 0 genproclimit turns on staking\n"
315             "See the getgenerate call for the current setting.\n"
316             "\nArguments:\n"
317             "1. generate         (boolean, required) Set to true to turn on generation, off to turn off.\n"
318             "2. genproclimit     (numeric, optional) Set processor limit when generation is on. Can be -1 for unlimited, 0 to turn on staking.\n"
319             "\nExamples:\n"
320             "\nSet the generation on with a limit of one processor\n"
321             + HelpExampleCli("setgenerate", "true 1") +
322             "\nTurn minting/staking on\n"
323             + HelpExampleCli("setgenerate", "true 0") +
324             "\nCheck the setting\n"
325             + HelpExampleCli("getgenerate", "") +
326             "\nTurn off generation and minting\n"
327             + HelpExampleCli("setgenerate", "false") +
328             "\nUsing json rpc\n"
329             + HelpExampleRpc("setgenerate", "true, 1")
330         );
331
332     if (GetArg("-mineraddress", "").empty()) {
333 #ifdef ENABLE_WALLET
334         if (!pwalletMain) {
335             throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
336         }
337 #else
338         throw JSONRPCError(RPC_METHOD_NOT_FOUND, "verusd compiled without wallet and -mineraddress not set");
339 #endif
340     }
341     if (Params().MineBlocksOnDemand())
342         throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network");
343
344     bool fGenerate = true;
345     if (params.size() > 0)
346         fGenerate = params[0].get_bool();
347
348     int nGenProcLimit = GetArg("-genproclimit", -1);
349     int gpl = -1;
350     if (params.size() > 1)
351     {
352         gpl = params[1].get_int();
353         if (gpl != 0)
354         {
355             nGenProcLimit = gpl;
356         }
357     }
358     else
359     {
360         VERUS_MINTBLOCKS = 1;
361         KOMODO_MININGTHREADS = -1;
362     }
363
364     if (fGenerate && !gpl && params.size() > 1)
365     {
366         VERUS_MINTBLOCKS = 1;
367     }
368     else if (!fGenerate)
369     {
370         VERUS_MINTBLOCKS = 0;
371         KOMODO_MININGTHREADS = 0;
372     }
373     else
374     {
375         KOMODO_MININGTHREADS = (int32_t)nGenProcLimit;
376     }
377
378     mapArgs["-gen"] = (fGenerate ? "1" : "0");
379     mapArgs ["-genproclimit"] = itostr(KOMODO_MININGTHREADS);
380
381 #ifdef ENABLE_WALLET
382     GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
383 #else
384     GenerateBitcoins(fGenerate, nGenProcLimit);
385 #endif
386
387     return NullUniValue;
388 }
389 #endif
390
391 UniValue getmininginfo(const UniValue& params, bool fHelp)
392 {
393     if (fHelp || params.size() != 0)
394         throw runtime_error(
395             "getmininginfo\n"
396             "\nReturns a json object containing mining-related information."
397             "\nResult:\n"
398             "{\n"
399             "  \"blocks\": nnn,             (numeric) The current block\n"
400             "  \"currentblocksize\": nnn,   (numeric) The last block size\n"
401             "  \"currentblocktx\": nnn,     (numeric) The last block transaction\n"
402             "  \"averageblockfees\": xxx.xxxxx (numeric) The average block fees, in addition to block reward, over the past 100 blocks\n"
403             "  \"difficulty\": xxx.xxxxx    (numeric) The current difficulty\n"
404             "  \"stakingsupply\": xxx.xxxxx (numeric) The current estimated total staking supply\n"
405             "  \"errors\": \"...\"          (string) Current errors\n"
406             "  \"generate\": true|false     (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
407             "  \"genproclimit\": n          (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
408             "  \"localsolps\": xxx.xxxxx    (numeric) The average local solution rate in Sol/s since this node was started\n"
409             "  \"networksolps\": x          (numeric) The estimated network solution rate in Sol/s\n"
410             "  \"pooledtx\": n              (numeric) The size of the mem pool\n"
411             "  \"testnet\": true|false      (boolean) If using testnet or not\n"
412             "  \"chain\": \"xxxx\",         (string) current network name as defined in BIP70 (main, test, regtest)\n"
413 #ifdef ENABLE_MINING
414             "  \"generate\": true|false     (boolean) If this instance is mining or staking\n"
415             "  \"staking\": true|false      (boolean) If staking\n"
416             "  \"numthreads\": n            (numeric) Number of CPU threads mining\n"
417             "  \"mergemining\": n           (numeric) Number of blockchains we are merge mining with\n"
418             "  \"mergeminedchains\": []     (optional, list of names) Blockchain names that are being merge mined with this blockchain\n"
419 #endif
420             "}\n"
421             "\nExamples:\n"
422             + HelpExampleCli("getmininginfo", "")
423             + HelpExampleRpc("getmininginfo", "")
424         );
425
426
427     LOCK(cs_main);
428
429     auto consensus = Params().GetConsensus();
430     uint32_t height = chainActive.Height();
431     CAmount estimatedStakingSupply = 0;
432     CAmount avgBlockFees = 0;
433     bool avgBlockFeesValid = true;
434
435     if (height > 200)
436     {
437         int first = height - 100;
438
439         arith_uint256 bigTotalFees(0);
440         arith_uint256 totalChainStake(0);
441         arith_uint256 bnStakeTarget;
442         int posCount = 0;
443
444         for (int i = first; i < height; i++)
445         {
446             CBlockIndex &index = *chainActive[i];
447             CBlock block;
448
449             if (avgBlockFeesValid && komodo_blockload(block, &index))
450             {
451                 avgBlockFeesValid = false;
452                 LogPrintf("%s: failed to estimate average block fees\n", __func__);
453             }
454             else
455             {
456                 // subtract block reward from total output of coinbase and add the rest for an average
457                 bigTotalFees = bigTotalFees + arith_uint256(block.vtx[0].GetValueOut() - GetBlockSubsidy(index.GetHeight(), consensus));
458             }
459
460             // if POS block, add stake
461             uint256 posWinVal;
462             if (i > 100 && index.IsVerusPOSBlock())
463             {
464                 bnStakeTarget.SetCompact(index.GetVerusPOSTarget());
465
466                 if (bnStakeTarget == 0)
467                 {
468                     totalChainStake = 0;
469                     avgBlockFees = false;
470                     LogPrintf("%s: failed to estimate staking supply\n", __func__);
471                     break;
472                 }
473
474                 // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
475                 // as it's too large for a arith_uint256. However, as 2**256 is at least as large
476                 // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
477                 // or ~bnTarget / (nTarget+1) + 1.
478                 totalChainStake = totalChainStake + (~bnStakeTarget / (bnStakeTarget + 1)) + 1;
479                 posCount++;
480             }
481         }
482
483         avgBlockFees = avgBlockFeesValid ? (bigTotalFees / arith_uint256(height - first)).GetLow64() : 0;
484
485         if (posCount > 5)
486         {
487             totalChainStake = totalChainStake / arith_uint256(height - first);
488         }
489
490         if (totalChainStake > arith_uint256(INT64_MAX))
491         {
492             LogPrintf("%s: overflow estimating staking supply\n", __func__);
493         }
494         else
495         {
496             estimatedStakingSupply = totalChainStake.GetLow64();
497         }
498     }
499
500     UniValue obj(UniValue::VOBJ);
501     obj.push_back(Pair("blocks",           (int)height));
502     obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
503     obj.push_back(Pair("currentblocktx",   (uint64_t)nLastBlockTx));
504     obj.push_back(Pair("averageblockfees", ValueFromAmount(avgBlockFees)));
505     obj.push_back(Pair("difficulty",       (double)GetNetworkDifficulty()));
506     obj.push_back(Pair("stakingsupply",    ValueFromAmount(estimatedStakingSupply)));
507     obj.push_back(Pair("errors",           GetWarnings("statusbar")));
508     obj.push_back(Pair("genproclimit",     (int)GetArg("-genproclimit", -1)));
509     if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH)
510     {
511         obj.push_back(Pair("localsolps"  , getlocalsolps(params, false)));
512         obj.push_back(Pair("networksolps", getnetworksolps(params, false)));
513     }
514     else
515     {
516         obj.push_back(Pair("localhashps"  , GetBoolArg("-gen", false) ? getlocalsolps(params, false) : (double)0.0));
517     }
518     obj.push_back(Pair("networkhashps",    getnetworksolps(params, false)));
519     obj.push_back(Pair("pooledtx",         (uint64_t)mempool.size()));
520     obj.push_back(Pair("testnet",          Params().TestnetToBeDeprecatedFieldRPC()));
521     obj.push_back(Pair("chain",            Params().NetworkIDString()));
522 #ifdef ENABLE_MINING
523     bool mining = GetBoolArg("-gen", false);
524     obj.push_back(Pair("generate",         mining));
525     obj.push_back(Pair("staking",          VERUS_MINTBLOCKS));
526
527     auto chains = ConnectedChains.GetMergeMinedChains();
528     bool mergeMining = mining && ((!IsVerusActive() && ConnectedChains.IsVerusPBaaSAvailable()) || (IsVerusActive() && chains.size()));
529     int numChains = mergeMining ? (IsVerusActive() ? chains.size() + 1 : 1) : 0;
530     obj.push_back(Pair("numthreads",       (int64_t)KOMODO_MININGTHREADS));
531     obj.push_back(Pair("mergemining",      numChains));
532     if (chains.size() || numChains)
533     {
534         UniValue chainNames(UniValue::VARR);
535         for (auto chain : chains)
536         {
537             chainNames.push_back(chain.name);
538         }
539         obj.push_back(Pair("mergeminedchains", chainNames));
540     }
541 #endif
542     return obj;
543 }
544
545
546 // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
547 UniValue prioritisetransaction(const UniValue& params, bool fHelp)
548 {
549     if (fHelp || params.size() != 3)
550         throw runtime_error(
551             "prioritisetransaction <txid> <priority delta> <fee delta>\n"
552             "Accepts the transaction into mined blocks at a higher (or lower) priority\n"
553             "\nArguments:\n"
554             "1. \"txid\"       (string, required) The transaction id.\n"
555             "2. priority delta (numeric, required) The priority to add or subtract.\n"
556             "                  The transaction selection algorithm considers the tx as it would have a higher priority.\n"
557             "                  (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n"
558             "3. fee delta      (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n"
559             "                  The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
560             "                  considers the transaction as it would have paid a higher (or lower) fee.\n"
561             "\nResult\n"
562             "true              (boolean) Returns true\n"
563             "\nExamples:\n"
564             + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
565             + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
566         );
567
568     LOCK(cs_main);
569
570     uint256 hash = ParseHashStr(params[0].get_str(), "txid");
571     CAmount nAmount = params[2].get_int64();
572
573     mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount);
574     return true;
575 }
576
577
578 // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
579 static UniValue BIP22ValidationResult(const CValidationState& state)
580 {
581     if (state.IsValid())
582         return NullUniValue;
583
584     std::string strRejectReason = state.GetRejectReason();
585     if (state.IsError())
586         throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason);
587     if (state.IsInvalid())
588     {
589         if (strRejectReason.empty())
590             return "rejected";
591         return strRejectReason;
592     }
593     // Should be impossible
594     return "valid?";
595 }
596
597 UniValue getblocktemplate(const UniValue& params, bool fHelp)
598 {
599     if (fHelp || params.size() > 1)
600         throw runtime_error(
601             "getblocktemplate ( \"jsonrequestobject\" )\n"
602             "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
603             "It returns data needed to construct a block to work on.\n"
604             "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
605
606             "\nArguments:\n"
607             "1. \"jsonrequestobject\"       (string, optional) A json object in the following spec\n"
608             "     {\n"
609             "       \"mode\":\"template\"    (string, optional) This must be set to \"template\" or omitted\n"
610             "       \"capabilities\":[       (array, optional) A list of strings\n"
611             "           \"support\"           (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
612             "           ,...\n"
613             "         ]\n"
614             "     }\n"
615             "\n"
616
617             "\nResult:\n"
618             "{\n"
619             "  \"version\" : n,                     (numeric) The block version\n"
620             "  \"previousblockhash\" : \"xxxx\",    (string) The hash of current highest block\n"
621             "  \"finalsaplingroothash\" : \"xxxx\", (string) The hash of the final sapling root\n"
622             "  \"transactions\" : [                 (array) contents of non-coinbase transactions that should be included in the next block\n"
623             "      {\n"
624             "         \"data\" : \"xxxx\",          (string) transaction data encoded in hexadecimal (byte-for-byte)\n"
625             "         \"hash\" : \"xxxx\",          (string) hash/id encoded in little-endian hexadecimal\n"
626             "         \"depends\" : [              (array) array of numbers \n"
627             "             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"
628             "             ,...\n"
629             "         ],\n"
630             "         \"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"
631             "         \"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"
632             "         \"required\" : true|false     (boolean) if provided and true, this transaction must be in the final block\n"
633             "      }\n"
634             "      ,...\n"
635             "  ],\n"
636 //            "  \"coinbaseaux\" : {                  (json object) data that should be included in the coinbase's scriptSig content\n"
637 //            "      \"flags\" : \"flags\"            (string) \n"
638 //            "  },\n"
639 //            "  \"coinbasevalue\" : n,               (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
640             "  \"coinbasetxn\" : { ... },           (json object) information for coinbase transaction\n"
641             "  \"target\" : \"xxxx\",               (string) The hash target\n"
642             "  \"mintime\" : xxx,                   (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
643             "  \"mutable\" : [                      (array of string) list of ways the block template may be changed \n"
644             "     \"value\"                         (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n"
645             "     ,...\n"
646             "  ],\n"
647             "  \"noncerange\" : \"00000000ffffffff\",   (string) A range of valid nonces\n"
648             "  \"sigoplimit\" : n,                 (numeric) limit of sigops in blocks\n"
649             "  \"sizelimit\" : n,                  (numeric) limit of block size\n"
650             "  \"curtime\" : ttt,                  (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
651             "  \"bits\" : \"xxx\",                 (string) compressed target of next block\n"
652             "  \"height\" : n                      (numeric) The height of the next block\n"
653             "}\n"
654
655             "\nExamples:\n"
656             + HelpExampleCli("getblocktemplate", "")
657             + HelpExampleRpc("getblocktemplate", "")
658          );
659
660     LOCK(cs_main);
661
662     // Wallet or miner address is required because we support coinbasetxn
663     if (GetArg("-mineraddress", "").empty()) {
664 #ifdef ENABLE_WALLET
665         if (!pwalletMain) {
666             throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
667         }
668 #else
669         throw JSONRPCError(RPC_METHOD_NOT_FOUND, "verusd compiled without wallet and -mineraddress not set");
670 #endif
671     }
672
673     std::string strMode = "template";
674     UniValue lpval = NullUniValue;
675
676     // TODO: Re-enable coinbasevalue once a specification has been written
677     bool coinbasetxn = true;
678
679     if (params.size() > 0)
680     {
681         const UniValue& oparam = params[0].get_obj();
682         const UniValue& modeval = find_value(oparam, "mode");
683         if (modeval.isStr())
684             strMode = modeval.get_str();
685         else if (modeval.isNull())
686         {
687             /* Do nothing */
688         }
689         else
690             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
691         lpval = find_value(oparam, "longpollid");
692
693         if (strMode == "proposal")
694         {
695             const UniValue& dataval = find_value(oparam, "data");
696             if (!dataval.isStr())
697                 throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
698
699             CBlock block;
700             if (!DecodeHexBlk(block, dataval.get_str()))
701                 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
702
703             uint256 hash = block.GetHash();
704             BlockMap::iterator mi = mapBlockIndex.find(hash);
705             if (mi != mapBlockIndex.end()) {
706                 CBlockIndex *pindex = mi->second;
707                 if (pindex)
708                 {
709                     if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
710                         return "duplicate";
711                     if (pindex->nStatus & BLOCK_FAILED_MASK)
712                         return "duplicate-invalid";
713                 }
714                 return "duplicate-inconclusive";
715             }
716
717             CBlockIndex* const pindexPrev = chainActive.LastTip();
718             // TestBlockValidity only supports blocks built on the current Tip
719             if (block.hashPrevBlock != pindexPrev->GetBlockHash())
720                 return "inconclusive-not-best-prevblk";
721             CValidationState state;
722             TestBlockValidity(state, Params(), block, pindexPrev, false, true);
723             return BIP22ValidationResult(state);
724         }
725     }
726
727     if (strMode != "template")
728         throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
729
730     bool fvNodesEmpty;
731     {
732         LOCK(cs_vNodes);
733         fvNodesEmpty = vNodes.empty();
734     }
735     if (Params().MiningRequiresPeers() && (IsNotInSync() || fvNodesEmpty))
736     {
737         throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Cannot get a block template while no peers are connected or chain not in sync!");
738     }
739
740     //if (IsInitialBlockDownload())
741     //   throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Zcash is downloading blocks...");
742
743     static unsigned int nTransactionsUpdatedLast;
744
745     if (!lpval.isNull())
746     {
747         // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
748         uint256 hashWatchedChain;
749         boost::system_time checktxtime;
750         unsigned int nTransactionsUpdatedLastLP;
751
752         if (lpval.isStr())
753         {
754             // Format: <hashBestChain><nTransactionsUpdatedLast>
755             std::string lpstr = lpval.get_str();
756
757             hashWatchedChain.SetHex(lpstr.substr(0, 64));
758             nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64));
759         }
760         else
761         {
762             // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
763             hashWatchedChain = chainActive.LastTip()->GetBlockHash();
764             nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
765         }
766
767         // Release the wallet and main lock while waiting
768         LEAVE_CRITICAL_SECTION(cs_main);
769         {
770             checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
771
772             boost::unique_lock<boost::mutex> lock(csBestBlock);
773             while (chainActive.LastTip()->GetBlockHash() == hashWatchedChain && IsRPCRunning())
774             {
775                 if (!cvBlockChange.timed_wait(lock, checktxtime))
776                 {
777                     // Timeout: Check transactions for update
778                     if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
779                         break;
780                     checktxtime += boost::posix_time::seconds(10);
781                 }
782             }
783         }
784         ENTER_CRITICAL_SECTION(cs_main);
785
786         if (!IsRPCRunning())
787             throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
788         // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
789     }
790
791     // Update block
792     static CBlockIndex* pindexPrev;
793     static int64_t nStart;
794     static CBlockTemplate* pblocktemplate;
795     if (pindexPrev != chainActive.LastTip() ||
796         (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
797     {
798         // Clear pindexPrev so future calls make a new block, despite any failures from here on
799         pindexPrev = NULL;
800
801         // Store the pindexBest used before CreateNewBlockWithKey, to avoid races
802         nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
803         CBlockIndex* pindexPrevNew = chainActive.LastTip();
804         nStart = GetTime();
805
806         // Create new block
807         if(pblocktemplate)
808         {
809             delete pblocktemplate;
810             pblocktemplate = NULL;
811         }
812 #ifdef ENABLE_WALLET
813         CReserveKey reservekey(pwalletMain);
814         pblocktemplate = CreateNewBlockWithKey(reservekey,chainActive.LastTip()->GetHeight()+1,KOMODO_MAXGPUCOUNT);
815 #else
816         pblocktemplate = CreateNewBlockWithKey();
817 #endif
818
819         /* keep Zcash script-based approach for reference
820         boost::shared_ptr<CReserveScript> coinbaseScript;
821         GetMainSignals().ScriptForMining(coinbaseScript);
822
823         // Throw an error if no script was provided
824         if (!coinbaseScript->reserveScript.size())
825             throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet or -mineraddress)");
826
827         pblocktemplate = CreateNewBlock(Params(), coinbaseScript->reserveScript);
828         */
829
830         if (!pblocktemplate)
831             throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory or no available utxo for staking");
832
833         // Mark script as important because it was used at least for one coinbase output
834         //coinbaseScript->KeepScript();
835
836         // Need to update only after we know CreateNewBlock succeeded
837         pindexPrev = pindexPrevNew;
838     }
839     CBlock* pblock = &pblocktemplate->block; // pointer for convenience
840
841     // Update nTime
842     UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
843     pblock->nNonce = uint256();
844
845     UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
846
847     UniValue txCoinbase = NullUniValue;
848     UniValue transactions(UniValue::VARR);
849     map<uint256, int64_t> setTxIndex;
850     int i = 0;
851     BOOST_FOREACH (const CTransaction& tx, pblock->vtx) {
852         uint256 txHash = tx.GetHash();
853         setTxIndex[txHash] = i++;
854
855         if (tx.IsCoinBase() && !coinbasetxn)
856             continue;
857
858         UniValue entry(UniValue::VOBJ);
859
860         entry.push_back(Pair("data", EncodeHexTx(tx)));
861
862         entry.push_back(Pair("hash", txHash.GetHex()));
863
864         UniValue deps(UniValue::VARR);
865         BOOST_FOREACH (const CTxIn &in, tx.vin)
866         {
867             if (setTxIndex.count(in.prevout.hash))
868                 deps.push_back(setTxIndex[in.prevout.hash]);
869         }
870         entry.push_back(Pair("depends", deps));
871
872         int index_in_template = i - 1;
873         entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
874         entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
875
876         if (tx.IsCoinBase()) {
877             // Show founders' reward if it is required
878             //if (pblock->vtx[0].vout.size() > 1) {
879                 // Correct this if GetBlockTemplate changes the order
880             //    entry.push_back(Pair("foundersreward", (int64_t)tx.vout[1].nValue));
881             //}
882             CAmount nReward = GetBlockSubsidy(chainActive.LastTip()->GetHeight()+1, Params().GetConsensus());
883             entry.push_back(Pair("coinbasevalue", nReward));
884             entry.push_back(Pair("required", true));
885             txCoinbase = entry;
886         } else
887             transactions.push_back(entry);
888     }
889
890     UniValue aux(UniValue::VOBJ);
891     aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
892
893     arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
894
895     static UniValue aMutable(UniValue::VARR);
896     if (aMutable.empty())
897     {
898         aMutable.push_back("time");
899         aMutable.push_back("transactions");
900         aMutable.push_back("prevblock");
901     }
902
903     UniValue result(UniValue::VOBJ);
904     result.push_back(Pair("capabilities", aCaps));
905     result.push_back(Pair("version", pblock->nVersion));
906     result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
907     result.push_back(Pair("finalsaplingroothash", pblock->hashFinalSaplingRoot.GetHex()));
908
909     if (CConstVerusSolutionVector::Version(pblock->nSolution) >= CActivationHeight::ACTIVATE_VERUSHASH2_1)
910     {
911         result.push_back(Pair("solution", HexBytes(pblock->nSolution.data(), pblock->nSolution.size())));
912     }
913     result.push_back(Pair("transactions", transactions));
914     if (coinbasetxn) {
915         assert(txCoinbase.isObject());
916         result.push_back(Pair("coinbasetxn", txCoinbase));
917     } else {
918         result.push_back(Pair("coinbaseaux", aux));
919         result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
920     }
921     result.push_back(Pair("longpollid", chainActive.LastTip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
922     if ( ASSETCHAINS_STAKED != 0 )
923     {
924         arith_uint256 POWtarget; int32_t PoSperc;
925         POWtarget = komodo_PoWtarget(&PoSperc,hashTarget,(int32_t)(pindexPrev->GetHeight()+1),ASSETCHAINS_STAKED);
926         result.push_back(Pair("target", POWtarget.GetHex()));
927         result.push_back(Pair("PoSperc", (int64_t)PoSperc));
928         result.push_back(Pair("ac_staked", (int64_t)ASSETCHAINS_STAKED));
929         result.push_back(Pair("origtarget", hashTarget.GetHex()));
930     } else result.push_back(Pair("target", hashTarget.GetHex()));
931     result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
932     result.push_back(Pair("mutable", aMutable));
933     result.push_back(Pair("noncerange", "00000000ffffffff"));
934     result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
935     result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
936     result.push_back(Pair("curtime", pblock->GetBlockTime()));
937     result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
938     result.push_back(Pair("height", (int64_t)(pindexPrev->GetHeight()+1)));
939
940     //fprintf(stderr,"return complete template\n");
941     return result;
942 }
943
944 class submitblock_StateCatcher : public CValidationInterface
945 {
946 public:
947     uint256 hash;
948     bool found;
949     CValidationState state;
950
951     submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {};
952
953 protected:
954     virtual void BlockChecked(const CBlock& block, const CValidationState& stateIn) {
955         if (block.GetHash() != hash)
956             return;
957         found = true;
958         state = stateIn;
959     };
960 };
961
962 UniValue submitblock(const UniValue& params, bool fHelp)
963 {
964     if (fHelp || params.size() < 1 || params.size() > 2)
965         throw runtime_error(
966             "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
967             "\nAttempts to submit new block to network.\n"
968             "The 'jsonparametersobject' parameter is currently ignored.\n"
969             "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
970
971             "\nArguments\n"
972             "1. \"hexdata\"    (string, required) the hex-encoded block data to submit\n"
973             "2. \"jsonparametersobject\"     (string, optional) object of optional parameters\n"
974             "    {\n"
975             "      \"workid\" : \"id\"    (string, optional) if the server provided a workid, it MUST be included with submissions\n"
976             "    }\n"
977             "\nResult:\n"
978             "\"duplicate\" - node already has valid copy of block\n"
979             "\"duplicate-invalid\" - node already has block, but it is invalid\n"
980             "\"duplicate-inconclusive\" - node already has block but has not validated it\n"
981             "\"inconclusive\" - node has not validated the block, it may not be on the node's current best chain\n"
982             "\"rejected\" - block was rejected as invalid\n"
983             "For more information on submitblock parameters and results, see: https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki#block-submission\n"
984             "\nExamples:\n"
985             + HelpExampleCli("submitblock", "\"mydata\"")
986             + HelpExampleRpc("submitblock", "\"mydata\"")
987         );
988
989     CBlock block;
990     try
991     {
992         //LogPrintStr("Hex block submission: " + params[0].get_str());
993         if (!DecodeHexBlk(block, params[0].get_str()))
994             throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
995     }
996     catch (exception e)
997     {
998         printf("Exception: %s\n", e.what());
999         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
1000     }
1001
1002     printf("Received block submission for %s\nhash: %s\n", ASSETCHAINS_SYMBOL, block.GetHash().GetHex().c_str());
1003
1004     uint256 hash = block.GetHash();
1005     bool fBlockPresent = false;
1006     {
1007         LOCK(cs_main);
1008         BlockMap::iterator mi = mapBlockIndex.find(hash);
1009         if (mi != mapBlockIndex.end()) {
1010             CBlockIndex *pindex = mi->second;
1011             if (pindex)
1012             {
1013                 printf("Already have block %s\n", block.GetHash().GetHex().c_str());
1014
1015                 if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
1016                     return "duplicate";
1017                 if (pindex->nStatus & BLOCK_FAILED_MASK)
1018                     return "duplicate-invalid";
1019                 // Otherwise, we might only have the header - process the block before returning
1020                 fBlockPresent = true;
1021             }
1022         }
1023     }
1024
1025     CValidationState state;
1026     submitblock_StateCatcher sc(block.GetHash());
1027     bool fAccepted;
1028     CCriticalSection cs_blocksubmission;
1029     {
1030         LOCK(cs_blocksubmission);
1031         RegisterValidationInterface(&sc);
1032         //printf("submitblock, height=%d, coinbase sequence: %d, scriptSig: %s\n", chainActive.LastTip()->GetHeight()+1, block.vtx[0].vin[0].nSequence, block.vtx[0].vin[0].scriptSig.ToString().c_str());
1033         fAccepted = ProcessNewBlock(1,chainActive.LastTip()->GetHeight()+1, state, Params(), NULL, &block, true, NULL);
1034         UnregisterValidationInterface(&sc);
1035     }
1036     if (fBlockPresent || !fAccepted || !sc.found)
1037     {
1038         //printf("Block was not accepted %s\n", state.GetRejectReason().c_str());
1039         ConnectedChains.lastSubmissionFailed = true;
1040     }
1041     if (fBlockPresent)
1042     {
1043         if (fAccepted && !sc.found)
1044             return "duplicate-inconclusive";
1045         return "duplicate";
1046     }
1047     if (fAccepted)
1048     {
1049         if (!sc.found)
1050             return "inconclusive";
1051         state = sc.state;
1052     }
1053     return BIP22ValidationResult(state);
1054 }
1055
1056 UniValue estimatefee(const UniValue& params, bool fHelp)
1057 {
1058     if (fHelp || params.size() != 1)
1059         throw runtime_error(
1060             "estimatefee nblocks\n"
1061             "\nEstimates the approximate fee per kilobyte\n"
1062             "needed for a transaction to begin confirmation\n"
1063             "within nblocks blocks.\n"
1064             "\nArguments:\n"
1065             "1. nblocks     (numeric)\n"
1066             "\nResult:\n"
1067             "n :    (numeric) estimated fee-per-kilobyte\n"
1068             "\n"
1069             "minimum fee is returned if not enough transactions and\n"
1070             "blocks have been observed to make an estimate.\n"
1071             "\nExample:\n"
1072             + HelpExampleCli("estimatefee", "6")
1073             );
1074
1075     RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
1076
1077     int nBlocks = params[0].get_int();
1078     if (nBlocks < 1)
1079         nBlocks = 1;
1080
1081     CFeeRate feeRate = mempool.estimateFee(nBlocks);
1082     if (feeRate == CFeeRate(0))
1083     {
1084         feeRate = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
1085     }
1086     return ValueFromAmount(feeRate.GetFeePerK());
1087 }
1088
1089 UniValue estimatepriority(const UniValue& params, bool fHelp)
1090 {
1091     if (fHelp || params.size() != 1)
1092         throw runtime_error(
1093             "estimatepriority nblocks\n"
1094             "\nEstimates the approximate priority\n"
1095             "a zero-fee transaction needs to begin confirmation\n"
1096             "within nblocks blocks.\n"
1097             "\nArguments:\n"
1098             "1. nblocks     (numeric)\n"
1099             "\nResult:\n"
1100             "n :    (numeric) estimated priority\n"
1101             "\n"
1102             "-1.0 is returned if not enough transactions and\n"
1103             "blocks have been observed to make an estimate.\n"
1104             "\nExample:\n"
1105             + HelpExampleCli("estimatepriority", "6")
1106             );
1107
1108     RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
1109
1110     int nBlocks = params[0].get_int();
1111     if (nBlocks < 1)
1112         nBlocks = 1;
1113
1114     return mempool.estimatePriority(nBlocks);
1115 }
1116
1117 UniValue getblocksubsidy(const UniValue& params, bool fHelp)
1118 {
1119     if (fHelp || params.size() > 1)
1120         throw runtime_error(
1121             "getblocksubsidy height\n"
1122             "\nReturns block subsidy reward, taking into account the mining slow start and the founders reward, of block at index provided.\n"
1123             "\nArguments:\n"
1124             "1. height         (numeric, optional) The block height.  If not provided, defaults to the current height of the chain.\n"
1125             "\nResult:\n"
1126             "{\n"
1127             "  \"miner\" : x.xxx           (numeric) The mining reward amount in KMD.\n"
1128             "}\n"
1129             "\nExamples:\n"
1130             + HelpExampleCli("getblocksubsidy", "1000")
1131             + HelpExampleRpc("getblockubsidy", "1000")
1132         );
1133
1134     LOCK(cs_main);
1135     int nHeight = (params.size()==1) ? params[0].get_int() : chainActive.Height();
1136     if (nHeight < 0)
1137         throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
1138
1139     CAmount nReward = GetBlockSubsidy(nHeight, Params().GetConsensus());
1140     UniValue result(UniValue::VOBJ);
1141     result.push_back(Pair("miner", ValueFromAmount(nReward)));
1142     //result.push_back(Pair("founders", ValueFromAmount(nFoundersReward)));
1143     return result;
1144 }
1145
1146 static const CRPCCommand commands[] =
1147 { //  category              name                      actor (function)         okSafeMode
1148   //  --------------------- ------------------------  -----------------------  ----------
1149     { "mining",             "getlocalsolps",          &getlocalsolps,          true  },
1150     { "mining",             "getnetworksolps",        &getnetworksolps,        true  },
1151     { "mining",             "getnetworkhashps",       &getnetworkhashps,       true  },
1152     { "mining",             "getmininginfo",          &getmininginfo,          true  },
1153     { "mining",             "prioritisetransaction",  &prioritisetransaction,  true  },
1154     { "mining",             "getblocktemplate",       &getblocktemplate,       true  },
1155     { "mining",             "submitblock",            &submitblock,            true  },
1156     { "mining",             "getblocksubsidy",        &getblocksubsidy,        true  },
1157
1158 #ifdef ENABLE_MINING
1159     { "generating",         "getgenerate",            &getgenerate,            true  },
1160     { "generating",         "setgenerate",            &setgenerate,            true  },
1161     { "generating",         "generate",               &generate,               true  },
1162 #endif
1163
1164     { "util",               "estimatefee",            &estimatefee,            true  },
1165     { "util",               "estimatepriority",       &estimatepriority,       true  },
1166 };
1167
1168 void RegisterMiningRPCCommands(CRPCTable &tableRPC)
1169 {
1170     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
1171         tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
1172 }
This page took 0.090901 seconds and 4 git commands to generate.