From ec54efd7d0dc773bc9db28ff8d35b6bd03993641 Mon Sep 17 00:00:00 2001 From: Jameson Lopp Date: Sat, 30 Sep 2023 15:06:36 -0400 Subject: [PATCH] Throw error if invalid parameters passed to getnetworkhashps RPC endpoint --- src/rpc/mining.cpp | 15 ++++++++++----- test/functional/rpc_blockchain.py | 21 ++++++++++++++++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 76170c32018dda..4549008ce12692 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -53,17 +53,22 @@ using node::UpdateTime; * If 'height' is nonnegative, compute the estimate at the time when a given block was found. */ static UniValue GetNetworkHashPS(int lookup, int height, const CChain& active_chain) { + if (height > active_chain.Height()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block does not exist at specified height"); + } + + if (lookup < -1 || lookup == 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid nblocks. Must be a positive number or -1."); + } + const CBlockIndex* pb = active_chain.Tip(); - if (height >= 0 && height < active_chain.Height()) { + if (height >= 0) { pb = active_chain[height]; } - if (pb == nullptr || !pb->nHeight) - return 0; - // If lookup is -1, then use blocks since last difficulty change. - if (lookup <= 0) + if (lookup == -1) lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1; // If lookup is larger than chain, then set it to chain length. diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 18a0a0c6ccedc7..de99d17de3f273 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -436,7 +436,6 @@ def _test_getdifficulty(self): def _test_getnetworkhashps(self): self.log.info("Test getnetworkhashps") - hashes_per_second = self.nodes[0].getnetworkhashps() assert_raises_rpc_error( -3, textwrap.dedent(""" @@ -448,9 +447,29 @@ def _test_getnetworkhashps(self): """).strip(), lambda: self.nodes[0].getnetworkhashps("a", []), ) + assert_raises_rpc_error( + -8, + "Block does not exist at specified height", + lambda: self.nodes[0].getnetworkhashps(100, self.nodes[0].getblockcount() + 1), + ) + assert_raises_rpc_error( + -8, + "Invalid nblocks. Must be a positive number or -1.", + lambda: self.nodes[0].getnetworkhashps(-100), + ) + assert_raises_rpc_error( + -8, + "Invalid nblocks. Must be a positive number or -1.", + lambda: self.nodes[0].getnetworkhashps(0), + ) # This should be 2 hashes every 10 minutes or 1/300 + hashes_per_second = self.nodes[0].getnetworkhashps() assert abs(hashes_per_second * 300 - 1) < 0.0001 + # Ensure long lookups get truncated to chain length + hashes_per_second = self.nodes[0].getnetworkhashps(self.nodes[0].getblockcount() + 1000) + assert hashes_per_second > 0.003 + def _test_stopatheight(self): self.log.info("Test stopping at height") assert_equal(self.nodes[0].getblockcount(), HEIGHT)