Skip to content

Commit 14c71a7

Browse files
authored
Merge pull request #31 from braydonf/hashes
rpc: option to include chain info in address index results
2 parents 33e35c8 + 491d6eb commit 14c71a7

File tree

2 files changed

+87
-9
lines changed

2 files changed

+87
-9
lines changed

qa/rpc-tests/addressindex.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def run_test(self):
171171
assert_equal(balance2["balance"], change_amount)
172172

173173
# Check that deltas are returned correctly
174-
deltas = self.nodes[1].getaddressdeltas({"addresses": [address2], "start": 0, "end": 200})
174+
deltas = self.nodes[1].getaddressdeltas({"addresses": [address2], "start": 1, "end": 200})
175175
balance3 = 0
176176
for delta in deltas:
177177
balance3 += delta["satoshis"]
@@ -321,6 +321,27 @@ def run_test(self):
321321
mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]})
322322
assert_equal(len(mempool_deltas), 2)
323323

324+
# Include chaininfo in results
325+
print "Testing results with chain info..."
326+
327+
deltas_with_info = self.nodes[1].getaddressdeltas({
328+
"addresses": [address2],
329+
"start": 1,
330+
"end": 200,
331+
"chainInfo": True
332+
})
333+
start_block_hash = self.nodes[1].getblockhash(1);
334+
end_block_hash = self.nodes[1].getblockhash(200);
335+
assert_equal(deltas_with_info["start"]["height"], 1)
336+
assert_equal(deltas_with_info["start"]["hash"], start_block_hash)
337+
assert_equal(deltas_with_info["end"]["height"], 200)
338+
assert_equal(deltas_with_info["end"]["hash"], end_block_hash)
339+
340+
utxos_with_info = self.nodes[1].getaddressutxos({"addresses": [address2], "chainInfo": True})
341+
expected_tip_block_hash = self.nodes[1].getblockhash(267);
342+
assert_equal(utxos_with_info["height"], 267)
343+
assert_equal(utxos_with_info["hash"], expected_tip_block_hash)
344+
324345
print "Passed\n"
325346

326347

src/rpcmisc.cpp

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,8 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
539539
" [\n"
540540
" \"address\" (string) The base58check encoded address\n"
541541
" ,...\n"
542-
" ]\n"
542+
" ],\n"
543+
" \"chainInfo\" (boolean) Include chain info with results\n"
543544
"}\n"
544545
"\nResult\n"
545546
"[\n"
@@ -555,7 +556,15 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
555556
"\nExamples:\n"
556557
+ HelpExampleCli("getaddressutxos", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'")
557558
+ HelpExampleRpc("getaddressutxos", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}")
558-
);
559+
);
560+
561+
bool includeChainInfo = false;
562+
if (params[0].isObject()) {
563+
UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo");
564+
if (chainInfo.isBool()) {
565+
includeChainInfo = chainInfo.get_bool();
566+
}
567+
}
559568

560569
std::vector<std::pair<uint160, int> > addresses;
561570

@@ -573,7 +582,7 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
573582

574583
std::sort(unspentOutputs.begin(), unspentOutputs.end(), heightSort);
575584

576-
UniValue result(UniValue::VARR);
585+
UniValue utxos(UniValue::VARR);
577586

578587
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) {
579588
UniValue output(UniValue::VOBJ);
@@ -588,10 +597,20 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
588597
output.push_back(Pair("script", HexStr(it->second.script.begin(), it->second.script.end())));
589598
output.push_back(Pair("satoshis", it->second.satoshis));
590599
output.push_back(Pair("height", it->second.blockHeight));
591-
result.push_back(output);
600+
utxos.push_back(output);
592601
}
593602

594-
return result;
603+
if (includeChainInfo) {
604+
UniValue result(UniValue::VOBJ);
605+
result.push_back(Pair("utxos", utxos));
606+
607+
LOCK(cs_main);
608+
result.push_back(Pair("hash", chainActive.Tip()->GetBlockHash().GetHex()));
609+
result.push_back(Pair("height", (int)chainActive.Height()));
610+
return result;
611+
} else {
612+
return utxos;
613+
}
595614
}
596615

597616
UniValue getaddressdeltas(const UniValue& params, bool fHelp)
@@ -609,6 +628,7 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
609628
" ]\n"
610629
" \"start\" (number) The start block height\n"
611630
" \"end\" (number) The end block height\n"
631+
" \"chainInfo\" (boolean) Include chain info in results, only applies if start and end specified\n"
612632
"}\n"
613633
"\nResult:\n"
614634
"[\n"
@@ -629,12 +649,21 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
629649
UniValue startValue = find_value(params[0].get_obj(), "start");
630650
UniValue endValue = find_value(params[0].get_obj(), "end");
631651

652+
UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo");
653+
bool includeChainInfo = false;
654+
if (chainInfo.isBool()) {
655+
includeChainInfo = chainInfo.get_bool();
656+
}
657+
632658
int start = 0;
633659
int end = 0;
634660

635661
if (startValue.isNum() && endValue.isNum()) {
636662
start = startValue.get_int();
637663
end = endValue.get_int();
664+
if (start <= 0 || end <= 0) {
665+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start and end is expected to be greater than zero");
666+
}
638667
if (end < start) {
639668
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "End value is expected to be greater than start");
640669
}
@@ -660,7 +689,7 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
660689
}
661690
}
662691

663-
UniValue result(UniValue::VARR);
692+
UniValue deltas(UniValue::VARR);
664693

665694
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
666695
std::string address;
@@ -675,10 +704,38 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
675704
delta.push_back(Pair("blockindex", (int)it->first.txindex));
676705
delta.push_back(Pair("height", it->first.blockHeight));
677706
delta.push_back(Pair("address", address));
678-
result.push_back(delta);
707+
deltas.push_back(delta);
679708
}
680709

681-
return result;
710+
UniValue result(UniValue::VOBJ);
711+
712+
if (includeChainInfo && start > 0 && end > 0) {
713+
LOCK(cs_main);
714+
715+
if (start > chainActive.Height() || end > chainActive.Height()) {
716+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start or end is outside chain range");
717+
}
718+
719+
CBlockIndex* startIndex = chainActive[start];
720+
CBlockIndex* endIndex = chainActive[end];
721+
722+
UniValue startInfo(UniValue::VOBJ);
723+
UniValue endInfo(UniValue::VOBJ);
724+
725+
startInfo.push_back(Pair("hash", startIndex->GetBlockHash().GetHex()));
726+
startInfo.push_back(Pair("height", start));
727+
728+
endInfo.push_back(Pair("hash", endIndex->GetBlockHash().GetHex()));
729+
endInfo.push_back(Pair("height", end));
730+
731+
result.push_back(Pair("deltas", deltas));
732+
result.push_back(Pair("start", startInfo));
733+
result.push_back(Pair("end", endInfo));
734+
735+
return result;
736+
} else {
737+
return deltas;
738+
}
682739
}
683740

684741
UniValue getaddressbalance(const UniValue& params, bool fHelp)

0 commit comments

Comments
 (0)