Coverage Report

Created: 2026-10-07 13:27

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