Coverage Report

Created: 2026-09-14 20:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/rpc/mining.cpp
Line
Count
Source
1
// Copyright (c) 2010 Satoshi Nakamoto
2
// Copyright (c) 2009-present The Bitcoin Core developers
3
// Distributed under the MIT software license, see the accompanying
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6
#include <bitcoin-build-config.h> // IWYU pragma: keep
7
8
#include <interfaces/mining.h>
9
#include <rpc/register.h> // IWYU pragma: associated
10
11
#include <addresstype.h>
12
#include <arith_uint256.h>
13
#include <chain.h>
14
#include <chainparams.h>
15
#include <chainparamsbase.h>
16
#include <consensus/amount.h>
17
#include <consensus/consensus.h>
18
#include <consensus/merkle.h>
19
#include <consensus/params.h>
20
#include <consensus/validation.h>
21
#include <core_io.h>
22
#include <crypto/hex_base.h>
23
#include <interfaces/types.h>
24
#include <key_io.h>
25
#include <net.h>
26
#include <netbase.h>
27
#include <node/blockstorage.h>
28
#include <node/context.h>
29
#include <node/miner.h>
30
#include <node/mining_args.h>
31
#include <node/mining_types.h>
32
#include <node/warnings.h>
33
#include <policy/feerate.h>
34
#include <policy/policy.h>
35
#include <pow.h>
36
#include <primitives/block.h>
37
#include <primitives/transaction.h>
38
#include <rpc/blockchain.h>
39
#include <rpc/mining.h>
40
#include <rpc/protocol.h>
41
#include <rpc/request.h>
42
#include <rpc/server.h>
43
#include <rpc/server_util.h>
44
#include <rpc/util.h>
45
#include <script/descriptor.h>
46
#include <script/script.h>
47
#include <script/signingprovider.h>
48
#include <serialize.h>
49
#include <streams.h>
50
#include <sync.h>
51
#include <tinyformat.h>
52
#include <txmempool.h>
53
#include <uint256.h>
54
#include <univalue.h>
55
#include <util/chaintype.h>
56
#include <util/check.h>
57
#include <util/signalinterrupt.h>
58
#include <util/strencodings.h>
59
#include <util/string.h>
60
#include <util/time.h>
61
#include <validation.h>
62
#include <validationinterface.h>
63
#include <versionbits.h>
64
65
#include <algorithm>
66
#include <cstddef>
67
#include <cstdint>
68
#include <functional>
69
#include <limits>
70
#include <map>
71
#include <memory>
72
#include <optional>
73
#include <set>
74
#include <span>
75
#include <string>
76
#include <string_view>
77
#include <utility>
78
#include <vector>
79
80
using interfaces::BlockRef;
81
using interfaces::BlockTemplate;
82
using interfaces::Mining;
83
using node::BlockAssembler;
84
using node::GetMinimumTime;
85
using node::NodeContext;
86
using node::RegenerateCommitments;
87
using node::UpdateTime;
88
using util::ToString;
89
90
/**
91
 * Return average network hashes per second based on the last 'lookup' blocks,
92
 * or from the last difficulty change if 'lookup' is -1.
93
 * If 'height' is -1, compute the estimate from current chain tip.
94
 * If 'height' is a valid block height, compute the estimate at the time when a given block was found.
95
 */
