Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues with DAO full mode in preferences #2736

1 change: 1 addition & 0 deletions common/src/main/proto/pb.proto
Expand Up @@ -1351,6 +1351,7 @@ message PreferencesPayload {
string rpc_pw = 48;
string take_offer_selected_payment_account_id = 49;
double buyer_security_deposit_as_percent = 50;
int32 block_notify_port = 51;
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/bisq/core/app/P2PNetworkSetup.java
Expand Up @@ -87,6 +87,7 @@ BooleanProperty init(Runnable initWalletServiceHandler, @Nullable Consumer<Boole
p2PNetworkInfoBinding = EasyBind.combine(bootstrapState, bootstrapWarning, p2PService.getNumConnectedPeers(), hiddenServicePublished, initialP2PNetworkDataReceived,
(state, warning, numPeers, hiddenService, dataReceived) -> {
String result;
String daoFullNode = preferences.isDaoFullNode() ? Res.get("mainView.footer.daoFullNode") + " / " : "";
int peers = (int) numPeers;
if (warning != null && peers == 0) {
result = warning;
Expand All @@ -99,7 +100,7 @@ BooleanProperty init(Runnable initWalletServiceHandler, @Nullable Consumer<Boole
else
result = state + " / " + p2pInfo;
}
return result;
return daoFullNode + result;
});
p2PNetworkInfoBinding.subscribe((observable, oldValue, newValue) -> {
p2PNetworkInfo.set(newValue);
Expand Down
9 changes: 6 additions & 3 deletions core/src/main/java/bisq/core/dao/node/BsqNodeProvider.java
Expand Up @@ -39,12 +39,15 @@ public BsqNodeProvider(LiteNode bsqLiteNode,
FullNode bsqFullNode,
Preferences preferences) {

boolean rpcDataSet = preferences.getRpcUser() != null && !preferences.getRpcUser().isEmpty()
&& preferences.getRpcPw() != null && !preferences.getRpcPw().isEmpty();
boolean rpcDataSet = preferences.getRpcUser() != null &&
!preferences.getRpcUser().isEmpty()
&& preferences.getRpcPw() != null &&
!preferences.getRpcPw().isEmpty() &&
preferences.getBlockNotifyPort() > 0;
boolean daoFullNode = preferences.isDaoFullNode();
if (daoFullNode && !rpcDataSet)
log.warn("daoFullNode is set but RPC user and pw are missing");

bsqNode = rpcDataSet && daoFullNode ? bsqFullNode : bsqLiteNode;
bsqNode = daoFullNode && rpcDataSet ? bsqFullNode : bsqLiteNode;
}
}
9 changes: 4 additions & 5 deletions core/src/main/java/bisq/core/dao/node/full/RpcService.java
Expand Up @@ -73,7 +73,7 @@ public class RpcService {
private final String rpcUser;
private final String rpcPassword;
private final String rpcPort;
private final String rpcBlockPort;
private final int blockNotifyPort;

private BtcdClient client;
private BtcdDaemon daemon;
Expand All @@ -90,10 +90,10 @@ public class RpcService {
@SuppressWarnings("WeakerAccess")
@Inject
public RpcService(Preferences preferences,
@Named(DaoOptionKeys.RPC_PORT) String rpcPort,
@Named(DaoOptionKeys.RPC_BLOCK_NOTIFICATION_PORT) String rpcBlockPort) {
@Named(DaoOptionKeys.RPC_PORT) String rpcPort) {
this.rpcUser = preferences.getRpcUser();
this.rpcPassword = preferences.getRpcPw();
this.blockNotifyPort = preferences.getBlockNotifyPort();

// mainnet is 8332, testnet 18332, regtest 18443
boolean isPortSet = rpcPort != null && !rpcPort.isEmpty();
Expand All @@ -104,7 +104,6 @@ public RpcService(Preferences preferences,
isMainnet || isDaoBetaNet ? "8332" :
isTestnet ? "18332" :
"18443"; // regtest
this.rpcBlockPort = rpcBlockPort != null && !rpcBlockPort.isEmpty() ? rpcBlockPort : "5125";

log.info("Version of btcd-cli4j library: {}", BtcdCli4jVersion.VERSION);
}
Expand All @@ -127,7 +126,7 @@ void setup(ResultHandler resultHandler, Consumer<Throwable> errorHandler) {
nodeConfig.setProperty("node.bitcoind.rpc.user", rpcUser);
nodeConfig.setProperty("node.bitcoind.rpc.password", rpcPassword);
nodeConfig.setProperty("node.bitcoind.rpc.port", rpcPort);
nodeConfig.setProperty("node.bitcoind.notification.block.port", rpcBlockPort);
nodeConfig.setProperty("node.bitcoind.notification.block.port", String.valueOf(blockNotifyPort));
nodeConfig.setProperty("node.bitcoind.notification.alert.port", String.valueOf(bisq.network.p2p.Utils.findFreeSystemPort()));
nodeConfig.setProperty("node.bitcoind.notification.wallet.port", String.valueOf(bisq.network.p2p.Utils.findFreeSystemPort()));

Expand Down
18 changes: 15 additions & 3 deletions core/src/main/java/bisq/core/setup/CoreNetworkCapabilities.java
Expand Up @@ -23,16 +23,28 @@
import bisq.common.app.Capabilities;
import bisq.common.app.Capability;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CoreNetworkCapabilities {
public static void setSupportedCapabilities(BisqEnvironment bisqEnvironment) {
Capabilities.app.addAll(Capability.TRADE_STATISTICS, Capability.TRADE_STATISTICS_2, Capability.ACCOUNT_AGE_WITNESS, Capability.ACK_MSG);

if (BisqEnvironment.isDaoActivated(bisqEnvironment)) {
Capabilities.app.addAll(Capability.PROPOSAL, Capability.BLIND_VOTE, Capability.BSQ_BLOCK, Capability.DAO_STATE);

String isFullDaoNode = bisqEnvironment.getProperty(DaoOptionKeys.FULL_DAO_NODE, String.class, "false");
if (isFullDaoNode != null && !isFullDaoNode.isEmpty() && isFullDaoNode.toLowerCase().equals("true"))
Capabilities.app.addAll(Capability.DAO_FULL_NODE);
maybeApplyDaoFullMode(bisqEnvironment);
}
}

public static void maybeApplyDaoFullMode(BisqEnvironment bisqEnvironment) {
// If we set dao full mode at the preferences view we add the capability there. We read the preferences a
// bit later than we call that method so we have to add DAO_FULL_NODE Capability at preferences as well to
// be sure it is set in both cases.
String isFullDaoNode = bisqEnvironment.getProperty(DaoOptionKeys.FULL_DAO_NODE, String.class, "false");
if (isFullDaoNode != null && !isFullDaoNode.isEmpty() && isFullDaoNode.toLowerCase().equals("true")) {
log.info("Set Capability.DAO_FULL_NODE");
Capabilities.app.addAll(Capability.DAO_FULL_NODE);
}
}
}
109 changes: 87 additions & 22 deletions core/src/main/java/bisq/core/user/Preferences.java
Expand Up @@ -32,6 +32,7 @@
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.TradeCurrency;
import bisq.core.payment.PaymentAccount;
import bisq.core.setup.CoreNetworkCapabilities;

import bisq.network.p2p.network.BridgeAddressProvider;

Expand Down Expand Up @@ -130,7 +131,7 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
private final Storage<PreferencesPayload> storage;
private final BisqEnvironment bisqEnvironment;
private final String btcNodesFromOptions, useTorFlagFromOptions, referralIdFromOptions, fullDaoNodeFromOptions,
rpcUserFromOptions, rpcPasswordFromOptions;
rpcUserFromOptions, rpcPwFromOptions, blockNotifyPortFromOptions;
@Getter
private final BooleanProperty useStandbyModeProperty = new SimpleBooleanProperty(prefPayload.isUseStandbyMode());

Expand All @@ -149,7 +150,8 @@ public Preferences(Storage<PreferencesPayload> storage,
@Named(AppOptionKeys.REFERRAL_ID) String referralId,
@Named(DaoOptionKeys.FULL_DAO_NODE) String fullDaoNode,
@Named(DaoOptionKeys.RPC_USER) String rpcUser,
@Named(DaoOptionKeys.RPC_PASSWORD) String rpcPassword) {
@Named(DaoOptionKeys.RPC_PASSWORD) String rpcPassword,
@Named(DaoOptionKeys.RPC_BLOCK_NOTIFICATION_PORT) String rpcBlockNotificationPort) {


this.storage = storage;
Expand All @@ -159,7 +161,8 @@ public Preferences(Storage<PreferencesPayload> storage,
this.referralIdFromOptions = referralId;
this.fullDaoNodeFromOptions = fullDaoNode;
this.rpcUserFromOptions = rpcUser;
this.rpcPasswordFromOptions = rpcPassword;
this.rpcPwFromOptions = rpcPassword;
this.blockNotifyPortFromOptions = rpcBlockNotificationPort;

useAnimationsProperty.addListener((ov) -> {
prefPayload.setUseAnimations(useAnimationsProperty.get());
Expand Down Expand Up @@ -279,15 +282,6 @@ else if (useTorFlagFromOptions.equals("true"))
if (referralIdFromOptions != null && !referralIdFromOptions.isEmpty())
setReferralId(referralIdFromOptions);

if (fullDaoNodeFromOptions != null && !fullDaoNodeFromOptions.isEmpty())
setDaoFullNode(fullDaoNodeFromOptions.toLowerCase().equals("true"));

if (rpcUserFromOptions != null && !rpcUserFromOptions.isEmpty())
setRpcUser(rpcUserFromOptions);

if (rpcPasswordFromOptions != null && !rpcPasswordFromOptions.isEmpty())
setRpcPw(rpcPasswordFromOptions);

// For users from old versions the 4 flags a false but we want to have it true by default
// PhoneKeyAndToken is also null so we can use that to enable the flags
if (prefPayload.getPhoneKeyAndToken() == null) {
Expand All @@ -297,10 +291,15 @@ else if (useTorFlagFromOptions.equals("true"))
setUsePriceNotifications(true);
}

// We set the capability in CoreNetworkCapabilities if the program argument is set.
// If we have set it in the preferences view we handle it here.
CoreNetworkCapabilities.maybeApplyDaoFullMode(bisqEnvironment);

initialReadDone = true;
persist();
}


///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -598,24 +597,43 @@ public void setUseStandbyMode(boolean useStandbyMode) {
this.useStandbyModeProperty.set(useStandbyMode);
}

public void setDaoFullNode(boolean value) {
prefPayload.setDaoFullNode(value);
public void setTakeOfferSelectedPaymentAccountId(String value) {
prefPayload.setTakeOfferSelectedPaymentAccountId(value);
persist();
}

public void setDaoFullNode(boolean value) {
// We only persist if we have not set the program argument
if (fullDaoNodeFromOptions == null || fullDaoNodeFromOptions.isEmpty()) {
prefPayload.setDaoFullNode(value);
persist();
}
}

public void setRpcUser(String value) {
// We only persist if we have not set the program argument
if (rpcUserFromOptions == null || rpcUserFromOptions.isEmpty()) {
prefPayload.setRpcUser(value);
persist();
}
prefPayload.setRpcUser(value);
persist();
}

public void setRpcPw(String value) {
prefPayload.setRpcPw(value);
persist();
// We only persist if we have not set the program argument
if (rpcPwFromOptions == null || rpcPwFromOptions.isEmpty()) {
prefPayload.setRpcPw(value);
persist();
}
}

public void setTakeOfferSelectedPaymentAccountId(String value) {
prefPayload.setTakeOfferSelectedPaymentAccountId(value);
persist();
public void setBlockNotifyPort(int value) {
// We only persist if we have not set the program argument
if (blockNotifyPortFromOptions == null || blockNotifyPortFromOptions.isEmpty()) {
prefPayload.setBlockNotifyPort(value);
persist();
}
}


Expand Down Expand Up @@ -732,6 +750,43 @@ public long getWithdrawalTxFeeInBytes() {
return Math.max(prefPayload.getWithdrawalTxFeeInBytes(), BisqEnvironment.getBaseCurrencyNetwork().getDefaultMinFeePerByte());
}

public boolean isDaoFullNode() {
if (fullDaoNodeFromOptions != null && !fullDaoNodeFromOptions.isEmpty()) {
return fullDaoNodeFromOptions.toLowerCase().equals("true");
} else {
return prefPayload.isDaoFullNode();
}
}

public String getRpcUser() {
if (rpcUserFromOptions != null && !rpcUserFromOptions.isEmpty()) {
return rpcUserFromOptions;
} else {
return prefPayload.getRpcUser();
}
}

public String getRpcPw() {
if (rpcPwFromOptions != null && !rpcPwFromOptions.isEmpty()) {
return rpcPwFromOptions;
} else {
return prefPayload.getRpcPw();
}
}

public int getBlockNotifyPort() {
if (blockNotifyPortFromOptions != null && !blockNotifyPortFromOptions.isEmpty()) {
try {
return Integer.parseInt(blockNotifyPortFromOptions);
} catch (Throwable ignore) {
return 0;
}

} else {
return prefPayload.getBlockNotifyPort();
}
}


///////////////////////////////////////////////////////////////////////////////////////////
// Private
Expand Down Expand Up @@ -840,16 +895,26 @@ private interface ExcludesDelegateMethods {

void setUseStandbyMode(boolean useStandbyMode);

void setTakeOfferSelectedPaymentAccountId(String value);

void setBuyerSecurityDepositAsPercent(double buyerSecurityDepositAsPercent);

double getBuyerSecurityDepositAsPercent();

void setDaoFullNode(boolean value);

void setRpcUser(String value);

void setRpcPw(String value);

void setTakeOfferSelectedPaymentAccountId(String value);
void setBlockNotifyPort(int value);

void setBuyerSecurityDepositAsPercent(double buyerSecurityDepositAsPercent);
boolean isDaoFullNode();

double getBuyerSecurityDepositAsPercent();
String getRpcUser();

String getRpcPw();

int getBlockNotifyPort();
}
}
37 changes: 20 additions & 17 deletions core/src/main/java/bisq/core/user/PreferencesPayload.java
Expand Up @@ -99,28 +99,29 @@ public final class PreferencesPayload implements PersistableEnvelope {
private boolean payFeeInBtc = true;
@Nullable
private List<String> bridgeAddresses;
int bridgeOptionOrdinal;
int torTransportOrdinal;
private int bridgeOptionOrdinal;
private int torTransportOrdinal;
@Nullable
String customBridges;
int bitcoinNodesOptionOrdinal;
private String customBridges;
private int bitcoinNodesOptionOrdinal;
@Nullable
String referralId;
private String referralId;
@Nullable
String phoneKeyAndToken;
boolean useSoundForMobileNotifications = true;
boolean useTradeNotifications = true;
boolean useMarketNotifications = true;
boolean usePriceNotifications = true;
boolean useStandbyMode = false;
boolean isDaoFullNode = false;
private String phoneKeyAndToken;
private boolean useSoundForMobileNotifications = true;
private boolean useTradeNotifications = true;
private boolean useMarketNotifications = true;
private boolean usePriceNotifications = true;
private boolean useStandbyMode = false;
private boolean isDaoFullNode = false;
@Nullable
String rpcUser;
private String rpcUser;
@Nullable
String rpcPw;
private String rpcPw;
@Nullable
String takeOfferSelectedPaymentAccountId;
private String takeOfferSelectedPaymentAccountId;
private double buyerSecurityDepositAsPercent = Restrictions.getDefaultBuyerSecurityDepositAsPercent();
private int blockNotifyPort;


///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -177,7 +178,8 @@ public Message toProtoMessage() {
.setUsePriceNotifications(usePriceNotifications)
.setUseStandbyMode(useStandbyMode)
.setIsDaoFullNode(isDaoFullNode)
.setBuyerSecurityDepositAsPercent(buyerSecurityDepositAsPercent);
.setBuyerSecurityDepositAsPercent(buyerSecurityDepositAsPercent)
.setBlockNotifyPort(blockNotifyPort);
Optional.ofNullable(backupDirectory).ifPresent(builder::setBackupDirectory);
Optional.ofNullable(preferredTradeCurrency).ifPresent(e -> builder.setPreferredTradeCurrency((PB.TradeCurrency) e.toProtoMessage()));
Optional.ofNullable(offerBookChartScreenCurrencyCode).ifPresent(builder::setOfferBookChartScreenCurrencyCode);
Expand Down Expand Up @@ -259,6 +261,7 @@ public static PersistableEnvelope fromProto(PB.PreferencesPayload proto, CorePro
proto.getRpcUser().isEmpty() ? null : proto.getRpcUser(),
proto.getRpcPw().isEmpty() ? null : proto.getRpcPw(),
proto.getTakeOfferSelectedPaymentAccountId().isEmpty() ? null : proto.getTakeOfferSelectedPaymentAccountId(),
proto.getBuyerSecurityDepositAsPercent());
proto.getBuyerSecurityDepositAsPercent(),
proto.getBlockNotifyPort());
}
}
5 changes: 4 additions & 1 deletion core/src/main/resources/i18n/displayStrings.properties
Expand Up @@ -245,6 +245,7 @@ mainView.footer.btcInfo.synchronizedWith=Synchronized with
mainView.footer.btcInfo.connectingTo=Connecting to
mainView.footer.btcInfo.connectionFailed=connection failed
mainView.footer.p2pInfo=P2P network peers: {0}
mainView.footer.daoFullNode=DAO full node

mainView.bootstrapState.connectionToTorNetwork=(1/4) Connecting to Tor network...
mainView.bootstrapState.torNodeCreated=(2/4) Tor node created
Expand Down Expand Up @@ -912,8 +913,10 @@ setting.preferences.dao.resync.popup=After an application restart the P2P networ
setting.preferences.dao.isDaoFullNode=Run Bisq as DAO full node
setting.preferences.dao.rpcUser=RPC username
setting.preferences.dao.rpcPw=RPC password
setting.preferences.dao.blockNotifyPort=Block notify port
setting.preferences.dao.fullNodeInfo=For running Bisq as DAO full node you need to have Bitcoin Core locally running \
and configured with RPC and other requirements which are documented in ''{0}''.
and RPC enabled. All requirements are documented in ''{0}''.\n\n\
After changing the mode you need to restart.
setting.preferences.dao.fullNodeInfo.ok=Open docs page
setting.preferences.dao.fullNodeInfo.cancel=No, I stick with lite node mode

Expand Down