| 167 | } |
| 168 | |
| 169 | CBlockIndex* ParseHashOrHeight(const UniValue& param, ChainstateManager& chainman) { |
| 170 | LOCK(::cs_main); |
| 171 | CChain& active_chain = chainman.ActiveChain(); |
| 172 | |
| 173 | if (param.isNum()) { |
| 174 | const int height{param.get_int()}; |
| 175 | if (height < 0) { |
| 176 | throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d is negative", height)); |
| 177 | } |
| 178 | const int current_tip{active_chain.Height()}; |
| 179 | if (height > current_tip) { |
| 180 | throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d after current tip %d", height, current_tip)); |
| 181 | } |
| 182 | |
| 183 | return active_chain[height]; |
| 184 | } else { |
| 185 | const uint256 hash{ParseHashV(param, "hash_or_height")}; |
| 186 | CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash); |
| 187 | |
| 188 | if (!pindex) { |
| 189 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); |
| 190 | } |
| 191 | |
| 192 | return pindex; |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex_) |
| 197 | { |
no test coverage detected