Skip to content

Commit

Permalink
Merge pull request #97 from alvasw/distinguish_wallet_not_running_and…
Browse files Browse the repository at this point in the history
…_wrong_rpc_credentials

Distinguish between wallet not running and wrong rpc credentials
  • Loading branch information
chimp1984 authored Feb 14, 2022
2 parents 0f5304d + 67262b4 commit bab7c4e
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 13 deletions.
17 changes: 7 additions & 10 deletions wallets/src/main/java/bisq/wallets/bitcoind/BitcoindWallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@

package bisq.wallets.bitcoind;

import bisq.wallets.*;
import bisq.wallets.AddressType;
import bisq.wallets.Wallet;
import bisq.wallets.bitcoind.responses.ListTransactionsResponseEntry;
import bisq.wallets.bitcoind.responses.ListUnspentResponseEntry;
import bisq.wallets.bitcoind.rpc.*;
import bisq.wallets.exceptions.InvalidRpcCredentialsException;
import bisq.wallets.exceptions.RpcCallFailureException;
import bisq.wallets.bitcoind.rpc.RpcClient;
import bisq.wallets.bitcoind.rpc.RpcConfig;
import bisq.wallets.bitcoind.rpc.WalletRpcConfig;
import bisq.wallets.exceptions.WalletInitializationFailedException;
import bisq.wallets.model.Transaction;
import bisq.wallets.model.Utxo;
Expand Down Expand Up @@ -55,12 +56,8 @@ public BitcoindWallet(Path walletPath, RpcConfig rpcConfig) {

@Override
public void initialize(String walletPassphrase) {
try {
chainBackend.createOrLoadWallet(walletPath, walletPassphrase, false, false);
walletBackend.walletPassphrase(walletPassphrase, BitcoindWalletBackend.DEFAULT_WALLET_TIMEOUT);
} catch (RpcCallFailureException e) {
throw new InvalidRpcCredentialsException(e);
}
chainBackend.createOrLoadWallet(walletPath, walletPassphrase, false, false);
walletBackend.walletPassphrase(walletPassphrase, BitcoindWalletBackend.DEFAULT_WALLET_TIMEOUT);
}

@Override
Expand Down
15 changes: 14 additions & 1 deletion wallets/src/main/java/bisq/wallets/bitcoind/rpc/RpcClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@

import bisq.common.encoding.Base64;
import bisq.wallets.bitcoind.BitcoindRpcEndpoint;
import bisq.wallets.exceptions.CannotConnectToWalletException;
import bisq.wallets.exceptions.InvalidRpcCredentialsException;
import bisq.wallets.exceptions.RpcCallFailureException;
import com.googlecode.jsonrpc4j.JsonRpcHttpClient;

import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
Expand All @@ -44,7 +47,13 @@ public RpcClient(RpcConfig config) throws MalformedURLException {
public <T> T invoke(BitcoindRpcEndpoint rpcEndpoint, Object argument, Class<T> clazz) {
try {
return jsonRpcClient.invoke(rpcEndpoint.getMethodName(), argument, clazz);
} catch (Throwable t) {
} catch (ConnectException e) {
throw new CannotConnectToWalletException(e);
}
catch (Throwable t) {
if (rpcAuthenticationFailed(t)) {
throw new InvalidRpcCredentialsException("Invalid RPC credentials", t);
}
throw new RpcCallFailureException("RPC call to " + rpcEndpoint.getMethodName() + " failed.", t);
}
}
Expand All @@ -64,6 +73,10 @@ private JsonRpcHttpClient createRpcClientWithUrlSuffix(RpcConfig rpcConfig, Opti
return new JsonRpcHttpClient(new URL(url), createAuthHeader(rpcConfig));
}

private boolean rpcAuthenticationFailed(Throwable t) {
return t.getCause().toString().contains("401");
}

private Map<String, String> createAuthHeader(RpcConfig rpcConfig) {
String auth = rpcConfig.user() + ":" + rpcConfig.password();
String base64Auth = Base64.encode(auth.getBytes(StandardCharsets.UTF_8));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.wallets.exceptions;

public class CannotConnectToWalletException extends RuntimeException {
public CannotConnectToWalletException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
package bisq.wallets.exceptions;

public class InvalidRpcCredentialsException extends RuntimeException {
public InvalidRpcCredentialsException(Throwable cause) {
super(cause);
public InvalidRpcCredentialsException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.wallets.bitcoind;

import bisq.wallets.NetworkType;
import bisq.wallets.bitcoind.rpc.RpcClient;
import bisq.wallets.bitcoind.rpc.RpcConfig;
import bisq.wallets.exceptions.CannotConnectToWalletException;
import bisq.wallets.exceptions.InvalidRpcCredentialsException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.net.ConnectException;
import java.net.MalformedURLException;

public class BitcoindConnectionFailureTests {
@Test
void bitcoindNotRunningTest() throws MalformedURLException {
var rpcClient = new RpcClient(BitcoindRegtestSetup.RPC_CONFIG);
var minerChainBackend = new BitcoindChainBackend(rpcClient);

CannotConnectToWalletException exception = Assertions
.assertThrows(CannotConnectToWalletException.class, minerChainBackend::listWallets);

Assertions.assertTrue(exception.getCause() instanceof ConnectException);
}

@Test
void wrongRpcCredentialsTest() throws IOException {
BitcoindProcess bitcoindProcess = BitcoindRegtestSetup.createAndStartBitcoind();

RpcConfig rpcConfig = new RpcConfig.Builder()
.networkType(NetworkType.REGTEST)
.hostname("127.0.0.1")
.user("bisq")
.password("WRONG_PASSWORD")
.build();

var rpcClient = new RpcClient(rpcConfig);
var minerChainBackend = new BitcoindChainBackend(rpcClient);

Assertions.assertThrows(InvalidRpcCredentialsException.class, minerChainBackend::listWallets);

bitcoindProcess.stopAndWaitUntilStopped();
}
}

0 comments on commit bab7c4e

Please sign in to comment.