@@ -837,6 +837,86 @@ UniValue getblockheaders(const JSONRPCRequest& request)
837837 return arrHeaders;
838838}
839839
840+ UniValue getmerkleblocks (const JSONRPCRequest& request)
841+ {
842+ if (request.fHelp || request.params .size () < 1 || request.params .size () > 3 )
843+ throw std::runtime_error (
844+ " getmerkleblocks \" filter\" \" hash\" ( count )\n "
845+ " \n Returns an array of items with information about <count> merkleblocks starting from <hash> which match <filter>.\n "
846+ " \n Arguments:\n "
847+ " 1. \" filter\" (string, required) The hex encoded bloom filter\n "
848+ " 2. \" hash\" (string, required) The block hash\n "
849+ " 3. count (numeric, optional, default/max=" + strprintf (" %s" , MAX_HEADERS_RESULTS) +" )\n "
850+ " \n Result (for verbose=false):\n "
851+ " [\n "
852+ " \" data\" , (string) A string that is serialized, hex-encoded data for a merkleblock.\n "
853+ " ...\n "
854+ " ]\n "
855+ " \n Examples:\n "
856+ + HelpExampleCli (" getmerkleblocks" , " \" 2303028005802040100040000008008400048141010000f8400420800080025004000004130000000000000001\" \" 00000000007e1432d2af52e8463278bf556b55cf5049262f25634557e2e91202\" 2000" )
857+ + HelpExampleRpc (" getmerkleblocks" , " \" 2303028005802040100040000008008400048141010000f8400420800080025004000004130000000000000001\" \" 00000000007e1432d2af52e8463278bf556b55cf5049262f25634557e2e91202\" 2000" )
858+ );
859+
860+ LOCK (cs_main);
861+
862+ CBloomFilter filter;
863+ std::string strFilter = request.params [0 ].get_str ();
864+ CDataStream ssBloomFilter (ParseHex (strFilter), SER_NETWORK, PROTOCOL_VERSION);
865+ ssBloomFilter >> filter;
866+ if (!filter.IsWithinSizeConstraints ()) {
867+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Filter is not within size constraints" );
868+ }
869+ filter.UpdateEmptyFull ();
870+
871+ std::string strHash = request.params [1 ].get_str ();
872+ uint256 hash (uint256S (strHash));
873+
874+ if (mapBlockIndex.count (hash) == 0 ) {
875+ throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Block not found" );
876+ }
877+
878+ int nCount = MAX_HEADERS_RESULTS;
879+ if (request.params .size () > 2 )
880+ nCount = request.params [2 ].get_int ();
881+
882+ if (nCount <= 0 || nCount > (int )MAX_HEADERS_RESULTS) {
883+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Count is out of range" );
884+ }
885+
886+ CBlock block;
887+ CBlockIndex* pblockindex = mapBlockIndex[hash];
888+
889+ if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0 ) {
890+ throw JSONRPCError (RPC_MISC_ERROR, " Block not available (pruned data)" );
891+ }
892+
893+ if (!ReadBlockFromDisk (block, pblockindex, Params ().GetConsensus ())) {
894+ // Block not found on disk. This could be because we have the block
895+ // header in our index but don't have the block (for example if a
896+ // non-whitelisted node sends us an unrequested long chain of valid
897+ // blocks, we add the headers to our index, but don't accept the
898+ // block).
899+ throw JSONRPCError (RPC_MISC_ERROR, " Block not found on disk" );
900+ }
901+
902+ UniValue arrMerkleBlocks (UniValue::VARR);
903+
904+ for (; pblockindex; pblockindex = chainActive.Next (pblockindex))
905+ {
906+ if (!ReadBlockFromDisk (block, pblockindex, Params ().GetConsensus ())) {
907+ // this shouldn't happen, we already checked pruning case earlier
908+ throw JSONRPCError (RPC_MISC_ERROR, " Block not found on disk" );
909+ }
910+ CDataStream ssMerkleBlock (SER_NETWORK, PROTOCOL_VERSION);
911+ ssMerkleBlock << CMerkleBlock (block, filter);
912+ std::string strHex = HexStr (ssMerkleBlock);
913+ arrMerkleBlocks.push_back (strHex);
914+ if (--nCount <= 0 )
915+ break ;
916+ }
917+ return arrMerkleBlocks;
918+ }
919+
840920UniValue getblock (const JSONRPCRequest& request)
841921{
842922 if (request.fHelp || request.params .size () < 1 || request.params .size () > 2 )
@@ -1760,6 +1840,7 @@ static const CRPCCommand commands[] =
17601840 { " blockchain" , " getblockhash" , &getblockhash, true , {" height" } },
17611841 { " blockchain" , " getblockheader" , &getblockheader, true , {" blockhash" ," verbose" } },
17621842 { " blockchain" , " getblockheaders" , &getblockheaders, true , {" blockhash" ," count" ," verbose" } },
1843+ { " blockchain" , " getmerkleblocks" , &getmerkleblocks, true , {" filter" ," blockhash" ," count" } },
17631844 { " blockchain" , " getchaintips" , &getchaintips, true , {" count" ," branchlen" } },
17641845 { " blockchain" , " getdifficulty" , &getdifficulty, true , {} },
17651846 { " blockchain" , " getmempoolancestors" , &getmempoolancestors, true , {" txid" ," verbose" } },
0 commit comments