diff --git a/cj-btc-jsonrpc-integ-test/src/integ/groovy/org/consensusj/bitcoin/rpc/bitcore/GetAddressBalanceSpec.groovy b/cj-btc-jsonrpc-integ-test/src/integ/groovy/org/consensusj/bitcoin/rpc/bitcore/GetAddressBalanceSpec.groovy index edd91eec3..489791419 100644 --- a/cj-btc-jsonrpc-integ-test/src/integ/groovy/org/consensusj/bitcoin/rpc/bitcore/GetAddressBalanceSpec.groovy +++ b/cj-btc-jsonrpc-integ-test/src/integ/groovy/org/consensusj/bitcoin/rpc/bitcore/GetAddressBalanceSpec.groovy @@ -3,21 +3,16 @@ package org.consensusj.bitcoin.rpc.bitcore import org.bitcoinj.core.Coin import org.consensusj.bitcoin.json.pojo.bitcore.AddressBalanceInfo import org.consensusj.bitcoin.test.BaseRegTestSpec -import org.consensusj.jsonrpc.JsonRpcException -import org.spockframework.runtime.extension.builtin.PreconditionContext -import spock.lang.IgnoreIf import spock.lang.Requires import spock.lang.Shared /** * Test of OmniCore Bitcore address index JSON-RPC method: {@code getaddressbalance} - * If {@code help} reports this method is not available, these tests are ignored. + * If {@code help} reports address index is not available, these tests are ignored. */ class GetAddressBalanceSpec extends BaseRegTestSpec { - @Shared - boolean hasMethod - @Requires({ instance.hasMethod}) + @Requires({ instance.isAddressIndexEnabled()}) def "get 1 address balance"() { given: def address = client.getNewAddress() @@ -34,7 +29,7 @@ class GetAddressBalanceSpec extends BaseRegTestSpec { } - @Requires({ instance.hasMethod}) + @Requires({ instance.isAddressIndexEnabled()}) def "get multi-address balance"() { given: def address1 = client.getNewAddress() @@ -52,8 +47,7 @@ class GetAddressBalanceSpec extends BaseRegTestSpec { balanceInfo.immature >= Coin.ZERO } - def setupSpec() { - hasMethod = client.commandExists("getaddressbalance") + boolean isAddressIndexEnabled() { + return client.isAddressIndexEnabled() } - } diff --git a/cj-btc-jsonrpc/src/main/java/org/consensusj/bitcoin/rpc/BitcoinClient.java b/cj-btc-jsonrpc/src/main/java/org/consensusj/bitcoin/rpc/BitcoinClient.java index 0dd69ece7..070b3c6c5 100644 --- a/cj-btc-jsonrpc/src/main/java/org/consensusj/bitcoin/rpc/BitcoinClient.java +++ b/cj-btc-jsonrpc/src/main/java/org/consensusj/bitcoin/rpc/BitcoinClient.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; +import org.bitcoinj.core.LegacyAddress; import org.consensusj.bitcoin.json.conversion.HexUtil; import org.consensusj.bitcoin.json.pojo.AddressGroupingItem; import org.consensusj.bitcoin.json.pojo.AddressInfo; @@ -23,6 +24,8 @@ import org.consensusj.bitcoin.json.pojo.bitcore.AddressBalanceInfo; import org.consensusj.bitcoin.json.pojo.bitcore.AddressRequest; import org.consensusj.bitcoin.rpc.internal.BitcoinClientThreadFactory; +import org.consensusj.jsonrpc.JsonRpcError; +import org.consensusj.jsonrpc.JsonRpcErrorException; import org.consensusj.jsonrpc.JsonRpcException; import org.consensusj.jsonrpc.JsonRpcMessage; import org.consensusj.jsonrpc.JsonRpcStatusException; @@ -91,6 +94,8 @@ public class BitcoinClient extends JsonRpcClientHttpUrlConnection implements Cha protected final ExecutorService executorService; private int serverVersion = 0; // 0 means unknown serverVersion + private boolean isAddressIndexSuccessfullyTested = false; + private boolean isAddressIndexEnabled; public BitcoinClient(SSLSocketFactory sslSocketFactory, NetworkParameters netParams, URI server, String rpcuser, String rpcpassword) { super(sslSocketFactory, JsonRpcMessage.Version.V2, server, rpcuser, rpcpassword); @@ -165,6 +170,55 @@ private synchronized int getServerVersion() throws IOException, JsonRpcStatusExc return serverVersion; } + /** + * Test if address index is enabled, caching the result of the first successful check + * + * @return true if enabled, false if not enabled + * @throws JsonRpcException an exception other than 1 of the two expected exceptions is thrown + * @throws IOException something else went wrong + */ + public synchronized boolean isAddressIndexEnabled() throws JsonRpcException, IOException { + if (!isAddressIndexSuccessfullyTested) { + try { + AddressBalanceInfo info = getAddressBalance(getTestAddress()); + isAddressIndexSuccessfullyTested = true; + isAddressIndexEnabled = true; + } catch (JsonRpcErrorException ee) { + // If method not found, the method we use for the test isn't even present, so definitely + // no address index support is available + if (ee.getError().getCode() == JsonRpcError.Error.METHOD_NOT_FOUND.getCode()) { + isAddressIndexSuccessfullyTested = true; + isAddressIndexEnabled = false; + } else { + // Some other, unexpected exception, throw it + throw ee; + } + } catch (JsonRpcStatusException se) { + // If the method is there and it returns an error of "Address index not enabled" then we also + // know that no address index support is available + if (se.getMessage().equals("Address index not enabled")) { + isAddressIndexSuccessfullyTested = true; + isAddressIndexEnabled = false; + } else { + // Some other, unexpected exception, throw it + throw se; + } + } + } + return isAddressIndexEnabled; + } + + private Address getTestAddress() { + switch (getNetParams().getId()) { + case NetworkParameters.ID_MAINNET: + return LegacyAddress.fromBase58(null, "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"); + case NetworkParameters.ID_TESTNET: + case NetworkParameters.ID_REGTEST: + default: + return LegacyAddress.fromBase58(null, "moneyqMan7uh8FqdCA2BV5yZ8qVrc9ikLP"); + } + } + /** * Wait until the server is available. * @@ -979,12 +1033,12 @@ public JsonNode getAddedNodeInfo(boolean details) throws JsonRpcStatusException, } // Bitcore/Omni transaction for getting non-wallet address balances - public AddressBalanceInfo getAddressBalance(Address address) throws JsonRpcStatusException, IOException { + public AddressBalanceInfo getAddressBalance(Address address) throws JsonRpcException, IOException { return send("getaddressbalance", AddressBalanceInfo.class, address); } // Bitcore/Omni transaction for getting non-wallet address balances - public AddressBalanceInfo getAddressBalance(List<Address> addressList) throws JsonRpcStatusException, IOException { + public AddressBalanceInfo getAddressBalance(List<Address> addressList) throws JsonRpcException, IOException { return send("getaddressbalance", AddressBalanceInfo.class, new AddressRequest(addressList)); } } \ No newline at end of file