Skip to content

Commit 2a7bfeb

Browse files
committed
Add target to getblock(header) in RPC and REST
1 parent 341f932 commit 2a7bfeb

File tree

7 files changed

+30
-16
lines changed

7 files changed

+30
-16
lines changed

src/bench/rpc_blockchain.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ struct TestBlockAndIndex {
4848
static void BlockToJsonVerbose(benchmark::Bench& bench)
4949
{
5050
TestBlockAndIndex data;
51+
const uint256 pow_limit{data.testing_setup->m_node.chainman->GetParams().GetConsensus().powLimit};
5152
bench.run([&] {
52-
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
53+
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT, pow_limit);
5354
ankerl::nanobench::doNotOptimizeAway(univalue);
5455
});
5556
}
@@ -59,7 +60,8 @@ BENCHMARK(BlockToJsonVerbose, benchmark::PriorityLevel::HIGH);
5960
static void BlockToJsonVerboseWrite(benchmark::Bench& bench)
6061
{
6162
TestBlockAndIndex data;
62-
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
63+
const uint256 pow_limit{data.testing_setup->m_node.chainman->GetParams().GetConsensus().powLimit};
64+
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT, pow_limit);
6365
bench.run([&] {
6466
auto str = univalue.write();
6567
ankerl::nanobench::doNotOptimizeAway(str);

src/rest.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ static bool rest_headers(const std::any& context,
225225
const CBlockIndex* tip = nullptr;
226226
std::vector<const CBlockIndex*> headers;
227227
headers.reserve(*parsed_count);
228+
ChainstateManager* maybe_chainman = GetChainman(context, req);
229+
if (!maybe_chainman) return false;
230+
ChainstateManager& chainman = *maybe_chainman;
228231
{
229-
ChainstateManager* maybe_chainman = GetChainman(context, req);
230-
if (!maybe_chainman) return false;
231-
ChainstateManager& chainman = *maybe_chainman;
232232
LOCK(cs_main);
233233
CChain& active_chain = chainman.ActiveChain();
234234
tip = active_chain.Tip();
@@ -268,7 +268,7 @@ static bool rest_headers(const std::any& context,
268268
case RESTResponseFormat::JSON: {
269269
UniValue jsonHeaders(UniValue::VARR);
270270
for (const CBlockIndex *pindex : headers) {
271-
jsonHeaders.push_back(blockheaderToJSON(*tip, *pindex));
271+
jsonHeaders.push_back(blockheaderToJSON(*tip, *pindex, chainman.GetConsensus().powLimit));
272272
}
273273
std::string strJSON = jsonHeaders.write() + "\n";
274274
req->WriteHeader("Content-Type", "application/json");
@@ -341,7 +341,7 @@ static bool rest_block(const std::any& context,
341341
CBlock block{};
342342
DataStream block_stream{block_data};
343343
block_stream >> TX_WITH_WITNESS(block);
344-
UniValue objBlock = blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity);
344+
UniValue objBlock = blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity, chainman.GetConsensus().powLimit);
345345
std::string strJSON = objBlock.write() + "\n";
346346
req->WriteHeader("Content-Type", "application/json");
347347
req->WriteReply(HTTP_OK, strJSON);

src/rpc/blockchain.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ static const CBlockIndex* ParseHashOrHeight(const UniValue& param, ChainstateMan
146146
}
147147
}
148148

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

178-
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity)
179+
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity, const uint256 pow_limit)
179180
{
180-
UniValue result = blockheaderToJSON(tip, blockindex);
181+
UniValue result = blockheaderToJSON(tip, blockindex, pow_limit);
181182

182183
result.pushKV("strippedsize", (int)::GetSerializeSize(TX_NO_WITNESS(block)));
183184
result.pushKV("size", (int)::GetSerializeSize(TX_WITH_WITNESS(block)));
@@ -554,6 +555,7 @@ static RPCHelpMan getblockheader()
554555
{RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
555556
{RPCResult::Type::NUM, "nonce", "The nonce"},
556557
{RPCResult::Type::STR_HEX, "bits", "nBits: compact representation of the block difficulty target"},
558+
{RPCResult::Type::STR_HEX, "target", "The difficulty target"},
557559
{RPCResult::Type::NUM, "difficulty", "The difficulty"},
558560
{RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"},
559561
{RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
@@ -577,8 +579,8 @@ static RPCHelpMan getblockheader()
577579

578580
const CBlockIndex* pblockindex;
579581
const CBlockIndex* tip;
582+
ChainstateManager& chainman = EnsureAnyChainman(request.context);
580583
{
581-
ChainstateManager& chainman = EnsureAnyChainman(request.context);
582584
LOCK(cs_main);
583585
pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
584586
tip = chainman.ActiveChain().Tip();
@@ -596,7 +598,7 @@ static RPCHelpMan getblockheader()
596598
return strHex;
597599
}
598600

599-
return blockheaderToJSON(*tip, *pblockindex);
601+
return blockheaderToJSON(*tip, *pblockindex, chainman.GetConsensus().powLimit);
600602
},
601603
};
602604
}
@@ -728,6 +730,7 @@ static RPCHelpMan getblock()
728730
{RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
729731
{RPCResult::Type::NUM, "nonce", "The nonce"},
730732
{RPCResult::Type::STR_HEX, "bits", "nBits: compact representation of the block difficulty target"},
733+
{RPCResult::Type::STR_HEX, "target", "The difficulty target"},
731734
{RPCResult::Type::NUM, "difficulty", "The difficulty"},
732735
{RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the chain up to this block (in hex)"},
733736
{RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
@@ -802,7 +805,7 @@ static RPCHelpMan getblock()
802805
tx_verbosity = TxVerbosity::SHOW_DETAILS_AND_PREVOUT;
803806
}
804807

805-
return blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity);
808+
return blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity, chainman.GetConsensus().powLimit);
806809
},
807810
};
808811
}

