From 8d793e9a8316dbc09bcab23013916f78e4ca50c3 Mon Sep 17 00:00:00 2001
From: cd2357
Date: Sun, 13 Sep 2020 12:19:44 +0200
Subject: [PATCH 01/17] Show info popup if Bisq started under Qubes OS
Show popup informing the user about the OS-specific setup guide.
---
.../src/main/java/bisq/common/util/Utilities.java | 13 +++++++++++++
.../main/java/bisq/core/app/BisqHeadlessApp.java | 1 +
core/src/main/java/bisq/core/app/BisqSetup.java | 15 +++++++++++++++
.../main/resources/i18n/displayStrings.properties | 3 +++
.../java/bisq/desktop/main/MainViewModel.java | 9 +++++++++
5 files changed, 41 insertions(+)
diff --git a/common/src/main/java/bisq/common/util/Utilities.java b/common/src/main/java/bisq/common/util/Utilities.java
index 291baa6843..d12c2d0a59 100644
--- a/common/src/main/java/bisq/common/util/Utilities.java
+++ b/common/src/main/java/bisq/common/util/Utilities.java
@@ -161,6 +161,19 @@ public class Utilities {
return getOSName().contains("win");
}
+ /**
+ * @return True, if Bisq is running on a virtualized OS within Qubes, false otherwise
+ */
+ public static boolean isQubesOS() {
+ // For Linux qubes, "os.version" looks like "4.19.132-1.pvops.qubes.x86_64"
+ // The presence of the "qubes" substring indicates this Linux is running as a qube
+ // This is the case for all 3 virtualization modes (PV, PVH, HVM)
+ // In addition, this works for both simple AppVMs, as well as for StandaloneVMs
+ // TODO This might not work for detecting Qubes virtualization for other OSes
+ // like Windows
+ return getOSVersion().contains("qubes");
+ }
+
public static boolean isOSX() {
return getOSName().contains("mac") || getOSName().contains("darwin");
}
diff --git a/core/src/main/java/bisq/core/app/BisqHeadlessApp.java b/core/src/main/java/bisq/core/app/BisqHeadlessApp.java
index b93d169788..03140f8dfa 100644
--- a/core/src/main/java/bisq/core/app/BisqHeadlessApp.java
+++ b/core/src/main/java/bisq/core/app/BisqHeadlessApp.java
@@ -98,6 +98,7 @@ public class BisqHeadlessApp implements HeadlessApp {
bisqSetup.setShowPopupIfInvalidBtcConfigHandler(() -> log.error("onShowPopupIfInvalidBtcConfigHandler"));
bisqSetup.setRevolutAccountsUpdateHandler(revolutAccountList -> log.info("setRevolutAccountsUpdateHandler: revolutAccountList={}", revolutAccountList));
bisqSetup.setOsxKeyLoggerWarningHandler(() -> log.info("setOsxKeyLoggerWarningHandler"));
+ bisqSetup.setQubesOSInfoHandler(() -> log.info("setQubesOSInfoHandler"));
//TODO move to bisqSetup
corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> log.warn("getCorruptedDatabaseFiles. files={}", files));
diff --git a/core/src/main/java/bisq/core/app/BisqSetup.java b/core/src/main/java/bisq/core/app/BisqSetup.java
index 164f74a04d..15c657552d 100644
--- a/core/src/main/java/bisq/core/app/BisqSetup.java
+++ b/core/src/main/java/bisq/core/app/BisqSetup.java
@@ -232,6 +232,9 @@ public class BisqSetup {
@Setter
@Nullable
private Runnable osxKeyLoggerWarningHandler;
+ @Setter
+ @Nullable
+ private Runnable qubesOSInfoHandler;
@Getter
final BooleanProperty newVersionAvailableProperty = new SimpleBooleanProperty(false);
@@ -357,6 +360,7 @@ public class BisqSetup {
checkCryptoSetup();
checkForCorrectOSArchitecture();
checkOSXVersion();
+ checkIfRunningOnQubesOS();
}
private void step3() {
@@ -678,6 +682,17 @@ public class BisqSetup {
}
}
+ /**
+ * If Bisq is running on an OS that is virtualized under Qubes, show info popup with
+ * link to the Setup Guide. The guide documents what other steps are needed, in
+ * addition to installing the Linux package (qube sizing, etc)
+ */
+ private void checkIfRunningOnQubesOS() {
+ if (Utilities.isQubesOS() && qubesOSInfoHandler != null) {
+ qubesOSInfoHandler.run();
+ }
+ }
+
private void initDomainServices() {
log.info("initDomainServices");
diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties
index 753d8bc339..405bd88f50 100644
--- a/core/src/main/resources/i18n/displayStrings.properties
+++ b/core/src/main/resources/i18n/displayStrings.properties
@@ -2759,6 +2759,9 @@ popup.info.shutDownWithOpenOffers=Bisq is being shut down, but there are open of
they will be re-published to the P2P network the next time you start Bisq.\n\n\
To keep your offers online, keep Bisq running and make sure this computer remains online too \
(i.e., make sure it doesn't go into standby mode...monitor standby is not a problem).
+popup.info.qubesOSSetupInfo=It appears you are running Bisq on Qubes OS. \n\n\
+ Please make sure your Bisq qube is setup according to our Setup Guide at \
+ https://bisq.wiki/Running_Bisq_on_Qubes
popup.privateNotification.headline=Important private notification!
diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java
index 1fd34cb7bd..95ea9fb148 100644
--- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java
@@ -397,6 +397,15 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
.show();
}
});
+ bisqSetup.setQubesOSInfoHandler(() -> {
+ String key = "qubesOSSetupInfo";
+ if (preferences.showAgain(key)) {
+ new Popup().information(Res.get("popup.info.qubesOSSetupInfo"))
+ .closeButtonText(Res.get("shared.iUnderstand"))
+ .dontShowAgainId(key)
+ .show();
+ }
+ });
corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> new Popup()
.warning(Res.get("popup.warning.incompatibleDB", files.toString(), config.appDataDir))
From f8213f2066e87535c4a54d40cb314f6f86e93ac8 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 17 Sep 2020 13:32:15 -0300
Subject: [PATCH 02/17] Give core api a simple way to verify init status
This change adds a new StatusCheck class, for use by Core*Service
instances needing to verify the server is ready to perform trading
related functions.
Currently implements one method, verifyCanTrade(), that throws an
IllegalStateException with a CLI friendly error message if any of
the following checks fail:
- the p2p network is bootstrapped
- the block chain sync is complete
- the minimum # of peers are connected
- the wallet is available
- the wallet balance is available (not null)
---
.../main/java/bisq/core/api/StatusCheck.java | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)
create mode 100644 core/src/main/java/bisq/core/api/StatusCheck.java
diff --git a/core/src/main/java/bisq/core/api/StatusCheck.java b/core/src/main/java/bisq/core/api/StatusCheck.java
new file mode 100644
index 0000000000..43d624fd6a
--- /dev/null
+++ b/core/src/main/java/bisq/core/api/StatusCheck.java
@@ -0,0 +1,60 @@
+package bisq.core.api;
+
+import bisq.core.btc.Balances;
+import bisq.core.btc.setup.WalletsSetup;
+import bisq.core.btc.wallet.WalletsManager;
+import bisq.core.dao.state.DaoStateService;
+
+import bisq.network.p2p.P2PService;
+
+import bisq.common.config.Config;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Singleton
+@Slf4j
+class StatusCheck {
+
+ private final Config config;
+ private final P2PService p2PService;
+ private final DaoStateService daoStateService;
+ private final WalletsSetup walletsSetup;
+ private final WalletsManager walletsManager;
+ private final Balances balances;
+
+ @Inject
+ public StatusCheck(Config config,
+ P2PService p2PService,
+ DaoStateService daoStateService,
+ WalletsSetup walletsSetup,
+ WalletsManager walletsManager,
+ Balances balances) {
+ this.config = config;
+ this.p2PService = p2PService;
+ this.daoStateService = daoStateService;
+ this.walletsSetup = walletsSetup;
+ this.walletsManager = walletsManager;
+ this.balances = balances;
+ }
+
+ public void verifyCanTrade() {
+ if (!p2PService.isBootstrapped())
+ throw new IllegalStateException("p2p service is not yet bootstrapped");
+
+ if (!daoStateService.isParseBlockChainComplete())
+ throw new IllegalStateException("dao block chain sync is not yet complete");
+
+ if (config.baseCurrencyNetwork.isMainnet()
+ && p2PService.getNumConnectedPeers().get() < walletsSetup.getMinBroadcastConnections())
+ throw new IllegalStateException("not enough connected peers");
+
+ if (!walletsManager.areWalletsAvailable())
+ throw new IllegalStateException("wallet is not yet available");
+
+ if (balances.getAvailableBalance().get() == null)
+ throw new IllegalStateException("balance is not yet available");
+ }
+}
From e2bd89f39a891c8b24364153a204177f37d0ccc4 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Fri, 18 Sep 2020 11:33:16 -0300
Subject: [PATCH 03/17] Refactor API & add registerdisputeagent method to CLI
This commit contains most of the changes suggested by @chimp1984 in
his api-suggestions branch. See
https://github.com/bisq-network/bisq/commit/961703ecea62df62946ab001ec28205662688ccd
A new 'registerdisputeagent' method was also added to MainCli, finishing
the work to support registration of mediators and refund agents on
arbitration daemons running in regtest mode. This method cannot be
used to register dispute agents on mainnet; users will see an error
msg if they try.
---
apitest/scripts/mainnet-test.sh | 14 +--
cli/src/main/java/bisq/cli/CliMain.java | 57 +++++++++---
core/src/main/java/bisq/core/api/CoreApi.java | 10 ++-
.../core/api/CoreDisputeAgentsService.java | 2 +-
.../java/bisq/core/api/CoreOffersService.java | 46 +++++-----
.../core/api/CorePaymentAccountsService.java | 86 ++++++++++++++++---
.../bisq/core/api/CoreWalletsService.java | 36 ++++----
.../bisq/core/btc/wallet/WalletService.java | 3 +
core/src/main/java/bisq/core/user/User.java | 10 +++
.../java/bisq/daemon/app/BisqDaemonMain.java | 23 +++--
.../grpc/GrpcGetTradeStatisticsService.java | 37 ++++++++
.../bisq/daemon/grpc/GrpcOffersService.java | 2 +-
.../grpc/GrpcPaymentAccountsService.java | 10 ++-
.../java/bisq/daemon/grpc/GrpcServer.java | 52 +++--------
.../bisq/daemon/grpc/GrpcVersionService.java | 28 ++++++
.../bisq/daemon/grpc/GrpcWalletsService.java | 19 ++--
.../daemon/grpc/PasswordAuthInterceptor.java | 11 ++-
proto/src/main/proto/grpc.proto | 14 +--
18 files changed, 317 insertions(+), 143 deletions(-)
create mode 100644 daemon/src/main/java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java
create mode 100644 daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java
diff --git a/apitest/scripts/mainnet-test.sh b/apitest/scripts/mainnet-test.sh
index 9c5889ff3a..bfab9fc3b5 100755
--- a/apitest/scripts/mainnet-test.sh
+++ b/apitest/scripts/mainnet-test.sh
@@ -48,14 +48,14 @@
run ./bisq-cli --password="xyz" getversion
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
- [ "$output" = "1.3.8" ]
+ [ "$output" = "1.3.9" ]
}
@test "test getversion" {
run ./bisq-cli --password=xyz getversion
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
- [ "$output" = "1.3.8" ]
+ [ "$output" = "1.3.9" ]
}
@test "test setwalletpassword \"a b c\"" {
@@ -166,15 +166,15 @@
[ "$output" = "Error: address bogus not found in wallet" ]
}
-@test "test createpaymentacct PerfectMoneyDummy (missing nbr, ccy params)" {
- run ./bisq-cli --password=xyz createpaymentacct PerfectMoneyDummy
+@test "test createpaymentacct PerfectMoneyDummy (missing name, nbr, ccy params)" {
+ run ./bisq-cli --password=xyz createpaymentacct PERFECT_MONEY
[ "$status" -eq 1 ]
echo "actual output: $output" >&2
- [ "$output" = "Error: incorrect parameter count, expecting account name, account number, currency code" ]
+ [ "$output" = "Error: incorrect parameter count, expecting payment method id, account name, account number, currency code" ]
}
-@test "test createpaymentacct PerfectMoneyDummy 0123456789 USD" {
- run ./bisq-cli --password=xyz createpaymentacct PerfectMoneyDummy 0123456789 USD
+@test "test createpaymentacct PERFECT_MONEY PerfectMoneyDummy 0123456789 USD" {
+ run ./bisq-cli --password=xyz createpaymentacct PERFECT_MONEY PerfectMoneyDummy 0123456789 USD
[ "$status" -eq 0 ]
}
diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java
index f229fcd453..341420666d 100644
--- a/cli/src/main/java/bisq/cli/CliMain.java
+++ b/cli/src/main/java/bisq/cli/CliMain.java
@@ -25,6 +25,7 @@ import bisq.proto.grpc.GetOffersRequest;
import bisq.proto.grpc.GetPaymentAccountsRequest;
import bisq.proto.grpc.GetVersionRequest;
import bisq.proto.grpc.LockWalletRequest;
+import bisq.proto.grpc.RegisterDisputeAgentRequest;
import bisq.proto.grpc.RemoveWalletPasswordRequest;
import bisq.proto.grpc.SetWalletPasswordRequest;
import bisq.proto.grpc.UnlockWalletRequest;
@@ -69,7 +70,8 @@ public class CliMain {
lockwallet,
unlockwallet,
removewalletpassword,
- setwalletpassword
+ setwalletpassword,
+ registerdisputeagent
}
public static void main(String[] args) {
@@ -114,9 +116,9 @@ public class CliMain {
}
var methodName = nonOptionArgs.get(0);
- final Method method;
+ Method method;
try {
- method = Method.valueOf(methodName);
+ method = getMethodFromCmd(methodName);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException(format("'%s' is not a supported method", methodName));
}
@@ -128,6 +130,7 @@ public class CliMain {
throw new IllegalArgumentException("missing required 'password' option");
GrpcStubs grpcStubs = new GrpcStubs(host, port, password);
+ var disputeAgentsService = grpcStubs.disputeAgentsService;
var versionService = grpcStubs.versionService;
var offersService = grpcStubs.offersService;
var paymentAccountsService = grpcStubs.paymentAccountsService;
@@ -166,34 +169,38 @@ public class CliMain {
}
case getoffers: {
if (nonOptionArgs.size() < 3)
- throw new IllegalArgumentException("incorrect parameter count, expecting direction (buy|sell), currency code");
+ throw new IllegalArgumentException("incorrect parameter count,"
+ + " expecting direction (buy|sell), currency code");
var direction = nonOptionArgs.get(1);
var fiatCurrency = nonOptionArgs.get(2);
var request = GetOffersRequest.newBuilder()
.setDirection(direction)
- .setFiatCurrencyCode(fiatCurrency)
+ .setCurrencyCode(fiatCurrency)
.build();
var reply = offersService.getOffers(request);
out.println(formatOfferTable(reply.getOffersList(), fiatCurrency));
return;
}
case createpaymentacct: {
- if (nonOptionArgs.size() < 4)
+ if (nonOptionArgs.size() < 5)
throw new IllegalArgumentException(
- "incorrect parameter count, expecting account name, account number, currency code");
+ "incorrect parameter count, expecting payment method id,"
+ + " account name, account number, currency code");
- var accountName = nonOptionArgs.get(1);
- var accountNumber = nonOptionArgs.get(2);
- var fiatCurrencyCode = nonOptionArgs.get(3);
+ var paymentMethodId = nonOptionArgs.get(1);
+ var accountName = nonOptionArgs.get(2);
+ var accountNumber = nonOptionArgs.get(3);
+ var currencyCode = nonOptionArgs.get(4);
var request = CreatePaymentAccountRequest.newBuilder()
+ .setPaymentMethodId(paymentMethodId)
.setAccountName(accountName)
.setAccountNumber(accountNumber)
- .setFiatCurrencyCode(fiatCurrencyCode).build();
+ .setCurrencyCode(currencyCode).build();
paymentAccountsService.createPaymentAccount(request);
- out.println(format("payment account %s saved", accountName));
+ out.printf("payment account %s saved", accountName);
return;
}
case getpaymentaccts: {
@@ -232,7 +239,8 @@ public class CliMain {
if (nonOptionArgs.size() < 2)
throw new IllegalArgumentException("no password specified");
- var request = RemoveWalletPasswordRequest.newBuilder().setPassword(nonOptionArgs.get(1)).build();
+ var request = RemoveWalletPasswordRequest.newBuilder()
+ .setPassword(nonOptionArgs.get(1)).build();
walletsService.removeWalletPassword(request);
out.println("wallet decrypted");
return;
@@ -241,7 +249,8 @@ public class CliMain {
if (nonOptionArgs.size() < 2)
throw new IllegalArgumentException("no password specified");
- var requestBuilder = SetWalletPasswordRequest.newBuilder().setPassword(nonOptionArgs.get(1));
+ var requestBuilder = SetWalletPasswordRequest.newBuilder()
+ .setPassword(nonOptionArgs.get(1));
var hasNewPassword = nonOptionArgs.size() == 3;
if (hasNewPassword)
requestBuilder.setNewPassword(nonOptionArgs.get(2));
@@ -249,6 +258,19 @@ public class CliMain {
out.println("wallet encrypted" + (hasNewPassword ? " with new password" : ""));
return;
}
+ case registerdisputeagent: {
+ if (nonOptionArgs.size() < 3)
+ throw new IllegalArgumentException(
+ "incorrect parameter count, expecting dispute agent type, registration key");
+
+ var disputeAgentType = nonOptionArgs.get(1);
+ var registrationKey = nonOptionArgs.get(2);
+ var requestBuilder = RegisterDisputeAgentRequest.newBuilder()
+ .setDisputeAgentType(disputeAgentType).setRegistrationKey(registrationKey);
+ disputeAgentsService.registerDisputeAgent(requestBuilder.build());
+ out.println(disputeAgentType + " registered");
+ return;
+ }
default: {
throw new RuntimeException(format("unhandled method '%s'", method));
}
@@ -260,6 +282,13 @@ public class CliMain {
}
}
+ private static Method getMethodFromCmd(String methodName) {
+ // TODO if we use const type for enum we need add some mapping. Even if we don't
+ // change now it is handy to have flexibility in case we change internal code
+ // and don't want to break user commands.
+ return Method.valueOf(methodName.toLowerCase());
+ }
+
private static void printHelp(OptionParser parser, PrintStream stream) {
try {
stream.println("Bisq RPC Client");
diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java
index 35af589f3d..81af1fae0f 100644
--- a/core/src/main/java/bisq/core/api/CoreApi.java
+++ b/core/src/main/java/bisq/core/api/CoreApi.java
@@ -139,8 +139,14 @@ public class CoreApi {
// PaymentAccounts
///////////////////////////////////////////////////////////////////////////////////////////
- public void createPaymentAccount(String accountName, String accountNumber, String fiatCurrencyCode) {
- paymentAccountsService.createPaymentAccount(accountName, accountNumber, fiatCurrencyCode);
+ public void createPaymentAccount(String paymentMethodId,
+ String accountName,
+ String accountNumber,
+ String currencyCode) {
+ paymentAccountsService.createPaymentAccount(paymentMethodId,
+ accountName,
+ accountNumber,
+ currencyCode);
}
public Set getPaymentAccounts() {
diff --git a/core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java b/core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java
index 29e51b8853..5aabdd822f 100644
--- a/core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java
+++ b/core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java
@@ -68,7 +68,7 @@ class CoreDisputeAgentsService {
this.languageCodes = Arrays.asList("de", "en", "es", "fr");
}
- public void registerDisputeAgent(String disputeAgentType, String registrationKey) {
+ void registerDisputeAgent(String disputeAgentType, String registrationKey) {
if (!p2PService.isBootstrapped())
throw new IllegalStateException("p2p service is not bootstrapped yet");
diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java
index c5fac7442a..61ee0e006d 100644
--- a/core/src/main/java/bisq/core/api/CoreOffersService.java
+++ b/core/src/main/java/bisq/core/api/CoreOffersService.java
@@ -58,7 +58,7 @@ class CoreOffersService {
this.user = user;
}
- public List getOffers(String direction, String fiatCurrencyCode) {
+ List getOffers(String direction, String fiatCurrencyCode) {
List offers = offerBookService.getOffers().stream()
.filter(o -> {
var offerOfWantedDirection = o.getDirection().name().equalsIgnoreCase(direction);
@@ -77,16 +77,16 @@ class CoreOffersService {
return offers;
}
- public void createOffer(String currencyCode,
- String directionAsString,
- long priceAsLong,
- boolean useMarketBasedPrice,
- double marketPriceMargin,
- long amountAsLong,
- long minAmountAsLong,
- double buyerSecurityDeposit,
- String paymentAccountId,
- TransactionResultHandler resultHandler) {
+ void createOffer(String currencyCode,
+ String directionAsString,
+ long priceAsLong,
+ boolean useMarketBasedPrice,
+ double marketPriceMargin,
+ long amountAsLong,
+ long minAmountAsLong,
+ double buyerSecurityDeposit,
+ String paymentAccountId,
+ TransactionResultHandler resultHandler) {
String offerId = createOfferService.getRandomOfferId();
OfferPayload.Direction direction = OfferPayload.Direction.valueOf(directionAsString);
Price price = Price.valueOf(currencyCode, priceAsLong);
@@ -111,18 +111,18 @@ class CoreOffersService {
resultHandler);
}
- public void createOffer(String offerId,
- String currencyCode,
- OfferPayload.Direction direction,
- Price price,
- boolean useMarketBasedPrice,
- double marketPriceMargin,
- Coin amount,
- Coin minAmount,
- double buyerSecurityDeposit,
- PaymentAccount paymentAccount,
- boolean useSavingsWallet,
- TransactionResultHandler resultHandler) {
+ void createOffer(String offerId,
+ String currencyCode,
+ OfferPayload.Direction direction,
+ Price price,
+ boolean useMarketBasedPrice,
+ double marketPriceMargin,
+ Coin amount,
+ Coin minAmount,
+ double buyerSecurityDeposit,
+ PaymentAccount paymentAccount,
+ boolean useSavingsWallet,
+ TransactionResultHandler resultHandler) {
Coin useDefaultTxFee = Coin.ZERO;
Offer offer = createOfferService.createAndGetOffer(offerId,
direction,
diff --git a/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java b/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java
index f40c56c20d..b49c57a23f 100644
--- a/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java
+++ b/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java
@@ -33,6 +33,9 @@ import java.util.Set;
import lombok.extern.slf4j.Slf4j;
+import static bisq.core.payment.payload.PaymentMethod.*;
+import static com.google.common.base.Preconditions.checkNotNull;
+
@Slf4j
class CorePaymentAccountsService {
@@ -49,17 +52,19 @@ class CorePaymentAccountsService {
this.user = user;
}
- public void createPaymentAccount(String accountName, String accountNumber, String fiatCurrencyCode) {
- // Create and persist a PerfectMoney dummy payment account. There is no guard
- // against creating accounts with duplicate names & numbers, only the uuid and
- // creation date are unique.
- PaymentMethod dummyPaymentMethod = PaymentMethod.getDummyPaymentMethod(PaymentMethod.PERFECT_MONEY_ID);
- PaymentAccount paymentAccount = PaymentAccountFactory.getPaymentAccount(dummyPaymentMethod);
- paymentAccount.init();
- paymentAccount.setAccountName(accountName);
- ((PerfectMoneyAccount) paymentAccount).setAccountNr(accountNumber);
- paymentAccount.setSingleTradeCurrency(new FiatCurrency(fiatCurrencyCode.toUpperCase()));
- user.addPaymentAccount(paymentAccount);
+ void createPaymentAccount(String paymentMethodId,
+ String accountName,
+ String accountNumber,
+ String currencyCode) {
+
+ PaymentAccount paymentAccount = getNewPaymentAccount(paymentMethodId,
+ accountName,
+ accountNumber,
+ currencyCode);
+
+ // TODO not sure if there is more to do at account creation.
+ // Need to check all the flow when its created from UI.
+ user.addPaymentAccountIfNotExists(paymentAccount);
// Don't do this on mainnet until thoroughly tested.
if (config.baseCurrencyNetwork.isRegtest())
@@ -68,7 +73,64 @@ class CorePaymentAccountsService {
log.info("Payment account {} saved", paymentAccount.getId());
}
- public Set getPaymentAccounts() {
+ Set getPaymentAccounts() {
return user.getPaymentAccounts();
}
+
+ private PaymentAccount getNewPaymentAccount(String paymentMethodId,
+ String accountName,
+ String accountNumber,
+ String currencyCode) {
+ PaymentAccount paymentAccount = null;
+ PaymentMethod paymentMethod = getPaymentMethodById(paymentMethodId);
+
+ switch (paymentMethod.getId()) {
+ case UPHOLD_ID:
+ case MONEY_BEAM_ID:
+ case POPMONEY_ID:
+ case REVOLUT_ID:
+ //noinspection DuplicateBranchesInSwitch
+ log.error("PaymentMethod {} not supported yet.", paymentMethod);
+ break;
+ case PERFECT_MONEY_ID:
+ // Create and persist a PerfectMoney dummy payment account. There is no
+ // guard against creating accounts with duplicate names & numbers, only
+ // the uuid and creation date are unique.
+ paymentAccount = PaymentAccountFactory.getPaymentAccount(paymentMethod);
+ paymentAccount.init();
+ paymentAccount.setAccountName(accountName);
+ ((PerfectMoneyAccount) paymentAccount).setAccountNr(accountNumber);
+ paymentAccount.setSingleTradeCurrency(new FiatCurrency(currencyCode));
+ break;
+ case SEPA_ID:
+ case SEPA_INSTANT_ID:
+ case FASTER_PAYMENTS_ID:
+ case NATIONAL_BANK_ID:
+ case SAME_BANK_ID:
+ case SPECIFIC_BANKS_ID:
+ case JAPAN_BANK_ID:
+ case ALI_PAY_ID:
+ case WECHAT_PAY_ID:
+ case SWISH_ID:
+ case CLEAR_X_CHANGE_ID:
+ case CHASE_QUICK_PAY_ID:
+ case INTERAC_E_TRANSFER_ID:
+ case US_POSTAL_MONEY_ORDER_ID:
+ case MONEY_GRAM_ID:
+ case WESTERN_UNION_ID:
+ case CASH_DEPOSIT_ID:
+ case HAL_CASH_ID:
+ case F2F_ID:
+ case PROMPT_PAY_ID:
+ case ADVANCED_CASH_ID:
+ default:
+ log.error("PaymentMethod {} not supported yet.", paymentMethod);
+ break;
+ }
+
+ checkNotNull(paymentAccount,
+ "Could not create payment account with paymentMethodId "
+ + paymentMethodId + ".");
+ return paymentAccount;
+ }
}
diff --git a/core/src/main/java/bisq/core/api/CoreWalletsService.java b/core/src/main/java/bisq/core/api/CoreWalletsService.java
index 10feea5b8e..4ae4efe7a1 100644
--- a/core/src/main/java/bisq/core/api/CoreWalletsService.java
+++ b/core/src/main/java/bisq/core/api/CoreWalletsService.java
@@ -71,7 +71,7 @@ class CoreWalletsService {
this.btcWalletService = btcWalletService;
}
- public long getAvailableBalance() {
+ long getAvailableBalance() {
verifyWalletsAreAvailable();
verifyEncryptedWalletIsUnlocked();
@@ -82,40 +82,38 @@ class CoreWalletsService {
return balance.getValue();
}
- public long getAddressBalance(String addressString) {
+ long getAddressBalance(String addressString) {
Address address = getAddressEntry(addressString).getAddress();
return btcWalletService.getBalanceForAddress(address).value;
}
- public AddressBalanceInfo getAddressBalanceInfo(String addressString) {
+ AddressBalanceInfo getAddressBalanceInfo(String addressString) {
var satoshiBalance = getAddressBalance(addressString);
var numConfirmations = getNumConfirmationsForMostRecentTransaction(addressString);
return new AddressBalanceInfo(addressString, satoshiBalance, numConfirmations);
}
- public List getFundingAddresses() {
+ List getFundingAddresses() {
verifyWalletsAreAvailable();
verifyEncryptedWalletIsUnlocked();
// Create a new funding address if none exists.
- if (btcWalletService.getAvailableAddressEntries().size() == 0)
+ if (btcWalletService.getAvailableAddressEntries().isEmpty())
btcWalletService.getFreshAddressEntry();
- List addressStrings =
- btcWalletService
- .getAvailableAddressEntries()
- .stream()
- .map(AddressEntry::getAddressString)
- .collect(Collectors.toList());
+ List addressStrings = btcWalletService
+ .getAvailableAddressEntries()
+ .stream()
+ .map(AddressEntry::getAddressString)
+ .collect(Collectors.toList());
// getAddressBalance is memoized, because we'll map it over addresses twice.
// To get the balances, we'll be using .getUnchecked, because we know that
// this::getAddressBalance cannot return null.
var balances = memoize(this::getAddressBalance);
- boolean noAddressHasZeroBalance =
- addressStrings.stream()
- .allMatch(addressString -> balances.getUnchecked(addressString) != 0);
+ boolean noAddressHasZeroBalance = addressStrings.stream()
+ .allMatch(addressString -> balances.getUnchecked(addressString) != 0);
if (noAddressHasZeroBalance) {
var newZeroBalanceAddress = btcWalletService.getFreshAddressEntry();
@@ -129,13 +127,13 @@ class CoreWalletsService {
.collect(Collectors.toList());
}
- public int getNumConfirmationsForMostRecentTransaction(String addressString) {
+ int getNumConfirmationsForMostRecentTransaction(String addressString) {
Address address = getAddressEntry(addressString).getAddress();
TransactionConfidence confidence = btcWalletService.getConfidenceForAddress(address);
return confidence == null ? 0 : confidence.getDepthInBlocks();
}
- public void setWalletPassword(String password, String newPassword) {
+ void setWalletPassword(String password, String newPassword) {
verifyWalletsAreAvailable();
KeyCrypterScrypt keyCrypterScrypt = getKeyCrypterScrypt();
@@ -165,7 +163,7 @@ class CoreWalletsService {
walletsManager.backupWallets();
}
- public void lockWallet() {
+ void lockWallet() {
if (!walletsManager.areWalletsEncrypted())
throw new IllegalStateException("wallet is not encrypted with a password");
@@ -175,7 +173,7 @@ class CoreWalletsService {
tempAesKey = null;
}
- public void unlockWallet(String password, long timeout) {
+ void unlockWallet(String password, long timeout) {
verifyWalletIsAvailableAndEncrypted();
KeyCrypterScrypt keyCrypterScrypt = getKeyCrypterScrypt();
@@ -213,7 +211,7 @@ class CoreWalletsService {
// Provided for automated wallet protection method testing, despite the
// security risks exposed by providing users the ability to decrypt their wallets.
- public void removeWalletPassword(String password) {
+ void removeWalletPassword(String password) {
verifyWalletIsAvailableAndEncrypted();
KeyCrypterScrypt keyCrypterScrypt = getKeyCrypterScrypt();
diff --git a/core/src/main/java/bisq/core/btc/wallet/WalletService.java b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
index d56b34a7c9..7013d529f7 100644
--- a/core/src/main/java/bisq/core/btc/wallet/WalletService.java
+++ b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
@@ -734,6 +734,9 @@ public abstract class WalletService {
return maybeAddTxToWallet(transaction.bitcoinSerialize(), wallet, source);
}
+ public Address getAddress(String addressString) {
+ return Address.fromBase58(params, addressString);
+ }
///////////////////////////////////////////////////////////////////////////////////////////
// bisqWalletEventListener
diff --git a/core/src/main/java/bisq/core/user/User.java b/core/src/main/java/bisq/core/user/User.java
index d9adac9a09..86cb5048b7 100644
--- a/core/src/main/java/bisq/core/user/User.java
+++ b/core/src/main/java/bisq/core/user/User.java
@@ -189,6 +189,12 @@ public class User implements PersistedDataHost {
// Collection operations
///////////////////////////////////////////////////////////////////////////////////////////
+ public void addPaymentAccountIfNotExists(PaymentAccount paymentAccount) {
+ if (!paymentAccountExists(paymentAccount)) {
+ addPaymentAccount(paymentAccount);
+ }
+ }
+
public void addPaymentAccount(PaymentAccount paymentAccount) {
paymentAccount.onAddToUser();
@@ -493,4 +499,8 @@ public class User implements PersistedDataHost {
public boolean isPaymentAccountImport() {
return isPaymentAccountImport;
}
+
+ private boolean paymentAccountExists(PaymentAccount paymentAccount) {
+ return getPaymentAccountsAsObservable().stream().anyMatch(e -> e.equals(paymentAccount));
+ }
}
diff --git a/daemon/src/main/java/bisq/daemon/app/BisqDaemonMain.java b/daemon/src/main/java/bisq/daemon/app/BisqDaemonMain.java
index f7a5dac3d6..9bc34648d6 100644
--- a/daemon/src/main/java/bisq/daemon/app/BisqDaemonMain.java
+++ b/daemon/src/main/java/bisq/daemon/app/BisqDaemonMain.java
@@ -23,6 +23,7 @@ import bisq.core.app.CoreModule;
import bisq.common.UserThread;
import bisq.common.app.AppModule;
+import bisq.common.handlers.ResultHandler;
import bisq.common.setup.CommonSetup;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
@@ -39,13 +40,15 @@ import bisq.daemon.grpc.GrpcServer;
@Slf4j
public class BisqDaemonMain extends BisqHeadlessAppMain implements BisqSetup.BisqSetupListener {
+ private GrpcServer grpcServer;
+
public static void main(String[] args) {
new BisqDaemonMain().execute(args);
}
- ///////////////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////////
// First synchronous execution tasks
- ///////////////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////////
@Override
protected void configUserThread() {
@@ -70,9 +73,9 @@ public class BisqDaemonMain extends BisqHeadlessAppMain implements BisqSetup.Bis
headlessApp.setGracefulShutDownHandler(this);
}
- ///////////////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////////
// We continue with a series of synchronous execution tasks
- ///////////////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////////
@Override
protected AppModule getModule() {
@@ -91,7 +94,8 @@ public class BisqDaemonMain extends BisqHeadlessAppMain implements BisqSetup.Bis
// We need to be in user thread! We mapped at launchApplication already...
headlessApp.startApplication();
- // In headless mode we don't have an async behaviour so we trigger the setup by calling onApplicationStarted
+ // In headless mode we don't have an async behaviour so we trigger the setup by
+ // calling onApplicationStarted.
onApplicationStarted();
}
@@ -99,7 +103,14 @@ public class BisqDaemonMain extends BisqHeadlessAppMain implements BisqSetup.Bis
protected void onApplicationStarted() {
super.onApplicationStarted();
- GrpcServer grpcServer = injector.getInstance(GrpcServer.class);
+ grpcServer = injector.getInstance(GrpcServer.class);
grpcServer.start();
}
+
+ @Override
+ public void gracefulShutDown(ResultHandler resultHandler) {
+ super.gracefulShutDown(resultHandler);
+
+ grpcServer.shutdown();
+ }
}
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java
new file mode 100644
index 0000000000..bbe8b3fdf7
--- /dev/null
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java
@@ -0,0 +1,37 @@
+package bisq.daemon.grpc;
+
+import bisq.core.api.CoreApi;
+import bisq.core.trade.statistics.TradeStatistics2;
+
+import bisq.proto.grpc.GetTradeStatisticsGrpc;
+import bisq.proto.grpc.GetTradeStatisticsReply;
+import bisq.proto.grpc.GetTradeStatisticsRequest;
+
+import io.grpc.stub.StreamObserver;
+
+import javax.inject.Inject;
+
+import java.util.stream.Collectors;
+
+public class GrpcGetTradeStatisticsService extends GetTradeStatisticsGrpc.GetTradeStatisticsImplBase {
+
+ private final CoreApi coreApi;
+
+ @Inject
+ public GrpcGetTradeStatisticsService(CoreApi coreApi) {
+ this.coreApi = coreApi;
+ }
+
+ @Override
+ public void getTradeStatistics(GetTradeStatisticsRequest req,
+ StreamObserver responseObserver) {
+
+ var tradeStatistics = coreApi.getTradeStatistics().stream()
+ .map(TradeStatistics2::toProtoTradeStatistics2)
+ .collect(Collectors.toList());
+
+ var reply = GetTradeStatisticsReply.newBuilder().addAllTradeStatistics(tradeStatistics).build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ }
+}
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
index 8a3fa548d9..b8b00f6d12 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
@@ -52,7 +52,7 @@ class GrpcOffersService extends OffersGrpc.OffersImplBase {
// The client cannot see bisq.core.Offer or its fromProto method.
// We use the lighter weight OfferInfo proto wrapper instead, containing just
// enough fields to view and create offers.
- List result = coreApi.getOffers(req.getDirection(), req.getFiatCurrencyCode())
+ List result = coreApi.getOffers(req.getDirection(), req.getCurrencyCode())
.stream().map(offer -> new OfferInfo.OfferInfoBuilder()
.withId(offer.getId())
.withDirection(offer.getDirection().name())
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java
index e630b30fc5..91060cbc82 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java
@@ -45,7 +45,10 @@ class GrpcPaymentAccountsService extends PaymentAccountsGrpc.PaymentAccountsImpl
@Override
public void createPaymentAccount(CreatePaymentAccountRequest req,
StreamObserver responseObserver) {
- coreApi.createPaymentAccount(req.getAccountName(), req.getAccountNumber(), req.getFiatCurrencyCode());
+ coreApi.createPaymentAccount(req.getPaymentMethodId(),
+ req.getAccountName(),
+ req.getAccountNumber(),
+ req.getCurrencyCode());
var reply = CreatePaymentAccountReply.newBuilder().build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
@@ -54,10 +57,11 @@ class GrpcPaymentAccountsService extends PaymentAccountsGrpc.PaymentAccountsImpl
@Override
public void getPaymentAccounts(GetPaymentAccountsRequest req,
StreamObserver responseObserver) {
- var tradeStatistics = coreApi.getPaymentAccounts().stream()
+ var paymentAccounts = coreApi.getPaymentAccounts().stream()
.map(PaymentAccount::toProtoMessage)
.collect(Collectors.toList());
- var reply = GetPaymentAccountsReply.newBuilder().addAllPaymentAccounts(tradeStatistics).build();
+ var reply = GetPaymentAccountsReply.newBuilder()
+ .addAllPaymentAccounts(paymentAccounts).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
index 0c0e2f5cb3..3090dce14a 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
@@ -18,30 +18,21 @@
package bisq.daemon.grpc;
import bisq.core.api.CoreApi;
-import bisq.core.trade.statistics.TradeStatistics2;
import bisq.common.config.Config;
-import bisq.proto.grpc.GetTradeStatisticsGrpc;
-import bisq.proto.grpc.GetTradeStatisticsReply;
-import bisq.proto.grpc.GetTradeStatisticsRequest;
-import bisq.proto.grpc.GetVersionGrpc;
-import bisq.proto.grpc.GetVersionReply;
-import bisq.proto.grpc.GetVersionRequest;
-
import io.grpc.Server;
import io.grpc.ServerBuilder;
-import io.grpc.stub.StreamObserver;
import javax.inject.Inject;
+import javax.inject.Singleton;
import java.io.IOException;
import java.io.UncheckedIOException;
-import java.util.stream.Collectors;
-
import lombok.extern.slf4j.Slf4j;
+@Singleton
@Slf4j
public class GrpcServer {
@@ -51,19 +42,22 @@ public class GrpcServer {
@Inject
public GrpcServer(Config config,
CoreApi coreApi,
+ PasswordAuthInterceptor passwordAuthInterceptor,
GrpcDisputeAgentsService disputeAgentsService,
GrpcOffersService offersService,
GrpcPaymentAccountsService paymentAccountsService,
+ GrpcVersionService versionService,
+ GrpcGetTradeStatisticsService tradeStatisticsService,
GrpcWalletsService walletsService) {
this.coreApi = coreApi;
this.server = ServerBuilder.forPort(config.apiPort)
.addService(disputeAgentsService)
- .addService(new GetVersionService())
- .addService(new GetTradeStatisticsService())
.addService(offersService)
.addService(paymentAccountsService)
+ .addService(tradeStatisticsService)
+ .addService(versionService)
.addService(walletsService)
- .intercept(new PasswordAuthInterceptor(config.apiPassword))
+ .intercept(passwordAuthInterceptor)
.build();
}
@@ -71,36 +65,14 @@ public class GrpcServer {
try {
server.start();
log.info("listening on port {}", server.getPort());
- Runtime.getRuntime().addShutdownHook(new Thread(() -> {
- server.shutdown();
- log.info("shutdown complete");
- }));
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
- class GetVersionService extends GetVersionGrpc.GetVersionImplBase {
- @Override
- public void getVersion(GetVersionRequest req, StreamObserver responseObserver) {
- var reply = GetVersionReply.newBuilder().setVersion(coreApi.getVersion()).build();
- responseObserver.onNext(reply);
- responseObserver.onCompleted();
- }
- }
-
- class GetTradeStatisticsService extends GetTradeStatisticsGrpc.GetTradeStatisticsImplBase {
- @Override
- public void getTradeStatistics(GetTradeStatisticsRequest req,
- StreamObserver responseObserver) {
-
- var tradeStatistics = coreApi.getTradeStatistics().stream()
- .map(TradeStatistics2::toProtoTradeStatistics2)
- .collect(Collectors.toList());
-
- var reply = GetTradeStatisticsReply.newBuilder().addAllTradeStatistics(tradeStatistics).build();
- responseObserver.onNext(reply);
- responseObserver.onCompleted();
- }
+ public void shutdown() {
+ log.info("Server shutdown started");
+ server.shutdown();
+ log.info("Server shutdown complete");
}
}
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java
new file mode 100644
index 0000000000..06c60bcf80
--- /dev/null
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java
@@ -0,0 +1,28 @@
+package bisq.daemon.grpc;
+
+import bisq.core.api.CoreApi;
+
+import bisq.proto.grpc.GetVersionGrpc;
+import bisq.proto.grpc.GetVersionReply;
+import bisq.proto.grpc.GetVersionRequest;
+
+import io.grpc.stub.StreamObserver;
+
+import javax.inject.Inject;
+
+public class GrpcVersionService extends GetVersionGrpc.GetVersionImplBase {
+
+ private final CoreApi coreApi;
+
+ @Inject
+ public GrpcVersionService(CoreApi coreApi) {
+ this.coreApi = coreApi;
+ }
+
+ @Override
+ public void getVersion(GetVersionRequest req, StreamObserver responseObserver) {
+ var reply = GetVersionReply.newBuilder().setVersion(coreApi.getVersion()).build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ }
+}
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcWalletsService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcWalletsService.java
index 04dd346023..1b5cb42e4c 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcWalletsService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcWalletsService.java
@@ -54,11 +54,17 @@ class GrpcWalletsService extends WalletsGrpc.WalletsImplBase {
this.coreApi = coreApi;
}
+ // TODO we need to support 3 or 4 balance types: available, reserved, lockedInTrade
+ // and maybe total wallet balance (available+reserved). To not duplicate the methods,
+ // we should pass an enum type. Enums in proto are a bit cumbersome as they are
+ // global so you quickly run into namespace conflicts if not always prefixes which
+ // makes it more verbose. In the core code base we move to the strategy to store the
+ // enum name and map it. This gives also more flexibility with updates.
@Override
public void getBalance(GetBalanceRequest req, StreamObserver responseObserver) {
try {
- long result = coreApi.getAvailableBalance();
- var reply = GetBalanceReply.newBuilder().setBalance(result).build();
+ long availableBalance = coreApi.getAvailableBalance();
+ var reply = GetBalanceReply.newBuilder().setBalance(availableBalance).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (IllegalStateException cause) {
@@ -72,8 +78,9 @@ class GrpcWalletsService extends WalletsGrpc.WalletsImplBase {
public void getAddressBalance(GetAddressBalanceRequest req,
StreamObserver responseObserver) {
try {
- AddressBalanceInfo result = coreApi.getAddressBalanceInfo(req.getAddress());
- var reply = GetAddressBalanceReply.newBuilder().setAddressBalanceInfo(result.toProtoMessage()).build();
+ AddressBalanceInfo balanceInfo = coreApi.getAddressBalanceInfo(req.getAddress());
+ var reply = GetAddressBalanceReply.newBuilder()
+ .setAddressBalanceInfo(balanceInfo.toProtoMessage()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (IllegalStateException cause) {
@@ -87,10 +94,10 @@ class GrpcWalletsService extends WalletsGrpc.WalletsImplBase {
public void getFundingAddresses(GetFundingAddressesRequest req,
StreamObserver responseObserver) {
try {
- List result = coreApi.getFundingAddresses();
+ List balanceInfo = coreApi.getFundingAddresses();
var reply = GetFundingAddressesReply.newBuilder()
.addAllAddressBalanceInfo(
- result.stream()
+ balanceInfo.stream()
.map(AddressBalanceInfo::toProtoMessage)
.collect(Collectors.toList()))
.build();
diff --git a/daemon/src/main/java/bisq/daemon/grpc/PasswordAuthInterceptor.java b/daemon/src/main/java/bisq/daemon/grpc/PasswordAuthInterceptor.java
index 7798857dd2..1bf542d7fe 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/PasswordAuthInterceptor.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/PasswordAuthInterceptor.java
@@ -17,12 +17,16 @@
package bisq.daemon.grpc;
+import bisq.common.config.Config;
+
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.StatusRuntimeException;
+import javax.inject.Inject;
+
import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
import static io.grpc.Metadata.Key;
import static io.grpc.Status.UNAUTHENTICATED;
@@ -36,12 +40,13 @@ import static java.lang.String.format;
*/
class PasswordAuthInterceptor implements ServerInterceptor {
- public static final String PASSWORD_KEY = "password";
+ private static final String PASSWORD_KEY = "password";
private final String expectedPasswordValue;
- public PasswordAuthInterceptor(String expectedPasswordValue) {
- this.expectedPasswordValue = expectedPasswordValue;
+ @Inject
+ public PasswordAuthInterceptor(Config config) {
+ this.expectedPasswordValue = config.apiPassword;
}
@Override
diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto
index ed2cb4fd61..21c59b8643 100644
--- a/proto/src/main/proto/grpc.proto
+++ b/proto/src/main/proto/grpc.proto
@@ -53,7 +53,7 @@ service Offers {
message GetOffersRequest {
string direction = 1;
- string fiatCurrencyCode = 2;
+ string currencyCode = 2;
}
message GetOffersReply {
@@ -61,7 +61,7 @@ message GetOffersReply {
}
message CreateOfferRequest {
- string currencyCode = 1; // TODO switch order w/ direction field in next PR
+ string currencyCode = 1;
string direction = 2;
uint64 price = 3;
bool useMarketBasedPrice = 4;
@@ -107,9 +107,11 @@ service PaymentAccounts {
}
message CreatePaymentAccountRequest {
- string accountName = 1;
- string accountNumber = 2;
- string fiatCurrencyCode = 3;
+string paymentMethodId = 1;
+ string accountName = 2;
+ string accountNumber = 3;
+ // TODO Support all currencies. Maybe add a repeated and if only one is used its a singletonList.
+ string currencyCode = 4;
}
message CreatePaymentAccountReply {
@@ -123,7 +125,7 @@ message GetPaymentAccountsReply {
}
///////////////////////////////////////////////////////////////////////////////////////////
-// TradeStatistics
+// GetTradeStatistics
///////////////////////////////////////////////////////////////////////////////////////////
service GetTradeStatistics {
From da78465fe4167f9d1b168bf15c13eb12cf4b50e4 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Fri, 18 Sep 2020 11:46:29 -0300
Subject: [PATCH 04/17] Make grpc boilerplate classes pkg protected
---
.../java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java | 2 +-
daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java
index bbe8b3fdf7..281fc12118 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcGetTradeStatisticsService.java
@@ -13,7 +13,7 @@ import javax.inject.Inject;
import java.util.stream.Collectors;
-public class GrpcGetTradeStatisticsService extends GetTradeStatisticsGrpc.GetTradeStatisticsImplBase {
+class GrpcGetTradeStatisticsService extends GetTradeStatisticsGrpc.GetTradeStatisticsImplBase {
private final CoreApi coreApi;
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java
index 06c60bcf80..658ef10e27 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java
@@ -10,7 +10,7 @@ import io.grpc.stub.StreamObserver;
import javax.inject.Inject;
-public class GrpcVersionService extends GetVersionGrpc.GetVersionImplBase {
+class GrpcVersionService extends GetVersionGrpc.GetVersionImplBase {
private final CoreApi coreApi;
From ab282c2c77269df51c041c0e0f6f962d754e0b66 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sat, 19 Sep 2020 15:41:12 -0300
Subject: [PATCH 05/17] Reduce apitest harness' dependency on string matching
- Pass list of supporting app names as enum vararg to scaffold setup.
- Use dispute agent type constants in RegisterDisputeAgentsTest case.
---
apitest/src/main/java/bisq/apitest/Scaffold.java | 7 ++++++-
.../src/test/java/bisq/apitest/ApiTestCase.java | 12 ++++++++++--
.../java/bisq/apitest/method/GetBalanceTest.java | 4 +++-
.../java/bisq/apitest/method/GetVersionTest.java | 2 +-
.../method/RegisterDisputeAgentsTest.java | 16 +++++++++++-----
.../apitest/method/WalletProtectionTest.java | 2 +-
.../apitest/scenario/FundWalletScenarioTest.java | 4 +++-
7 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/Scaffold.java b/apitest/src/main/java/bisq/apitest/Scaffold.java
index d195b78701..333f59285a 100644
--- a/apitest/src/main/java/bisq/apitest/Scaffold.java
+++ b/apitest/src/main/java/bisq/apitest/Scaffold.java
@@ -41,6 +41,7 @@ import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
+import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.BisqAppConfig.*;
import static java.lang.String.format;
import static java.lang.System.exit;
@@ -64,6 +65,10 @@ public class Scaffold {
public static final int EXIT_SUCCESS = 0;
public static final int EXIT_FAILURE = 1;
+ public enum BitcoinCoreApp {
+ bitcoind
+ }
+
public final ApiTestConfig config;
@Nullable
@@ -295,7 +300,7 @@ public class Scaffold {
log.info("Starting supporting apps {}", config.supportingApps.toString());
- if (config.hasSupportingApp("bitcoind")) {
+ if (config.hasSupportingApp(bitcoind.name())) {
BitcoinDaemon bitcoinDaemon = new BitcoinDaemon(config);
bitcoinDaemon.verifyBitcoinPathsExist(true);
bitcoindTask = new SetupTask(bitcoinDaemon, countdownLatch);
diff --git a/apitest/src/test/java/bisq/apitest/ApiTestCase.java b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
index 30e7472e2a..a8422d9f4a 100644
--- a/apitest/src/test/java/bisq/apitest/ApiTestCase.java
+++ b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
@@ -24,7 +24,9 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+import static java.util.Arrays.stream;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -68,15 +70,21 @@ public class ApiTestCase {
// gRPC service stubs are used by method & scenario tests, but not e2e tests.
private static final Map grpcStubsCache = new HashMap<>();
- public static void setUpScaffold(String supportingApps)
+ public static void setUpScaffold(Enum>... supportingApps)
throws InterruptedException, ExecutionException, IOException {
- scaffold = new Scaffold(supportingApps).setUp();
+ scaffold = new Scaffold(stream(supportingApps).map(Enum::name)
+ .collect(Collectors.joining(",")))
+ .setUp();
config = scaffold.config;
bitcoinCli = new BitcoinCliHelper((config));
}
public static void setUpScaffold(String[] params)
throws InterruptedException, ExecutionException, IOException {
+ // Test cases needing to pass more than just an ApiTestConfig
+ // --supportingApps option will use this setup method, but the
+ // --supportingApps option will need to be passed too, with its comma
+ // delimited app list value, e.g., "bitcoind,seednode,arbdaemon".
scaffold = new Scaffold(params).setUp();
config = scaffold.config;
}
diff --git a/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java b/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java
index a77fe633ea..abce9a78a6 100644
--- a/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java
@@ -27,7 +27,9 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
+import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static bisq.apitest.config.BisqAppConfig.seednode;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
@@ -41,7 +43,7 @@ public class GetBalanceTest extends MethodTest {
@BeforeAll
public static void setUp() {
try {
- setUpScaffold("bitcoind,seednode,alicedaemon");
+ setUpScaffold(bitcoind, seednode, alicedaemon);
// Have to generate 1 regtest block for alice's wallet to show 10 BTC balance.
bitcoinCli.generateBlocks(1);
diff --git a/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java b/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java
index ed6083c8d3..82780340ee 100644
--- a/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java
@@ -41,7 +41,7 @@ public class GetVersionTest extends MethodTest {
@BeforeAll
public static void setUp() {
try {
- setUpScaffold(alicedaemon.name());
+ setUpScaffold(alicedaemon);
} catch (Exception ex) {
fail(ex);
}
diff --git a/apitest/src/test/java/bisq/apitest/method/RegisterDisputeAgentsTest.java b/apitest/src/test/java/bisq/apitest/method/RegisterDisputeAgentsTest.java
index 1ad3a36f16..e09de2b061 100644
--- a/apitest/src/test/java/bisq/apitest/method/RegisterDisputeAgentsTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/RegisterDisputeAgentsTest.java
@@ -29,7 +29,9 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
+import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.BisqAppConfig.arbdaemon;
+import static bisq.apitest.config.BisqAppConfig.seednode;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -42,10 +44,14 @@ import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
@TestMethodOrder(OrderAnnotation.class)
public class RegisterDisputeAgentsTest extends MethodTest {
+ private static final String ARBITRATOR = "arbitrator";
+ private static final String MEDIATOR = "mediator";
+ private static final String REFUNDAGENT = "refundagent";
+
@BeforeAll
public static void setUp() {
try {
- setUpScaffold("bitcoind,seednode,arbdaemon");
+ setUpScaffold(bitcoind, seednode, arbdaemon);
} catch (Exception ex) {
fail(ex);
}
@@ -55,7 +61,7 @@ public class RegisterDisputeAgentsTest extends MethodTest {
@Order(1)
public void testRegisterArbitratorShouldThrowException() {
var req =
- createRegisterDisputeAgentRequest("arbitrator");
+ createRegisterDisputeAgentRequest(ARBITRATOR);
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
assertEquals("INVALID_ARGUMENT: arbitrators must be registered in a Bisq UI",
@@ -77,7 +83,7 @@ public class RegisterDisputeAgentsTest extends MethodTest {
@Order(3)
public void testInvalidRegistrationKeyArgShouldThrowException() {
var req = RegisterDisputeAgentRequest.newBuilder()
- .setDisputeAgentType("refundagent")
+ .setDisputeAgentType(REFUNDAGENT)
.setRegistrationKey("invalid" + DEV_PRIVILEGE_PRIV_KEY).build();
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
@@ -89,7 +95,7 @@ public class RegisterDisputeAgentsTest extends MethodTest {
@Order(4)
public void testRegisterMediator() {
var req =
- createRegisterDisputeAgentRequest("mediator");
+ createRegisterDisputeAgentRequest(MEDIATOR);
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req);
}
@@ -97,7 +103,7 @@ public class RegisterDisputeAgentsTest extends MethodTest {
@Order(5)
public void testRegisterRefundAgent() {
var req =
- createRegisterDisputeAgentRequest("refundagent");
+ createRegisterDisputeAgentRequest(REFUNDAGENT);
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req);
}
diff --git a/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java b/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
index f74c8e705c..61f3c27e4a 100644
--- a/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
@@ -25,7 +25,7 @@ public class WalletProtectionTest extends MethodTest {
@BeforeAll
public static void setUp() {
try {
- setUpScaffold(alicedaemon.name());
+ setUpScaffold(alicedaemon);
MILLISECONDS.sleep(2000);
} catch (Exception ex) {
fail(ex);
diff --git a/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java b/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
index 0b30d72c1c..75977949c3 100644
--- a/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
+++ b/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
@@ -26,7 +26,9 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
+import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static bisq.apitest.config.BisqAppConfig.seednode;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
@@ -38,7 +40,7 @@ public class FundWalletScenarioTest extends ScenarioTest {
@BeforeAll
public static void setUp() {
try {
- setUpScaffold("bitcoind,seednode,alicedaemon");
+ setUpScaffold(bitcoind, seednode, alicedaemon);
bitcoinCli.generateBlocks(1);
MILLISECONDS.sleep(1500);
} catch (Exception ex) {
From 992441b9b5fc37f129dc90b5e9cba61bec7d48c9 Mon Sep 17 00:00:00 2001
From: Oscar Guindzberg
Date: Mon, 21 Sep 2020 16:52:16 -0300
Subject: [PATCH 06/17] Remove unnecessary listeners
---
.../funds/transactions/TransactionsView.java | 35 -------------------
1 file changed, 35 deletions(-)
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
index 6f60c7ba93..3a05f22a14 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
@@ -103,12 +103,6 @@ public class TransactionsView extends ActivatableView {
private final TradeDetailsWindow tradeDetailsWindow;
private final OfferDetailsWindow offerDetailsWindow;
- private WalletCoinsReceivedEventListener walletCoinsReceivedEventListener;
- private WalletCoinsSentEventListener walletCoinsSentEventListener;
- private WalletReorganizeEventListener walletReorganizeEventListener;
- private TransactionConfidenceEventListener transactionConfidenceEventListener;
- private KeyChainEventListener keyChainEventListener;
- private ScriptsChangeEventListener scriptsChangeEventListener;
private WalletChangeEventListener walletChangeEventListener;
private EventHandler keyEventEventHandler;
@@ -173,23 +167,6 @@ public class TransactionsView extends ActivatableView {
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
tableView.getSortOrder().add(dateColumn);
- walletCoinsReceivedEventListener = (wallet, tx, prevBalance, newBalance) -> {
- displayedTransactions.update();
- };
- walletCoinsSentEventListener = (wallet, tx, prevBalance, newBalance) -> {
- displayedTransactions.update();
- };
- walletReorganizeEventListener = wallet -> {
- displayedTransactions.update();
- };
- transactionConfidenceEventListener = (wallet, tx) -> {
- };
- keyChainEventListener = keys -> {
- displayedTransactions.update();
- };
- scriptsChangeEventListener = (wallet, scripts, isAddingScripts) -> {
- displayedTransactions.update();
- };
walletChangeEventListener = wallet -> {
displayedTransactions.update();
};
@@ -215,12 +192,6 @@ public class TransactionsView extends ActivatableView {
tableView.setItems(sortedDisplayedTransactions);
displayedTransactions.update();
- btcWalletService.addCoinsReceivedEventListener(walletCoinsReceivedEventListener);
- btcWalletService.addCoinsSentEventListener(walletCoinsSentEventListener);
- btcWalletService.addReorganizeEventListener(walletReorganizeEventListener);
- btcWalletService.addTransactionConfidenceEventListener(transactionConfidenceEventListener);
- btcWalletService.addKeyChainEventListener(keyChainEventListener);
- btcWalletService.addScriptChangeEventListener(scriptsChangeEventListener);
btcWalletService.addChangeEventListener(walletChangeEventListener);
scene = root.getScene();
@@ -257,12 +228,6 @@ public class TransactionsView extends ActivatableView {
protected void deactivate() {
sortedDisplayedTransactions.comparatorProperty().unbind();
displayedTransactions.forEach(TransactionsListItem::cleanup);
- btcWalletService.removeCoinsReceivedEventListener(walletCoinsReceivedEventListener);
- btcWalletService.removeCoinsSentEventListener(walletCoinsSentEventListener);
- btcWalletService.removeReorganizeEventListener(walletReorganizeEventListener);
- btcWalletService.removeTransactionConfidenceEventListener(transactionConfidenceEventListener);
- btcWalletService.removeKeyChainEventListener(keyChainEventListener);
- btcWalletService.removeScriptChangeEventListener(scriptsChangeEventListener);
btcWalletService.removeChangeEventListener(walletChangeEventListener);
if (scene != null)
From c890d3c02afb77df47f478e0d2d439d43c559e14 Mon Sep 17 00:00:00 2001
From: Oscar Guindzberg
Date: Mon, 21 Sep 2020 17:19:01 -0300
Subject: [PATCH 07/17] Remove unused code
---
.../bisq/core/btc/wallet/WalletService.java | 48 -------------------
1 file changed, 48 deletions(-)
diff --git a/core/src/main/java/bisq/core/btc/wallet/WalletService.java b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
index a91c2ed619..8fa5e2c09a 100644
--- a/core/src/main/java/bisq/core/btc/wallet/WalletService.java
+++ b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
@@ -551,58 +551,10 @@ public abstract class WalletService {
// Wallet delegates to avoid direct access to wallet outside the service class
///////////////////////////////////////////////////////////////////////////////////////////
- public void addCoinsReceivedEventListener(WalletCoinsReceivedEventListener listener) {
- wallet.addCoinsReceivedEventListener(Threading.USER_THREAD, listener);
- }
-
- public void addCoinsSentEventListener(WalletCoinsSentEventListener listener) {
- wallet.addCoinsSentEventListener(Threading.USER_THREAD, listener);
- }
-
- public void addReorganizeEventListener(WalletReorganizeEventListener listener) {
- wallet.addReorganizeEventListener(Threading.USER_THREAD, listener);
- }
-
- public void addTransactionConfidenceEventListener(TransactionConfidenceEventListener listener) {
- wallet.addTransactionConfidenceEventListener(Threading.USER_THREAD, listener);
- }
-
- public void addKeyChainEventListener(KeyChainEventListener listener) {
- wallet.addKeyChainEventListener(Threading.USER_THREAD, listener);
- }
-
- public void addScriptChangeEventListener(ScriptsChangeEventListener listener) {
- wallet.addScriptChangeEventListener(Threading.USER_THREAD, listener);
- }
-
public void addChangeEventListener(WalletChangeEventListener listener) {
wallet.addChangeEventListener(Threading.USER_THREAD, listener);
}
- public void removeCoinsReceivedEventListener(WalletCoinsReceivedEventListener listener) {
- wallet.removeCoinsReceivedEventListener(listener);
- }
-
- public void removeCoinsSentEventListener(WalletCoinsSentEventListener listener) {
- wallet.removeCoinsSentEventListener(listener);
- }
-
- public void removeReorganizeEventListener(WalletReorganizeEventListener listener) {
- wallet.removeReorganizeEventListener(listener);
- }
-
- public void removeTransactionConfidenceEventListener(TransactionConfidenceEventListener listener) {
- wallet.removeTransactionConfidenceEventListener(listener);
- }
-
- public void removeKeyChainEventListener(KeyChainEventListener listener) {
- wallet.removeKeyChainEventListener(listener);
- }
-
- public void removeScriptChangeEventListener(ScriptsChangeEventListener listener) {
- wallet.removeScriptChangeEventListener(listener);
- }
-
public void removeChangeEventListener(WalletChangeEventListener listener) {
wallet.removeChangeEventListener(listener);
}
From 6cf7a9977a7f24944be14aefc33c9a1473031c65 Mon Sep 17 00:00:00 2001
From: Oscar Guindzberg
Date: Mon, 21 Sep 2020 17:32:47 -0300
Subject: [PATCH 08/17] Code cleanup
---
.../java/bisq/core/btc/nodes/BtcNodeConverter.java | 7 +++----
.../java/bisq/core/btc/setup/BisqKeyChainFactory.java | 5 ++---
.../main/java/bisq/core/btc/setup/WalletConfig.java | 10 +++++-----
.../main/java/bisq/core/btc/setup/WalletsSetup.java | 2 +-
.../java/bisq/core/btc/wallet/BtcWalletService.java | 4 ++--
.../main/java/bisq/core/btc/wallet/WalletService.java | 5 ++---
.../dao/governance/proposal/BaseProposalFactory.java | 2 +-
core/src/main/java/bisq/core/trade/Trade.java | 3 ++-
.../main/overlays/windows/SelectDepositTxWindow.java | 4 +++-
9 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java b/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java
index 7740b17e35..ce94e16d34 100644
--- a/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java
+++ b/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java
@@ -55,8 +55,7 @@ class BtcNodeConverter {
PeerAddress convertOnionHost(BtcNode node) {
// no DNS lookup for onion addresses
String onionAddress = Objects.requireNonNull(node.getOnionAddress());
- PeerAddress result = new PeerAddress(onionAddress, node.getPort());
- return result;
+ return new PeerAddress(onionAddress, node.getPort());
}
@Nullable
@@ -69,7 +68,7 @@ class BtcNodeConverter {
if (address != null) {
result = create(address, port);
} else {
- log.warn("Lookup failed, no address for node", node);
+ log.warn("Lookup failed, no address for node {}", node);
}
}
return result;
@@ -85,7 +84,7 @@ class BtcNodeConverter {
if (address != null) {
result = create(proxy, address, port);
} else {
- log.warn("Lookup failed, no address for node", node);
+ log.warn("Lookup failed, no address for node {}", node);
}
}
return result;
diff --git a/core/src/main/java/bisq/core/btc/setup/BisqKeyChainFactory.java b/core/src/main/java/bisq/core/btc/setup/BisqKeyChainFactory.java
index 5c31e0d64c..7c576a3c84 100644
--- a/core/src/main/java/bisq/core/btc/setup/BisqKeyChainFactory.java
+++ b/core/src/main/java/bisq/core/btc/setup/BisqKeyChainFactory.java
@@ -26,7 +26,6 @@ import org.bitcoinj.wallet.DeterministicKeyChain;
import org.bitcoinj.wallet.DeterministicSeed;
import org.bitcoinj.wallet.KeyChainGroupStructure;
import org.bitcoinj.wallet.Protos;
-import org.bitcoinj.wallet.UnreadableWalletException;
import com.google.common.collect.ImmutableList;
@@ -63,12 +62,12 @@ public class BisqKeyChainFactory extends DefaultKeyChainFactory {
}
@Override
- public DeterministicKeyChain makeWatchingKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicKey accountKey, boolean isFollowingKey, boolean isMarried, Script.ScriptType outputScriptType) throws UnreadableWalletException {
+ public DeterministicKeyChain makeWatchingKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicKey accountKey, boolean isFollowingKey, boolean isMarried, Script.ScriptType outputScriptType) {
throw new UnsupportedOperationException("Bisq is not supposed to use this");
}
@Override
- public DeterministicKeyChain makeSpendingKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicKey accountKey, boolean isMarried, Script.ScriptType outputScriptType) throws UnreadableWalletException {
+ public DeterministicKeyChain makeSpendingKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicKey accountKey, boolean isMarried, Script.ScriptType outputScriptType) {
throw new UnsupportedOperationException("Bisq is not supposed to use this");
}
}
diff --git a/core/src/main/java/bisq/core/btc/setup/WalletConfig.java b/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
index 13f18dd4f7..d181d0d463 100644
--- a/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
+++ b/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
@@ -20,6 +20,7 @@ package bisq.core.btc.setup;
import bisq.core.btc.nodes.LocalBitcoinNode;
import bisq.core.btc.nodes.ProxySocketFactory;
import bisq.core.btc.wallet.BisqRiskAnalysis;
+
import bisq.common.config.Config;
import com.google.common.collect.*;
@@ -124,8 +125,7 @@ public class WalletConfig extends AbstractIdleService {
/**
* Creates a new WalletConfig, with the given {@link Context}. Files will be stored in the given directory.
*/
- public WalletConfig(Context context,
- File directory, String filePrefix) {
+ public WalletConfig(Context context, File directory, String filePrefix) {
this.context = context;
this.params = checkNotNull(context.getParams());
this.directory = checkDir(directory);
@@ -275,7 +275,7 @@ public class WalletConfig extends AbstractIdleService {
* When this is called, chain(), store(), and peerGroup() will return the created objects, however they are not
* initialized/started.
*/
- protected List provideWalletExtensions() throws Exception {
+ protected List provideWalletExtensions() {
return ImmutableList.of();
}
@@ -413,8 +413,8 @@ public class WalletConfig extends AbstractIdleService {
@Override
public void onSuccess(@Nullable Object result) {
//completeExtensionInitiations(vPeerGroup);
- final DownloadProgressTracker l = downloadListener == null ? new DownloadProgressTracker() : downloadListener;
- vPeerGroup.startBlockChainDownload(l);
+ DownloadProgressTracker tracker = downloadListener == null ? new DownloadProgressTracker() : downloadListener;
+ vPeerGroup.startBlockChainDownload(tracker);
}
@Override
diff --git a/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java b/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
index 1f3cc0aab3..3ead34decb 100644
--- a/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
+++ b/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
@@ -249,7 +249,7 @@ public class WalletsSetup {
UserThread.execute(() -> {
addressEntryList.onWalletReady(walletConfig.btcWallet());
timeoutTimer.stop();
- setupCompletedHandlers.stream().forEach(Runnable::run);
+ setupCompletedHandlers.forEach(Runnable::run);
});
// onSetupCompleted in walletAppKit is not the called on the last invocations, so we add a bit of delay
diff --git a/core/src/main/java/bisq/core/btc/wallet/BtcWalletService.java b/core/src/main/java/bisq/core/btc/wallet/BtcWalletService.java
index d75e4f273b..bb92c92187 100644
--- a/core/src/main/java/bisq/core/btc/wallet/BtcWalletService.java
+++ b/core/src/main/java/bisq/core/btc/wallet/BtcWalletService.java
@@ -123,7 +123,7 @@ public class BtcWalletService extends WalletService {
@Override
void encryptWallet(KeyCrypterScrypt keyCrypterScrypt, KeyParameter key) {
super.encryptWallet(keyCrypterScrypt, key);
- addressEntryList.getAddressEntriesAsListImmutable().stream().forEach(e -> {
+ addressEntryList.getAddressEntriesAsListImmutable().forEach(e -> {
DeterministicKey keyPair = e.getKeyPair();
if (keyPair.isEncrypted())
e.setDeterministicKey(keyPair.encrypt(keyCrypterScrypt, key));
@@ -134,7 +134,7 @@ public class BtcWalletService extends WalletService {
@Override
String getWalletAsString(boolean includePrivKeys) {
StringBuilder sb = new StringBuilder();
- getAddressEntryListAsImmutableList().stream().forEach(e -> sb.append(e.toString()).append("\n"));
+ getAddressEntryListAsImmutableList().forEach(e -> sb.append(e.toString()).append("\n"));
return "Address entry list:\n" +
sb.toString() +
"\n\n" +
diff --git a/core/src/main/java/bisq/core/btc/wallet/WalletService.java b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
index a91c2ed619..7575f69b63 100644
--- a/core/src/main/java/bisq/core/btc/wallet/WalletService.java
+++ b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
@@ -38,8 +38,6 @@ import org.bitcoinj.core.Context;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.InsufficientMoneyException;
import org.bitcoinj.core.NetworkParameters;
-import org.bitcoinj.core.listeners.TransactionConfidenceEventListener;
-import org.bitcoinj.script.ScriptException;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
@@ -47,12 +45,14 @@ import org.bitcoinj.core.TransactionInput;
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.core.VerificationException;
import org.bitcoinj.core.listeners.NewBestBlockListener;
+import org.bitcoinj.core.listeners.TransactionConfidenceEventListener;
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.crypto.KeyCrypter;
import org.bitcoinj.crypto.KeyCrypterScrypt;
import org.bitcoinj.crypto.TransactionSignature;
import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptChunk;
+import org.bitcoinj.script.ScriptException;
import org.bitcoinj.script.ScriptPattern;
import org.bitcoinj.signers.TransactionSigner;
import org.bitcoinj.utils.Threading;
@@ -106,7 +106,6 @@ public abstract class WalletService {
protected final Preferences preferences;
protected final FeeService feeService;
protected final NetworkParameters params;
- @SuppressWarnings("deprecation")
protected final BisqWalletListener walletEventListener = new BisqWalletListener();
protected final CopyOnWriteArraySet addressConfidenceListeners = new CopyOnWriteArraySet<>();
protected final CopyOnWriteArraySet txConfidenceListeners = new CopyOnWriteArraySet<>();
diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalFactory.java b/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalFactory.java
index 2ed73422e0..53c2967feb 100644
--- a/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalFactory.java
+++ b/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalFactory.java
@@ -74,7 +74,7 @@ public abstract class BaseProposalFactory {
R proposal = createProposalWithoutTxId();
proposalValidator.validateDataFields(proposal);
Transaction transaction = createTransaction(proposal);
- final Proposal proposalWithTxId = proposal.cloneProposalAndAddTxId(transaction.getTxId().toString());
+ Proposal proposalWithTxId = proposal.cloneProposalAndAddTxId(transaction.getTxId().toString());
return new ProposalWithTransaction(proposalWithTxId, transaction);
}
diff --git a/core/src/main/java/bisq/core/trade/Trade.java b/core/src/main/java/bisq/core/trade/Trade.java
index 4f0f900a38..26140812ab 100644
--- a/core/src/main/java/bisq/core/trade/Trade.java
+++ b/core/src/main/java/bisq/core/trade/Trade.java
@@ -952,7 +952,8 @@ public abstract class Trade implements Tradable, Model {
log.debug("We set the start for the trade period to {}. Trade started at: {}. Block got mined at: {}",
new Date(startTime), new Date(tradeTime), new Date(blockTime));
} else {
- log.debug("depositTx not confirmed yet. We don't start counting remaining trade period yet. txId={}", depositTx.getTxId().toString());
+ log.debug("depositTx not confirmed yet. We don't start counting remaining trade period yet. txId={}",
+ depositTx.getTxId().toString());
startTime = now;
}
} else {
diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/SelectDepositTxWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/SelectDepositTxWindow.java
index aa50f23ab8..c736c02476 100644
--- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/SelectDepositTxWindow.java
+++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/SelectDepositTxWindow.java
@@ -104,7 +104,9 @@ public class SelectDepositTxWindow extends Overlay {
});
transactionsComboBox.setItems(FXCollections.observableArrayList(transactions));
transactionsComboBox.setOnAction(event -> {
- selectHandlerOptional.get().accept(transactionsComboBox.getSelectionModel().getSelectedItem());
+ if (selectHandlerOptional.isPresent()) {
+ selectHandlerOptional.get().accept(transactionsComboBox.getSelectionModel().getSelectedItem());
+ }
hide();
});
}
From 64dc4fbf8401fe5a930db044423e18e939d2d5be Mon Sep 17 00:00:00 2001
From: Oscar Guindzberg
Date: Mon, 21 Sep 2020 18:17:12 -0300
Subject: [PATCH 09/17] Remove unused code from WalletConfig
---
.../bisq/core/btc/setup/WalletConfig.java | 192 ++----------------
.../bisq/core/btc/setup/WalletsSetup.java | 7 +-
2 files changed, 25 insertions(+), 174 deletions(-)
diff --git a/core/src/main/java/bisq/core/btc/setup/WalletConfig.java b/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
index d181d0d463..48d1d9e922 100644
--- a/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
+++ b/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
@@ -55,9 +55,7 @@ import static com.google.common.base.Preconditions.*;
/**
* Utility class that wraps the boilerplate needed to set up a new SPV bitcoinj app. Instantiate it with a directory
* and file prefix, optionally configure a few things, then use startAsync and optionally awaitRunning. The object will
- * construct and configure a {@link BlockChain}, {@link SPVBlockStore}, {@link Wallet} and {@link PeerGroup}. Depending
- * on the value of the blockingStartup property, startup will be considered complete once the block chain has fully
- * synchronized, so it can take a while.
+ * construct and configure a {@link BlockChain}, {@link SPVBlockStore}, {@link Wallet} and {@link PeerGroup}.
*
* To add listeners and modify the objects that are constructed, you can either do that by overriding the
* {@link #onSetupCompleted()} method (which will run on a background thread) and make your changes there,
@@ -93,16 +91,12 @@ public class WalletConfig extends AbstractIdleService {
protected volatile File vBtcWalletFile;
protected volatile File vBsqWalletFile;
- protected boolean useAutoSave = true;
protected PeerAddress[] peerAddresses;
protected DownloadProgressTracker downloadListener;
- protected boolean autoStop = true;
protected InputStream checkpoints;
- protected boolean blockingStartup = true;
protected String userAgent, version;
protected WalletProtobufSerializer.WalletFactory walletFactory;
@Nullable protected DeterministicSeed restoreFromSeed;
- @Nullable protected DeterministicKey restoreFromKey;
@Nullable protected PeerDiscovery discovery;
protected volatile Context context;
@@ -125,7 +119,7 @@ public class WalletConfig extends AbstractIdleService {
/**
* Creates a new WalletConfig, with the given {@link Context}. Files will be stored in the given directory.
*/
- public WalletConfig(Context context, File directory, String filePrefix) {
+ private WalletConfig(Context context, File directory, String filePrefix) {
this.context = context;
this.params = checkNotNull(context.getParams());
this.directory = checkDir(directory);
@@ -170,29 +164,15 @@ public class WalletConfig extends AbstractIdleService {
return setPeerNodes(new PeerAddress(params, localHost, params.getPort()));
}
- /** If true, the wallet will save itself to disk automatically whenever it changes. */
- public WalletConfig setAutoSave(boolean value) {
- checkState(state() == State.NEW, "Cannot call after startup");
- useAutoSave = value;
- return this;
- }
-
/**
* If you want to learn about the sync process, you can provide a listener here. For instance, a
- * {@link DownloadProgressTracker} is a good choice. This has no effect unless setBlockingStartup(false) has been called
- * too, due to some missing implementation code.
+ * {@link DownloadProgressTracker} is a good choice.
*/
public WalletConfig setDownloadListener(DownloadProgressTracker listener) {
this.downloadListener = listener;
return this;
}
- /** If true, will register a shutdown hook to stop the library. Defaults to true. */
- public WalletConfig setAutoStop(boolean autoStop) {
- this.autoStop = autoStop;
- return this;
- }
-
/**
* If set, the file is expected to contain a checkpoints file calculated with BuildCheckpoints. It makes initial
* block sync faster for new users - please refer to the documentation on the bitcoinj website
@@ -205,17 +185,6 @@ public class WalletConfig extends AbstractIdleService {
return this;
}
- /**
- * If true (the default) then the startup of this service won't be considered complete until the network has been
- * brought up, peer connections established and the block chain synchronised. Therefore {@link #awaitRunning()} can
- * potentially take a very long time. If false, then startup is considered complete once the network activity
- * begins and peer connections/block chain sync will continue in the background.
- */
- public WalletConfig setBlockingStartup(boolean blockingStartup) {
- this.blockingStartup = blockingStartup;
- return this;
- }
-
/**
* Sets the string that will appear in the subver field of the version message.
* @param userAgent A short string that should be the name of your app, e.g. "My Wallet"
@@ -227,14 +196,6 @@ public class WalletConfig extends AbstractIdleService {
return this;
}
- /**
- * Sets a wallet factory which will be used when the kit creates a new wallet.
- */
- public WalletConfig setWalletFactory(WalletProtobufSerializer.WalletFactory walletFactory) {
- this.walletFactory = walletFactory;
- return this;
- }
-
/**
* If a seed is set here then any existing wallet that matches the file name will be renamed to a backup name,
* the chain file will be deleted, and the wallet object will be instantiated with the given seed instead of
@@ -248,19 +209,6 @@ public class WalletConfig extends AbstractIdleService {
return this;
}
- /**
- * If an account key is set here then any existing wallet that matches the file name will be renamed to a backup name,
- * the chain file will be deleted, and the wallet object will be instantiated with the given key instead of
- * a fresh seed being created. This is intended for restoring a wallet from an account key. To implement restore
- * you would shut down the existing appkit, if any, then recreate it with the key given by the user, then start
- * up the new kit. The next time your app starts it should work as normal (that is, don't keep calling this each
- * time).
- */
- public WalletConfig restoreWalletFromKey(DeterministicKey accountKey) {
- this.restoreFromKey = accountKey;
- return this;
- }
-
/**
* Sets the peer discovery class to use. If none is provided then DNS is used, which is a reasonable default.
*/
@@ -269,16 +217,6 @@ public class WalletConfig extends AbstractIdleService {
return this;
}
- /**
- *
Override this to return wallet extensions if any are necessary.
- *
- * When this is called, chain(), store(), and peerGroup() will return the created objects, however they are not
- * initialized/started.
- */
- protected List provideWalletExtensions() {
- return ImmutableList.of();
- }
-
/**
* This method is invoked on a background thread after all objects are initialised, but before the peer group
* or block chain download is started. You can tweak the objects configuration here.
@@ -287,49 +225,17 @@ public class WalletConfig extends AbstractIdleService {
// Meant to be overridden by subclasses
}
- /**
- * Tests to see if the spvchain file has an operating system file lock on it. Useful for checking if your app
- * is already running. If another copy of your app is running and you start the appkit anyway, an exception will
- * be thrown during the startup process. Returns false if the chain file does not exist or is a directory.
- */
- public boolean isChainFileLocked() throws IOException {
- RandomAccessFile file2 = null;
- try {
- File file = new File(directory, filePrefix + ".spvchain");
- if (!file.exists())
- return false;
- if (file.isDirectory())
- return false;
- file2 = new RandomAccessFile(file, "rw");
- FileLock lock = file2.getChannel().tryLock();
- if (lock == null)
- return true;
- lock.release();
- return false;
- } finally {
- if (file2 != null)
- file2.close();
- }
- }
-
@Override
protected void startUp() throws Exception {
// Runs in a separate thread.
Context.propagate(context);
- // bitcoinj's WalletAppKit creates the wallet directory if it was not created already,
- // but WalletConfig should not do that.
- // if (!directory.exists()) {
- // if (!directory.mkdirs()) {
- // throw new IOException("Could not create directory " + directory.getAbsolutePath());
- // }
- // }
log.info("Starting up with directory = {}", directory);
try {
File chainFile = new File(directory, filePrefix + ".spvchain");
boolean chainFileExists = chainFile.exists();
String btcPrefix = "_BTC";
vBtcWalletFile = new File(directory, filePrefix + btcPrefix + ".wallet");
- boolean shouldReplayWallet = (vBtcWalletFile.exists() && !chainFileExists) || restoreFromSeed != null || restoreFromKey != null;
+ boolean shouldReplayWallet = (vBtcWalletFile.exists() && !chainFileExists) || restoreFromSeed != null;
vBtcWallet = createOrLoadWallet(shouldReplayWallet, vBtcWalletFile, false);
vBtcWallet.allowSpendingUnconfirmedTransactions();
vBtcWallet.setRiskAnalyzer(new BisqRiskAnalysis.Analyzer());
@@ -341,8 +247,8 @@ public class WalletConfig extends AbstractIdleService {
// Initiate Bitcoin network objects (block store, blockchain and peer group)
vStore = new SPVBlockStore(params, chainFile);
- if (!chainFileExists || restoreFromSeed != null || restoreFromKey != null) {
- if (checkpoints == null && !Utils.isAndroidRuntime()) {
+ if (!chainFileExists || restoreFromSeed != null) {
+ if (checkpoints == null) {
checkpoints = CheckpointManager.openStream(params);
}
@@ -355,12 +261,6 @@ public class WalletConfig extends AbstractIdleService {
log.info("Clearing the chain file in preparation for restore.");
vStore.clear();
}
- } else if (restoreFromKey != null) {
- time = restoreFromKey.getCreationTimeSeconds();
- if (chainFileExists) {
- log.info("Clearing the chain file in preparation for restore.");
- vStore.clear();
- }
} else {
time = vBtcWallet.getEarliestKeyCreationTime();
}
@@ -398,32 +298,20 @@ public class WalletConfig extends AbstractIdleService {
vPeerGroup.addWallet(vBsqWallet);
onSetupCompleted();
- if (blockingStartup) {
- vPeerGroup.start();
- // Make sure we shut down cleanly.
- installShutdownHook();
- //completeExtensionInitiations(vPeerGroup);
+ Futures.addCallback((ListenableFuture>) vPeerGroup.startAsync(), new FutureCallback() {
+ @Override
+ public void onSuccess(@Nullable Object result) {
+ //completeExtensionInitiations(vPeerGroup);
+ DownloadProgressTracker tracker = downloadListener == null ? new DownloadProgressTracker() : downloadListener;
+ vPeerGroup.startBlockChainDownload(tracker);
+ }
- // TODO: Be able to use the provided download listener when doing a blocking startup.
- final DownloadProgressTracker listener = new DownloadProgressTracker();
- vPeerGroup.startBlockChainDownload(listener);
- listener.await();
- } else {
- Futures.addCallback((ListenableFuture>) vPeerGroup.startAsync(), new FutureCallback() {
- @Override
- public void onSuccess(@Nullable Object result) {
- //completeExtensionInitiations(vPeerGroup);
- DownloadProgressTracker tracker = downloadListener == null ? new DownloadProgressTracker() : downloadListener;
- vPeerGroup.startBlockChainDownload(tracker);
- }
+ @Override
+ public void onFailure(Throwable t) {
+ throw new RuntimeException(t);
- @Override
- public void onFailure(Throwable t) {
- throw new RuntimeException(t);
-
- }
- }, MoreExecutors.directExecutor());
- }
+ }
+ }, MoreExecutors.directExecutor());
} catch (BlockStoreException e) {
throw new IOException(e);
}
@@ -439,9 +327,6 @@ public class WalletConfig extends AbstractIdleService {
} else {
wallet = createWallet(isBsqWallet);
wallet.freshReceiveKey();
- for (WalletExtension e : provideWalletExtensions()) {
- wallet.addExtension(e);
- }
// Currently the only way we can be sure that an extension is aware of its containing wallet is by
// deserializing the extension (see WalletExtension#deserializeWalletExtension(Wallet, byte[]))
@@ -450,9 +335,7 @@ public class WalletConfig extends AbstractIdleService {
wallet = loadWallet(false, walletFile, isBsqWallet);
}
- if (useAutoSave) {
- this.setupAutoSave(wallet, walletFile);
- }
+ this.setupAutoSave(wallet, walletFile);
return wallet;
}
@@ -465,8 +348,7 @@ public class WalletConfig extends AbstractIdleService {
Wallet wallet;
FileInputStream walletStream = new FileInputStream(walletFile);
try {
- List extensions = provideWalletExtensions();
- WalletExtension[] extArray = extensions.toArray(new WalletExtension[extensions.size()]);
+ WalletExtension[] extArray = new WalletExtension[]{};
Protos.Wallet proto = WalletProtobufSerializer.parseToProto(walletStream);
final WalletProtobufSerializer serializer;
if (walletFactory != null)
@@ -492,8 +374,6 @@ public class WalletConfig extends AbstractIdleService {
KeyChainGroup.Builder kcg = KeyChainGroup.builder(params, structure);
if (restoreFromSeed != null) {
kcg.fromSeed(restoreFromSeed, preferredOutputScriptType).build();
- } else if (restoreFromKey != null) {
- kcg.addChain(DeterministicKeyChain.builder().spend(restoreFromKey).outputScriptType(preferredOutputScriptType).build());
} else {
// new wallet
if (!isBsqWallet) {
@@ -512,7 +392,7 @@ public class WalletConfig extends AbstractIdleService {
}
private void maybeMoveOldWalletOutOfTheWay(File walletFile) {
- if (restoreFromSeed == null && restoreFromKey == null) return;
+ if (restoreFromSeed == null) return;
if (!walletFile.exists()) return;
int counter = 1;
File newName;
@@ -527,23 +407,6 @@ public class WalletConfig extends AbstractIdleService {
}
}
- /*
- * As soon as the transaction broadcaster han been created we will pass it to the
- * payment channel extensions
- */
- // private void completeExtensionInitiations(TransactionBroadcaster transactionBroadcaster) {
- // StoredPaymentChannelClientStates clientStoredChannels = (StoredPaymentChannelClientStates)
- // vWallet.getExtensions().get(StoredPaymentChannelClientStates.class.getName());
- // if(clientStoredChannels != null) {
- // clientStoredChannels.setTransactionBroadcaster(transactionBroadcaster);
- // }
- // StoredPaymentChannelServerStates serverStoredChannels = (StoredPaymentChannelServerStates)
- // vWallet.getExtensions().get(StoredPaymentChannelServerStates.class.getName());
- // if(serverStoredChannels != null) {
- // serverStoredChannels.setTransactionBroadcaster(transactionBroadcaster);
- // }
- // }
-
private PeerGroup createPeerGroup() {
PeerGroup peerGroup;
// no proxy case.
@@ -573,19 +436,6 @@ public class WalletConfig extends AbstractIdleService {
return peerGroup;
}
- private void installShutdownHook() {
- if (autoStop) Runtime.getRuntime().addShutdownHook(new Thread("WalletConfig ShutdownHook") {
- @Override public void run() {
- try {
- WalletConfig.this.stopAsync();
- WalletConfig.this.awaitTerminated();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- });
- }
-
@Override
protected void shutDown() throws Exception {
// Runs in a separate thread.
diff --git a/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java b/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
index 3ead34decb..e94e65bbea 100644
--- a/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
+++ b/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
@@ -307,11 +307,12 @@ public class WalletsSetup {
}
}
- walletConfig.setDownloadListener(downloadListener)
- .setBlockingStartup(false);
+ walletConfig.setDownloadListener(downloadListener);
// If seed is non-null it means we are restoring from backup.
- walletConfig.restoreWalletFromSeed(seed);
+ if (seed != null) {
+ walletConfig.restoreWalletFromSeed(seed);
+ }
walletConfig.addListener(new Service.Listener() {
@Override
From ca00433492f9b3a828cf08ffb9c090a255ba58da Mon Sep 17 00:00:00 2001
From: wiz
Date: Tue, 22 Sep 2020 06:30:14 +0900
Subject: [PATCH 10/17] Set btcdcli4j loglevel to WARN for statsnode
entrypoint, fixes #4537
---
statsnode/src/main/resources/logback.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/statsnode/src/main/resources/logback.xml b/statsnode/src/main/resources/logback.xml
index 5cabc40449..a4685e4d70 100644
--- a/statsnode/src/main/resources/logback.xml
+++ b/statsnode/src/main/resources/logback.xml
@@ -14,5 +14,6 @@
+
From 86c62c13331a9d76627a14b9f861e061d3188957 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 22 Sep 2020 11:16:53 -0300
Subject: [PATCH 11/17] Revert WalletService change (accessor breaks build)
The accessor added in commit e2bd89f broke the build, and was not
used as originally intended -- by CoreWalletsService -- because the
the api's wallet methods need addresses from the wallet, not just
a valid address.
---
.../src/main/java/bisq/core/btc/wallet/WalletService.java | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/core/src/main/java/bisq/core/btc/wallet/WalletService.java b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
index 4d8ecd729a..ed2dd15367 100644
--- a/core/src/main/java/bisq/core/btc/wallet/WalletService.java
+++ b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
@@ -38,8 +38,6 @@ import org.bitcoinj.core.Context;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.InsufficientMoneyException;
import org.bitcoinj.core.NetworkParameters;
-import org.bitcoinj.core.listeners.TransactionConfidenceEventListener;
-import org.bitcoinj.script.ScriptException;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
@@ -47,12 +45,14 @@ import org.bitcoinj.core.TransactionInput;
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.core.VerificationException;
import org.bitcoinj.core.listeners.NewBestBlockListener;
+import org.bitcoinj.core.listeners.TransactionConfidenceEventListener;
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.crypto.KeyCrypter;
import org.bitcoinj.crypto.KeyCrypterScrypt;
import org.bitcoinj.crypto.TransactionSignature;
import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptChunk;
+import org.bitcoinj.script.ScriptException;
import org.bitcoinj.script.ScriptPattern;
import org.bitcoinj.signers.TransactionSigner;
import org.bitcoinj.utils.Threading;
@@ -793,10 +793,6 @@ public abstract class WalletService {
return maybeAddTxToWallet(transaction.bitcoinSerialize(), wallet, source);
}
- public Address getAddress(String addressString) {
- return Address.fromBase58(params, addressString);
- }
-
///////////////////////////////////////////////////////////////////////////////////////////
// bisqWalletEventListener
///////////////////////////////////////////////////////////////////////////////////////////
From c1c9ff3de8424c0e3d861a31a538ad6ff1a52efb Mon Sep 17 00:00:00 2001
From: Oscar Guindzberg
Date: Tue, 22 Sep 2020 14:07:31 -0300
Subject: [PATCH 12/17] Fix logging message
---
core/src/main/java/bisq/core/btc/wallet/WalletService.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/core/src/main/java/bisq/core/btc/wallet/WalletService.java b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
index 9c81181df8..253d26daa8 100644
--- a/core/src/main/java/bisq/core/btc/wallet/WalletService.java
+++ b/core/src/main/java/bisq/core/btc/wallet/WalletService.java
@@ -507,17 +507,17 @@ public abstract class WalletService {
sendRequest.feePerKb = getTxFeeForWithdrawalPerByte().multiply(1000);
sendRequest.aesKey = aesKey;
Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
- printTx("empty wallet", sendResult.tx);
+ printTx("empty btc wallet", sendResult.tx);
Futures.addCallback(sendResult.broadcastComplete, new FutureCallback() {
@Override
public void onSuccess(Transaction result) {
- log.info("emptyWallet onSuccess Transaction=" + result);
+ log.info("emptyBtcWallet onSuccess Transaction=" + result);
resultHandler.handleResult();
}
@Override
public void onFailure(@NotNull Throwable t) {
- log.error("emptyWallet onFailure " + t.toString());
+ log.error("emptyBtcWallet onFailure " + t.toString());
errorMessageHandler.handleErrorMessage(t.getMessage());
}
}, MoreExecutors.directExecutor());
From 59124e3e33edb3042570d27e1c8bf0694c1367d6 Mon Sep 17 00:00:00 2001
From: Oscar Guindzberg
Date: Mon, 14 Sep 2020 16:58:47 -0300
Subject: [PATCH 13/17] Replace deprecated bitcoinj methods
Replace output.getAddressFromP2PKHScript() and
output.getAddressFromP2SH() with
output.getScriptPubKey().getToAddress()
---
.../java/bisq/core/btc/model/AddressEntryList.java | 2 +-
.../bisq/core/trade/DelayedPayoutTxValidation.java | 14 +++++---------
.../tasks/buyer/BuyerSetupDepositTxListener.java | 2 +-
.../funds/transactions/TransactionAwareTrade.java | 2 +-
4 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/core/src/main/java/bisq/core/btc/model/AddressEntryList.java b/core/src/main/java/bisq/core/btc/model/AddressEntryList.java
index a3fea3bd40..913a8e996a 100644
--- a/core/src/main/java/bisq/core/btc/model/AddressEntryList.java
+++ b/core/src/main/java/bisq/core/btc/model/AddressEntryList.java
@@ -211,7 +211,7 @@ public final class AddressEntryList implements UserThreadMappedPersistableEnvelo
private void maybeAddNewAddressEntry(Transaction tx) {
tx.getOutputs().stream()
.filter(output -> output.isMine(wallet))
- .map(output -> output.getAddressFromP2PKHScript(wallet.getNetworkParameters()))
+ .map(output -> output.getScriptPubKey().getToAddress(wallet.getNetworkParameters()))
.filter(Objects::nonNull)
.filter(this::isAddressNotInEntries)
.map(address -> (DeterministicKey) wallet.findKeyFromPubKeyHash(address.getHash(),
diff --git a/core/src/main/java/bisq/core/trade/DelayedPayoutTxValidation.java b/core/src/main/java/bisq/core/trade/DelayedPayoutTxValidation.java
index 088716b806..f2eec5988a 100644
--- a/core/src/main/java/bisq/core/trade/DelayedPayoutTxValidation.java
+++ b/core/src/main/java/bisq/core/trade/DelayedPayoutTxValidation.java
@@ -146,16 +146,12 @@ public class DelayedPayoutTxValidation {
NetworkParameters params = btcWalletService.getParams();
- Address address = output.getAddressFromP2PKHScript(params);
+ Address address = output.getScriptPubKey().getToAddress(params);
if (address == null) {
- // The donation address can be as well be a multisig address.
- address = output.getAddressFromP2SH(params);
- if (address == null) {
- errorMsg = "Donation address cannot be resolved (not of type P2PKHScript or P2SH). Output: " + output;
- log.error(errorMsg);
- log.error(delayedPayoutTx.toString());
- throw new DonationAddressException(errorMsg);
- }
+ errorMsg = "Donation address cannot be resolved (not of type P2PK nor P2SH nor P2WH). Output: " + output;
+ log.error(errorMsg);
+ log.error(delayedPayoutTx.toString());
+ throw new DonationAddressException(errorMsg);
}
String addressAsString = address.toString();
diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupDepositTxListener.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupDepositTxListener.java
index 454761b4ae..27df62128e 100644
--- a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupDepositTxListener.java
+++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerSetupDepositTxListener.java
@@ -59,7 +59,7 @@ public class BuyerSetupDepositTxListener extends TradeTask {
final NetworkParameters params = walletService.getParams();
Transaction preparedDepositTx = new Transaction(params, processModel.getPreparedDepositTx());
checkArgument(!preparedDepositTx.getOutputs().isEmpty(), "preparedDepositTx.getOutputs() must not be empty");
- Address depositTxAddress = preparedDepositTx.getOutput(0).getAddressFromP2SH(params);
+ Address depositTxAddress = preparedDepositTx.getOutput(0).getScriptPubKey().getToAddress(params);
final TransactionConfidence confidence = walletService.getConfidenceForAddress(depositTxAddress);
if (isInNetwork(confidence)) {
applyConfidence(confidence);
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionAwareTrade.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionAwareTrade.java
index d609621908..c357d2630b 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionAwareTrade.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionAwareTrade.java
@@ -157,7 +157,7 @@ class TransactionAwareTrade implements TransactionAwareTradable {
tx.getOutputs().forEach(txo -> {
if (btcWalletService.isTransactionOutputMine(txo)) {
try {
- Address receiverAddress = txo.getAddressFromP2PKHScript(btcWalletService.getParams());
+ Address receiverAddress = txo.getScriptPubKey().getToAddress(btcWalletService.getParams());
Contract contract = checkNotNull(trade.getContract());
String myPayoutAddressString = contract.isMyRoleBuyer(pubKeyRing) ?
contract.getBuyerPayoutAddressString() :
From abcd0653255915c460d85b986c3e768f0edaa7e7 Mon Sep 17 00:00:00 2001
From: Oscar Guindzberg
Date: Tue, 15 Sep 2020 16:19:42 -0300
Subject: [PATCH 14/17] DAO setup doc fix
Stress a full dao seed node is required to run lite nodes.
---
docs/dao-setup.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docs/dao-setup.md b/docs/dao-setup.md
index 098ce925e3..a21272df93 100644
--- a/docs/dao-setup.md
+++ b/docs/dao-setup.md
@@ -108,6 +108,8 @@ Full node mode:
Lite node mode:
+Note: At least one seed node must be running as a full DAO node to support other lite nodes.
+
`--daoActivated=true --genesisBlockHeight=111 --genesisTxId=30af0050040befd8af25068cc697e418e09c2d8ebd8d411d2240591b9ec203cf --baseCurrencyNetwork=BTC_REGTEST --useDevPrivilegeKeys=true --useLocalhostForP2P=true --nodePort=8888 --appName=bisq-BTC_REGTEST_Bob_dao`
_Don't forget to use different rpcBlockNotificationPorts for different full node instances, otherwise only one node will receive the new block event forwarded to that port._
From f37446b9919a9905d5c7dda97ea983924bcf52af Mon Sep 17 00:00:00 2001
From: chimp1984
Date: Fri, 25 Sep 2020 09:39:45 -0500
Subject: [PATCH 15/17] Change log level
---
.../src/main/java/bisq/core/support/dispute/DisputeManager.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/src/main/java/bisq/core/support/dispute/DisputeManager.java b/core/src/main/java/bisq/core/support/dispute/DisputeManager.java
index bd1a33d0cc..c5dbe54b09 100644
--- a/core/src/main/java/bisq/core/support/dispute/DisputeManager.java
+++ b/core/src/main/java/bisq/core/support/dispute/DisputeManager.java
@@ -388,7 +388,7 @@ public abstract class DisputeManager
Date: Fri, 25 Sep 2020 14:23:06 -0500
Subject: [PATCH 16/17] Commit to trigger travis as it got stuck...
---
.../src/main/java/bisq/core/support/dispute/DisputeManager.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/src/main/java/bisq/core/support/dispute/DisputeManager.java b/core/src/main/java/bisq/core/support/dispute/DisputeManager.java
index c5dbe54b09..bc4f53c603 100644
--- a/core/src/main/java/bisq/core/support/dispute/DisputeManager.java
+++ b/core/src/main/java/bisq/core/support/dispute/DisputeManager.java
@@ -388,7 +388,7 @@ public abstract class DisputeManager
Date: Fri, 25 Sep 2020 15:01:20 -0500
Subject: [PATCH 17/17] Add changes from merge conflict (class was renamed)
---
.../bisq/core/trade/DelayedPayoutTxValidation.java | 0
.../java/bisq/core/trade/TradeDataValidation.java | 14 +++++---------
2 files changed, 5 insertions(+), 9 deletions(-)
delete mode 100644 core/src/main/java/bisq/core/trade/DelayedPayoutTxValidation.java
diff --git a/core/src/main/java/bisq/core/trade/DelayedPayoutTxValidation.java b/core/src/main/java/bisq/core/trade/DelayedPayoutTxValidation.java
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/core/src/main/java/bisq/core/trade/TradeDataValidation.java b/core/src/main/java/bisq/core/trade/TradeDataValidation.java
index eea5799225..993759b873 100644
--- a/core/src/main/java/bisq/core/trade/TradeDataValidation.java
+++ b/core/src/main/java/bisq/core/trade/TradeDataValidation.java
@@ -291,16 +291,12 @@ public class TradeDataValidation {
}
NetworkParameters params = btcWalletService.getParams();
- Address address = output.getAddressFromP2PKHScript(params);
+ Address address = output.getScriptPubKey().getToAddress(params);
if (address == null) {
- // The donation address can be a multisig address as well.
- address = output.getAddressFromP2SH(params);
- if (address == null) {
- errorMsg = "Donation address cannot be resolved (not of type P2PKHScript or P2SH). Output: " + output;
- log.error(errorMsg);
- log.error(delayedPayoutTx.toString());
- throw new AddressException(dispute, errorMsg);
- }
+ errorMsg = "Donation address cannot be resolved (not of type P2PK nor P2SH nor P2WH). Output: " + output;
+ log.error(errorMsg);
+ log.error(delayedPayoutTx.toString());
+ throw new AddressException(dispute, errorMsg);
}
String addressAsString = address.toString();