96
43
static UniValue GetNetworkHashPS(int lookup, int height, const CChain& active_chain) {
97
43
    if (lookup < -1 || lookup == 0) {
98
4
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid nblocks. Must be a positive number or -1.");
99
4
    }
100
101
39
    if (height < -1 || height > active_chain.Height()) {
102
4
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Block does not exist at specified height");
103
4
    }
104
105
35
    const CBlockIndex* pb = active_chain.Tip();
106
107
35
    if (height >= 0) {
108
2
        pb = active_chain[height];
109
2
    }
110
111
35
    if (pb == nullptr || !pb->nHeight)
112
5
        return 0;
113
114
    // If lookup is -1, then use blocks since last difficulty change.
115
30
    if (lookup == -1)
116
2
        lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1;
117
118
    // If lookup is larger than chain, then set it to chain length.
119
30
    if (lookup > pb->nHeight)
120
2
        lookup = pb->nHeight;
121
122
30
    const CBlockIndex* pb0 = pb;
123
30
    int64_t minTime = pb0->GetBlockTime();
124
30
    int64_t maxTime = minTime;
125
3.53k
    for (int i = 0; i < lookup; i++) {
126
3.50k
        pb0 = pb0->pprev;
127
3.50k
        int64_t time = pb0->GetBlockTime();
128
3.50k
        minTime = std::min(time, minTime);
129
3.50k
        maxTime = std::max(time, maxTime);
130
3.50k
    }
131
132
    // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
133
30
    if (minTime == maxTime)
134
0
        return 0;
135
136
30
    arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
137
30
    int64_t timeDiff = maxTime - minTime;
138
139
30
    return workDiff.getdouble() / timeDiff;
140
30
}
141
142
static RPCMethod getnetworkhashps()
143
2.51k
{
144
2.51k
    return RPCMethod{
145
2.51k
        "getnetworkhashps",
146
2.51k
        "Returns the estimated network hashes per second based on the last n blocks.\n"
147
2.51k
                "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
148
2.51k
                "Pass in [height] to estimate the network speed at the time when a certain block was found.\n",
149
2.51k
                {
150
2.51k
                    {"nblocks", RPCArg::Type::NUM, RPCArg::Default{120}, "The number of previous blocks to calculate estimate from, or -1 for blocks since last difficulty change."},
151
2.51k
                    {"height", RPCArg::Type::NUM, RPCArg::Default{-1}, "To estimate at the time of the given height."},
152
2.51k
                },
153
2.51k
                RPCResult{
154
2.51k
                    RPCResult::Type::NUM, "", "Hashes per second estimated"},
155
2.51k
                RPCExamples{
156
2.51k
                    HelpExampleCli("getnetworkhashps", "")
157
2.51k
            + HelpExampleRpc("getnetworkhashps", "")
158
2.51k
                },
159
2.51k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
160
2.51k
{
161
43
    ChainstateManager& chainman = EnsureAnyChainman(request.context);
162
43
    LOCK(cs_main);
163
43
    return GetNetworkHashPS(self.Arg<int>("nblocks"), self.Arg<int>("height"), chainman.ActiveChain());
164
43
},
165
2.51k
    };
166
2.51k
}
167
168
static bool GenerateBlock(ChainstateManager& chainman, CBlock&& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block)
169
33.7k
{
170
33.7k
    block_out.reset();
171
33.7k
    block.hashMerkleRoot = BlockMerkleRoot(block);
172
173
1.06M
    while (max_tries > 0 && block.nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(block.GetHash(), block.nBits, chainman.GetConsensus()) && !chainman.m_interrupt) {
174
1.03M
        ++block.nNonce;
175
1.03M
        --max_tries;
176
1.03M
    }
177
33.7k
    if (max_tries == 0 || chainman.m_interrupt) {
178
1
        return false;
179
1
    }
180
33.7k
    if (block.nNonce == std::numeric_limits<uint32_t>::max()) {
181
0
        return true;
182
0
    }
183
184
33.7k
    block_out = std::make_shared<const CBlock>(std::move(block));
185
186
33.7k
    if (!process_new_block) return true;
187
188
33.7k
    if (!chainman.ProcessNewBlock(block_out, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)) {
189
0
        throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
190
0
    }
191
192
33.7k
    return true;
193
33.7k
}
194
195
static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const CScript& coinbase_output_script, int nGenerate, uint64_t nMaxTries)
196
2.94k
{
197
2.94k
    UniValue blockHashes(UniValue::VARR);
198
36.3k
    while (nGenerate > 0 && !chainman.m_interrupt) {
199
33.4k
        std::unique_ptr<BlockTemplate> block_template(miner.createNewBlock({ .coinbase_output_script = coinbase_output_script }, /*cooldown=*/false));
200
33.4k
        CHECK_NONFATAL(block_template);
201
202
33.4k
        std::shared_ptr<const CBlock> block_out;
203
33.4k
        if (!GenerateBlock(chainman, block_template->getBlock(), nMaxTries, block_out, /*process_new_block=*/true)) {
204
1
            break;
205
1
        }
206
207
33.4k
        if (block_out) {
208
33.4k
            --nGenerate;
209
33.4k
            blockHashes.push_back(block_out->GetHash().GetHex());
210
33.4k
        }
211
33.4k
    }
212
2.94k
    return blockHashes;
213
2.94k
}
214
215
static bool getScriptFromDescriptor(std::string_view descriptor, CScript& script, std::string& error)
216
1.19k
{
217
1.19k
    FlatSigningProvider key_provider;
218
1.19k
    const auto descs = Parse(descriptor, key_provider, error, /* require_checksum = */ false);
219
1.19k
    if (descs.empty()) return false;
220
863
    if (descs.size() > 1) {
221
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Multipath descriptor not accepted");
222
0
    }
223
863
    const auto& desc = descs.at(0);
224
863
    if (desc->IsRange()) {
225
1
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Ranged descriptor not accepted. Maybe pass through deriveaddresses first?");
226
1
    }
227
228
862
    FlatSigningProvider provider;
229
862
    std::vector<CScript> scripts;
230
862
    if (!desc->Expand(0, key_provider, scripts, provider)) {
231
1
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys");
232
1
    }
233
234
    // Combo descriptors can have 2 or 4 scripts, so we can't just check scripts.size() == 1
235
861
    CHECK_NONFATAL(scripts.size() > 0 && scripts.size() <= 4);
236
237
861
    if (scripts.size() == 1) {
238
858
        script = scripts.at(0);
239
858
    } else if (scripts.size() == 4) {
240
        // For uncompressed keys, take the 3rd script, since it is p2wpkh
241
1
        script = scripts.at(2);
242
2
    } else {
243
        // Else take the 2nd script, since it is p2pkh
244
2
        script = scripts.at(1);
245
2
    }
246
247
861
    return true;
248
862
}
249
250
static RPCMethod generatetodescriptor()
251
3.28k
{
252
3.28k
    return RPCMethod{
253
3.28k
        "generatetodescriptor",
254
3.28k
        "Mine to a specified descriptor and return the block hashes.",
255
3.28k
        {
256
3.28k
            {"num_blocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."},
257
3.28k
            {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor to send the newly generated bitcoin to."},
258
3.28k
            {"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."},
259
3.28k
        },
260
3.28k
        RPCResult{
261
3.28k
            RPCResult::Type::ARR, "", "hashes of blocks generated",
262
3.28k
            {
263
3.28k
                {RPCResult::Type::STR_HEX, "", "blockhash"},
264
3.28k
            }
265
3.28k
        },
266
3.28k
        RPCExamples{
267
3.28k
            "\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")},
268
3.28k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
269
3.28k
{
270
831
    const auto num_blocks{self.Arg<int>("num_blocks")};
271
831
    const auto max_tries{self.Arg<uint64_t>("maxtries")};
272
273
831
    CScript coinbase_output_script;
274
831
    std::string error;
275
831
    if (!getScriptFromDescriptor(self.Arg<std::string_view>("descriptor"), coinbase_output_script, error)) {
276
0
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
277
0
    }
278
279
831
    NodeContext& node = EnsureAnyNodeContext(request.context);
280
831
    Mining& miner = EnsureMining(node);
281
831
    ChainstateManager& chainman = EnsureChainman(node);
282
283
831
    return generateBlocks(chainman, miner, coinbase_output_script, num_blocks, max_tries);
284
831
},
285
3.28k
    };
286
3.28k
}
287
288
static RPCMethod generate()
289
2.45k
{
290
2.45k
    return RPCMethod{"generate", "has been replaced by the -generate cli option. Refer to -help for more information.", {}, {}, RPCExamples{""}, [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue {
291
1
        throw JSONRPCError(RPC_METHOD_NOT_FOUND, self.ToString());
292
1
    }};
293
2.45k
}
294
295
static RPCMethod generatetoaddress()
296
4.56k
{
297
4.56k
    return RPCMethod{"generatetoaddress",
298
4.56k
        "Mine to a specified address and return the block hashes.",
299
4.56k
         {
300
4.56k
             {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."},
301
4.56k
             {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The address to send the newly generated bitcoin to."},
302
4.56k
             {"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."},
303
4.56k
         },
304
4.56k
         RPCResult{
305
4.56k
             RPCResult::Type::ARR, "", "hashes of blocks generated",
306
4.56k
             {
307
4.56k
                 {RPCResult::Type::STR_HEX, "", "blockhash"},
308
4.56k
             }},
309
4.56k
         RPCExamples{
310
4.56k
            "\nGenerate 11 blocks to myaddress\n"
311
4.56k
            + HelpExampleCli("generatetoaddress", "11 \"myaddress\"")
312
4.56k
            + "If you are using the " CLIENT_NAME " wallet, you can get a new address to send the newly generated bitcoin to with:\n"
313
4.56k
            + HelpExampleCli("getnewaddress", "")
314
4.56k
                },
315
4.56k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
316
4.56k
{
317
2.11k
    const int num_blocks{request.params[0].getInt<int>()};
318
2.11k
    const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].getInt<int>()};
319
320
2.11k
    CTxDestination destination = DecodeDestination(request.params[1].get_str());
321
2.11k
    if (!IsValidDestination(destination)) {
322
2
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address");
323
2
    }
324
325
2.11k
    NodeContext& node = EnsureAnyNodeContext(request.context);
326
2.11k
    Mining& miner = EnsureMining(node);
327
2.11k
    ChainstateManager& chainman = EnsureChainman(node);
328
329
2.11k
    CScript coinbase_output_script = GetScriptForDestination(destination);
330
331
2.11k
    return generateBlocks(chainman, miner, coinbase_output_script, num_blocks, max_tries);
332
2.11k
},
333
4.56k
    };
334
4.56k
}
335
336
static RPCMethod generateblock()
337
2.81k
{
338
2.81k
    return RPCMethod{"generateblock",
339
2.81k
        "Mine a set of ordered transactions to a specified address or descriptor and return the block hash.\n"
340
2.81k
        "Transaction fees are not collected in the block reward.",
341
2.81k
        {
342
2.81k
            {"output", RPCArg::Type::STR, RPCArg::Optional::NO, "The address or descriptor to send the newly generated bitcoin to."},
343
2.81k
            {"transactions", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings which are either txids or raw transactions.\n"
344
2.81k
                "Txids must reference transactions currently in the mempool.\n"
345
2.81k
                "All transactions must be valid and in valid order, otherwise the block will be rejected.",
346
2.81k
                {
347
2.81k
                    {"rawtx/txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},
348
2.81k
                },
349
2.81k
            },
350
2.81k
            {"submit", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to submit the block before the RPC call returns or to return it as hex."},
351
2.81k
        },
352
2.81k
        RPCResult{
353
2.81k
            RPCResult::Type::OBJ, "", "",
354
2.81k
            {
355
2.81k
                {RPCResult::Type::STR_HEX, "hash", "hash of generated block"},
356
2.81k
                {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "hex of generated block, only present when submit=false"},
357
2.81k
            }
358
2.81k
        },
359
2.81k
        RPCExamples{
360
2.81k
            "\nGenerate a block to myaddress, with txs rawtx and mempool_txid\n"
361
2.81k
            + HelpExampleCli("generateblock", R"("myaddress" '["rawtx", "mempool_txid"]')")
362
2.81k
        },
363
2.81k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
364
2.81k
{
365
363
    const auto address_or_descriptor = request.params[0].get_str();
366
363
    CScript coinbase_output_script;
367
363
    std::string error;
368
369
363
    if (!getScriptFromDescriptor(address_or_descriptor, coinbase_output_script, error)) {
370
331
        const auto destination = DecodeDestination(address_or_descriptor);
371
331
        if (!IsValidDestination(destination)) {
372
1
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address or descriptor");
373
1
        }
374
375
330
        coinbase_output_script = GetScriptForDestination(destination);
376
330
    }
377
378
362
    NodeContext& node = EnsureAnyNodeContext(request.context);
379
362
    Mining& miner = EnsureMining(node);
380
362
    const CTxMemPool& mempool = EnsureMemPool(node);
381
382
362
    std::vector<CTransactionRef> txs;
383
362
    const auto raw_txs_or_txids = request.params[1].get_array();
384
479
    for (size_t i = 0; i < raw_txs_or_txids.size(); i++) {
385
119
        const auto& str{raw_txs_or_txids[i].get_str()};
386
387
119
        CMutableTransaction mtx;
388
119
        if (auto txid{Txid::FromHex(str)}) {
389
4
            const auto tx{mempool.get(*txid)};
390
4
            if (!tx) {
391
1
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Transaction %s not in mempool.", str));
392
1
            }
393
394
3
            txs.emplace_back(tx);
395
396
115
        } else if (DecodeHexTx(mtx, str)) {
397
114
            txs.push_back(MakeTransactionRef(std::move(mtx)));
398
399
114
        } else {
400
1
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Transaction decode failed for %s. Make sure the tx has at least one input.", str));
401
1
        }
402
119
    }
403
404
360
    const bool process_new_block{request.params[2].isNull() ? true : request.params[2].get_bool()};
405
360
    CBlock block;
406
407
360
    ChainstateManager& chainman = EnsureChainman(node);
408
360
    {
409
360
        LOCK(chainman.GetMutex());
410
360
        {
411
360
            std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock({.use_mempool = false, .coinbase_output_script = coinbase_output_script}, /*cooldown=*/false)};
412
360
            CHECK_NONFATAL(block_template);
413
414
360
            block = block_template->getBlock();
415
360
        }
416
417
360
        CHECK_NONFATAL(block.vtx.size() == 1);
418
419
        // Add transactions
420
360
        block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
421
360
        RegenerateCommitments(block, chainman);
422
423
360
        if (BlockValidationState state{TestBlockValidity(chainman.ActiveChainstate(), block, /*check_pow=*/false, /*check_merkle_root=*/false)}; !state.IsValid()) {
424
2
            throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));
425
2
        }
426
360
    }
427
428
358
    std::shared_ptr<const CBlock> block_out;
429
358
    uint64_t max_tries{DEFAULT_MAX_TRIES};
430
431
358
    if (!GenerateBlock(chainman, std::move(block), max_tries, block_out, process_new_block) || !block_out) {
432
0
        throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");
433
0
    }
434
435
358
    UniValue obj(UniValue::VOBJ);
436
358
    obj.pushKV("hash", block_out->GetHash().GetHex());
437
358
    if (!process_new_block) {
438
5
        DataStream block_ser;
439
5
        block_ser << TX_WITH_WITNESS(*block_out);
440
5
        obj.pushKV("hex", HexStr(block_ser));
441
5
    }
442
358
    return obj;
443
358
},
444
2.81k
    };
445
2.81k
}
446
447
static RPCMethod getmininginfo()
448
2.49k
{
449
2.49k
    return RPCMethod{
450
2.49k
        "getmininginfo",
451
2.49k
        "Returns a json object containing mining-related information.",
452
2.49k
                {},
453
2.49k
                RPCResult{
454
2.49k
                    RPCResult::Type::OBJ, "", "",
455
2.49k
                    {
456
2.49k
                        {RPCResult::Type::NUM, "blocks", "The current block"},
457
2.49k
                        {RPCResult::Type::STR_HEX, "bestblockhash", "The hash of the current best block"},
458
2.49k
                        {RPCResult::Type::NUM, "currentblockweight", /*optional=*/true, "The block weight (including reserved weight for block header, txs count and coinbase tx) of the last assembled block (only present if a block was ever assembled)"},
459
2.49k
                        {RPCResult::Type::NUM, "currentblocktx", /*optional=*/true, "The number of block transactions (excluding coinbase) of the last assembled block (only present if a block was ever assembled)"},
460
2.49k
                        {RPCResult::Type::STR_HEX, "bits", "The current nBits, compact representation of the block difficulty target"},
461
2.49k
                        {RPCResult::Type::NUM, "difficulty", "The current difficulty"},
462
2.49k
                        {RPCResult::Type::STR_HEX, "target", "The current target"},
463
2.49k
                        {RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
464
2.49k
                        {RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
465
2.49k
                        {RPCResult::Type::STR_AMOUNT, "blockmintxfee", "Minimum feerate of packages selected for block inclusion in " + CURRENCY_UNIT + "/kvB"},
466
2.49k
                        {RPCResult::Type::STR, "chain", "current network name (" LIST_CHAIN_NAMES ")"},
467
2.49k
                        {RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "The block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"},
468
2.49k
                        {RPCResult::Type::OBJ, "next", "The next block",
469
2.49k
                        {
470
2.49k
                            {RPCResult::Type::NUM, "height", "The next height"},
471
2.49k
                            {RPCResult::Type::STR_HEX, "bits", "The next target nBits"},
472
2.49k
                            {RPCResult::Type::NUM, "difficulty", "The next difficulty"},
473
2.49k
                            {RPCResult::Type::STR_HEX, "target", "The next target"}
474
2.49k
                        }},
475
2.49k
                        (IsDeprecatedRPCEnabled("warnings") ?
476
0
                            RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
477
2.49k
                            RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
478
2.49k
                            {
479
2.49k
                                {RPCResult::Type::STR, "", "warning"},
480
2.49k
                            }
481
2.49k
                            }
482
2.49k
                        ),
483
2.49k
                    }},
484
2.49k
                RPCExamples{
485
2.49k
                    HelpExampleCli("getmininginfo", "")
486
2.49k
            + HelpExampleRpc("getmininginfo", "")
487
2.49k
                },
488
2.49k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
489
2.49k
{
490
25
    NodeContext& node = EnsureAnyNodeContext(request.context);
491
25
    const CTxMemPool& mempool = EnsureMemPool(node);
492
25
    ChainstateManager& chainman = EnsureChainman(node);
493
25
    LOCK(cs_main);
494
25
    const CChain& active_chain = chainman.ActiveChain();
495
25
    CBlockIndex& tip{*CHECK_NONFATAL(active_chain.Tip())};
496
497
25
    UniValue obj(UniValue::VOBJ);
498
25
    obj.pushKV("blocks", active_chain.Height());
499
25
    obj.pushKV("bestblockhash", tip.GetBlockHash().GetHex());
500
25
    if (BlockAssembler::m_last_block_weight) obj.pushKV("currentblockweight", *BlockAssembler::m_last_block_weight);
501
25
    if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
502
25
    obj.pushKV("bits", strprintf("%08x", tip.nBits));
503
25
    obj.pushKV("difficulty", GetDifficulty(tip));
504
25
    obj.pushKV("target", GetTarget(tip, chainman.GetConsensus().powLimit).GetHex());
505
25
    obj.pushKV("networkhashps",    getnetworkhashps().HandleRequest(request));
506
25
    obj.pushKV("pooledtx", mempool.size());
507
25
    const auto mining_options{node::FlattenMiningOptions(node.mining_args)};
508
25
    obj.pushKV("blockmintxfee", ValueFromAmount(CHECK_NONFATAL(mining_options.block_min_fee_rate)->GetFeePerK()));
509
25
    obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
510
511
25
    UniValue next(UniValue::VOBJ);
512
25
    CBlockIndex next_index;
513
25
    NextEmptyBlockIndex(tip, chainman.GetConsensus(), next_index);
514
515
25
    next.pushKV("height", next_index.nHeight);
516
25
    next.pushKV("bits", strprintf("%08x", next_index.nBits));
517
25
    next.pushKV("difficulty", GetDifficulty(next_index));
518
25
    next.pushKV("target", GetTarget(next_index, chainman.GetConsensus().powLimit).GetHex());
519
25
    obj.pushKV("next", next);
520
521
25
    if (chainman.GetParams().GetChainType() == ChainType::SIGNET) {
522
3
        const std::vector<uint8_t>& signet_challenge =
523
3
            chainman.GetConsensus().signet_challenge;
524
3
        obj.pushKV("signet_challenge", HexStr(signet_challenge));
525
3
    }
526
25
    obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings")));
527
25
    return obj;
528
25
},
529
2.49k
    };
530
2.49k
}
531
532
533
// NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
534
static RPCMethod prioritisetransaction()
535
3.19k
{
536
3.19k
    return RPCMethod{"prioritisetransaction",
537
3.19k
                "Accepts the transaction into mined blocks at a higher (or lower) priority\n",
538
3.19k
                {
539
3.19k
                    {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id."},
540
3.19k
                    {"dummy", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "API-Compatibility for previous API. Must be zero or null.\n"
541
3.19k
            "                  DEPRECATED. For forward compatibility use named arguments and omit this parameter.",
542
3.19k
                        RPCArgOptions{.placeholder = true}},
543
3.19k
                    {"fee_delta", RPCArg::Type::NUM, RPCArg::Optional::NO, "The fee value (in satoshis) to add (or subtract, if negative).\n"
544
3.19k
            "                  Note, that this value is not a fee rate. It is a value to modify absolute fee of the TX.\n"
545
3.19k
            "                  The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
546
3.19k
            "                  considers the transaction as it would have paid a higher (or lower) fee."},
547
3.19k
                },
548
3.19k
                RPCResult{
549
3.19k
                    RPCResult::Type::BOOL, "", "Returns true"},
550
3.19k
                RPCExamples{
551
3.19k
                    HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
552
3.19k
            + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
553
3.19k
                },
554
3.19k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
555
3.19k
{
556
723
    LOCK(cs_main);
557
558
723
    auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
559
723
    const auto dummy{self.MaybeArg<double>("dummy")};
560
723
    CAmount nAmount = request.params[2].getInt<int64_t>();
561
562
723
    if (dummy && *dummy != 0) {
563
1
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is no longer supported, dummy argument to prioritisetransaction must be 0.");
564
1
    }
565
566
722
    CTxMemPool& mempool = EnsureAnyMemPool(request.context);
567
568
    // Non-0 fee dust transactions are not allowed for entry, and modification not allowed afterwards
569
722
    const auto& tx = mempool.get(txid);
570
722
    if (mempool.m_opts.require_standard && tx && !GetDust(*tx, mempool.m_opts.dust_relay_feerate).empty()) {
571
1
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is not supported for transactions with dust outputs.");
572
1
    }
573
574
721
    mempool.PrioritiseTransaction(txid, nAmount);
575
721
    return true;
576
722
},
577
3.19k
    };
578
3.19k
}
579
580
static RPCMethod getprioritisedtransactions()
581
2.49k
{
582
2.49k
    return RPCMethod{"getprioritisedtransactions",
583
2.49k
        "Returns a map of all user-created (see prioritisetransaction) fee deltas by txid, and whether the tx is present in mempool.",
584
2.49k
        {},
585
2.49k
        RPCResult{
586
2.49k
            RPCResult::Type::OBJ_DYN, "", "prioritisation keyed by txid",
587
2.49k
            {
588
2.49k
                {RPCResult::Type::OBJ, "<transactionid>", "", {
589
2.49k
                    {RPCResult::Type::NUM, "fee_delta", "transaction fee delta in satoshis"},
590
2.49k
                    {RPCResult::Type::BOOL, "in_mempool", "whether this transaction is currently in mempool"},
591
2.49k
                    {RPCResult::Type::NUM, "modified_fee", /*optional=*/true, "modified fee in satoshis. Only returned if in_mempool=true"},
592
2.49k
                }}
593
2.49k
            },
594
2.49k
        },
595
2.49k
        RPCExamples{
596
2.49k
            HelpExampleCli("getprioritisedtransactions", "")
597
2.49k
            + HelpExampleRpc("getprioritisedtransactions", "")
598
2.49k
        },
599
2.49k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
600
2.49k
        {
601
31
            NodeContext& node = EnsureAnyNodeContext(request.context);
602
31
            CTxMemPool& mempool = EnsureMemPool(node);
603
31
            UniValue rpc_result{UniValue::VOBJ};
604
31
            for (const auto& delta_info : mempool.GetPrioritisedTransactions()) {
605
30
                UniValue result_inner{UniValue::VOBJ};
606
30
                result_inner.pushKV("fee_delta", delta_info.delta);
607
30
                result_inner.pushKV("in_mempool", delta_info.in_mempool);
608
30
                if (delta_info.in_mempool) {
609
19
                    result_inner.pushKV("modified_fee", *delta_info.modified_fee);
610
19
                }
611
30
                rpc_result.pushKVEnd(delta_info.txid.GetHex(), std::move(result_inner));
612
30
            }
613
31
            return rpc_result;
614
31
        },
615
2.49k
    };
616
2.49k
}
617
618
619
// NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
620
static UniValue BIP22ValidationResult(const BlockValidationState& state)
621
7.27k
{
622
7.27k
    if (state.IsValid())
623
4.36k
        return UniValue::VNULL;
624
625
2.91k
    if (state.IsError())
626
0
        throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
627
2.91k
    if (state.IsInvalid())
628
2.91k
    {
629
2.91k
        std::string strRejectReason = state.GetRejectReason();
630
2.91k
        if (strRejectReason.empty())
631
0
            return "rejected";
632
2.91k
        return strRejectReason;
633
2.91k
    }
634
    // Should be impossible
635
0
    return "valid?";
636
2.91k
}
637
638
// Prefix rule name with ! if not optional, see BIP9
639
static std::string gbt_rule_value(const std::string& name, bool gbt_optional_rule)
640
77
{
641
77
    std::string s{name};
642
77
    if (!gbt_optional_rule) {
643
0
        s.insert(s.begin(), '!');
644
0
    }
645
77
    return s;
646
77
}
647
648
static RPCMethod getblocktemplate()
649
2.87k
{
650
2.87k
    return RPCMethod{
651
2.87k
        "getblocktemplate",
652
2.87k
        "If the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
653
2.87k
        "It returns data needed to construct a block to work on.\n"
654
2.87k
        "For full specification, see BIPs 22, 23, 9, and 145:\n"
655
2.87k
        "    https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n"
656
2.87k
        "    https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n"
657
2.87k
        "    https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
658
2.87k
        "    https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n",
659
2.87k
        {
660
2.87k
            {"template_request", RPCArg::Type::OBJ, RPCArg::Optional::NO, "Format of the template",
661
2.87k
            {
662
2.87k
                {"mode", RPCArg::Type::STR, /* treat as named arg */ RPCArg::Optional::OMITTED, "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
663
2.87k
                {"capabilities", RPCArg::Type::ARR, /* treat as named arg */ RPCArg::Optional::OMITTED, "A list of strings",
664
2.87k
                {
665
2.87k
                    {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported feature, 'longpoll', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
666
2.87k
                }},
667
2.87k
                {"rules", RPCArg::Type::ARR, RPCArg::Optional::NO, "A list of strings",
668
2.87k
                {
669
2.87k
                    {"segwit", RPCArg::Type::STR, RPCArg::Optional::NO, "(literal) indicates client side segwit support"},
670
2.87k
                    {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "other client side supported softfork deployment"},
671
2.87k
                }},
672
2.87k
                {"longpollid", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "delay processing request until the result would vary significantly from the \"longpollid\" of a prior template"},
673
2.87k
                {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "proposed block data to check, encoded in hexadecimal; valid only for mode=\"proposal\""},
674
2.87k
            },
675
2.87k
            },
676
2.87k
        },
677
2.87k
        {
678
2.87k
            RPCResult{"If the proposal was accepted with mode=='proposal'", RPCResult::Type::NONE, "", ""},
679
2.87k
            RPCResult{"If the proposal was not accepted with mode=='proposal'", RPCResult::Type::STR, "", "According to BIP22"},
680
2.87k
            RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "",
681
2.87k
            {
682
2.87k
                {RPCResult::Type::NUM, "version", "The preferred block version"},
683
2.87k
                {RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced",
684
2.87k
                {
685
2.87k
                    {RPCResult::Type::STR, "", "name of a rule the client must understand to some extent; see BIP 9 for format"},
686
2.87k
                }},
687
2.87k
                {RPCResult::Type::OBJ_DYN, "vbavailable", "set of pending, supported versionbit (BIP 9) softfork deployments",
688
2.87k
                {
689
2.87k
                    {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"},
690
2.87k
                }},
691
2.87k
                {RPCResult::Type::ARR, "capabilities", "",
692
2.87k
                {
693
2.87k
                    {RPCResult::Type::STR, "value", "A supported feature, for example 'proposal'"},
694
2.87k
                }},
695
2.87k
                {RPCResult::Type::NUM, "vbrequired", "bit mask of versionbits the server requires set in submissions"},
696
2.87k
                {RPCResult::Type::STR, "previousblockhash", "The hash of current highest block"},
697
2.87k
                {RPCResult::Type::ARR, "transactions", "contents of non-coinbase transactions that should be included in the next block",
698
2.87k
                {
699
2.87k
                    {RPCResult::Type::OBJ, "", "",
700
2.87k
                    {
701
2.87k
                        {RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"},
702
2.87k
                        {RPCResult::Type::STR_HEX, "txid", "transaction hash excluding witness data, shown in byte-reversed hex"},
703
2.87k
                        {RPCResult::Type::STR_HEX, "hash", "transaction hash including witness data, shown in byte-reversed hex"},
704
2.87k
                        {RPCResult::Type::ARR, "depends", "array of numbers",
705
2.87k
                        {
706
2.87k
                            {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"},
707
2.87k
                        }},
708
2.87k
                        {RPCResult::Type::NUM, "fee", "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"},
709
2.87k
                        {RPCResult::Type::NUM, "sigops", "total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero"},
710
2.87k
                        {RPCResult::Type::NUM, "weight", "total transaction weight, as counted for purposes of block limits"},
711
2.87k
                    }},
712
2.87k
                }},
713
2.87k
                {RPCResult::Type::OBJ_DYN, "coinbaseaux", "data that should be included in the coinbase's scriptSig content",
714
2.87k
                {
715
2.87k
                    {RPCResult::Type::STR_HEX, "key", "values must be in the coinbase (keys may be ignored)"},
716
2.87k
                }},
717
2.87k
                {RPCResult::Type::NUM, "coinbasevalue", "maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)"},
718
2.87k
                {RPCResult::Type::STR, "longpollid", "an id to include with a request to longpoll on an update to this template"},
719
2.87k
                {RPCResult::Type::STR, "target", "The hash target"},
720
2.87k
                {RPCResult::Type::NUM_TIME, "mintime", "The minimum timestamp appropriate for the next block time, expressed in " + UNIX_EPOCH_TIME + ". Adjusted for the proposed BIP94 timewarp rule."},
721
2.87k
                {RPCResult::Type::ARR, "mutable", "list of ways the block template may be changed",
722
2.87k
                {
723
2.87k
                    {RPCResult::Type::STR, "value", "A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'"},
724
2.87k
                }},
725
2.87k
                {RPCResult::Type::STR_HEX, "noncerange", "A range of valid nonces"},
726
2.87k
                {RPCResult::Type::NUM, "sigoplimit", "limit of sigops in blocks"},
727
2.87k
                {RPCResult::Type::NUM, "sizelimit", "limit of block size"},
728
2.87k
                {RPCResult::Type::NUM, "weightlimit", /*optional=*/true, "limit of block weight"},
729
2.87k
                {RPCResult::Type::NUM_TIME, "curtime", "current timestamp in " + UNIX_EPOCH_TIME + ". Adjusted for the proposed BIP94 timewarp rule."},
730
2.87k
                {RPCResult::Type::STR, "bits", "compressed target of next block"},
731
2.87k
                {RPCResult::Type::NUM, "height", "The height of the next block"},
732
2.87k
                {RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "Only on signet"},
733
2.87k
                {RPCResult::Type::STR_HEX, "default_witness_commitment", /*optional=*/true, "a valid witness commitment for the unmodified block template"},
734
2.87k
            }},
735
2.87k
        },
736
2.87k
        RPCExamples{
737
2.87k
                    HelpExampleCli("getblocktemplate", "'{\"rules\": [\"segwit\"]}'")
738
2.87k
            + HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}")
739
2.87k
                },
740
2.87k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
741
2.87k
{
742
413
    NodeContext& node = EnsureAnyNodeContext(request.context);
743
413
    ChainstateManager& chainman = EnsureChainman(node);
744
413
    Mining& miner = EnsureMining(node);
745
746
413
    std::string strMode = "template";
747
413
    UniValue lpval = NullUniValue;
748
413
    std::set<std::string> setClientRules;
749
413
    if (!request.params[0].isNull())
750
413
    {
751
413
        const UniValue& oparam = request.params[0].get_obj();
752
413
        const UniValue& modeval = oparam.find_value("mode");
753
413
        if (modeval.isStr())
754
321
            strMode = modeval.get_str();
755
92
        else if (modeval.isNull())
756
92
        {
757
            /* Do nothing */
758
92
        }
759
0
        else
760
0
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
761
413
        lpval = oparam.find_value("longpollid");
762
763
413
        if (strMode == "proposal")
764
321
        {
765
321
            const UniValue& dataval = oparam.find_value("data");
766
321
            if (!dataval.isStr())
767
0
                throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
768
769
321
            CBlock block;
770
321
            if (!DecodeHexBlk(block, dataval.get_str()))
771
2
                throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
772
773
319
            uint256 hash = block.GetHash();
774
319
            LOCK(cs_main);
775
319
            const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
776
319
            if (pindex) {
777
0
                if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
778
0
                    return "duplicate";
779
0
                if (pindex->nStatus & BLOCK_FAILED_VALID)
780
0
                    return "duplicate-invalid";
781
0
                return "duplicate-inconclusive";
782
0
            }
783
784
319
            return BIP22ValidationResult(TestBlockValidity(chainman.ActiveChainstate(), block, /*check_pow=*/false, /*check_merkle_root=*/true));
785
319
        }
786
787
92
        const UniValue& aClientRules = oparam.find_value("rules");
788
92
        if (aClientRules.isArray()) {
789
188
            for (unsigned int i = 0; i < aClientRules.size(); ++i) {
790
97
                const UniValue& v = aClientRules[i];
791
97
                setClientRules.insert(v.get_str());
792
97
            }
793
91
        }
794
92
    }
795
796
92
    if (strMode != "template")
797
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
798
799
92
    if (!miner.isTestChain()) {
800
0
        const CConnman& connman = EnsureConnman(node);
801
0
        if (connman.GetNodeCount(ConnectionDirection::Both) == 0) {
802
0
            throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, CLIENT_NAME " is not connected!");
803
0
        }
804
805
0
        if (miner.isInitialBlockDownload()) {
806
0
            throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, CLIENT_NAME " is in initial sync and waiting for blocks...");
807
0
        }
808
0
    }
809
810
92
    static unsigned int nTransactionsUpdatedLast;
811
92
    const CTxMemPool& mempool = EnsureMemPool(node);
812
813
92
    WAIT_LOCK(cs_main, cs_main_lock);
814
92
    uint256 tip{CHECK_NONFATAL(miner.getTip()).value().hash};
815
816
    // Long Polling (BIP22)
817
92
    if (!lpval.isNull()) {
818
        /**
819
         * Wait to respond until either the best block changes, OR there are more
820
         * transactions.
821
         *
822
         * The check for new transactions first happens after 1 minute and
823
         * subsequently every 10 seconds. BIP22 does not require this particular interval.
824
         * On mainnet the mempool changes frequently enough that in practice this RPC
825
         * returns after 60 seconds, or sooner if the best block changes.
826
         *
827
         * getblocktemplate is unlikely to be called by bitcoin-cli, so
828
         * -rpcclienttimeout is not a concern. BIP22 recommends a long request timeout.
829
         *
830
         * The longpollid is assumed to be a tip hash if it has the right format.
831
         */
832
3
        uint256 hashWatchedChain;
833
3
        unsigned int nTransactionsUpdatedLastLP;
834
835
3
        if (lpval.isStr())
836
3
        {
837
            // Format: <hashBestChain><nTransactionsUpdatedLast>
838
3
            const std::string& lpstr = lpval.get_str();
839
840
            // Assume the longpollid is a block hash. If it's not then we return
841
            // early below.
842
3
            hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid");
843
3
            nTransactionsUpdatedLastLP = LocaleIndependentAtoi<int64_t>(lpstr.substr(64));
844
3
        }
845
0
        else
846
0
        {
847
            // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
848
0
            hashWatchedChain = tip;
849
0
            nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
850
0
        }
851
852
        // Release lock while waiting
853
3
        {
854
3
            REVERSE_LOCK(cs_main_lock, cs_main);
855
3
            MillisecondsDouble checktxtime{std::chrono::minutes(1)};
856
3
            while (IsRPCRunning()) {
857
                // If hashWatchedChain is not a real block hash, this will
858
                // return immediately.
859
3
                std::optional<BlockRef> maybe_tip{miner.waitTipChanged(hashWatchedChain, checktxtime)};
860
                // Node is shutting down
861
3
                if (!maybe_tip) break;
862
3
                tip = maybe_tip->hash;
863
3
                if (tip != hashWatchedChain) break;
864
865
                // Check transactions for update without holding the mempool
866
                // lock to avoid deadlocks.
867
1
                if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) {
868
1
                    break;
869
1
                }
870
0
                checktxtime = std::chrono::seconds(10);
871
0
            }
872
3
        }
873
3
        tip = CHECK_NONFATAL(miner.getTip()).value().hash;
874
875
3
        if (!IsRPCRunning())
876
0
            throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
877
        // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
878
3
    }
879
880
92
    const Consensus::Params& consensusParams = chainman.GetParams().GetConsensus();
881
882
    // GBT must be called with 'signet' set in the rules for signet chains
883
92
    if (consensusParams.signet_blocks && !setClientRules.contains("signet")) {
884
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "getblocktemplate must be called with the signet rule set (call with {\"rules\": [\"segwit\", \"signet\"]})");
885
0
    }
886
887
    // GBT must be called with 'segwit' set in the rules
888
92
    if (!setClientRules.contains("segwit")) {
889
1
        throw JSONRPCError(RPC_INVALID_PARAMETER, "getblocktemplate must be called with the segwit rule set (call with {\"rules\": [\"segwit\"]})");
890
1
    }
891
892
    // Update block
893
91
    static CBlockIndex* pindexPrev;
894
91
    static int64_t time_start;
895
91
    static std::unique_ptr<BlockTemplate> block_template;
896
91
    if (!pindexPrev || pindexPrev->GetBlockHash() != tip ||
897
91
        (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5))
898
75
    {
899
        // Clear pindexPrev so future calls make a new block, despite any failures from here on
900
75
        pindexPrev = nullptr;
901
902
        // Store the pindexBest used before createNewBlock, to avoid races
903
75
        nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
904
75
        CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(tip);
905
75
        time_start = GetTime();
906
907
        // Create new block. Opt-out of cooldown mechanism, because it would add
908
        // a delay to each getblocktemplate call. This differs from typical
909
        // long-lived IPC usage, where the overhead is paid only when creating
910
        // the initial template.
911
75
        block_template = miner.createNewBlock({}, /*cooldown=*/false);
912
75
        CHECK_NONFATAL(block_template);
913
914
915
        // Need to update only after we know createNewBlock succeeded
916
75
        pindexPrev = pindexPrevNew;
917
75
    }
918
91
    CHECK_NONFATAL(pindexPrev);
919
91
    CBlock block{block_template->getBlock()};
920
921
    // Update nTime
922
91
    UpdateTime(&block, consensusParams, pindexPrev);
923
91
    block.nNonce = 0;
924
925
    // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
926
91
    const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT);
927
928
91
    UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
929
930
91
    UniValue transactions(UniValue::VARR);
931
91
    std::map<Txid, int64_t> setTxIndex;
932
91
    std::vector<CAmount> tx_fees{block_template->getTxFees()};
933
91
    std::vector<int64_t> tx_sigops{block_template->getTxSigops()};
934
935
91
    int i = 0;
936
200
    for (const auto& it : block.vtx) {
937
200
        const CTransaction& tx = *it;
938
200
        Txid txHash = tx.GetHash();
939
200
        setTxIndex[txHash] = i++;
940
941
200
        if (tx.IsCoinBase())
942
91
            continue;
943
944
109
        UniValue entry(UniValue::VOBJ);
945
946
109
        entry.pushKV("data", EncodeHexTx(tx));
947
109
        entry.pushKV("txid", txHash.GetHex());
948
109
        entry.pushKV("hash", tx.GetWitnessHash().GetHex());
949
950
109
        UniValue deps(UniValue::VARR);
951
109
        for (const CTxIn &in : tx.vin)
952
109
        {
953
109
            if (setTxIndex.contains(in.prevout.hash))
954
8
                deps.push_back(setTxIndex[in.prevout.hash]);
955
109
        }
956
109
        entry.pushKV("depends", std::move(deps));
957
958
109
        int index_in_template = i - 2;
959
109
        entry.pushKV("fee", tx_fees.at(index_in_template));
960
109
        int64_t nTxSigOps{tx_sigops.at(index_in_template)};
961
109
        if (fPreSegWit) {
962
5
            CHECK_NONFATAL(nTxSigOps % WITNESS_SCALE_FACTOR == 0);
963
5
            nTxSigOps /= WITNESS_SCALE_FACTOR;
964
5
        }
965
109
        entry.pushKV("sigops", nTxSigOps);
966
109
        entry.pushKV("weight", GetTransactionWeight(tx));
967
968
109
        transactions.push_back(std::move(entry));
969
109
    }
970
971
91
    UniValue aux(UniValue::VOBJ);
972
973
91
    arith_uint256 hashTarget = arith_uint256().SetCompact(block.nBits);
974
975
91
    UniValue aMutable(UniValue::VARR);
976
91
    aMutable.push_back("time");
977
91
    aMutable.push_back("transactions");
978
91
    aMutable.push_back("prevblock");
979
980
91
    UniValue result(UniValue::VOBJ);
981
91
    result.pushKV("capabilities", std::move(aCaps));
982
983
91
    UniValue aRules(UniValue::VARR);
984
    // See getblocktemplate changes in BIP 9:
985
    // ! indicates a more subtle change to the block structure or generation transaction
986
    // Otherwise clients may assume the rule will not impact usage of the template as-is.
987
91
    aRules.push_back("csv");
988
91
    if (!fPreSegWit) {
989
87
        aRules.push_back("!segwit");
990
87
        aRules.push_back("taproot");
991
87
    }
992
91
    if (consensusParams.signet_blocks) {
993
        // indicate to miner that they must understand signet rules
994
        // when attempting to mine with this template
995
6
        aRules.push_back("!signet");
996
6
    }
997
998
91
    UniValue vbavailable(UniValue::VOBJ);
999
91
    const auto gbtstatus = chainman.m_versionbitscache.GBTStatus(*pindexPrev, consensusParams);
1000
1001
91
    for (const auto& [name, info] : gbtstatus.signalling) {
1002
50
        vbavailable.pushKV(gbt_rule_value(name, info.gbt_optional_rule), info.bit);
1003
50
        if (!info.gbt_optional_rule && !setClientRules.contains(name)) {
1004
            // If the client doesn't support this, don't indicate it in the [default] version
1005
0
            block.nVersion &= ~info.mask;
1006
0
        }
1007
50
    }
1008
1009
91
    for (const auto& [name, info] : gbtstatus.locked_in) {
1010
25
        block.nVersion |= info.mask;
1011
25
        vbavailable.pushKV(gbt_rule_value(name, info.gbt_optional_rule), info.bit);
1012
25
        if (!info.gbt_optional_rule && !setClientRules.contains(name)) {
1013
            // If the client doesn't support this, don't indicate it in the [default] version
1014
0
            block.nVersion &= ~info.mask;
1015
0
        }
1016
25
    }
1017
1018
91
    for (const auto& [name, info] : gbtstatus.active) {
1019
2
        aRules.push_back(gbt_rule_value(name, info.gbt_optional_rule));
1020
2
        if (!info.gbt_optional_rule && !setClientRules.contains(name)) {
1021
            // Not supported by the client; make sure it's safe to proceed
1022
0
            throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", name));
1023
0
        }
1024
2
    }
1025
1026
91
    result.pushKV("version", block.nVersion);
1027
91
    result.pushKV("rules", std::move(aRules));
1028
91
    result.pushKV("vbavailable", std::move(vbavailable));
1029
91
    result.pushKV("vbrequired", 0);
1030
1031
91
    result.pushKV("previousblockhash", block.hashPrevBlock.GetHex());
1032
91
    result.pushKV("transactions", std::move(transactions));
1033
91
    result.pushKV("coinbaseaux", std::move(aux));
1034
91
    result.pushKV("coinbasevalue", block.vtx[0]->vout[0].nValue);
1035
91
    result.pushKV("longpollid", tip.GetHex() + ToString(nTransactionsUpdatedLast));
1036
91
    result.pushKV("target", hashTarget.GetHex());
1037
91
    result.pushKV("mintime", GetMinimumTime(pindexPrev, consensusParams.DifficultyAdjustmentInterval()));
1038
91
    result.pushKV("mutable", std::move(aMutable));
1039
91
    result.pushKV("noncerange", "00000000ffffffff");
1040
91
    int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST;
1041
91
    int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE;
1042
91
    if (fPreSegWit) {
1043
4
        CHECK_NONFATAL(nSigOpLimit % WITNESS_SCALE_FACTOR == 0);
1044
4
        nSigOpLimit /= WITNESS_SCALE_FACTOR;
1045
4
        CHECK_NONFATAL(nSizeLimit % WITNESS_SCALE_FACTOR == 0);
1046
4
        nSizeLimit /= WITNESS_SCALE_FACTOR;
1047
4
    }
1048
91
    result.pushKV("sigoplimit", nSigOpLimit);
1049
91
    result.pushKV("sizelimit", nSizeLimit);
1050
91
    if (!fPreSegWit) {
1051
87
        result.pushKV("weightlimit", MAX_BLOCK_WEIGHT);
1052
87
    }
1053
91
    result.pushKV("curtime", block.GetBlockTime());
1054
91
    result.pushKV("bits", strprintf("%08x", block.nBits));
1055
91
    result.pushKV("height", pindexPrev->nHeight + 1);
1056
1057
91
    if (consensusParams.signet_blocks) {
1058
6
        result.pushKV("signet_challenge", HexStr(consensusParams.signet_challenge));
1059
6
    }
1060
1061
91
    if (auto coinbase{block_template->getCoinbaseTx()}; coinbase.required_outputs.size() > 0) {
1062
91
        CHECK_NONFATAL(coinbase.required_outputs.size() == 1); // Only one output is currently expected
1063
91
        result.pushKV("default_witness_commitment", HexStr(coinbase.required_outputs[0].scriptPubKey));
1064
91
    }
1065
1066
91
    return result;
1067
91
},
1068
2.87k
    };
1069
2.87k
}
1070
1071
class submitblock_StateCatcher final : public CValidationInterface
1072
{
1073
public:
1074
    uint256 hash;
1075
    bool found{false};
1076
    BlockValidationState state;
1077
1078
7.21k
    explicit submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), state() {}
