Skip to content

Commit

Permalink
Allow first parameter to be either blocknum or hash
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescowens committed Jun 29, 2021
1 parent 36796c3 commit 0eddd1e
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 18 deletions.
83 changes: 66 additions & 17 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,45 +525,92 @@ UniValue getblocksbatch(const UniValue& params, bool fHelp)
if (fHelp || params.size() < 2 || params.size() > 3)
{
throw runtime_error(
"getblocksbatch <starting number> <number of blocks> [bool:txinfo]\n"
"getblocksbatch <starting block number or hash> <number of blocks> [bool:txinfo]\n"
"\n"
"<starting number> the block number at the start of the batch"
"<starting block number or hash> the block number or hash for the block at the\n"
"start of the batch"
"\n"
"<number of blocks> the number of blocks to return in the batch, limited to 500"
"<number of blocks> the number of blocks to return in the batch, limited to 1000"
"\n"
"[bool:txinfo] optional to print more detailed tx info\n"
"\n"
"Returns a JSON array with details of the requested blocks starting with\n"
"the given block-number.\n");
"the given block-number or hash.\n");
}

UniValue result(UniValue::VOBJ);
UniValue blocks(UniValue::VARR);

int nHeight = params[0].get_int();
if (nHeight < 0 || nHeight > nBestHeight) throw runtime_error("Starting block number out of range");
int nHeight = 0;
uint256 hash;
bool block_hash_provided = false;

// Validate parameters.
try
{
// Have to do it this way, because the rpc param 0 must be left out of the special parameter handling in client.cpp.
nHeight = boost::lexical_cast<int>(params[0].get_str());
}
catch (const boost::bad_lexical_cast& e)
{
std::string strHash = params[0].get_str();
hash = uint256S(strHash);
block_hash_provided = true;
}
catch (...)
{
throw JSONRPCError(RPC_INVALID_PARAMETER, "Either a valid block number or block hash must be provided.");
}

if (!block_hash_provided)
{
if (nHeight < 0 || nHeight > nBestHeight)
{
throw JSONRPCError(RPC_INVALID_PARAMETER, "Starting block number out of range");
}
}
else
{
if (mapBlockIndex.count(hash) == 0)
{
throw JSONRPCError(RPC_INVALID_PARAMETER, "Starting block for batch not found.");
}
}

int batch_size = params[1].get_int();
if (batch_size < 1 || batch_size > 500)
if (batch_size < 1 || batch_size > 1000)
{
throw JSONRPCError(RPC_INVALID_PARAMETER, "Batch size must be between 1 and 500, inclusive.");
throw JSONRPCError(RPC_INVALID_PARAMETER, "Batch size must be between 1 and 1000, inclusive.");
}

bool transaction_details = false;
if (params.size() > 2) transaction_details = params[2].get_bool();

LOCK(cs_main);

g_timer.GetTimes("Finished parsing parameters", __func__);
g_timer.GetTimes("Finished validating parameters", __func__);

// Select the block index for the head of the chain.
CBlockIndex* pblockindex_head = mapBlockIndex[hashBestChain];
CBlockIndex* pblockindex = pblockindex_head;
CBlockIndex* pblockindex_head = nullptr;
CBlockIndex* pblockindex = nullptr;

// Rewind to the block corresponding to the specified height.
while (pblockindex->nHeight > nHeight)
// Find the starting block's index entry point by either rewinding from the head (if the block number was
// provided), or directly from the mapBlockIndex, if the hash was provided.
if (!block_hash_provided)
{
pblockindex = pblockindex->pprev;
// Select the block index for the head of the chain.
pblockindex_head = mapBlockIndex[hashBestChain];
pblockindex = pblockindex_head;

// Rewind to the block corresponding to the specified height.
while (pblockindex->nHeight > nHeight)
{
pblockindex = pblockindex->pprev;
}

}
else
{
pblockindex = mapBlockIndex[hash];
}

g_timer.GetTimes("Finished finding starting block", __func__);
Expand All @@ -572,7 +619,10 @@ UniValue getblocksbatch(const UniValue& params, bool fHelp)
while (i < batch_size)
{
CBlock block;
if (!block.ReadFromDisk(pblockindex, transaction_details)) throw runtime_error("Error reading block from specified batch.");
if (!block.ReadFromDisk(pblockindex, true))
{
throw runtime_error("Error reading block from specified batch.");
}

blocks.push_back(blockToJSON(block, pblockindex, transaction_details));
++i;
Expand All @@ -582,7 +632,6 @@ UniValue getblocksbatch(const UniValue& params, bool fHelp)
pblockindex = pblockindex->pnext;
}

result.pushKV("starting_block_number", nHeight);
result.pushKV("block_count", i);
result.pushKV("blocks", blocks);

Expand Down
1 change: 0 additions & 1 deletion src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getblock" , 1 },
{ "getblockbynumber" , 0 },
{ "getblockbynumber" , 1 },
{ "getblocksbatch" , 0 },
{ "getblocksbatch" , 1 },
{ "getblocksbatch" , 2 },
{ "getblockhash" , 0 },
Expand Down

0 comments on commit 0eddd1e

Please sign in to comment.