Coverage Report

Created: 2026-04-29 19:21

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