Skip to content

Commit

Permalink
Merge bitcoin#31583: rpc: add target to getmininginfo field and show …
Browse files Browse the repository at this point in the history
…next block info

a4df123 doc: add release notes (Sjors Provoost)
c75872f test: use DIFF_1_N_BITS in tool_signet_miner (tdb3)
4131f32 test: check difficulty adjustment using alternate mainnet (Sjors Provoost)
c4f68c1 Use OP_0 for BIP34 padding in signet and tests (Sjors Provoost)
cf0a628 rpc: add next to getmininginfo (Sjors Provoost)
2d18a07 rpc: add target and bits to getchainstates (Sjors Provoost)
f153f57 rpc: add target and bits to getblockchaininfo (Sjors Provoost)
baa504f rpc: add target to getmininginfo result (Sjors Provoost)
2a7bfeb Add target to getblock(header) in RPC and REST (Sjors Provoost)
341f932 rpc: add GetTarget helper (Sjors Provoost)
d20d96f test: use REGTEST_N_BITS in feature_block (tdb3)
7ddbed4 rpc: add nBits to getmininginfo (Sjors Provoost)
ba7b9f3 build: move pow and chain to bitcoin_common (Sjors Provoost)
c4cc9e3 consensus: add DeriveTarget() to pow.h (Sjors Provoost)

Pull request description:

  **tl&dr for consensus-code only reviewers**: the first commit splits `CheckProofOfWorkImpl()` in order to create a `DeriveTarget()` helper. The rest of this PR does not touch consensus code.

  There are three ways to represent the proof-of-work in a block:

  1. nBits
  2. Difficulty
  3. Target

  The latter notation is useful when you want to compare share work against either the pool target (to get paid) or network difficulty (found an actual block). E.g. for difficulty 1 which corresponds to an nBits value of `0x00ffff`:

  ```
  share hash: f6b973257df982284715b0c7a20640dad709d22b0b1a58f2f88d35886ea5ac45
  target:     7fffff0000000000000000000000000000000000000000000000000000000000
  ```

  It's immediately clear that the share is invalid because the hash is above the target.

  This type of logging is mostly done by the pool software. It's a nice extra convenience, but not very important. It impacts the following RPC calls:

  1. `getmininginfo` displays the `target` for the tip block
  2. `getblock` and `getblockheader` display the `target` for a specific block (ditto for their REST equivalents)

  The `getdifficulty` method is a bit useless in its current state, because what miners really want to know if the difficulty for the _next_ block. So I added a boolean argument `next` to `getdifficulty`. (These values are typically the same, except for the first block in a retarget period. On testnet3 / testnet4 they change when no block is found after 20 minutes).

  Similarly I added a `next` object to `getmininginfo` which shows `bit`, `difficulty` and `target` for the next block.

  In order to test the difficulty transition, an alternate mainnet chain with 2016 blocks was generated and used in `mining_mainnet.py`. The chain is deterministic except for its timestamp and nonce values, which are stored in `mainnet_alt.json`.

  As described at the top, this PR introduces a helper method `DeriveTarget()` which is split out from `CheckProofOfWorkImpl`. The proposed `checkblock` RPC in bitcoin#31564 needs this helper method internally to figure out the consensus target.

  Finally, this PR moves `pow.cpp` and `chain.cpp` from `bitcoin_node` to `bitcoin_common`, in order to give `rpc/util.cpp` (which lives in `bitcoin_common`) access to `pow.h`.

ACKs for top commit:
  ismaelsadeeq:
    re-ACK a4df123
  tdb3:
    code review re ACK a4df123
  ryanofsky:
    Code review ACK a4df123. Only overall changes since last review were dropping new `gettarget` method and dropping changes to `getdifficulty`, but there were also various internal changes splitting and rearranging commits.

Tree-SHA512: edef5633590379c4be007ac96fd1deda8a5b9562ca6ff19fe377cb552b5166f3890d158554c249ab8345977a06da5df07866c9f42ac43ee83dfe3830c61cd169
  • Loading branch information
ryanofsky committed Jan 22, 2025
2 parents 78fa88c + a4df123 commit 5acf12b
Show file tree
Hide file tree
Showing 24 changed files with 4,385 additions and 37 deletions.
9 changes: 9 additions & 0 deletions doc/release-notes-31583.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Updated RPCs
---
- `getmininginfo` now returns `nBits` and the current target in the `target` field. It also returns a `next` object which specifies the `height`, `nBits`, `difficulty`, and `target` for the next block.
- `getblock` and `getblockheader` now return the current target in the `target` field
- `getblockchaininfo` and `getchainstates` now return `nBits` and the current target in the `target` field