1079
1080
protected:
1081
    void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& stateIn) override
1082
7.05k
    {
1083
7.05k
        if (block->GetHash() != hash) return;
1084
6.95k
        found = true;
1085
6.95k
        state = stateIn;
1086
6.95k
    }
1087
};
1088
1089
static RPCMethod submitblock()
1090
9.67k
{
1091
    // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.
1092
9.67k
    return RPCMethod{
1093
9.67k
        "submitblock",
1094
9.67k
        "Attempts to submit new block to network.\n"
1095
9.67k
        "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n",
1096
9.67k
        {
1097
9.67k
            {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block data to submit"},
1098
9.67k
            {"dummy", RPCArg::Type::STR, RPCArg::DefaultHint{"ignored"}, "dummy value, for compatibility with BIP22. This value is ignored.",
1099
9.67k
                RPCArgOptions{.placeholder = true}},
1100
9.67k
        },
1101
9.67k
        {
1102
9.67k
            RPCResult{"If the block was accepted", RPCResult::Type::NONE, "", ""},
1103
9.67k
            RPCResult{"Otherwise", RPCResult::Type::STR, "", "According to BIP22"},
1104
9.67k
        },
1105
9.67k
        RPCExamples{
1106
9.67k
                    HelpExampleCli("submitblock", "\"mydata\"")
1107
9.67k
            + HelpExampleRpc("submitblock", "\"mydata\"")
1108
9.67k
                },
1109
9.67k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
1110
9.67k
{
1111
7.21k
    std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
1112
7.21k
    CBlock& block = *blockptr;
1113
7.21k
    if (!DecodeHexBlk(block, request.params[0].get_str())) {
1114
2
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
1115
2
    }
1116
1117
7.21k
    ChainstateManager& chainman = EnsureAnyChainman(request.context);
1118
7.21k
    {
1119
7.21k
        LOCK(cs_main);
1120
7.21k
        const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
1121
7.21k
        if (pindex) {
1122
7.20k
            chainman.UpdateUncommittedBlockStructures(block, pindex);
1123
7.20k
        }
1124
7.21k
    }
1125
1126
7.21k
    bool new_block;
1127
7.21k
    auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
1128
7.21k
    CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc);
1129
7.21k
    bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
1130
7.21k
    CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc);
1131
7.21k
    if (!new_block && accepted) {
1132
127
        return "duplicate";
1133
127
    }
1134
7.08k
    if (!sc->found) {
1135
126
        return "inconclusive";
1136
126
    }
1137
6.95k
    return BIP22ValidationResult(sc->state);
1138
7.08k
},
1139
9.67k
    };
