Coverage Report

Created: 2026-10-19 15:22

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