rpc: gettarget

This commit is contained in:
Sjors Provoost 2025-01-08 13:03:08 +01:00
parent ddd2ede17a
commit ef9e86039a
No known key found for this signature in database
GPG key ID: 57FF9BDBCC301009
6 changed files with 55 additions and 0 deletions

View file

@ -447,6 +447,26 @@ static RPCHelpMan getdifficulty()
};
}
static RPCHelpMan gettarget()
{
return RPCHelpMan{"gettarget",
"\nReturns the proof-of-work target.\n",
{},
RPCResult{
RPCResult::Type::STR_HEX, "", "the proof-of-work target."},
RPCExamples{
HelpExampleCli("gettarget", "")
+ HelpExampleRpc("gettarget", "")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
ChainstateManager& chainman = EnsureAnyChainman(request.context);
CBlockIndex& tip{*CHECK_NONFATAL(WITH_LOCK(chainman.GetMutex(), return chainman.ActiveChain().Tip()))};
return GetTarget(tip, chainman.GetParams().GetConsensus().powLimit).GetHex();
},
};
}
static RPCHelpMan getblockfrompeer()
{
return RPCHelpMan{
@ -3382,6 +3402,7 @@ void RegisterBlockchainRPCCommands(CRPCTable& t)
{"blockchain", &getblockheader},
{"blockchain", &getchaintips},
{"blockchain", &getdifficulty},
{"blockchain", &gettarget},
{"blockchain", &getdeploymentinfo},
{"blockchain", &gettxout},
{"blockchain", &gettxoutsetinfo},

View file

@ -4,6 +4,7 @@
#include <bitcoin-build-config.h> // IWYU pragma: keep
#include <chain.h>
#include <clientversion.h>
#include <common/args.h>
#include <common/messages.h>
@ -13,6 +14,7 @@
#include <key_io.h>
#include <node/types.h>
#include <outputtype.h>
#include <pow.h>
#include <rpc/util.h>
#include <script/descriptor.h>
#include <script/interpreter.h>
@ -1418,3 +1420,9 @@ std::vector<RPCResult> ScriptPubKeyDoc() {
{RPCResult::Type::STR, "type", "The type (one of: " + GetAllOutputTypes() + ")"},
};
}
uint256 GetTarget(const CBlockIndex& blockindex, const uint256 pow_limit)
{
arith_uint256 target{*CHECK_NONFATAL(DeriveTarget(blockindex.nBits, pow_limit))};
return ArithToUint256(target);
}

View file

@ -516,4 +516,14 @@ void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj);
std::vector<RPCResult> ScriptPubKeyDoc();
/***
* Get the target for a given block index.
*
* @param[in] blockindex the block
* @param[in] pow_limit PoW limit (consensus parameter)
*
* @return the target
*/
uint256 GetTarget(const CBlockIndex& blockindex, const uint256 pow_limit);
#endif // BITCOIN_RPC_UTIL_H

View file

@ -147,6 +147,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
"getorphantxs",
"getpeerinfo",
"getprioritisedtransactions",
"gettarget",
"getrawaddrman",
"getrawmempool",
"getrawtransaction",

View file

@ -11,6 +11,7 @@ Test the following RPCs:
- gettxoutsetinfo
- getblockheader
- getdifficulty
- gettarget
- getnetworkhashps
- waitforblockheight
- getblock
@ -31,10 +32,12 @@ from test_framework.blocktools import (
MAX_FUTURE_BLOCK_TIME,
TIME_GENESIS_BLOCK,
REGTEST_N_BITS,
REGTEST_TARGET,
create_block,
create_coinbase,
create_tx_with_script,
nbits_str,
target_str,
)
from test_framework.messages import (
CBlockHeader,
@ -90,6 +93,7 @@ class BlockchainTest(BitcoinTestFramework):
self._test_gettxoutsetinfo()
self._test_getblockheader()
self._test_getdifficulty()
self._test_gettarget()
self._test_getnetworkhashps()
self._test_stopatheight()
self._test_waitforblock() # also tests waitfornewblock
@ -440,6 +444,11 @@ class BlockchainTest(BitcoinTestFramework):
# binary => decimal => binary math is why we do this check
assert abs(difficulty * 2**31 - 1) < 0.0001
def _test_gettarget(self):
self.log.info("Test gettarget")
target = self.nodes[0].gettarget()
assert_equal(target, target_str(REGTEST_TARGET))
def _test_getnetworkhashps(self):
self.log.info("Test getnetworkhashps")
assert_raises_rpc_error(

View file

@ -27,6 +27,7 @@ from .messages import (
hash256,
ser_uint256,
tx_from_hex,
uint256_from_compact,
uint256_from_str,
WITNESS_SCALE_FACTOR,
)
@ -66,10 +67,15 @@ VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4
MIN_BLOCKS_TO_KEEP = 288
REGTEST_N_BITS = 0x207fffff # difficulty retargeting is disabled in REGTEST chainparams"
REGTEST_TARGET = 0x7fffff0000000000000000000000000000000000000000000000000000000000
assert_equal(uint256_from_compact(REGTEST_N_BITS), REGTEST_TARGET)
def nbits_str(nbits):
return f"{nbits:08x}"
def target_str(target):
return f"{target:064x}"
def create_block(hashprev=None, coinbase=None, ntime=None, *, version=None, tmpl=None, txlist=None):
"""Create a block (with regtest difficulty)."""
block = CBlock()