rpc: option to include chain info in address index results
This commit is contained in:
parent
3008944c71
commit
a76b4b9655
|
@ -171,7 +171,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||||
assert_equal(balance2["balance"], change_amount)
|
assert_equal(balance2["balance"], change_amount)
|
||||||
|
|
||||||
# Check that deltas are returned correctly
|
# 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
|
balance3 = 0
|
||||||
for delta in deltas:
|
for delta in deltas:
|
||||||
balance3 += delta["satoshis"]
|
balance3 += delta["satoshis"]
|
||||||
|
@ -321,6 +321,27 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||||
mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]})
|
mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]})
|
||||||
assert_equal(len(mempool_deltas), 2)
|
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"
|
print "Passed\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -653,7 +653,8 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
|
||||||
" [\n"
|
" [\n"
|
||||||
" \"address\" (string) The base58check encoded address\n"
|
" \"address\" (string) The base58check encoded address\n"
|
||||||
" ,...\n"
|
" ,...\n"
|
||||||
" ]\n"
|
" ],\n"
|
||||||
|
" \"chainInfo\" (boolean) Include chain info with results\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"\nResult\n"
|
"\nResult\n"
|
||||||
"[\n"
|
"[\n"
|
||||||
|
@ -671,6 +672,14 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
|
||||||
+ HelpExampleRpc("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;
|
std::vector<std::pair<uint160, int> > addresses;
|
||||||
|
|
||||||
if (!getAddressesFromParams(params, addresses)) {
|
if (!getAddressesFromParams(params, addresses)) {
|
||||||
|
@ -687,7 +696,7 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp)
|
||||||
|
|
||||||
std::sort(unspentOutputs.begin(), unspentOutputs.end(), heightSort);
|
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++) {
|
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) {
|
||||||
UniValue output(UniValue::VOBJ);
|
UniValue output(UniValue::VOBJ);
|
||||||
|
@ -702,10 +711,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("script", HexStr(it->second.script.begin(), it->second.script.end())));
|
||||||
output.push_back(Pair("satoshis", it->second.satoshis));
|
output.push_back(Pair("satoshis", it->second.satoshis));
|
||||||
output.push_back(Pair("height", it->second.blockHeight));
|
output.push_back(Pair("height", it->second.blockHeight));
|
||||||
result.push_back(output);
|
utxos.push_back(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return result;
|
||||||
|
} else {
|
||||||
|
return utxos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue getaddressdeltas(const UniValue& params, bool fHelp)
|
UniValue getaddressdeltas(const UniValue& params, bool fHelp)
|
||||||
|
@ -723,6 +742,7 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
|
||||||
" ]\n"
|
" ]\n"
|
||||||
" \"start\" (number) The start block height\n"
|
" \"start\" (number) The start block height\n"
|
||||||
" \"end\" (number) The end 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"
|
"}\n"
|
||||||
"\nResult:\n"
|
"\nResult:\n"
|
||||||
"[\n"
|
"[\n"
|
||||||
|
@ -743,12 +763,21 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
|
||||||
UniValue startValue = find_value(params[0].get_obj(), "start");
|
UniValue startValue = find_value(params[0].get_obj(), "start");
|
||||||
UniValue endValue = find_value(params[0].get_obj(), "end");
|
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 start = 0;
|
||||||
int end = 0;
|
int end = 0;
|
||||||
|
|
||||||
if (startValue.isNum() && endValue.isNum()) {
|
if (startValue.isNum() && endValue.isNum()) {
|
||||||
start = startValue.get_int();
|
start = startValue.get_int();
|
||||||
end = endValue.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) {
|
if (end < start) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "End value is expected to be greater than start");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "End value is expected to be greater than start");
|
||||||
}
|
}
|
||||||
|
@ -774,7 +803,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++) {
|
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
|
||||||
std::string address;
|
std::string address;
|
||||||
|
@ -789,10 +818,38 @@ UniValue getaddressdeltas(const UniValue& params, bool fHelp)
|
||||||
delta.push_back(Pair("blockindex", (int)it->first.txindex));
|
delta.push_back(Pair("blockindex", (int)it->first.txindex));
|
||||||
delta.push_back(Pair("height", it->first.blockHeight));
|
delta.push_back(Pair("height", it->first.blockHeight));
|
||||||
delta.push_back(Pair("address", address));
|
delta.push_back(Pair("address", address));
|
||||||
result.push_back(delta);
|
deltas.push_back(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return result;
|
||||||
|
} else {
|
||||||
|
return deltas;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue getaddressbalance(const UniValue& params, bool fHelp)
|
UniValue getaddressbalance(const UniValue& params, bool fHelp)
|
||||||
|
|
Loading…
Reference in New Issue