src/rpc/blockchain.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
3636
double GetDifficulty(const CBlockIndex& blockindex);
3737

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

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

4444
/** Used by getblockstats to get feerates at different percentiles by weight */
4545
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);

test/functional/interface_rest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def run_test(self):
289289

290290
# Compare with normal RPC block response
291291
rpc_block_json = self.nodes[0].getblock(bb_hash)
292-
for key in ['hash', 'confirmations', 'height', 'version', 'merkleroot', 'time', 'nonce', 'bits', 'difficulty', 'chainwork', 'previousblockhash']:
292+
for key in ['hash', 'confirmations', 'height', 'version', 'merkleroot', 'time', 'nonce', 'bits', 'target', 'difficulty', 'chainwork', 'previousblockhash']:
293293
assert_equal(json_obj[0][key], rpc_block_json[key])
294294

295295
# See if we can get 5 headers in one response

test/functional/rpc_blockchain.py

+3
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131
MAX_FUTURE_BLOCK_TIME,
3232
TIME_GENESIS_BLOCK,
3333
REGTEST_N_BITS,
34+
REGTEST_TARGET,
3435
create_block,
3536
create_coinbase,
3637
create_tx_with_script,
3738
nbits_str,
39+
target_str,
3840
)
3941
from test_framework.messages import (
4042
CBlockHeader,
@@ -415,6 +417,7 @@ def _test_getblockheader(self):
415417
assert_is_hash_string(header['previousblockhash'])
416418
assert_is_hash_string(header['merkleroot'])
417419
assert_equal(header['bits'], nbits_str(REGTEST_N_BITS))
420+
assert_equal(header['target'], target_str(REGTEST_TARGET))
418421
assert isinstance(header['time'], int)
419422
assert_equal(header['mediantime'], TIME_RANGE_MTP)
420423
assert isinstance(header['nonce'], int)

test/functional/test_framework/blocktools.py

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
hash256,
2828
ser_uint256,
2929
tx_from_hex,
30+
uint256_from_compact,
3031
uint256_from_str,
3132
WITNESS_SCALE_FACTOR,
3233
)
@@ -66,10 +67,15 @@
6667
MIN_BLOCKS_TO_KEEP = 288
6768

6869
REGTEST_N_BITS = 0x207fffff # difficulty retargeting is disabled in REGTEST chainparams"
70+
REGTEST_TARGET = 0x7fffff0000000000000000000000000000000000000000000000000000000000
71+
assert_equal(uint256_from_compact(REGTEST_N_BITS), REGTEST_TARGET)
6972

7073
def nbits_str(nbits):
7174
return f"{nbits:08x}"
7275

76+
def target_str(target):
77+
return f"{target:064x}"
78+
7379
def create_block(hashprev=None, coinbase=None, ntime=None, *, version=None, tmpl=None, txlist=None):
7480
"""Create a block (with regtest difficulty)."""
7581
block = CBlock()

0 commit comments

Comments
 (0)