Line data Source code
1 : // Copyright (c) 2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2021 The Bitcoin Core developers
3 : // Copyright (c) 2014-2025 The Dash Core developers
4 : // Distributed under the MIT software license, see the accompanying
5 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 :
7 : #include <chain.h>
8 : #include <chainparams.h>
9 : #include <consensus/amount.h>
10 : #include <consensus/consensus.h>
11 : #include <consensus/merkle.h>
12 : #include <consensus/params.h>
13 : #include <consensus/validation.h>
14 : #include <core_io.h>
15 : #include <deploymentinfo.h>
16 : #include <deploymentstatus.h>
17 : #include <governance/superblock.h>
18 : #include <key_io.h>
19 : #include <llmq/blockprocessor.h>
20 : #include <llmq/context.h>
21 : #include <evo/evodb.h>
22 : #include <masternode/sync.h>
23 : #include <net.h>
24 : #include <node/context.h>
25 : #include <node/miner.h>
26 : #include <pow.h>
27 : #include <rpc/blockchain.h>
28 : #include <rpc/mining.h>
29 : #include <rpc/server.h>
30 : #include <rpc/server_util.h>
31 : #include <rpc/util.h>
32 : #include <script/descriptor.h>
33 : #include <script/script.h>
34 : #include <script/sign.h>
35 : #include <shutdown.h>
36 : #include <txmempool.h>
37 : #include <univalue.h>
38 : #include <util/check.h>
39 : #include <util/strencodings.h>
40 : #include <util/string.h>
41 : #include <util/system.h>
42 : #include <util/translation.h>
43 : #include <validation.h>
44 : #include <validationinterface.h>
45 : #include <warnings.h>
46 :
47 : #include <memory>
48 : #include <stdint.h>
49 :
50 : using node::BlockAssembler;
51 : using node::CBlockTemplate;
52 : using node::NodeContext;
53 : using node::UpdateTime;
54 :
55 : /**
56 : * Return average network hashes per second based on the last 'lookup' blocks,
57 : * or from the last difficulty change if 'lookup' is nonpositive.
58 : * If 'height' is nonnegative, compute the estimate at the time when a given block was found.
59 : */
60 28 : static UniValue GetNetworkHashPS(int lookup, int height, const CChain& active_chain) {
61 28 : const CBlockIndex* pb = active_chain.Tip();
62 :
63 28 : if (height >= 0 && height < active_chain.Height()) {
64 0 : pb = active_chain[height];
65 0 : }
66 :
67 28 : if (pb == nullptr || !pb->nHeight)
68 0 : return 0;
69 :
70 : // If lookup is -1, then use blocks since last difficulty change.
71 28 : if (lookup <= 0)
72 8 : lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1;
73 :
74 : // If lookup is larger than chain, then set it to chain length.
75 28 : if (lookup > pb->nHeight)
76 12 : lookup = pb->nHeight;
77 :
78 28 : const CBlockIndex* pb0 = pb;
79 28 : int64_t minTime = pb0->GetBlockTime();
80 28 : int64_t maxTime = minTime;
81 4348 : for (int i = 0; i < lookup; i++) {
82 4320 : pb0 = pb0->pprev;
83 4320 : int64_t time = pb0->GetBlockTime();
84 4320 : minTime = std::min(time, minTime);
85 4320 : maxTime = std::max(time, maxTime);
86 4320 : }
87 :
88 : // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
89 28 : if (minTime == maxTime)
90 0 : return 0;
91 :
92 28 : arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
93 28 : int64_t timeDiff = maxTime - minTime;
94 :
95 28 : return workDiff.getdouble() / timeDiff;
96 28 : }
97 :
98 6184 : static RPCHelpMan getnetworkhashps()
99 : {
100 12368 : return RPCHelpMan{"getnetworkhashps",
101 6184 : "\nReturns the estimated network hashes per second based on the last n blocks.\n"
102 : "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
103 : "Pass in [height] to estimate the network speed at the time when a certain block was found.\n",
104 18552 : {
105 6184 : {"nblocks", RPCArg::Type::NUM, RPCArg::Default{120}, "The number of blocks, or -1 for blocks since last difficulty change."},
106 6184 : {"height", RPCArg::Type::NUM, RPCArg::Default{-1}, "To estimate at the time of the given height."},
107 : },
108 6184 : RPCResult{
109 6184 : RPCResult::Type::NUM, "", "Hashes per second estimated"},
110 6184 : RPCExamples{
111 6184 : HelpExampleCli("getnetworkhashps", "")
112 6184 : + HelpExampleRpc("getnetworkhashps", "")
113 : },
114 6212 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
115 : {
116 :
117 28 : ChainstateManager& chainman = EnsureAnyChainman(request.context);
118 28 : LOCK(cs_main);
119 28 : return GetNetworkHashPS(self.Arg<int>(0), self.Arg<int>(1), chainman.ActiveChain());
120 28 : },
121 : };
122 0 : }
123 :
124 : #if ENABLE_MINER
125 62626 : static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& max_tries, uint256& block_hash)
126 : {
127 62626 : block_hash.SetNull();
128 62626 : block.hashMerkleRoot = BlockMerkleRoot(block);
129 :
130 62626 : const CChainParams& chainparams(Params());
131 :
132 126177 : while (max_tries > 0 && block.nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus()) && !ShutdownRequested()) {
133 63551 : ++block.nNonce;
134 63551 : --max_tries;
135 : }
136 62626 : if (max_tries == 0 || ShutdownRequested()) {
137 0 : return false;
138 : }
139 62626 : if (block.nNonce == std::numeric_limits<uint32_t>::max()) {
140 0 : return true;
141 : }
142 :
143 62626 : std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
144 62626 : if (!chainman.ProcessNewBlock(shared_pblock, true, nullptr)) {
145 0 : throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
146 : }
147 :
148 62626 : block_hash = block.GetHash();
149 62626 : return true;
150 62626 : }
151 :
152 9398 : static UniValue generateBlocks(ChainstateManager& chainman, const NodeContext& node, const CTxMemPool& mempool, const CScript& coinbase_script,
153 : int nGenerate, uint64_t nMaxTries)
154 : {
155 9398 : EnsureLLMQContext(node);
156 :
157 9398 : UniValue blockHashes(UniValue::VARR);
158 72010 : while (nGenerate > 0 && !ShutdownRequested()) {
159 62612 : std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(chainman.ActiveChainstate(), node, &mempool, Params()).CreateNewBlock(coinbase_script));
160 62612 : if (!pblocktemplate.get())
161 0 : throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
162 62612 : CBlock *pblock = &pblocktemplate->block;
163 :
164 62612 : uint256 block_hash;
165 62612 : if (!GenerateBlock(chainman, *pblock, nMaxTries, block_hash)) {
166 0 : break;
167 : }
168 :
169 62612 : if (!block_hash.IsNull()) {
170 62612 : --nGenerate;
171 62612 : blockHashes.push_back(block_hash.GetHex());
172 62612 : }
173 62612 : }
174 9398 : return blockHashes;
175 9398 : }
176 :
177 1362 : static bool getScriptFromDescriptor(const std::string& descriptor, CScript& script, std::string& error)
178 : {
179 1362 : FlatSigningProvider key_provider;
180 1362 : const auto desc = Parse(descriptor, key_provider, error, /* require_checksum = */ false);
181 1362 : if (desc) {
182 1346 : if (desc->IsRange()) {
183 2 : throw JSONRPCError(RPC_INVALID_PARAMETER, "Ranged descriptor not accepted. Maybe pass through deriveaddresses first?");
184 : }
185 :
186 1344 : FlatSigningProvider provider;
187 1344 : std::vector<CScript> scripts;
188 1344 : if (!desc->Expand(0, key_provider, scripts, provider)) {
189 2 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys");
190 : }
191 :
192 : // Combo descriptors can have 2 or 4 scripts, so we can't just check scripts.size() == 1
193 1342 : CHECK_NONFATAL(scripts.size() > 0 && scripts.size() <= 4);
194 :
195 1342 : if (scripts.size() == 1) {
196 1340 : script = scripts.at(0);
197 1342 : } else if (scripts.size() == 4) {
198 : // For uncompressed keys, take the 3rd script, since it is p2wpkh
199 0 : script = scripts.at(2);
200 0 : } else {
201 : // Else take the 2nd script, since it is p2pkh
202 2 : script = scripts.at(1);
203 : }
204 :
205 1342 : return true;
206 1344 : } else {
207 16 : return false;
208 : }
209 1366 : }
210 :
211 7476 : static RPCHelpMan generatetodescriptor()
212 : {
213 7476 : return RPCHelpMan{
214 7476 : "generatetodescriptor",
215 7476 : "Mine to a specified descriptor and return the block hashes.",
216 29904 : {
217 7476 : {"num_blocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."},
218 7476 : {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor to send the newly generated coins to."},
219 7476 : {"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."},
220 : },
221 7476 : RPCResult{
222 7476 : RPCResult::Type::ARR, "", "",
223 14952 : {
224 7476 : {RPCResult::Type::STR_HEX, "blockhashes", "hashes of blocks generated"},
225 : }
226 : },
227 7476 : RPCExamples{
228 7476 : "\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")},
229 8812 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
230 : {
231 1336 : const auto num_blocks{self.Arg<int>(0)};
232 1336 : const auto max_tries{self.Arg<uint64_t>(2)};
233 :
234 1336 : CScript coinbase_script;
235 1336 : std::string error;
236 1336 : if (!getScriptFromDescriptor(self.Arg<std::string>(1), coinbase_script, error)) {
237 0 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
238 : }
239 :
240 1336 : const NodeContext& node = EnsureAnyNodeContext(request.context);
241 1336 : const CTxMemPool& mempool = EnsureMemPool(node);
242 1336 : ChainstateManager& chainman = EnsureChainman(node);
243 :
244 1336 : return generateBlocks(chainman, node, mempool, coinbase_script, num_blocks, max_tries);
245 1336 : },
246 : };
247 0 : }
248 :
249 14210 : static RPCHelpMan generatetoaddress()
250 : {
251 28420 : return RPCHelpMan{"generatetoaddress",
252 14210 : "\nMine to a specified address and return the block hashes.\n",
253 56840 : {
254 14210 : {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."},
255 14210 : {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The address to send the newly generated coins to."},
256 14210 : {"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."},
257 : },
258 14210 : RPCResult{
259 14210 : RPCResult::Type::ARR, "", "hashes of blocks generated",
260 28420 : {
261 14210 : {RPCResult::Type::STR_HEX, "", "blockhash"},
262 : }},
263 14210 : RPCExamples{
264 : "\nGenerate 11 blocks to myaddress\n"
265 14210 : + HelpExampleCli("generatetoaddress", "11 \"myaddress\"")
266 14210 : + "If you are using the " PACKAGE_NAME " wallet, you can get a new address to send the newly generated coins to with:\n"
267 14210 : + HelpExampleCli("getnewaddress", "")
268 : },
269 22274 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
270 : {
271 8064 : const int num_blocks{request.params[0].getInt<int>()};
272 8064 : const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].getInt<int>()};
273 :
274 8064 : CTxDestination destination = DecodeDestination(request.params[1].get_str());
275 8064 : if (!IsValidDestination(destination)) {
276 2 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address");
277 : }
278 :
279 8062 : const NodeContext& node = EnsureAnyNodeContext(request.context);
280 8062 : const CTxMemPool& mempool = EnsureMemPool(node);
281 8062 : ChainstateManager& chainman = EnsureChainman(node);
282 :
283 8062 : CScript coinbase_script = GetScriptForDestination(destination);
284 :
285 8062 : return generateBlocks(chainman, node, mempool, coinbase_script, num_blocks, max_tries);
286 8064 : },
287 : };
288 0 : }
289 :
290 6166 : static RPCHelpMan generateblock()
291 : {
292 12332 : return RPCHelpMan{"generateblock",
293 6166 : "Mine a set of ordered transactions to a specified address or descriptor and return the block hash.",
294 18498 : {
295 6166 : {"output", RPCArg::Type::STR, RPCArg::Optional::NO, "The address or descriptor to send the newly generated coins to."},
296 12332 : {"transactions", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings which are either txids or raw transactions.\n"
297 : "Txids must reference transactions currently in the mempool.\n"
298 : "All transactions must be valid and in valid order, otherwise the block will be rejected.",
299 12332 : {
300 6166 : {"rawtx/txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},
301 : },
302 : },
303 : },
304 6166 : RPCResult{
305 6166 : RPCResult::Type::OBJ, "", "",
306 12332 : {
307 6166 : {RPCResult::Type::STR_HEX, "hash", "hash of generated block"},
308 : }
309 : },
310 6166 : RPCExamples{
311 : "\nGenerate a block to myaddress, with txs rawtx and mempool_txid\n"
312 6166 : + HelpExampleCli("generateblock", R"("myaddress" '["rawtx", "mempool_txid"]')")
313 : },
314 6192 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
315 : {
316 26 : const auto address_or_descriptor = request.params[0].get_str();
317 26 : CScript coinbase_script;
318 26 : std::string error;
319 :
320 26 : if (!getScriptFromDescriptor(address_or_descriptor, coinbase_script, error)) {
321 16 : const auto destination = DecodeDestination(address_or_descriptor);
322 16 : if (!IsValidDestination(destination)) {
323 2 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address or descriptor");
324 : }
325 :
326 14 : coinbase_script = GetScriptForDestination(destination);
327 14 : }
328 :
329 20 : const NodeContext& node = EnsureAnyNodeContext(request.context);
330 20 : const CTxMemPool& mempool = EnsureMemPool(node);
331 :
332 20 : std::vector<CTransactionRef> txs;
333 20 : const auto raw_txs_or_txids = request.params[1].get_array();
334 32 : for (size_t i = 0; i < raw_txs_or_txids.size(); i++) {
335 16 : const auto str(raw_txs_or_txids[i].get_str());
336 :
337 16 : uint256 hash;
338 16 : CMutableTransaction mtx;
339 16 : if (ParseHashStr(str, hash)) {
340 :
341 8 : const auto tx = mempool.get(hash);
342 8 : if (!tx) {
343 2 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Transaction %s not in mempool.", str));
344 : }
345 :
346 6 : txs.emplace_back(tx);
347 :
348 16 : } else if (DecodeHexTx(mtx, str)) {
349 6 : txs.push_back(MakeTransactionRef(std::move(mtx)));
350 :
351 6 : } else {
352 2 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Transaction decode failed for %s. Make sure the tx has at least one input.", str));
353 : }
354 16 : }
355 :
356 16 : const CChainParams& chainparams(Params());
357 :
358 16 : ChainstateManager& chainman = EnsureChainman(node);
359 16 : CChainState& active_chainstate = chainman.ActiveChainstate();
360 :
361 16 : CBlock block;
362 : {
363 16 : LOCK(cs_main);
364 :
365 16 : std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(active_chainstate, node, nullptr, chainparams).CreateNewBlock(coinbase_script));
366 16 : if (!blocktemplate) {
367 0 : throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
368 : }
369 16 : block = blocktemplate->block;
370 16 : }
371 :
372 : // 1 coinbase + could have a few quorum commitments
373 16 : CHECK_NONFATAL(block.vtx.size() >= 1);
374 :
375 : // Add transactions
376 16 : block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
377 :
378 : {
379 16 : LOCK(cs_main);
380 :
381 16 : BlockValidationState state;
382 16 : if (!TestBlockValidity(state, *CHECK_NONFATAL(node.chainlocks), *CHECK_NONFATAL(node.evodb), chainparams, active_chainstate,
383 16 : block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), false, false)) {
384 2 : throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.GetRejectReason()));
385 : }
386 16 : }
387 :
388 14 : uint256 block_hash;
389 14 : uint64_t max_tries{DEFAULT_MAX_TRIES};
390 :
391 14 : if (!GenerateBlock(chainman, block, max_tries, block_hash) || block_hash.IsNull()) {
392 0 : throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");
393 : }
394 :
395 14 : UniValue obj(UniValue::VOBJ);
396 14 : obj.pushKV("hash", block_hash.GetHex());
397 14 : return obj;
398 34 : },
399 : };
400 0 : }
401 : #else
402 : static RPCHelpMan generatetoaddress()
403 : {
404 : return RPCHelpMan{"generatetoaddress", "This call is not available because RPC miner isn't compiled", {}, {}, RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
405 : throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This call is not available because RPC miner isn't compiled");
406 : }};
407 : }
408 :
409 : static RPCHelpMan generatetodescriptor()
410 : {
411 : return RPCHelpMan{"generatetodescriptor", "This call is not available because RPC miner isn't compiled", {}, {}, RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
412 : throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This call is not available because RPC miner isn't compiled");
413 : }};
414 : }
415 : static RPCHelpMan generateblock()
416 : {
417 : return RPCHelpMan{"generateblock", "This call is not available because RPC miner isn't compiled", {}, {}, RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
418 : throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This call is not available because RPC miner isn't compiled");
419 : }};
420 : }
421 : #endif // ENABLE_MINER
422 :
423 6144 : static RPCHelpMan generate()
424 : {
425 6146 : return RPCHelpMan{"generate", "has been replaced by the -generate cli option. Refer to -help for more information.", {}, {}, RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
426 :
427 2 : throw JSONRPCError(RPC_METHOD_NOT_FOUND, self.ToString());
428 2 : }};
429 0 : }
430 :
431 6168 : static RPCHelpMan getmininginfo()
432 : {
433 12336 : return RPCHelpMan{"getmininginfo",
434 6168 : "\nReturns a json object containing mining-related information.",
435 6168 : {},
436 6168 : RPCResult{
437 6168 : RPCResult::Type::OBJ, "", "",
438 55512 : {
439 6168 : {RPCResult::Type::NUM, "blocks", "The current block"},
440 6168 : {RPCResult::Type::NUM, "currentblocksize", /*optional=*/true, "The block size of the last assembled block (only present if a block was ever assembled)"},
441 6168 : {RPCResult::Type::NUM, "currentblocktx", /*optional=*/true, "The number of block transactions of the last assembled block (only present if a block was ever assembled)"},
442 6168 : {RPCResult::Type::NUM, "difficulty", "The current difficulty"},
443 6168 : {RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
444 6168 : {RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
445 6168 : {RPCResult::Type::STR, "chain", "current network name (main, test, devnet, regtest)"},
446 6168 : {RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
447 : }},
448 6168 : RPCExamples{
449 6168 : HelpExampleCli("getmininginfo", "")
450 6168 : + HelpExampleRpc("getmininginfo", "")
451 : },
452 6180 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
453 : {
454 :
455 12 : const NodeContext& node = EnsureAnyNodeContext(request.context);
456 :
457 12 : ChainstateManager& chainman = EnsureChainman(node);
458 12 : LOCK(cs_main);
459 :
460 12 : const CTxMemPool& mempool = EnsureMemPool(node);
461 12 : const CChain& active_chain = chainman.ActiveChain();
462 :
463 12 : UniValue obj(UniValue::VOBJ);
464 12 : obj.pushKV("blocks", active_chain.Height());
465 12 : if (BlockAssembler::m_last_block_size) obj.pushKV("currentblocksize", *BlockAssembler::m_last_block_size);
466 12 : if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
467 12 : obj.pushKV("difficulty", (double)GetDifficulty(active_chain.Tip()));
468 12 : obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
469 12 : obj.pushKV("pooledtx", (uint64_t)mempool.size());
470 12 : obj.pushKV("chain", Params().NetworkIDString());
471 12 : obj.pushKV("warnings", GetWarnings(false).original);
472 12 : return obj;
473 12 : },
474 : };
475 0 : }
476 :
477 :
478 : // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
479 6221 : static RPCHelpMan prioritisetransaction()
480 : {
481 12442 : return RPCHelpMan{"prioritisetransaction",
482 6221 : "Accepts the transaction into mined blocks at a higher (or lower) priority\n",
483 18663 : {
484 6221 : {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id."},
485 6221 : {"fee_delta", RPCArg::Type::NUM, RPCArg::Optional::NO, "The fee value (in duffs) to add (or subtract, if negative).\n"
486 : " Note, that this value is not a fee rate. It is a value to modify absolute fee of the TX.\n"
487 : " The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
488 : " considers the transaction as it would have paid a higher (or lower) fee."},
489 : },
490 6221 : RPCResult{
491 6221 : RPCResult::Type::BOOL, "", "Returns true"},
492 6221 : RPCExamples{
493 6221 : HelpExampleCli("prioritisetransaction", "\"txid\" 10000")
494 6221 : + HelpExampleRpc("prioritisetransaction", "\"txid\", 10000")
495 : },
496 6280 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
497 :
498 : {
499 59 : LOCK(cs_main);
500 :
501 59 : uint256 hash(ParseHashV(request.params[0].get_str(), "txid"));
502 55 : CAmount nAmount = request.params[1].getInt<int64_t>();
503 :
504 53 : EnsureAnyMemPool(request.context).PrioritiseTransaction(hash, nAmount);
505 53 : return true;
506 63 : },
507 : };
508 0 : }
509 :
510 :
511 : // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
512 637 : static UniValue BIP22ValidationResult(const BlockValidationState& state)
513 : {
514 637 : if (state.IsValid())
515 397 : return UniValue::VNULL;
516 :
517 240 : if (state.IsError())
518 0 : throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
519 240 : if (state.IsInvalid())
520 : {
521 240 : std::string strRejectReason = state.GetRejectReason();
522 240 : if (strRejectReason.empty())
523 0 : return "rejected";
524 240 : return strRejectReason;
525 240 : }
526 : // Should be impossible
527 0 : return "valid?";
528 637 : }
529 :
530 586 : static std::string gbt_vb_name(const Consensus::DeploymentPos pos) {
531 586 : const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
532 586 : std::string s = vbinfo.name;
533 586 : if (!vbinfo.gbt_force) {
534 0 : s.insert(s.begin(), '!');
535 0 : }
536 586 : return s;
537 586 : }
538 :
539 6731 : static RPCHelpMan getblocktemplate()
540 : {
541 13462 : return RPCHelpMan{"getblocktemplate",
542 6731 : "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
543 : "It returns data needed to construct a block to work on.\n"
544 : "For full specification, see BIPs 22, 23, and 9:\n"
545 : " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n"
546 : " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n"
547 : " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n",
548 13462 : {
549 13462 : {"template_request", RPCArg::Type::OBJ, RPCArg::Default{UniValue::VOBJ}, "Format of the template",
550 26924 : {
551 6731 : {"mode", RPCArg::Type::STR, /* treat as named arg */ RPCArg::Optional::OMITTED_NAMED_ARG, "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
552 13462 : {"capabilities", RPCArg::Type::ARR, /* treat as named arg */ RPCArg::Optional::OMITTED_NAMED_ARG, "A list of strings",
553 13462 : {
554 6731 : {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported feature, 'longpoll', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
555 : },
556 : },
557 13462 : {"rules", RPCArg::Type::ARR, RPCArg::Optional::NO, "A list of strings",
558 13462 : {
559 6731 : {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported softfork deployment"},
560 : },
561 : },
562 : },
563 6731 : "\"template_request\""},
564 : },
565 26924 : {
566 6731 : RPCResult{"If the proposal was accepted with mode=='proposal'", RPCResult::Type::NONE, "", ""},
567 6731 : RPCResult{"If the proposal was not accepted with mode=='proposal'", RPCResult::Type::STR, "", "According to BIP22"},
568 13462 : RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "",
569 195199 : {
570 13462 : {RPCResult::Type::ARR, "capabilities", "specific client side supported features",
571 13462 : {
572 6731 : {RPCResult::Type::STR, "", "capability"},
573 : }},
574 6731 : {RPCResult::Type::NUM, "version", "The preferred block version"},
575 13462 : {RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced",
576 13462 : {
577 6731 : {RPCResult::Type::STR, "", "name of a rule the client must understand to some extent; see BIP 9 for format"},
578 : }},
579 13462 : {RPCResult::Type::OBJ_DYN, "vbavailable", "set of pending, supported versionbit (BIP 9) softfork deployments",
580 13462 : {
581 6731 : {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"},
582 : }},
583 13462 : {RPCResult::Type::ARR, "capabilities", "",
584 13462 : {
585 6731 : {RPCResult::Type::STR, "value", "A supported feature, for example 'proposal'"},
586 : }},
587 6731 : {RPCResult::Type::NUM, "vbrequired", "bit mask of versionbits the server requires set in submissions"},
588 6731 : {RPCResult::Type::STR, "previousblockhash", "The hash of current highest block"},
589 13462 : {RPCResult::Type::ARR, "transactions", "contents of non-coinbase transactions that should be included in the next block",
590 13462 : {
591 13462 : {RPCResult::Type::OBJ, "", "",
592 47117 : {
593 6731 : {RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"},
594 6731 : {RPCResult::Type::STR_HEX, "txid", "transaction id encoded in little-endian hexadecimal"},
595 6731 : {RPCResult::Type::STR_HEX, "hash", "hash encoded in little-endian hexadecimal"},
596 13462 : {RPCResult::Type::ARR, "depends", "array of numbers",
597 13462 : {
598 6731 : {RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"},
599 : }},
600 6731 : {RPCResult::Type::NUM, "fee", "difference in value between transaction inputs and outputs (in duffs); 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"},
601 6731 : {RPCResult::Type::NUM, "sigops", "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"},
602 : }},
603 : }},
604 13462 : {RPCResult::Type::OBJ_DYN, "coinbaseaux", "data that should be included in the coinbase's scriptSig content",
605 13462 : {
606 6731 : {RPCResult::Type::STR_HEX, "key", "values must be in the coinbase (keys may be ignored)"},
607 : }},
608 6731 : {RPCResult::Type::NUM, "coinbasevalue", "maximum allowable input to coinbase transaction, including the generation award and transaction fees (in duffs)"},
609 6731 : {RPCResult::Type::STR, "longpollid", "an id to include with a request to longpoll on an update to this template"},
610 6731 : {RPCResult::Type::STR, "target", "The hash target"},
611 6731 : {RPCResult::Type::NUM_TIME, "mintime", "The minimum timestamp appropriate for the next block time, expressed in " + UNIX_EPOCH_TIME},
612 13462 : {RPCResult::Type::ARR, "mutable", "list of ways the block template may be changed",
613 13462 : {
614 6731 : {RPCResult::Type::STR, "value", "A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'"},
615 : }},
616 6731 : {RPCResult::Type::STR_HEX, "noncerange", "A range of valid nonces"},
617 6731 : {RPCResult::Type::NUM, "sigoplimit", "limit of sigops in blocks"},
618 6731 : {RPCResult::Type::NUM, "sizelimit", "limit of block size"},
619 6731 : {RPCResult::Type::NUM_TIME, "curtime", "current timestamp in " + UNIX_EPOCH_TIME},
620 6731 : {RPCResult::Type::STR, "bits", "compressed target of next block"},
621 6731 : {RPCResult::Type::STR, "previousbits", "compressed target of current highest block"},
622 6731 : {RPCResult::Type::NUM, "height", "The height of the next block"},
623 13462 : {RPCResult::Type::ARR, "masternode", "required masternode payments that must be included in the next block",
624 13462 : {
625 13462 : {RPCResult::Type::OBJ, "", "",
626 26924 : {
627 6731 : {RPCResult::Type::STR_HEX, "payee", "payee address"},
628 6731 : {RPCResult::Type::STR_HEX, "script", "payee scriptPubKey"},
629 6731 : {RPCResult::Type::NUM, "amount", "required amount to pay"},
630 : }},
631 : }},
632 6731 : {RPCResult::Type::BOOL, "masternode_payments_started", "true, if masternode payments started"},
633 6731 : {RPCResult::Type::BOOL, "masternode_payments_enforced", "true, if masternode payments are enforced"},
634 13462 : {RPCResult::Type::ARR, "superblock", "required superblock payees that must be included in the next block",
635 13462 : {
636 13462 : {RPCResult::Type::OBJ, "", "",
637 26924 : {
638 6731 : {RPCResult::Type::STR_HEX, "payee", "payee address"},
639 6731 : {RPCResult::Type::STR_HEX, "script", "payee scriptPubKey"},
640 6731 : {RPCResult::Type::NUM, "amount", "required amount to pay"},
641 : }},
642 : }},
643 6731 : {RPCResult::Type::BOOL, "superblocks_started", "true, if superblock payments started"},
644 6731 : {RPCResult::Type::BOOL, "superblocks_enabled", "true, if superblock payments are enabled"},
645 6731 : {RPCResult::Type::STR_HEX, "coinbase_payload", "coinbase transaction payload data encoded in hexadecimal"},
646 : }},
647 : },
648 6731 : RPCExamples{
649 6731 : HelpExampleCli("getblocktemplate", "")
650 6731 : + HelpExampleRpc("getblocktemplate", "")
651 : },
652 7310 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
653 : {
654 579 : const NodeContext& node = EnsureAnyNodeContext(request.context);
655 :
656 579 : ChainstateManager& chainman = EnsureChainman(node);
657 579 : LOCK(cs_main);
658 :
659 579 : std::string strMode = "template";
660 579 : UniValue lpval = NullUniValue;
661 579 : std::set<std::string> setClientRules;
662 579 : CChainState& active_chainstate = chainman.ActiveChainstate();
663 575 : CChain& active_chain = active_chainstate.m_chain;
664 575 : if (!request.params[0].isNull())
665 : {
666 83 : const UniValue& oparam = request.params[0].get_obj();
667 83 : const UniValue& modeval = oparam.find_value("mode");
668 83 : if (modeval.isStr())
669 24 : strMode = modeval.get_str();
670 59 : else if (modeval.isNull())
671 : {
672 : /* Do nothing */
673 59 : }
674 : else
675 0 : throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
676 83 : lpval = oparam.find_value("longpollid");
677 :
678 83 : if (strMode == "proposal")
679 : {
680 24 : const UniValue& dataval = oparam.find_value("data");
681 24 : if (!dataval.isStr())
682 0 : throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
683 :
684 24 : CBlock block;
685 24 : if (!DecodeHexBlk(block, dataval.get_str()))
686 4 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
687 :
688 20 : uint256 hash = block.GetHash();
689 20 : const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
690 20 : if (pindex) {
691 0 : if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
692 0 : return "duplicate";
693 0 : if (pindex->nStatus & BLOCK_FAILED_MASK)
694 0 : return "duplicate-invalid";
695 0 : return "duplicate-inconclusive";
696 : }
697 :
698 20 : CBlockIndex* const pindexPrev = active_chain.Tip();
699 : // TestBlockValidity only supports blocks built on the current Tip
700 20 : if (block.hashPrevBlock != pindexPrev->GetBlockHash())
701 2 : return "inconclusive-not-best-prevblk";
702 18 : BlockValidationState state;
703 18 : TestBlockValidity(state, *CHECK_NONFATAL(node.chainlocks), *CHECK_NONFATAL(node.evodb), Params(), active_chainstate,
704 18 : block, pindexPrev, false, true);
705 18 : return BIP22ValidationResult(state);
706 24 : }
707 :
708 59 : const UniValue& aClientRules = oparam.find_value("rules");
709 59 : if (aClientRules.isArray()) {
710 50 : for (unsigned int i = 0; i < aClientRules.size(); ++i) {
711 0 : const UniValue& v = aClientRules[i];
712 0 : setClientRules.insert(v.get_str());
713 0 : }
714 50 : }
715 59 : }
716 :
717 551 : if (strMode != "template")
718 0 : throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
719 :
720 551 : const CConnman& connman = EnsureConnman(node);
721 :
722 551 : if (!Params().IsTestChain()) {
723 0 : if (connman.GetNodeCount(ConnectionDirection::Both) == 0) {
724 0 : throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!");
725 : }
726 :
727 0 : if (active_chainstate.IsInitialBlockDownload()) {
728 0 : throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks...");
729 : }
730 :
731 0 : if (!node.mn_sync->IsSynced() && CSuperblock::IsValidBlockHeight(active_chain.Height() + 1)) {
732 : // Next block is a superblock but we need governance info to correctly construct it.
733 0 : throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is syncing with network...");
734 : }
735 0 : }
736 :
737 : static unsigned int nTransactionsUpdatedLast;
738 551 : const CTxMemPool& mempool = EnsureMemPool(node);
739 :
740 551 : if (!lpval.isNull())
741 : {
742 : // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
743 9 : uint256 hashWatchedChain;
744 9 : std::chrono::steady_clock::time_point checktxtime;
745 : unsigned int nTransactionsUpdatedLastLP;
746 :
747 9 : if (lpval.isStr())
748 : {
749 : // Format: <hashBestChain><nTransactionsUpdatedLast>
750 9 : const std::string& lpstr = lpval.get_str();
751 :
752 9 : hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid");
753 9 : nTransactionsUpdatedLastLP = LocaleIndependentAtoi<int64_t>(lpstr.substr(64));
754 9 : }
755 : else
756 : {
757 : // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
758 0 : hashWatchedChain = active_chain.Tip()->GetBlockHash();
759 0 : nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
760 : }
761 :
762 : // Release lock while waiting
763 9 : LEAVE_CRITICAL_SECTION(cs_main);
764 : {
765 9 : checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1);
766 :
767 9 : WAIT_LOCK(g_best_block_mutex, lock);
768 24 : while (g_best_block == hashWatchedChain && IsRPCRunning())
769 : {
770 9 : if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout)
771 : {
772 : // Timeout: Check transactions for update
773 : // without holding the mempool lock to avoid deadlocks
774 3 : if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
775 3 : break;
776 0 : checktxtime += std::chrono::seconds(10);
777 0 : }
778 : }
779 9 : }
780 9 : ENTER_CRITICAL_SECTION(cs_main);
781 :
782 9 : if (!IsRPCRunning())
783 0 : throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
784 : // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
785 9 : }
786 :
787 551 : const Consensus::Params& consensusParams = Params().GetConsensus();
788 :
789 : // Update block
790 : static CBlockIndex* pindexPrev;
791 : static int64_t nStart;
792 551 : static std::unique_ptr<CBlockTemplate> pblocktemplate;
793 558 : if (pindexPrev != active_chain.Tip() ||
794 100 : (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
795 : {
796 : // Clear pindexPrev so future calls make a new block, despite any failures from here on
797 458 : pindexPrev = nullptr;
798 :
799 : // Store the ::ChainActive().Tip() used before CreateNewBlock, to avoid races
800 458 : nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
801 456 : CBlockIndex* pindexPrevNew = active_chain.Tip();
802 456 : nStart = GetTime();
803 :
804 : // Create new block
805 456 : CScript scriptDummy = CScript() << OP_TRUE;
806 456 : EnsureLLMQContext(node);
807 456 : pblocktemplate = BlockAssembler(active_chainstate, node, &mempool, Params()).CreateNewBlock(scriptDummy);
808 456 : if (!pblocktemplate)
809 0 : throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
810 :
811 : // Need to update only after we know CreateNewBlock succeeded
812 456 : pindexPrev = pindexPrevNew;
813 456 : }
814 549 : CHECK_NONFATAL(pindexPrev);
815 551 : CBlock* pblock = &pblocktemplate->block; // pointer for convenience
816 :
817 : // Update nTime
818 551 : UpdateTime(pblock, consensusParams, pindexPrev);
819 551 : pblock->nNonce = 0;
820 :
821 551 : UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
822 :
823 551 : UniValue transactions(UniValue::VARR);
824 551 : std::map<uint256, int64_t> setTxIndex;
825 551 : int i = 0;
826 2269 : for (const auto& it : pblock->vtx) {
827 1718 : const CTransaction& tx = *it;
828 1718 : uint256 txHash = tx.GetHash();
829 1718 : setTxIndex[txHash] = i++;
830 :
831 1718 : if (tx.IsCoinBase())
832 551 : continue;
833 :
834 1167 : UniValue entry(UniValue::VOBJ);
835 :
836 1167 : entry.pushKV("data", EncodeHexTx(tx));
837 :
838 1167 : entry.pushKV("hash", txHash.GetHex());
839 :
840 1167 : UniValue deps(UniValue::VARR);
841 1349 : for (const CTxIn &in : tx.vin)
842 : {
843 182 : if (setTxIndex.count(in.prevout.hash))
844 11 : deps.push_back(setTxIndex[in.prevout.hash]);
845 : }
846 1167 : entry.pushKV("depends", deps);
847 :
848 1167 : int index_in_template = i - 1;
849 1167 : entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]);
850 1167 : entry.pushKV("sigops", pblocktemplate->vTxSigOps[index_in_template]);
851 :
852 1167 : transactions.push_back(entry);
853 1167 : }
854 :
855 551 : UniValue aux(UniValue::VOBJ);
856 :
857 551 : arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
858 :
859 551 : UniValue aMutable(UniValue::VARR);
860 551 : aMutable.push_back("time");
861 551 : aMutable.push_back("transactions");
862 551 : aMutable.push_back("prevblock");
863 :
864 551 : UniValue result(UniValue::VOBJ);
865 551 : result.pushKV("capabilities", aCaps);
866 :
867 551 : UniValue aRules(UniValue::VARR);
868 551 : aRules.push_back("csv");
869 551 : UniValue vbavailable(UniValue::VOBJ);
870 1653 : for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
871 1102 : Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
872 1102 : ThresholdState state = chainman.m_versionbitscache.State(pindexPrev, consensusParams, pos);
873 1102 : switch (state) {
874 : case ThresholdState::DEFINED:
875 : case ThresholdState::FAILED:
876 : // Not exposed to GBT at all
877 516 : break;
878 : case ThresholdState::LOCKED_IN:
879 : // Ensure bit is set in block version
880 98 : pblock->nVersion |= chainman.m_versionbitscache.Mask(consensusParams, pos);
881 : [[fallthrough]];
882 : case ThresholdState::STARTED:
883 : {
884 540 : const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
885 540 : vbavailable.pushKV(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit);
886 540 : if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
887 540 : if (!vbinfo.gbt_force) {
888 : // If the client doesn't support this, don't indicate it in the [default] version
889 0 : pblock->nVersion &= ~chainman.m_versionbitscache.Mask(consensusParams, pos);
890 0 : }
891 540 : }
892 540 : break;
893 : }
894 : case ThresholdState::ACTIVE:
895 : {
896 : // Add to rules only
897 46 : const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
898 46 : aRules.push_back(gbt_vb_name(pos));
899 46 : if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
900 : // Not supported by the client; make sure it's safe to proceed
901 46 : if (!vbinfo.gbt_force) {
902 0 : throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name));
903 : }
904 46 : }
905 46 : break;
906 : }
907 : }
908 1102 : }
909 551 : result.pushKV("version", pblock->nVersion);
910 551 : result.pushKV("rules", aRules);
911 551 : result.pushKV("vbavailable", vbavailable);
912 551 : result.pushKV("vbrequired", int(0));
913 :
914 551 : const bool fDIP0001Active_context{DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DIP0001)};
915 551 : result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex());
916 551 : result.pushKV("transactions", transactions);
917 551 : result.pushKV("coinbaseaux", aux);
918 551 : result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->GetValueOut());
919 551 : result.pushKV("longpollid", active_chain.Tip()->GetBlockHash().GetHex() + ToString(nTransactionsUpdatedLast));
920 551 : result.pushKV("target", hashTarget.GetHex());
921 551 : result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1);
922 551 : result.pushKV("mutable", aMutable);
923 551 : result.pushKV("noncerange", "00000000ffffffff");
924 551 : result.pushKV("sigoplimit", (int64_t)MaxBlockSigOps(fDIP0001Active_context));
925 551 : result.pushKV("sizelimit", (int64_t)MaxBlockSize(fDIP0001Active_context));
926 551 : result.pushKV("curtime", pblock->GetBlockTime());
927 551 : result.pushKV("bits", strprintf("%08x", pblock->nBits));
928 551 : result.pushKV("previousbits", strprintf("%08x", pblocktemplate->nPrevBits));
929 551 : result.pushKV("height", (int64_t)(pindexPrev->nHeight+1));
930 :
931 551 : UniValue masternodeObj(UniValue::VARR);
932 1348 : for (const auto& txout : pblocktemplate->voutMasternodePayments) {
933 797 : CTxDestination dest;
934 797 : ExtractDestination(txout.scriptPubKey, dest);
935 :
936 797 : UniValue obj(UniValue::VOBJ);
937 797 : obj.pushKV("payee", EncodeDestination(dest).c_str());
938 797 : obj.pushKV("script", HexStr(txout.scriptPubKey));
939 797 : obj.pushKV("amount", txout.nValue);
940 797 : masternodeObj.push_back(obj);
941 797 : }
942 :
943 551 : result.pushKV("masternode", masternodeObj);
944 551 : result.pushKV("masternode_payments_started", pindexPrev->nHeight + 1 > consensusParams.nMasternodePaymentsStartBlock);
945 551 : result.pushKV("masternode_payments_enforced", true);
946 :
947 551 : UniValue superblockObjArray(UniValue::VARR);
948 551 : if(pblocktemplate->voutSuperblockPayments.size()) {
949 0 : for (const auto& txout : pblocktemplate->voutSuperblockPayments) {
950 0 : UniValue entry(UniValue::VOBJ);
951 0 : CTxDestination dest;
952 0 : ExtractDestination(txout.scriptPubKey, dest);
953 0 : entry.pushKV("payee", EncodeDestination(dest).c_str());
954 0 : entry.pushKV("script", HexStr(txout.scriptPubKey));
955 0 : entry.pushKV("amount", txout.nValue);
956 0 : superblockObjArray.push_back(entry);
957 0 : }
958 0 : }
959 551 : result.pushKV("superblock", superblockObjArray);
960 551 : result.pushKV("superblocks_started", pindexPrev->nHeight + 1 > consensusParams.nSuperblockStartBlock);
961 551 : result.pushKV("superblocks_enabled", true);
962 :
963 551 : result.pushKV("coinbase_payload", HexStr(pblock->vtx[0]->vExtraPayload));
964 :
965 551 : return result;
966 587 : },
967 : };
968 0 : }
969 :
970 : class submitblock_StateCatcher final : public CValidationInterface
971 : {
972 : public:
973 : uint256 hash;
974 658 : bool found{false};
975 : BlockValidationState state;
976 :
977 1974 : explicit submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), state() {}
978 :
979 : protected:
980 626 : void BlockChecked(const CBlock& block, const BlockValidationState& stateIn) override {
981 626 : if (block.GetHash() != hash)
982 7 : return;
983 619 : found = true;
984 619 : state = stateIn;
985 626 : }
986 : };
987 :
988 7046 : static RPCHelpMan submitblock()
989 : {
990 : // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.
991 14092 : return RPCHelpMan{"submitblock",
992 7046 : "\nAttempts to submit new block to network.\n"
993 : "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n",
994 21138 : {
995 7046 : {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block data to submit"},
996 7046 : {"dummy", RPCArg::Type::STR, RPCArg::DefaultHint{"ignored"}, "dummy value, for compatibility with BIP22. This value is ignored."},
997 : },
998 21138 : {
999 7046 : RPCResult{"If the block was accepted", RPCResult::Type::NONE, "", ""},
1000 7046 : RPCResult{"Otherwise", RPCResult::Type::STR, "", "According to BIP22"},
1001 : },
1002 7046 : RPCExamples{
1003 7046 : HelpExampleCli("submitblock", "\"mydata\"")
1004 7046 : + HelpExampleRpc("submitblock", "\"mydata\"")
1005 : },
1006 7940 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1007 : {
1008 894 : std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
1009 894 : CBlock& block = *blockptr;
1010 894 : if (!DecodeHexBlk(block, request.params[0].get_str())) {
1011 2 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
1012 : }
1013 :
1014 890 : if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) {
1015 4 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block does not start with a coinbase");
1016 : }
1017 :
1018 884 : ChainstateManager& chainman = EnsureAnyChainman(request.context);
1019 884 : uint256 hash = block.GetHash();
1020 : {
1021 884 : LOCK(cs_main);
1022 884 : const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
1023 884 : if (pindex) {
1024 234 : if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
1025 210 : return "duplicate";
1026 : }
1027 24 : if (pindex->nStatus & BLOCK_FAILED_MASK) {
1028 16 : return "duplicate-invalid";
1029 : }
1030 8 : }
1031 884 : }
1032 :
1033 : bool new_block;
1034 658 : auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
1035 658 : RegisterSharedValidationInterface(sc);
1036 658 : bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
1037 658 : UnregisterSharedValidationInterface(sc);
1038 658 : if (!new_block && accepted) {
1039 2 : return "duplicate";
1040 : }
1041 656 : if (!sc->found) {
1042 37 : return "inconclusive";
1043 : }
1044 619 : return BIP22ValidationResult(sc->state);
1045 904 : },
1046 : };
1047 0 : }
1048 :
1049 6182 : static RPCHelpMan submitheader()
1050 : {
1051 12364 : return RPCHelpMan{"submitheader",
1052 6182 : "\nDecode the given hexdata as a header and submit it as a candidate chain tip if valid."
1053 : "\nThrows when the header is invalid.\n",
1054 12364 : {
1055 6182 : {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"},
1056 : },
1057 6182 : RPCResult{
1058 6182 : RPCResult::Type::NONE, "", "None"},
1059 6182 : RPCExamples{
1060 12364 : HelpExampleCli("submitheader", "\"aabbcc\"") +
1061 6182 : HelpExampleRpc("submitheader", "\"aabbcc\"")
1062 : },
1063 6208 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1064 : {
1065 26 : CBlockHeader h;
1066 26 : if (!DecodeHexBlockHeader(h, request.params[0].get_str())) {
1067 14 : throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block header decode failed");
1068 : }
1069 22 : ChainstateManager& chainman = EnsureAnyChainman(request.context);
1070 : {
1071 22 : LOCK(cs_main);
1072 22 : if (!chainman.m_blockman.LookupBlockIndex(h.hashPrevBlock)) {
1073 2 : throw JSONRPCError(RPC_VERIFY_ERROR, "Must submit previous header (" + h.hashPrevBlock.GetHex() + ") first");
1074 : }
1075 22 : }
1076 :
1077 20 : BlockValidationState state;
1078 20 : chainman.ProcessNewBlockHeaders({h}, state);
1079 20 : if (state.IsValid()) return UniValue::VNULL;
1080 8 : if (state.IsError()) {
1081 0 : throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
1082 : }
1083 8 : throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason());
1084 34 : },
1085 : };
1086 0 : }
1087 :
1088 3201 : void RegisterMiningRPCCommands(CRPCTable& t)
1089 : {
1090 33891 : static const CRPCCommand commands[]{
1091 3069 : {"mining", &getnetworkhashps},
1092 3069 : {"mining", &getmininginfo},
1093 3069 : {"mining", &prioritisetransaction},
1094 3069 : {"mining", &getblocktemplate},
1095 3069 : {"mining", &submitblock},
1096 3069 : {"mining", &submitheader},
1097 3069 : {"hidden", &generatetoaddress},
1098 3069 : {"hidden", &generatetodescriptor},
1099 3069 : {"hidden", &generateblock},
1100 3069 : {"hidden", &generate},
1101 : };
1102 35211 : for (const auto& c : commands) {
1103 32010 : t.appendCommand(c.name, &c);
1104 : }
1105 3201 : }
|