Skip to content

Commit

Permalink
rpc: option to include chain info in address index results
Browse files Browse the repository at this point in the history
  • Loading branch information
Braydon Fuller committed Aug 23, 2016
1 parent 33e35c8 commit 491d6eb
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 9 deletions.
23 changes: 22 additions & 1 deletion qa/rpc-tests/addressindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def run_test(self):
assert_equal(balance2["balance"], change_amount)

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

# Include chaininfo in results
print "Testing results with chain info..."

deltas_with_info = self.nodes[1].getaddressdeltas({
"addresses": [address2],
"start": 1,
"end": 200,
"chainInfo": True
})
start_block_hash = self.nodes[1].getblockhash(1);
end_block_hash = self.nodes[1].getblockhash(200);
assert_equal(deltas_with_info["start"]["height"], 1)
assert_equal(deltas_with_info["start"]["hash"], start_block_hash)
assert_equal(deltas_with_info["end"]["height"], 200)
assert_equal(deltas_with_info["end"]["hash"], end_block_hash)

utxos_with_info = self.nodes[1].getaddressutxos({"addresses": [address2], "chainInfo": True})
expected_tip_block_hash = self.nodes[1].getblockhash(267);
assert_equal(utxos_with_info["height"], 267)
assert_equal(utxos_with_info["hash"], expected_tip_block_hash)

print "Passed\n"


Expand Down
73 changes: 65 additions & 8 deletions src/rpcmisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,8 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
" [\n"
" \"address\" (string) The base58check encoded address\n"
" ,...\n"
" ]\n"
" ],\n"
" \"chainInfo\" (boolean) Include chain info with results\n"
"}\n"
"\nResult\n"
"[\n"
Expand All @@ -555,7 +556,15 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
"\nExamples:\n"
+ HelpExampleCli("getaddressutxos", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'")
+ HelpExampleRpc("getaddressutxos", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}")
);
);

bool includeChainInfo = false;
if (params[0].isObject()) {
UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo");
if (chainInfo.isBool()) {
includeChainInfo = chainInfo.get_bool();
}
}

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

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

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

UniValue result(UniValue::VARR);
UniValue utxos(UniValue::VARR);

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

return result;
if (includeChainInfo) {
UniValue result(UniValue::VOBJ);
result.push_back(Pair("utxos", utxos));

LOCK(cs_main);
result.push_back(Pair("hash", chainActive.Tip()->GetBlockHash().GetHex()));
result.push_back(Pair("height", (int)chainActive.Height()));
return result;
} else {
return utxos;
}
}

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

UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo");
bool includeChainInfo = false;
if (chainInfo.isBool()) {
includeChainInfo = chainInfo.get_bool();
}

int start = 0;
int end = 0;

if (startValue.isNum() && endValue.isNum()) {
start = startValue.get_int();
end = endValue.get_int();
if (start <= 0 || end <= 0) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start and end is expected to be greater than zero");
}
if (end < start) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "End value is expected to be greater than start");
}
Expand All @@ -660,7 +689,7 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
}
}

UniValue result(UniValue::VARR);
UniValue deltas(UniValue::VARR);

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

return result;
UniValue result(UniValue::VOBJ);

if (includeChainInfo && start > 0 && end > 0) {
LOCK(cs_main);

if (start > chainActive.Height() || end > chainActive.Height()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start or end is outside chain range");
}

CBlockIndex* startIndex = chainActive[start];
CBlockIndex* endIndex = chainActive[end];

UniValue startInfo(UniValue::VOBJ);
UniValue endInfo(UniValue::VOBJ);

startInfo.push_back(Pair("hash", startIndex->GetBlockHash().GetHex()));
startInfo.push_back(Pair("height", start));

endInfo.push_back(Pair("hash", endIndex->GetBlockHash().GetHex()));
endInfo.push_back(Pair("height", end));

result.push_back(Pair("deltas", deltas));
result.push_back(Pair("start", startInfo));
result.push_back(Pair("end", endInfo));

return result;
} else {
return deltas;
}
}

UniValue getaddressbalance(const UniValue& params, bool fHelp)
Expand Down

0 comments on commit 491d6eb

Please sign in to comment.