rpc: add next to getmininginfo

Obtain difficulty and target for the next block without having to call
getblocktemplate.
This commit is contained in:
Sjors Provoost 2024-12-31 10:44:53 +01:00
parent 2d18a078a2
commit cf0a62878b
No known key found for this signature in database
GPG key ID: 57FF9BDBCC301009
4 changed files with 50 additions and 1 deletions

View file

@ -428,6 +428,13 @@ static RPCHelpMan getmininginfo()
{RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
{RPCResult::Type::STR, "chain", "current network name (" LIST_CHAIN_NAMES ")"},
{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)"},
{RPCResult::Type::OBJ, "next", "The next block",
{
{RPCResult::Type::NUM, "height", "The next height"},
{RPCResult::Type::STR_HEX, "bits", "The next target nBits"},
{RPCResult::Type::NUM, "difficulty", "The next difficulty"},
{RPCResult::Type::STR_HEX, "target", "The next target"}
}},
(IsDeprecatedRPCEnabled("warnings") ?
RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
@ -460,9 +467,20 @@ static RPCHelpMan getmininginfo()
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
obj.pushKV("pooledtx", (uint64_t)mempool.size());
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
UniValue next(UniValue::VOBJ);
CBlockIndex next_index;
NextEmptyBlockIndex(tip, chainman.GetConsensus(), next_index);
next.pushKV("height", next_index.nHeight);
next.pushKV("bits", strprintf("%08x", next_index.nBits));
next.pushKV("difficulty", GetDifficulty(next_index));
next.pushKV("target", GetTarget(next_index, chainman.GetConsensus().powLimit).GetHex());
obj.pushKV("next", next);
if (chainman.GetParams().GetChainType() == ChainType::SIGNET) {
const std::vector<uint8_t>& signet_challenge =
chainman.GetParams().GetConsensus().signet_challenge;
chainman.GetConsensus().signet_challenge;
obj.pushKV("signet_challenge", HexStr(signet_challenge));
}
obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings")));

View file

@ -4,10 +4,13 @@
#include <rpc/server_util.h>
#include <chain.h>
#include <common/args.h>
#include <net_processing.h>
#include <node/context.h>
#include <node/miner.h>
#include <policy/fees.h>
#include <pow.h>
#include <rpc/protocol.h>
#include <rpc/request.h>
#include <txmempool.h>
@ -17,6 +20,7 @@
#include <any>
using node::NodeContext;
using node::UpdateTime;
NodeContext& EnsureAnyNodeContext(const std::any& context)
{
@ -129,3 +133,18 @@ AddrMan& EnsureAnyAddrman(const std::any& context)
{
return EnsureAddrman(EnsureAnyNodeContext(context));
}
void NextEmptyBlockIndex(CBlockIndex& tip, const Consensus::Params& consensusParams, CBlockIndex& next_index)
{
CBlockHeader next_header{};
next_header.hashPrevBlock = tip.GetBlockHash();
UpdateTime(&next_header, consensusParams, &tip);
next_header.nBits = GetNextWorkRequired(&tip, &next_header, consensusParams);
next_header.nNonce = 0;
next_index.pprev = &tip;
next_index.nTime = next_header.nTime;
next_index.nBits = next_header.nBits;
next_index.nNonce = next_header.nNonce;
next_index.nHeight = tip.nHeight + 1;
}

View file

@ -7,8 +7,11 @@
#include <any>
#include <consensus/params.h>
class AddrMan;
class ArgsManager;
class CBlockIndex;
class CBlockPolicyEstimator;
class CConnman;
class CTxMemPool;
@ -39,4 +42,7 @@ PeerManager& EnsurePeerman(const node::NodeContext& node);
AddrMan& EnsureAddrman(const node::NodeContext& node);
AddrMan& EnsureAnyAddrman(const std::any& context);
/** Return an empty block index on top of the tip, with height, time and nBits set */
void NextEmptyBlockIndex(CBlockIndex& tip, const Consensus::Params& consensusParams, CBlockIndex& next_index);
#endif // BITCOIN_RPC_SERVER_UTIL_H

View file

@ -213,6 +213,12 @@ class MiningTest(BitcoinTestFramework):
assert_equal(mining_info['bits'], nbits_str(REGTEST_N_BITS))
assert_equal(mining_info['target'], target_str(REGTEST_TARGET))
assert_equal(mining_info['difficulty'], Decimal('4.656542373906925E-10'))
assert_equal(mining_info['next'], {
'height': 201,
'target': target_str(REGTEST_TARGET),
'bits': nbits_str(REGTEST_N_BITS),
'difficulty': Decimal('4.656542373906925E-10')
})
assert_equal(mining_info['networkhashps'], Decimal('0.003333333333333334'))
assert_equal(mining_info['pooledtx'], 0)