REST interface
---
- `GET /rest/block/<BLOCK-HASH>.json` and `GET /rest/headers/<BLOCK-HASH>.json` now return the current target in the `target` field
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL
addresstype.cpp
base58.cpp
bech32.cpp
chain.cpp
chainparams.cpp
chainparamsbase.cpp
coins.cpp
Expand Down Expand Up @@ -142,6 +143,7 @@ add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL
outputtype.cpp
policy/feerate.cpp
policy/policy.cpp
pow.cpp
protocol.cpp
psbt.cpp
rpc/external_signer.cpp
Expand Down Expand Up @@ -200,7 +202,6 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL
bip324.cpp
blockencodings.cpp
blockfilter.cpp
chain.cpp
consensus/tx_verify.cpp
dbwrapper.cpp
deploymentstatus.cpp
Expand Down Expand Up @@ -262,7 +263,6 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL
policy/rbf.cpp
policy/settings.cpp
policy/truc_policy.cpp
pow.cpp
rest.cpp
rpc/blockchain.cpp
rpc/fees.cpp
Expand Down
6 changes: 4 additions & 2 deletions src/bench/rpc_blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ struct TestBlockAndIndex {
static void BlockToJsonVerbose(benchmark::Bench& bench)
{
TestBlockAndIndex data;
const uint256 pow_limit{data.testing_setup->m_node.chainman->GetParams().GetConsensus().powLimit};
bench.run([&] {
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT, pow_limit);
ankerl::nanobench::doNotOptimizeAway(univalue);
});
}
Expand All @@ -59,7 +60,8 @@ BENCHMARK(BlockToJsonVerbose, benchmark::PriorityLevel::HIGH);
static void BlockToJsonVerboseWrite(benchmark::Bench& bench)
{
TestBlockAndIndex data;
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
const uint256 pow_limit{data.testing_setup->m_node.chainman->GetParams().GetConsensus().powLimit};
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT, pow_limit);
bench.run([&] {
auto str = univalue.write();
ankerl::nanobench::doNotOptimizeAway(str);
Expand Down
14 changes: 11 additions & 3 deletions src/pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&
return CheckProofOfWorkImpl(hash, nBits, params);
}

bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params& params)
std::optional<arith_uint256> DeriveTarget(unsigned int nBits, const uint256 pow_limit)
{
bool fNegative;
bool fOverflow;
Expand All @@ -152,8 +152,16 @@ bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Par
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

// Check range
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
return false;
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(pow_limit))
return {};

return bnTarget;
}

bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
auto bnTarget{DeriveTarget(nBits, params.powLimit)};
if (!bnTarget) return false;

// Check proof of work matches claimed amount
if (UintToArith256(hash) > bnTarget)
Expand Down
12 changes: 12 additions & 0 deletions src/pow.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@
class CBlockHeader;
class CBlockIndex;
class uint256;
class arith_uint256;

/**
* Convert nBits value to target.
*
* @param[in] nBits compact representation of the target
* @param[in] pow_limit PoW limit (consensus parameter)
*
* @return the proof-of-work target or nullopt if the nBits value
* is invalid (due to overflow or exceeding pow_limit)
*/
std::optional<arith_uint256> DeriveTarget(unsigned int nBits, const uint256 pow_limit);

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);
Expand Down
10 changes: 5 additions & 5 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,10 @@ static bool rest_headers(const std::any& context,
const CBlockIndex* tip = nullptr;
std::vector<const CBlockIndex*> headers;
headers.reserve(*parsed_count);
ChainstateManager* maybe_chainman = GetChainman(context, req);
if (!maybe_chainman) return false;
ChainstateManager& chainman = *maybe_chainman;
{
ChainstateManager* maybe_chainman = GetChainman(context, req);
if (!maybe_chainman) return false;
ChainstateManager& chainman = *maybe_chainman;
LOCK(cs_main);
CChain& active_chain = chainman.ActiveChain();
tip = active_chain.Tip();
Expand Down Expand Up @@ -268,7 +268,7 @@ static bool rest_headers(const std::any& context,
case RESTResponseFormat::JSON: {
UniValue jsonHeaders(UniValue::VARR);
for (const CBlockIndex *pindex : headers) {
jsonHeaders.push_back(blockheaderToJSON(*tip, *pindex));
jsonHeaders.push_back(blockheaderToJSON(*tip, *pindex, chainman.GetConsensus().powLimit));
}
std::string strJSON = jsonHeaders.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
Expand Down Expand Up @@ -341,7 +341,7 @@ static bool rest_block(const std::any& context,
CBlock block{};
DataStream block_stream{block_data};
block_stream >> TX_WITH_WITNESS(block);
UniValue objBlock = blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity);
UniValue objBlock = blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity, chainman.GetConsensus().powLimit);
std::string strJSON = objBlock.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
req->WriteReply(HTTP_OK, strJSON);
Expand Down
27 changes: 19 additions & 8 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ static const CBlockIndex* ParseHashOrHeight(const UniValue& param, ChainstateMan
}
}

UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex)
UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex, const uint256 pow_limit)
{
// Serialize passed information without accessing chain state of the active chain!
AssertLockNotHeld(cs_main); // For performance reasons
Expand All @@ -164,6 +164,7 @@ UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex
result.pushKV("mediantime", blockindex.GetMedianTimePast());
result.pushKV("nonce", blockindex.nNonce);
result.pushKV("bits", strprintf("%08x", blockindex.nBits));
result.pushKV("target", GetTarget(tip, pow_limit).GetHex());
result.pushKV("difficulty", GetDifficulty(blockindex));
result.pushKV("chainwork", blockindex.nChainWork.GetHex());
result.pushKV("nTx", blockindex.nTx);
Expand All @@ -175,9 +176,9 @@ UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex
return result;
}

UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity)
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity, const uint256 pow_limit)
{
UniValue result = blockheaderToJSON(tip, blockindex);
UniValue result = blockheaderToJSON(tip, blockindex, pow_limit);

result.pushKV("strippedsize", (int)::GetSerializeSize(TX_NO_WITNESS(block)));
result.pushKV("size", (int)::GetSerializeSize(TX_WITH_WITNESS(block)));
Expand Down Expand Up @@ -553,7 +554,8 @@ static RPCHelpMan getblockheader()
{RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
{RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
{RPCResult::Type::NUM, "nonce", "The nonce"},
{RPCResult::Type::STR_HEX, "bits", "The bits"},
{RPCResult::Type::STR_HEX, "bits", "nBits: compact representation of the block difficulty target"},
{RPCResult::Type::STR_HEX, "target", "The difficulty target"},
{RPCResult::Type::NUM, "difficulty", "The difficulty"},
{RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"},
{RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
Expand All @@ -577,8 +579,8 @@ static RPCHelpMan getblockheader()

const CBlockIndex* pblockindex;
const CBlockIndex* tip;
ChainstateManager& chainman = EnsureAnyChainman(request.context);
{
ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
tip = chainman.ActiveChain().Tip();
Expand All @@ -596,7 +598,7 @@ static RPCHelpMan getblockheader()
return strHex;
}

return blockheaderToJSON(*tip, *pblockindex);
return blockheaderToJSON(*tip, *pblockindex, chainman.GetConsensus().powLimit);
},
};
}
Expand Down Expand Up @@ -727,7 +729,8 @@ static RPCHelpMan getblock()
{RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
{RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
{RPCResult::Type::NUM, "nonce", "The nonce"},
{RPCResult::Type::STR_HEX, "bits", "The bits"},
{RPCResult::Type::STR_HEX, "bits", "nBits: compact representation of the block difficulty target"},
{RPCResult::Type::STR_HEX, "target", "The difficulty target"},
{RPCResult::Type::NUM, "difficulty", "The difficulty"},
{RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the chain up to this block (in hex)"},
{RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
Expand Down Expand Up @@ -802,7 +805,7 @@ static RPCHelpMan getblock()
tx_verbosity = TxVerbosity::SHOW_DETAILS_AND_PREVOUT;
}

return blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity);
return blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity, chainman.GetConsensus().powLimit);
},
};
}
Expand Down Expand Up @@ -1296,6 +1299,8 @@ RPCHelpMan getblockchaininfo()
{RPCResult::Type::NUM, "blocks", "the height of the most-work fully-validated chain. The genesis block has height 0"},
{RPCResult::Type::NUM, "headers", "the current number of headers we have validated"},
{RPCResult::Type::STR, "bestblockhash", "the hash of the currently best block"},
{RPCResult::Type::STR_HEX, "bits", "nBits: compact representation of the block difficulty target"},
{RPCResult::Type::STR_HEX, "target", "The difficulty target"},
{RPCResult::Type::NUM, "difficulty", "the current difficulty"},
{RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
{RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
Expand Down Expand Up @@ -1334,6 +1339,8 @@ RPCHelpMan getblockchaininfo()
obj.pushKV("blocks", height);
obj.pushKV("headers", chainman.m_best_header ? chainman.m_best_header->nHeight : -1);
obj.pushKV("bestblockhash", tip.GetBlockHash().GetHex());
obj.pushKV("bits", strprintf("%08x", tip.nBits));
obj.pushKV("target", GetTarget(tip, chainman.GetConsensus().powLimit).GetHex());
obj.pushKV("difficulty", GetDifficulty(tip));
obj.pushKV("time", tip.GetBlockTime());
obj.pushKV("mediantime", tip.GetMedianTimePast());
Expand Down Expand Up @@ -3301,6 +3308,8 @@ static RPCHelpMan loadtxoutset()
const std::vector<RPCResult> RPCHelpForChainstate{
{RPCResult::Type::NUM, "blocks", "number of blocks in this chainstate"},
{RPCResult::Type::STR_HEX, "bestblockhash", "blockhash of the tip"},
{RPCResult::Type::STR_HEX, "bits", "nBits: compact representation of the block difficulty target"},
{RPCResult::Type::STR_HEX, "target", "The difficulty target"},
{RPCResult::Type::NUM, "difficulty", "difficulty of the tip"},
{RPCResult::Type::NUM, "verificationprogress", "progress towards the network tip"},
{RPCResult::Type::STR_HEX, "snapshot_blockhash", /*optional=*/true, "the base block of the snapshot this chainstate is based on, if any"},
Expand Down Expand Up @@ -3343,6 +3352,8 @@ return RPCHelpMan{

data.pushKV("blocks", (int)chain.Height());
data.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
data.pushKV("bits", strprintf("%08x", tip->nBits));
data.pushKV("target", GetTarget(*tip, chainman.GetConsensus().powLimit).GetHex());
data.pushKV("difficulty", GetDifficulty(*tip));
data.pushKV("verificationprogress", chainman.GuessVerificationProgress(tip));
data.pushKV("coins_db_cache_bytes", cs.m_coinsdb_cache_size_bytes);
Expand Down
4 changes: 2 additions & 2 deletions src/rpc/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
double GetDifficulty(const CBlockIndex& blockindex);

/** Block description to JSON */
UniValue blockToJSON(node::BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity) LOCKS_EXCLUDED(cs_main);
UniValue blockToJSON(node::BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity, const uint256 pow_limit) LOCKS_EXCLUDED(cs_main);

/** Block header to JSON */
UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex) LOCKS_EXCLUDED(cs_main);
UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex, const uint256 pow_limit) LOCKS_EXCLUDED(cs_main);

/** Used by getblockstats to get feerates at different percentiles by weight */
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);
Expand Down
27 changes: 25 additions & 2 deletions src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,20 @@ static RPCHelpMan getmininginfo()
{RPCResult::Type::NUM, "blocks", "The current block"},
{RPCResult::Type::NUM, "currentblockweight", /*optional=*/true, "The block weight of the last assembled block (only present if a block was ever assembled)"},
{RPCResult::Type::NUM, "currentblocktx", /*optional=*/true, "The number of block transactions of the last assembled block (only present if a block was ever assembled)"},
{RPCResult::Type::STR_HEX, "bits", "The current nBits, compact representation of the block difficulty target"},
{RPCResult::Type::NUM, "difficulty", "The current difficulty"},
{RPCResult::Type::STR_HEX, "target", "The current target"},
{RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
{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)",
Expand All @@ -446,18 +455,32 @@ static RPCHelpMan getmininginfo()
ChainstateManager& chainman = EnsureChainman(node);
LOCK(cs_main);
const CChain& active_chain = chainman.ActiveChain();
CBlockIndex& tip{*CHECK_NONFATAL(active_chain.Tip())};

UniValue obj(UniValue::VOBJ);
obj.pushKV("blocks", active_chain.Height());
if (BlockAssembler::m_last_block_weight) obj.pushKV("currentblockweight", *BlockAssembler::m_last_block_weight);
if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
obj.pushKV("difficulty", GetDifficulty(*CHECK_NONFATAL(active_chain.Tip())));
obj.pushKV("bits", strprintf("%08x", tip.nBits));
obj.pushKV("difficulty", GetDifficulty(tip));
obj.pushKV("target", GetTarget(tip, chainman.GetConsensus().powLimit).GetHex());
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")));
Expand Down
19 changes: 19 additions & 0 deletions src/rpc/server_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -17,6 +20,7 @@
#include <any>

using node::NodeContext;
using node::UpdateTime;

NodeContext& EnsureAnyNodeContext(const std::any& context)
{
Expand Down Expand Up @@ -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;
}
Loading

0 comments on commit 5acf12b

Please sign in to comment.