@@ -518,6 +518,130 @@ UniValue getblockbynumber(const UniValue& params, bool fHelp)
518
518
return blockToJSON (block, pblockindex, params.size () > 1 ? params[1 ].get_bool () : false );
519
519
}
520
520
521
+ UniValue getblocksbatch (const UniValue& params, bool fHelp )
522
+ {
523
+ g_timer.InitTimer (__func__, LogInstance ().WillLogCategory (BCLog::LogFlags::RPC));
524
+
525
+ if (fHelp || params.size () < 2 || params.size () > 3 )
526
+ {
527
+ throw runtime_error (
528
+ " getblocksbatch <starting block number or hash> <number of blocks> [bool:txinfo]\n "
529
+ " \n "
530
+ " <starting block number or hash> the block number or hash for the block at the\n "
531
+ " start of the batch\n "
532
+ " \n "
533
+ " <number of blocks> the number of blocks to return in the batch, limited to 1000"
534
+ " \n "
535
+ " [bool:txinfo] optional to print more detailed tx info\n "
536
+ " \n "
537
+ " Returns a JSON array with details of the requested blocks starting with\n "
538
+ " the given block-number or hash.\n " );
539
+ }
540
+
541
+ UniValue result (UniValue::VOBJ);
542
+ UniValue blocks (UniValue::VARR);
543
+
544
+ int nHeight = 0 ;
545
+ uint256 hash;
546
+ bool block_hash_provided = false ;
547
+
548
+ // Validate parameters.
549
+ try
550
+ {
551
+ // Have to do it this way, because the rpc param 0 must be left out of the special parameter handling in client.cpp.
552
+ nHeight = boost::lexical_cast<int >(params[0 ].get_str ());
553
+ }
554
+ catch (const boost::bad_lexical_cast& e)
555
+ {
556
+ std::string strHash = params[0 ].get_str ();
557
+ hash = uint256S (strHash);
558
+ block_hash_provided = true ;
559
+ }
560
+ catch (...)
561
+ {
562
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Either a valid block number or block hash must be provided." );
563
+ }
564
+
565
+ if (!block_hash_provided)
566
+ {
567
+ if (nHeight < 0 || nHeight > nBestHeight)
568
+ {
569
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Starting block number out of range" );
570
+ }
571
+ }
572
+ else
573
+ {
574
+ if (mapBlockIndex.count (hash) == 0 )
575
+ {
576
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Starting block for batch not found." );
577
+ }
578
+ }
579
+
580
+ int batch_size = params[1 ].get_int ();
581
+ if (batch_size < 1 || batch_size > 1000 )
582
+ {
583
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Batch size must be between 1 and 1000, inclusive." );
584
+ }
585
+
586
+ bool transaction_details = false ;
587
+ if (params.size () > 2 ) transaction_details = params[2 ].get_bool ();
588
+
589
+ LOCK (cs_main);
590
+
591
+ g_timer.GetTimes (" Finished validating parameters" , __func__);
592
+
593
+ CBlockIndex* pblockindex_head = nullptr ;
594
+ CBlockIndex* pblockindex = nullptr ;
595
+
596
+ // Find the starting block's index entry point by either rewinding from the head (if the block number was
597
+ // provided), or directly from the mapBlockIndex, if the hash was provided.
598
+
599
+ // Select the block index for the head of the chain.
600
+ pblockindex_head = mapBlockIndex[hashBestChain];
601
+
602
+ if (!block_hash_provided)
603
+ {
604
+ pblockindex = pblockindex_head;
605
+
606
+ // Rewind to the block corresponding to the specified height.
607
+ while (pblockindex->nHeight > nHeight)
608
+ {
609
+ pblockindex = pblockindex->pprev ;
610
+ }
611
+
612
+ }
613
+ else
614
+ {
615
+ pblockindex = mapBlockIndex[hash];
616
+ }
617
+
618
+ g_timer.GetTimes (" Finished finding starting block" , __func__);
619
+
620
+ int i = 0 ;
621
+ while (i < batch_size)
622
+ {
623
+ CBlock block;
624
+ if (!block.ReadFromDisk (pblockindex, true ))
625
+ {
626
+ throw runtime_error (" Error reading block from specified batch." );
627
+ }
628
+
629
+ blocks.push_back (blockToJSON (block, pblockindex, transaction_details));
630
+ ++i;
631
+
632
+ if (pblockindex == pblockindex_head) break ;
633
+
634
+ pblockindex = pblockindex->pnext ;
635
+ }
636
+
637
+ result.pushKV (" block_count" , i);
638
+ result.pushKV (" blocks" , blocks);
639
+
640
+ g_timer.GetTimes (" Finished populating result for block batch" , __func__);
641
+
642
+ return result;
643
+ }
644
+
521
645
UniValue backupprivatekeys (const UniValue& params, bool fHelp )
522
646
{
523
647
if (fHelp || params.size () != 0 )
0 commit comments