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

Add hint to upgrade to tor v3 #5573

Merged
merged 9 commits into from
Jun 23, 2021
1 change: 1 addition & 0 deletions core/src/main/java/bisq/core/app/BisqHeadlessApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ protected void setupHandlers() {
gracefulShutDownHandler.gracefulShutDown(() -> {
});
});
bisqSetup.setTorAddressUpgradeHandler(() -> log.info("setTorAddressUpgradeHandler"));

corruptedStorageFileHandler.getFiles().ifPresent(files -> log.warn("getCorruptedDatabaseFiles. files={}", files));
tradeManager.setTakeOfferRequestErrorMessageHandler(errorMessage -> log.error("onTakeOfferRequestErrorMessageHandler"));
Expand Down
51 changes: 45 additions & 6 deletions core/src/main/java/bisq/core/app/BisqSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.RevolutAccount;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.arbitration.ArbitrationManager;
import bisq.core.support.dispute.mediation.MediationManager;
import bisq.core.support.dispute.refund.RefundManager;
import bisq.core.trade.TradeManager;
import bisq.core.trade.TradeTxException;
import bisq.core.user.Preferences;
Expand All @@ -47,6 +51,7 @@
import bisq.network.Socks5ProxyProvider;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.network.utils.Utils;

import bisq.common.Timer;
import bisq.common.UserThread;
Expand Down Expand Up @@ -84,6 +89,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -135,10 +141,12 @@ default void onRequestWalletPassword() {
private final UnconfirmedBsqChangeOutputListService unconfirmedBsqChangeOutputListService;
private final Config config;
private final AccountAgeWitnessService accountAgeWitnessService;
private final TorSetup torSetup;
private final CoinFormatter formatter;
private final LocalBitcoinNode localBitcoinNode;
private final AppStartupState appStartupState;
private final MediationManager mediationManager;
private final RefundManager refundManager;
private final ArbitrationManager arbitrationManager;

@Setter
@Nullable
Expand Down Expand Up @@ -189,6 +197,9 @@ default void onRequestWalletPassword() {
private Runnable daoRequiresRestartHandler;
@Setter
@Nullable
private Runnable torAddressUpgradeHandler;
@Setter
@Nullable
private Consumer<String> downGradePreventionHandler;

@Getter
Expand Down Expand Up @@ -217,11 +228,13 @@ public BisqSetup(DomainInitialisation domainInitialisation,
UnconfirmedBsqChangeOutputListService unconfirmedBsqChangeOutputListService,
Config config,
AccountAgeWitnessService accountAgeWitnessService,
TorSetup torSetup,
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
LocalBitcoinNode localBitcoinNode,
AppStartupState appStartupState,
Socks5ProxyProvider socks5ProxyProvider) {
Socks5ProxyProvider socks5ProxyProvider,
MediationManager mediationManager,
RefundManager refundManager,
ArbitrationManager arbitrationManager) {
this.domainInitialisation = domainInitialisation;
this.p2PNetworkSetup = p2PNetworkSetup;
this.walletAppSetup = walletAppSetup;
Expand All @@ -238,10 +251,12 @@ public BisqSetup(DomainInitialisation domainInitialisation,
this.unconfirmedBsqChangeOutputListService = unconfirmedBsqChangeOutputListService;
this.config = config;
this.accountAgeWitnessService = accountAgeWitnessService;
this.torSetup = torSetup;
this.formatter = formatter;
this.localBitcoinNode = localBitcoinNode;
this.appStartupState = appStartupState;
this.mediationManager = mediationManager;
this.refundManager = refundManager;
this.arbitrationManager = arbitrationManager;

MemPoolSpaceTxBroadcaster.init(socks5ProxyProvider, preferences, localBitcoinNode);
}
Expand Down Expand Up @@ -312,6 +327,7 @@ private void step4() {
maybeShowSecurityRecommendation();
maybeShowLocalhostRunningInfo();
maybeShowAccountSigningStateInfo();
maybeShowTorAddressUpgradeInformation();
}


Expand Down Expand Up @@ -563,8 +579,6 @@ public static void setResyncSpvSemaphore(boolean isResyncSpvRequested) {
}




private static File getVersionFile() {
return new File(Config.appDataDir(), VERSION_FILE_NAME);
}
Expand Down Expand Up @@ -702,6 +716,31 @@ private void maybeTriggerDisplayHandler(String key, Consumer<String> displayHand
}
}

private void maybeShowTorAddressUpgradeInformation() {
if (Config.baseCurrencyNetwork().isRegtest() ||
Utils.isV3Address(Objects.requireNonNull(p2PService.getNetworkNode().getNodeAddress()).getHostName())) {
return;
}

maybeRunTorNodeAddressUpgradeHandler();

tradeManager.getNumPendingTrades().addListener((observable, oldValue, newValue) -> {
long numPendingTrades = (long) newValue;
if (numPendingTrades == 0) {
maybeRunTorNodeAddressUpgradeHandler();
}
});
}

private void maybeRunTorNodeAddressUpgradeHandler() {
if (mediationManager.getDisputesAsObservableList().stream().allMatch(Dispute::isClosed) &&
refundManager.getDisputesAsObservableList().stream().allMatch(Dispute::isClosed) &&
arbitrationManager.getDisputesAsObservableList().stream().allMatch(Dispute::isClosed) &&
tradeManager.getNumPendingTrades().isEqualTo(0).get()) {
Objects.requireNonNull(torAddressUpgradeHandler).run();
}
}


///////////////////////////////////////////////////////////////////////////////////////////
// Getters
Expand Down
11 changes: 6 additions & 5 deletions core/src/main/java/bisq/core/offer/OfferRestrictions.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import bisq.common.app.Capabilities;
import bisq.common.app.Capability;
import bisq.common.config.Config;
import bisq.common.util.Utilities;

import org.bitcoinj.core.Coin;
Expand All @@ -28,12 +29,12 @@
import java.util.Map;

public class OfferRestrictions {
// The date when traders who have not updated cannot take offers from updated clients and their offers become
// invisible for updated clients.
private static final Date REQUIRE_UPDATE_DATE = Utilities.getUTCDate(2019, GregorianCalendar.SEPTEMBER, 19);
// The date when traders who have not upgraded to a Tor v3 Node Address cannot take offers and their offers become
// invisible.
private static final Date REQUIRE_TOR_NODE_ADDRESS_V3_DATE = Utilities.getUTCDate(2021, GregorianCalendar.AUGUST, 15);

static boolean requiresUpdate() {
return new Date().after(REQUIRE_UPDATE_DATE);
public static boolean requiresNodeAddressUpdate() {
return new Date().after(REQUIRE_TOR_NODE_ADDRESS_V3_DATE) && !Config.baseCurrencyNetwork().isRegtest();
}

public static Coin TOLERATED_SMALL_TRADE_AMOUNT = Coin.parseCoin("0.01");
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/java/bisq/core/offer/OpenOfferManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import bisq.network.p2p.SendDirectMessageListener;
import bisq.network.p2p.peers.Broadcaster;
import bisq.network.p2p.peers.PeerManager;
import bisq.network.utils.Utils;

import bisq.common.Timer;
import bisq.common.UserThread;
Expand Down Expand Up @@ -598,6 +599,13 @@ private void handleOfferAvailabilityRequest(OfferAvailabilityRequest request, No
boolean result = false;
String errorMessage = null;

if (OfferRestrictions.requiresNodeAddressUpdate() && !Utils.isV3Address(peer.getHostName())) {
errorMessage = "We got a handleOfferAvailabilityRequest from a Tor node v2 address where a Tor node v3 address is required.";
log.info(errorMessage);
sendAckMessage(request, peer, false, errorMessage);
return;
}

if (!p2PService.isBootstrapped()) {
errorMessage = "We got a handleOfferAvailabilityRequest but we have not bootstrapped yet.";
log.info(errorMessage);
Expand Down
11 changes: 10 additions & 1 deletion core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ portfolio.pending.failedTrade.txChainValid.moveToFailed=The trade protocol encou
portfolio.pending.failedTrade.moveTradeToFailedIcon.tooltip=Move trade to failed trades
portfolio.pending.failedTrade.warningIcon.tooltip=Click to open details about the issues of this trade
portfolio.failed.revertToPending.popup=Do you want to move this trade to open trades?
portfolio.failed.revertToPending.failed=Failed to move this trade to open trades.
portfolio.failed.revertToPending=Move trade to open trades

portfolio.closed.completed=Completed
Expand Down Expand Up @@ -1111,6 +1112,7 @@ support.sigCheck.popup.failed=Signature verification failed
support.sigCheck.popup.invalidFormat=Message is not of expected format. Copy & paste summary message from dispute.

support.reOpenByTrader.prompt=Are you sure you want to re-open the dispute?
support.reOpenByTrader.failed=Failed to re-open the dispute.
support.reOpenButton.label=Re-open
support.sendNotificationButton.label=Private notification
support.reportButton.label=Report
Expand Down Expand Up @@ -2992,6 +2994,13 @@ popup.accountSigning.unsignedPubKeys.signed=Pubkeys were signed
popup.accountSigning.unsignedPubKeys.result.signed=Signed pubkeys
popup.accountSigning.unsignedPubKeys.result.failed=Failed to sign

popup.info.torMigration.msg=Your Bisq node is currently using a Tor v2 address. Tor v2 is being deprecated soon \
[HYPERLINK:https://blog.torproject.org/v2-deprecation-timeline], and \
Bisq nodes with Tor v2 addresses will no longer be able to trade on August 15th, 2021.\n\n\
Please switch your Bisq node to a Tor v3 address. It's quick and simple -- see details in this doc \
[HYPERLINK:https://bisq.wiki/Changing_your_onion_address] or in this video [HYPERLINK:https://bitcointv.com/videos/watch/f96adc20-4092-4253-84c0-1b18088b4b95]. \n\n\
Make sure to back up your data directory beforehand.

####################################################################
# Notifications
####################################################################
Expand Down Expand Up @@ -3107,7 +3116,7 @@ txIdTextField.missingTx.warning.tooltip=Missing required transaction
####################################################################

navigation.account=\"Account\"
navigation.account.walletSeed=\"Account/Wallet seed\"
navigation.account.backup=\"Account/Backup\"
navigation.funds.availableForWithdrawal=\"Funds/Send funds\"
navigation.portfolio.myOpenOffers=\"Portfolio/My open offers\"
navigation.portfolio.pending=\"Portfolio/Open trades\"
Expand Down
15 changes: 14 additions & 1 deletion desktop/src/main/java/bisq/desktop/main/MainViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@

package bisq.desktop.main;

import bisq.desktop.Navigation;
import bisq.desktop.app.BisqApp;
import bisq.desktop.common.model.ViewModel;
import bisq.desktop.components.TxIdTextField;
import bisq.desktop.main.account.AccountView;
import bisq.desktop.main.account.content.backup.BackupView;
import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.main.overlays.notifications.NotificationCenter;
import bisq.desktop.main.overlays.popups.Popup;
Expand Down Expand Up @@ -135,6 +138,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
@Getter
private final TorNetworkSettingsWindow torNetworkSettingsWindow;
private final CorruptedStorageFileHandler corruptedStorageFileHandler;
private final Navigation navigation;

@Getter
private final BooleanProperty showAppScreen = new SimpleBooleanProperty();
Expand Down Expand Up @@ -178,7 +182,8 @@ public MainViewModel(BisqSetup bisqSetup,
LocalBitcoinNode localBitcoinNode,
AccountAgeWitnessService accountAgeWitnessService,
TorNetworkSettingsWindow torNetworkSettingsWindow,
CorruptedStorageFileHandler corruptedStorageFileHandler) {
CorruptedStorageFileHandler corruptedStorageFileHandler,
Navigation navigation) {
this.bisqSetup = bisqSetup;
this.walletsSetup = walletsSetup;
this.user = user;
Expand All @@ -203,6 +208,7 @@ public MainViewModel(BisqSetup bisqSetup,
this.accountAgeWitnessService = accountAgeWitnessService;
this.torNetworkSettingsWindow = torNetworkSettingsWindow;
this.corruptedStorageFileHandler = corruptedStorageFileHandler;
this.navigation = navigation;

TxIdTextField.setPreferences(preferences);

Expand Down Expand Up @@ -415,6 +421,13 @@ private void setupHandlers() {
.hideCloseButton()
.show());

bisqSetup.setTorAddressUpgradeHandler(() -> new Popup().information(Res.get("popup.info.torMigration.msg"))
.actionButtonTextWithGoTo("navigation.account.backup")
.onAction(() -> {
navigation.setReturnPath(navigation.getCurrentPath());
navigation.navigateTo(MainView.class, AccountView.class, BackupView.class);
}).show());

corruptedStorageFileHandler.getFiles().ifPresent(files -> new Popup()
.warning(Res.get("popup.warning.incompatibleDB", files.toString(), config.appDataDir))
.useShutDownButton()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
import bisq.core.filter.FilterManager;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferBookService;
import bisq.core.offer.OfferRestrictions;
import bisq.core.trade.TradeManager;

import bisq.network.utils.Utils;

import javax.inject.Inject;
import javax.inject.Singleton;

Expand Down Expand Up @@ -75,6 +78,11 @@ public void onAdded(Offer offer) {
return;
}

if (OfferRestrictions.requiresNodeAddressUpdate() && !Utils.isV3Address(offer.getMakerNodeAddress().getHostName())) {
log.debug("Ignored offer with Tor v2 node address. ID={}", offer.getId());
return;
}

boolean hasSameOffer = offerBookListItems.stream()
.anyMatch(item -> item.getOffer().equals(offer));
if (!hasSameOffer) {
Expand Down Expand Up @@ -126,6 +134,7 @@ public void fillOfferBookListItems() {
offerBookListItems.clear();
offerBookListItems.addAll(offerBookService.getOffers().stream()
.filter(o -> !filterManager.isOfferIdBanned(o.getId()))
.filter(o -> !OfferRestrictions.requiresNodeAddressUpdate() || Utils.isV3Address(o.getMakerNodeAddress().getHostName()))
.map(OfferBookListItem::new)
.collect(Collectors.toList()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,39 @@
import bisq.core.trade.TradeManager;
import bisq.core.trade.failed.FailedTradesManager;

import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;

import bisq.common.crypto.KeyRing;

import com.google.inject.Inject;

import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;

import java.util.Objects;
import java.util.stream.Collectors;

class FailedTradesDataModel extends ActivatableDataModel {

private final FailedTradesManager failedTradesManager;
private final TradeManager tradeManager;
private final P2PService p2PService;
private final KeyRing keyRing;

private final ObservableList<FailedTradesListItem> list = FXCollections.observableArrayList();
private final ListChangeListener<Trade> tradesListChangeListener;

@Inject
public FailedTradesDataModel(FailedTradesManager failedTradesManager, TradeManager tradeManager) {
public FailedTradesDataModel(FailedTradesManager failedTradesManager,
TradeManager tradeManager,
P2PService p2PService,
KeyRing keyRing) {
this.failedTradesManager = failedTradesManager;
this.tradeManager = tradeManager;
this.p2PService = p2PService;
this.keyRing = keyRing;

tradesListChangeListener = change -> applyList();
}
Expand Down Expand Up @@ -77,9 +90,19 @@ private void applyList() {
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
}

public void onMoveTradeToPendingTrades(Trade trade) {
public boolean onMoveTradeToPendingTrades(Trade trade) {
if (!isTradeWithSameCurrentNodeAddress(trade)) {
return false;
}

failedTradesManager.removeTrade(trade);
tradeManager.addFailedTradeToPendingTrades(trade);
return true;
}

private boolean isTradeWithSameCurrentNodeAddress(Trade trade) {
NodeAddress tradeNodeAddress = trade.getContract().getMyNodeAddress(keyRing.getPubKeyRing());
return Objects.equals(p2PService.getNetworkNode().getNodeAddress(), tradeNodeAddress);
}

public void unfailTrade(Trade trade) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,18 @@ private String checkTxs() {

private void onRevertTrade(Trade trade) {
new Popup().attention(Res.get("portfolio.failed.revertToPending.popup"))
.onAction(() -> onMoveTradeToPendingTrades(trade))
.onAction(() -> {
if (!onMoveTradeToPendingTrades(trade)) {
new Popup().warning(Res.get("portfolio.failed.revertToPending.failed")).show();
}
})
.actionButtonText(Res.get("shared.yes"))
.closeButtonText(Res.get("shared.no"))
.show();
}

private void onMoveTradeToPendingTrades(Trade trade) {
model.dataModel.onMoveTradeToPendingTrades(trade);
private boolean onMoveTradeToPendingTrades(Trade trade) {
return model.dataModel.onMoveTradeToPendingTrades(trade);
}

private void setTradeIdColumnCellFactory() {
Expand Down
Loading