1140
9.67k
}
1141
1142
static RPCMethod submitheader()
1143
4.30k
{
1144
4.30k
    return RPCMethod{
1145
4.30k
        "submitheader",
1146
4.30k
        "Decode the given hexdata as a header and submit it as a candidate chain tip if valid."
1147
4.30k
                "\nThrows when the header is invalid.\n",
1148
4.30k
                {
1149
4.30k
                    {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"},
1150
4.30k
                },
1151
4.30k
                RPCResult{
1152
4.30k
                    RPCResult::Type::NONE, "", "None"},
1153
4.30k
                RPCExamples{
1154
4.30k
                    HelpExampleCli("submitheader", "\"aabbcc\"") +
1155
4.30k
                    HelpExampleRpc("submitheader", "\"aabbcc\"")
1156
4.30k
                },
1157
4.30k
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
1158
4.30k
{
1159
1.84k
    CBlockHeader h;
1160
1.84k
    if (!DecodeHexBlockHeader(h, request.params[0].get_str())) {
1161
2
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block header decode failed");
1162
2
    }
1163
1.84k
    ChainstateManager& chainman = EnsureAnyChainman(request.context);
1164
1.84k
    {
1165
1.84k
        LOCK(cs_main);
1166
1.84k
        if (!chainman.m_blockman.LookupBlockIndex(h.hashPrevBlock)) {
1167
1
            throw JSONRPCError(RPC_VERIFY_ERROR, "Must submit previous header (" + h.hashPrevBlock.GetHex() + ") first");
1168
1
        }
1169
1.84k
    }
1170
1171
1.84k
    BlockValidationState state;
1172
1.84k
    chainman.ProcessNewBlockHeaders({{h}}, /*min_pow_checked=*/true, state);
1173
1.84k
    if (state.IsValid()) return UniValue::VNULL;
1174
6
    if (state.IsError()) {
1175
0
        throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
1176
0
    }
1177
6
    throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason());
1178
6
},
1179
4.30k
    };
1180
4.30k
}
1181
1182
void RegisterMiningRPCCommands(CRPCTable& t)
1183
1.36k
{
1184
1.36k
    static const CRPCCommand commands[]{
1185
1.36k
        {"mining", &getnetworkhashps},
1186
1.36k
        {"mining", &getmininginfo},
1187
1.36k
        {"mining", &prioritisetransaction},
1188
1.36k
        {"mining", &getprioritisedtransactions},
1189
1.36k
        {"mining", &getblocktemplate},
1190
1.36k
        {"mining", &submitblock},
1191
1.36k
        {"mining", &submitheader},
1192
1193
1.36k
        {"hidden", &generatetoaddress},
1194
1.36k
        {"hidden", &generatetodescriptor},
1195
1.36k
        {"hidden", &generateblock},
1196
1.36k
        {"hidden", &generate},
1197
1.36k
    };
1198
14.9k
    for (const auto& c : commands) {
1199
14.9k
        t.appendCommand(c.name, &c);
1200
14.9k
    }
1201
1.36k
}