From d98f3c12cf4b58fc16ed6a076ba9a25e2e5e38a8 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 23 Nov 2018 20:48:52 +0100 Subject: [PATCH 1/4] Add default genesis tx info for regtest --- .../src/main/java/bisq/core/dao/state/GenesisTxInfo.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/main/java/bisq/core/dao/state/GenesisTxInfo.java b/core/src/main/java/bisq/core/dao/state/GenesisTxInfo.java index 80fef4601ce..2a32f28d21e 100644 --- a/core/src/main/java/bisq/core/dao/state/GenesisTxInfo.java +++ b/core/src/main/java/bisq/core/dao/state/GenesisTxInfo.java @@ -52,6 +52,10 @@ public class GenesisTxInfo { private static final int TESTNET_GENESIS_BLOCK_HEIGHT = 1443359; // 2018-11-13 + private static final String REGTEST_GENESIS_TX_ID = "30af0050040befd8af25068cc697e418e09c2d8ebd8d411d2240591b9ec203cf"; + private static final int REGTEST_GENESIS_BLOCK_HEIGHT = 111; + + /////////////////////////////////////////////////////////////////////////////////////////// // Instance fields /////////////////////////////////////////////////////////////////////////////////////////// @@ -90,12 +94,15 @@ public GenesisTxInfo(@Named(DaoOptionKeys.GENESIS_TX_ID) String genesisTxId, BaseCurrencyNetwork baseCurrencyNetwork = BisqEnvironment.getBaseCurrencyNetwork(); boolean isMainnet = baseCurrencyNetwork.isMainnet(); boolean isTestnet = baseCurrencyNetwork.isTestnet(); + boolean isRegtest = baseCurrencyNetwork.isRegtest(); if (!genesisTxId.isEmpty()) { this.genesisTxId = genesisTxId; } else if (isMainnet) { this.genesisTxId = MAINNET_GENESIS_TX_ID; } else if (isTestnet) { this.genesisTxId = TESTNET_GENESIS_TX_ID; + } else if (isRegtest) { + this.genesisTxId = REGTEST_GENESIS_TX_ID; } else { this.genesisTxId = "genesisTxId is undefined"; } @@ -106,6 +113,8 @@ public GenesisTxInfo(@Named(DaoOptionKeys.GENESIS_TX_ID) String genesisTxId, this.genesisBlockHeight = MAINNET_GENESIS_BLOCK_HEIGHT; } else if (isTestnet) { this.genesisBlockHeight = TESTNET_GENESIS_BLOCK_HEIGHT; + } else if (isRegtest) { + this.genesisBlockHeight = REGTEST_GENESIS_BLOCK_HEIGHT; } else { this.genesisBlockHeight = 0; } From 1ba0402dfb0e06d248dbde3ca927aedbb49b1af4 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 23 Nov 2018 22:14:31 +0100 Subject: [PATCH 2/4] Handle backward compatibility with new arbitration selection model. --- .../availability/OfferAvailabilityModel.java | 8 +++- .../ProcessOfferAvailabilityResponse.java | 37 +++++++++++++++---- .../java/bisq/core/trade/TradeManager.java | 3 +- .../bisq/desktop/main/offer/OfferView.java | 31 +++++++++++++--- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/bisq/core/offer/availability/OfferAvailabilityModel.java b/core/src/main/java/bisq/core/offer/availability/OfferAvailabilityModel.java index 5215664ae96..982540b54c2 100644 --- a/core/src/main/java/bisq/core/offer/availability/OfferAvailabilityModel.java +++ b/core/src/main/java/bisq/core/offer/availability/OfferAvailabilityModel.java @@ -19,6 +19,7 @@ import bisq.core.offer.Offer; import bisq.core.offer.messages.OfferAvailabilityResponse; +import bisq.core.user.User; import bisq.network.p2p.NodeAddress; import bisq.network.p2p.P2PService; @@ -38,7 +39,8 @@ public class OfferAvailabilityModel implements Model { private final PubKeyRing pubKeyRing; // takers PubKey (my pubkey) @Getter private final P2PService p2PService; - + @Getter + final private User user; private NodeAddress peerNodeAddress; // maker private OfferAvailabilityResponse message; @Nullable @@ -48,10 +50,12 @@ public class OfferAvailabilityModel implements Model { public OfferAvailabilityModel(Offer offer, PubKeyRing pubKeyRing, - P2PService p2PService) { + P2PService p2PService, + User user) { this.offer = offer; this.pubKeyRing = pubKeyRing; this.p2PService = p2PService; + this.user = user; } public NodeAddress getPeerNodeAddress() { diff --git a/core/src/main/java/bisq/core/offer/availability/tasks/ProcessOfferAvailabilityResponse.java b/core/src/main/java/bisq/core/offer/availability/tasks/ProcessOfferAvailabilityResponse.java index aa3a274f74a..526c1f38123 100644 --- a/core/src/main/java/bisq/core/offer/availability/tasks/ProcessOfferAvailabilityResponse.java +++ b/core/src/main/java/bisq/core/offer/availability/tasks/ProcessOfferAvailabilityResponse.java @@ -22,12 +22,20 @@ import bisq.core.offer.availability.ArbitratorSelection; import bisq.core.offer.availability.OfferAvailabilityModel; import bisq.core.offer.messages.OfferAvailabilityResponse; +import bisq.core.trade.protocol.ArbitratorSelectionRule; import bisq.network.p2p.NodeAddress; import bisq.common.taskrunner.Task; import bisq.common.taskrunner.TaskRunner; +import com.google.common.collect.Lists; + +import java.util.List; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j public class ProcessOfferAvailabilityResponse extends Task { public ProcessOfferAvailabilityResponse(TaskRunner taskHandler, OfferAvailabilityModel model) { super(taskHandler, model); @@ -35,29 +43,44 @@ public ProcessOfferAvailabilityResponse(TaskRunner taskHandler, OfferAvailabilit @Override protected void run() { + Offer offer = model.getOffer(); try { runInterceptHook(); OfferAvailabilityResponse offerAvailabilityResponse = model.getMessage(); - if (model.getOffer().getState() != Offer.State.REMOVED) { + if (offer.getState() != Offer.State.REMOVED) { if (offerAvailabilityResponse.getAvailabilityResult() == AvailabilityResult.AVAILABLE) { - model.getOffer().setState(Offer.State.AVAILABLE); + offer.setState(Offer.State.AVAILABLE); if (ArbitratorSelection.isNewRuleActivated()) { NodeAddress selectedArbitrator = offerAvailabilityResponse.getArbitrator(); - if (selectedArbitrator == null) - failed("You cannot take that offer because the offer maker is running an incompatible version."); - else + if (selectedArbitrator == null) { + log.debug("Maker is on old version and does not send the selected arbitrator in the offerAvailabilityResponse. " + + "We use the old selection model instead with the supported arbitrators of the offers"); + List acceptedArbitratorAddresses = model.getUser().getAcceptedArbitratorAddresses(); + log.error("acceptedArbitratorAddresses " + acceptedArbitratorAddresses); + if (acceptedArbitratorAddresses != null) { + try { + model.setSelectedArbitrator(ArbitratorSelectionRule.select(Lists.newArrayList(acceptedArbitratorAddresses), offer)); + } catch (Throwable t) { + failed("There is no arbitrator matching that offer. The maker has " + + "not updated to the latest version and the arbitrators selected for that offer are not available anymore."); + } + } else { + failed("There is no arbitrator available."); + } + } else { model.setSelectedArbitrator(selectedArbitrator); + } } } else { - model.getOffer().setState(Offer.State.NOT_AVAILABLE); + offer.setState(Offer.State.NOT_AVAILABLE); failed("Take offer attempt rejected because of: " + offerAvailabilityResponse.getAvailabilityResult()); } } complete(); } catch (Throwable t) { - model.getOffer().setErrorMessage("An error occurred.\n" + + offer.setErrorMessage("An error occurred.\n" + "Error message:\n" + t.getMessage()); diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java index e4cb74d467b..77e28418433 100644 --- a/core/src/main/java/bisq/core/trade/TradeManager.java +++ b/core/src/main/java/bisq/core/trade/TradeManager.java @@ -473,7 +473,8 @@ private OfferAvailabilityModel getOfferAvailabilityModel(Offer offer) { return new OfferAvailabilityModel( offer, keyRing.getPubKeyRing(), - p2PService); + p2PService, + user); } diff --git a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java index aa655fc805a..22b6a496bb8 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java @@ -35,8 +35,11 @@ import bisq.core.locale.TradeCurrency; import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; +import bisq.core.offer.availability.ArbitratorSelection; import bisq.core.user.Preferences; +import bisq.network.p2p.NodeAddress; + import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.layout.AnchorPane; @@ -164,7 +167,8 @@ private void loadView(Class viewClass) { @Override public void onCreateOffer(TradeCurrency tradeCurrency) { if (!createOfferViewOpen) { - if (!arbitratorManager.isArbitratorAvailableForLanguage(preferences.getUserLanguage())) { + boolean arbitratorAvailableForLanguage = arbitratorManager.isArbitratorAvailableForLanguage(preferences.getUserLanguage()); + if (!arbitratorAvailableForLanguage) { showNoArbitratorForUserLocaleWarning(); } openCreateOffer(tradeCurrency); @@ -177,11 +181,28 @@ public void onCreateOffer(TradeCurrency tradeCurrency) { @Override public void onTakeOffer(Offer offer) { if (!takeOfferViewOpen) { - if (!arbitratorManager.getArbitratorLanguages(offer.getArbitratorNodeAddresses()).stream() - .anyMatch(languages -> languages.equals(preferences.getUserLanguage()))) { - showNoArbitratorForUserLocaleWarning(); + if (ArbitratorSelection.isNewRuleActivated()) { + openTakeOffer(offer); + } else { + List arbitratorNodeAddresses = offer.getArbitratorNodeAddresses(); + List arbitratorLanguages = arbitratorManager.getArbitratorLanguages(arbitratorNodeAddresses); + if (!arbitratorLanguages.isEmpty()) { + if (arbitratorLanguages.stream() + .noneMatch(languages -> languages.equals(preferences.getUserLanguage()))) { + showNoArbitratorForUserLocaleWarning(); + } + openTakeOffer(offer); + } else { + // No need to translate that as this should only be a very temporary issue after 0.9 release. + String message = "There is no arbitrator available matching the offer's " + + "supported arbitrators list. That might happen if the arbitrators of the offer have " + + "revoked and the maker has not updated to version 0.9."; + log.warn(message + " offer.getArbitratorNodeAddresses()={}", arbitratorNodeAddresses); + new Popup<>().warning(message) + .closeButtonText(Res.get("shared.ok")) + .show(); + } } - openTakeOffer(offer); } else { log.error("You have already a \"Take offer\" tab open."); } From 319c043e434807c6253af28557913bb1e9c19b74 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 24 Nov 2018 00:23:46 +0100 Subject: [PATCH 3/4] Handle backward compatibility with new arbitr. selection - Remove activationDate - Refactor ProcessOfferAvailabilityResponse and handle offers from old versions in case the available arbitrators has changed. - Remove MakerVerifyMediatorSelection and TakerSelectArbitrator The mediator handling should be removed as it is not used and not intended anymore to be used with the current trade protocol, but we leave that as it is a bit tricky to ensure backward compatibility. Also the setting of the arbitrator in trade should be further refactored but as it is also easy to break backward compatibility here we leave that for now. As we work on the new trade protocol that domain will become deprecated anyway in the next months... --- .../availability/ArbitratorSelection.java | 17 ---- .../ProcessOfferAvailabilityResponse.java | 80 ++++++++++++------- core/src/main/java/bisq/core/trade/Trade.java | 15 ++-- .../trade/protocol/BuyerAsMakerProtocol.java | 2 - .../trade/protocol/BuyerAsTakerProtocol.java | 2 - .../trade/protocol/SellerAsMakerProtocol.java | 2 - .../trade/protocol/SellerAsTakerProtocol.java | 2 - .../maker/MakerVerifyMediatorSelection.java | 55 ------------- .../tasks/taker/TakerSelectArbitrator.java | 51 ------------ .../tasks/taker/TakerSelectMediator.java | 23 +++++- .../bisq/desktop/main/debug/DebugView.java | 7 -- .../bisq/desktop/main/offer/OfferView.java | 35 ++++---- 12 files changed, 91 insertions(+), 200 deletions(-) delete mode 100644 core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerVerifyMediatorSelection.java delete mode 100644 core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSelectArbitrator.java diff --git a/core/src/main/java/bisq/core/offer/availability/ArbitratorSelection.java b/core/src/main/java/bisq/core/offer/availability/ArbitratorSelection.java index 71f28920029..10ca64faa2f 100644 --- a/core/src/main/java/bisq/core/offer/availability/ArbitratorSelection.java +++ b/core/src/main/java/bisq/core/offer/availability/ArbitratorSelection.java @@ -24,13 +24,9 @@ import bisq.common.util.Tuple2; -import java.text.ParseException; -import java.text.SimpleDateFormat; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.Date; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -38,25 +34,12 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import static com.google.common.base.Preconditions.checkArgument; @Slf4j public class ArbitratorSelection { - @Getter - private static boolean isNewRuleActivated; - - static { - try { - //TODO set activation data to 3 weeks after release - Date activationDate = new SimpleDateFormat("dd/MM/yyyy").parse("15/12/2018"); - isNewRuleActivated = new Date().after(activationDate); - } catch (ParseException e) { - e.printStackTrace(); - } - } public static Arbitrator getLeastUsedArbitrator(TradeStatisticsManager tradeStatisticsManager, ArbitratorManager arbitratorManager) { diff --git a/core/src/main/java/bisq/core/offer/availability/tasks/ProcessOfferAvailabilityResponse.java b/core/src/main/java/bisq/core/offer/availability/tasks/ProcessOfferAvailabilityResponse.java index 526c1f38123..2fddd54e62a 100644 --- a/core/src/main/java/bisq/core/offer/availability/tasks/ProcessOfferAvailabilityResponse.java +++ b/core/src/main/java/bisq/core/offer/availability/tasks/ProcessOfferAvailabilityResponse.java @@ -19,7 +19,6 @@ import bisq.core.offer.AvailabilityResult; import bisq.core.offer.Offer; -import bisq.core.offer.availability.ArbitratorSelection; import bisq.core.offer.availability.OfferAvailabilityModel; import bisq.core.offer.messages.OfferAvailabilityResponse; import bisq.core.trade.protocol.ArbitratorSelectionRule; @@ -32,9 +31,13 @@ import com.google.common.collect.Lists; import java.util.List; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + @Slf4j public class ProcessOfferAvailabilityResponse extends Task { public ProcessOfferAvailabilityResponse(TaskRunner taskHandler, OfferAvailabilityModel model) { @@ -46,39 +49,56 @@ protected void run() { Offer offer = model.getOffer(); try { runInterceptHook(); + + checkArgument(offer.getState() != Offer.State.REMOVED, "Offer state must not be Offer.State.REMOVED"); + OfferAvailabilityResponse offerAvailabilityResponse = model.getMessage(); - if (offer.getState() != Offer.State.REMOVED) { - if (offerAvailabilityResponse.getAvailabilityResult() == AvailabilityResult.AVAILABLE) { - offer.setState(Offer.State.AVAILABLE); - if (ArbitratorSelection.isNewRuleActivated()) { - NodeAddress selectedArbitrator = offerAvailabilityResponse.getArbitrator(); - if (selectedArbitrator == null) { - log.debug("Maker is on old version and does not send the selected arbitrator in the offerAvailabilityResponse. " + - "We use the old selection model instead with the supported arbitrators of the offers"); - List acceptedArbitratorAddresses = model.getUser().getAcceptedArbitratorAddresses(); - log.error("acceptedArbitratorAddresses " + acceptedArbitratorAddresses); - if (acceptedArbitratorAddresses != null) { - try { - model.setSelectedArbitrator(ArbitratorSelectionRule.select(Lists.newArrayList(acceptedArbitratorAddresses), offer)); - } catch (Throwable t) { - failed("There is no arbitrator matching that offer. The maker has " + - "not updated to the latest version and the arbitrators selected for that offer are not available anymore."); - } - } else { - failed("There is no arbitrator available."); - } - } else { - model.setSelectedArbitrator(selectedArbitrator); - } - } - } else { - offer.setState(Offer.State.NOT_AVAILABLE); - failed("Take offer attempt rejected because of: " + offerAvailabilityResponse.getAvailabilityResult()); - } + if (offerAvailabilityResponse.getAvailabilityResult() != AvailabilityResult.AVAILABLE) { + offer.setState(Offer.State.NOT_AVAILABLE); + failed("Take offer attempt rejected because of: " + offerAvailabilityResponse.getAvailabilityResult()); + return; + } + + offer.setState(Offer.State.AVAILABLE); + + NodeAddress selectedArbitrator = offerAvailabilityResponse.getArbitrator(); + + if (selectedArbitrator != null) { + model.setSelectedArbitrator(selectedArbitrator); + complete(); + return; } - complete(); + // We have an offer from a maker who runs a pre 0.9 version. + log.info("Maker has on old version and does not send the selected arbitrator in the offerAvailabilityResponse. " + + "We use the old selection model instead with the supported arbitrators of the offers"); + + List userArbitratorAddresses = model.getUser().getAcceptedArbitratorAddresses(); + checkNotNull(userArbitratorAddresses, "model.getUser().getAcceptedArbitratorAddresses() must not be null"); + + List offerArbitratorNodeAddresses = offer.getArbitratorNodeAddresses(); + + List matchingArbitrators = offerArbitratorNodeAddresses.stream() + .filter(userArbitratorAddresses::contains) + .collect(Collectors.toList()); + + if (!matchingArbitrators.isEmpty()) { + // We have at least one arbitrator which was used in the offer and is still available. + try { + model.setSelectedArbitrator(ArbitratorSelectionRule.select(Lists.newArrayList(matchingArbitrators), offer)); + complete(); + } catch (Throwable t) { + failed("There is no arbitrator matching that offer. The maker has " + + "not updated to the latest version and the arbitrators selected for that offer are not available anymore."); + } + } else { + // If an arbitrator which was selected in the offer from an old version has revoked we would get a failed take-offer attempt + // with lost trade fees. To avoid that we fail here after 1 week after the new rule is activated. + // Because one arbitrator need to revoke his application and register new as he gets too many transactions already + // we need to handle the planned revoke case. + failed("You cannot take that offer because the maker has not updated to version 0.9."); + } } catch (Throwable t) { offer.setErrorMessage("An error occurred.\n" + "Error message:\n" diff --git a/core/src/main/java/bisq/core/trade/Trade.java b/core/src/main/java/bisq/core/trade/Trade.java index 38829fd4a67..ef9e7438850 100644 --- a/core/src/main/java/bisq/core/trade/Trade.java +++ b/core/src/main/java/bisq/core/trade/Trade.java @@ -30,7 +30,6 @@ import bisq.core.offer.Offer; import bisq.core.offer.OfferUtil; import bisq.core.offer.OpenOfferManager; -import bisq.core.offer.availability.ArbitratorSelection; import bisq.core.payment.AccountAgeWitnessService; import bisq.core.payment.payload.PaymentMethod; import bisq.core.proto.CoreProtoResolver; @@ -523,14 +522,12 @@ public void init(P2PService p2PService, useSavingsWallet, fundsNeededForTrade); - if (ArbitratorSelection.isNewRuleActivated()) { - Optional optionalArbitrator = processModel.getArbitratorManager().getArbitratorByNodeAddress(arbitratorNodeAddress); - if (optionalArbitrator.isPresent()) { - Arbitrator arbitrator = optionalArbitrator.get(); - arbitratorBtcPubKey = arbitrator.getBtcPubKey(); - arbitratorPubKeyRing = arbitrator.getPubKeyRing(); - UserThread.runAfter(() -> this.persist(), 1); - } + Optional optionalArbitrator = processModel.getArbitratorManager().getArbitratorByNodeAddress(arbitratorNodeAddress); + if (optionalArbitrator.isPresent()) { + Arbitrator arbitrator = optionalArbitrator.get(); + arbitratorBtcPubKey = arbitrator.getBtcPubKey(); + arbitratorPubKeyRing = arbitrator.getPubKeyRing(); + UserThread.runAfter(this::persist, 1); } createTradeProtocol(); diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java index 1a064376dc8..9f50d309517 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java @@ -36,7 +36,6 @@ import bisq.core.trade.protocol.tasks.maker.MakerProcessPayDepositRequest; import bisq.core.trade.protocol.tasks.maker.MakerSendPublishDepositTxRequest; import bisq.core.trade.protocol.tasks.maker.MakerSetupDepositTxListener; -import bisq.core.trade.protocol.tasks.maker.MakerVerifyMediatorSelection; import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerAccount; import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerFeePayment; import bisq.core.util.Validator; @@ -131,7 +130,6 @@ public void handleTakeOfferRequest(TradeMessage tradeMessage, NodeAddress peerNo taskRunner.addTasks( MakerProcessPayDepositRequest.class, CheckIfPeerIsBanned.class, - MakerVerifyMediatorSelection.class, MakerVerifyTakerAccount.class, VerifyPeersAccountAgeWitness.class, MakerVerifyTakerFeePayment.class, diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java index 168944a2ba6..b77d702e01b 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java @@ -34,7 +34,6 @@ import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSignAndPublishDepositTx; import bisq.core.trade.protocol.tasks.taker.CreateTakerFeeTx; import bisq.core.trade.protocol.tasks.taker.TakerProcessPublishDepositTxRequest; -import bisq.core.trade.protocol.tasks.taker.TakerSelectArbitrator; import bisq.core.trade.protocol.tasks.taker.TakerSelectMediator; import bisq.core.trade.protocol.tasks.taker.TakerSendDepositTxPublishedMessage; import bisq.core.trade.protocol.tasks.taker.TakerSendPayDepositRequest; @@ -114,7 +113,6 @@ public void takeAvailableOffer() { this::handleTaskRunnerFault); taskRunner.addTasks( - TakerSelectArbitrator.class, TakerSelectMediator.class, TakerVerifyMakerAccount.class, TakerVerifyMakerFeePayment.class, diff --git a/core/src/main/java/bisq/core/trade/protocol/SellerAsMakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/SellerAsMakerProtocol.java index 6f586f303ff..1bcd137643c 100644 --- a/core/src/main/java/bisq/core/trade/protocol/SellerAsMakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/SellerAsMakerProtocol.java @@ -32,7 +32,6 @@ import bisq.core.trade.protocol.tasks.maker.MakerProcessPayDepositRequest; import bisq.core.trade.protocol.tasks.maker.MakerSendPublishDepositTxRequest; import bisq.core.trade.protocol.tasks.maker.MakerSetupDepositTxListener; -import bisq.core.trade.protocol.tasks.maker.MakerVerifyMediatorSelection; import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerAccount; import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerFeePayment; import bisq.core.trade.protocol.tasks.seller.SellerBroadcastPayoutTx; @@ -126,7 +125,6 @@ public void handleTakeOfferRequest(TradeMessage tradeMessage, NodeAddress sender taskRunner.addTasks( MakerProcessPayDepositRequest.class, CheckIfPeerIsBanned.class, - MakerVerifyMediatorSelection.class, MakerVerifyTakerAccount.class, VerifyPeersAccountAgeWitness.class, MakerVerifyTakerFeePayment.class, diff --git a/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java index 83f5b0cd42a..5d3cb300686 100644 --- a/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/SellerAsTakerProtocol.java @@ -34,7 +34,6 @@ import bisq.core.trade.protocol.tasks.seller_as_taker.SellerAsTakerSignAndPublishDepositTx; import bisq.core.trade.protocol.tasks.taker.CreateTakerFeeTx; import bisq.core.trade.protocol.tasks.taker.TakerProcessPublishDepositTxRequest; -import bisq.core.trade.protocol.tasks.taker.TakerSelectArbitrator; import bisq.core.trade.protocol.tasks.taker.TakerSelectMediator; import bisq.core.trade.protocol.tasks.taker.TakerSendDepositTxPublishedMessage; import bisq.core.trade.protocol.tasks.taker.TakerSendPayDepositRequest; @@ -107,7 +106,6 @@ public void takeAvailableOffer() { taskRunner.addTasks( TakerVerifyMakerAccount.class, TakerVerifyMakerFeePayment.class, - TakerSelectArbitrator.class, TakerSelectMediator.class, CreateTakerFeeTx.class, SellerAsTakerCreatesDepositTxInputs.class, diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerVerifyMediatorSelection.java b/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerVerifyMediatorSelection.java deleted file mode 100644 index ac0b06c9d44..00000000000 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/maker/MakerVerifyMediatorSelection.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.trade.protocol.tasks.maker; - -import bisq.core.trade.Trade; -import bisq.core.trade.protocol.MediatorSelectionRule; -import bisq.core.trade.protocol.tasks.TradeTask; - -import bisq.network.p2p.NodeAddress; - -import bisq.common.taskrunner.TaskRunner; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class MakerVerifyMediatorSelection extends TradeTask { - - @SuppressWarnings({"WeakerAccess", "unused"}) - public MakerVerifyMediatorSelection(TaskRunner taskHandler, Trade trade) { - super(taskHandler, trade); - } - - @Override - protected void run() { - try { - runInterceptHook(); - - final NodeAddress selectedAddress = MediatorSelectionRule.select( - processModel.getTakerAcceptedMediatorNodeAddresses(), - processModel.getOffer()); - if (trade.getMediatorNodeAddress() != null && - trade.getMediatorNodeAddress().equals(selectedAddress)) - complete(); - else - failed("Mediator selection verification failed"); - } catch (Throwable t) { - failed(t); - } - } -} diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSelectArbitrator.java b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSelectArbitrator.java deleted file mode 100644 index 4785141d24a..00000000000 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSelectArbitrator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.trade.protocol.tasks.taker; - -import bisq.core.offer.availability.ArbitratorSelection; -import bisq.core.trade.Trade; -import bisq.core.trade.protocol.ArbitratorSelectionRule; -import bisq.core.trade.protocol.tasks.TradeTask; - -import bisq.common.taskrunner.TaskRunner; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class TakerSelectArbitrator extends TradeTask { - @SuppressWarnings({"WeakerAccess", "unused"}) - public TakerSelectArbitrator(TaskRunner taskHandler, Trade trade) { - super(taskHandler, trade); - } - - @Override - protected void run() { - try { - runInterceptHook(); - - // TODO can be removed after new rule is activated - if (!ArbitratorSelection.isNewRuleActivated()) { - trade.setArbitratorNodeAddress(ArbitratorSelectionRule.select(processModel.getUser().getAcceptedArbitratorAddresses(), processModel.getOffer())); - } - - complete(); - } catch (Throwable t) { - failed(t); - } - } -} diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSelectMediator.java b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSelectMediator.java index e540e41e0a2..e6e5dc92daf 100644 --- a/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSelectMediator.java +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/taker/TakerSelectMediator.java @@ -21,10 +21,17 @@ import bisq.core.trade.protocol.MediatorSelectionRule; import bisq.core.trade.protocol.tasks.TradeTask; +import bisq.network.p2p.NodeAddress; + import bisq.common.taskrunner.TaskRunner; +import java.util.List; + import lombok.extern.slf4j.Slf4j; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + @Slf4j public class TakerSelectMediator extends TradeTask { @SuppressWarnings({"WeakerAccess", "unused"}) @@ -36,10 +43,20 @@ public TakerSelectMediator(TaskRunner taskHandler, Trade trade) { protected void run() { try { runInterceptHook(); + List acceptedMediatorAddresses = processModel.getUser().getAcceptedMediatorAddresses(); + checkNotNull(acceptedMediatorAddresses, "acceptedMediatorAddresses must not be null"); + checkArgument(!acceptedMediatorAddresses.isEmpty(), "acceptedMediatorAddresses must not be empty"); + NodeAddress mediatorNodeAddress; + try { + mediatorNodeAddress = MediatorSelectionRule.select(acceptedMediatorAddresses, processModel.getOffer()); + } catch (Throwable t) { + // In case the mediator from the offer is not available anymore we just use the first. + // Mediators are not implemented anyway and we will remove it with the new trade protocol but we + // still need to be backward compatible so we cannot remove it now. + mediatorNodeAddress = acceptedMediatorAddresses.get(0); + } - trade.setMediatorNodeAddress(MediatorSelectionRule.select(processModel.getUser().getAcceptedMediatorAddresses(), - processModel.getOffer())); - + trade.setMediatorNodeAddress(mediatorNodeAddress); complete(); } catch (Throwable t) { failed(t); diff --git a/desktop/src/main/java/bisq/desktop/main/debug/DebugView.java b/desktop/src/main/java/bisq/desktop/main/debug/DebugView.java index b4dd0472088..a2418463245 100644 --- a/desktop/src/main/java/bisq/desktop/main/debug/DebugView.java +++ b/desktop/src/main/java/bisq/desktop/main/debug/DebugView.java @@ -39,7 +39,6 @@ import bisq.core.trade.protocol.tasks.maker.MakerProcessPayDepositRequest; import bisq.core.trade.protocol.tasks.maker.MakerSendPublishDepositTxRequest; import bisq.core.trade.protocol.tasks.maker.MakerSetupDepositTxListener; -import bisq.core.trade.protocol.tasks.maker.MakerVerifyMediatorSelection; import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerAccount; import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerFeePayment; import bisq.core.trade.protocol.tasks.seller.SellerBroadcastPayoutTx; @@ -51,7 +50,6 @@ import bisq.core.trade.protocol.tasks.seller_as_taker.SellerAsTakerSignAndPublishDepositTx; import bisq.core.trade.protocol.tasks.taker.CreateTakerFeeTx; import bisq.core.trade.protocol.tasks.taker.TakerProcessPublishDepositTxRequest; -import bisq.core.trade.protocol.tasks.taker.TakerSelectArbitrator; import bisq.core.trade.protocol.tasks.taker.TakerSelectMediator; import bisq.core.trade.protocol.tasks.taker.TakerSendDepositTxPublishedMessage; import bisq.core.trade.protocol.tasks.taker.TakerSendPayDepositRequest; @@ -110,7 +108,6 @@ public void initialize() { FXCollections.observableArrayList(Arrays.asList( MakerProcessPayDepositRequest.class, CheckIfPeerIsBanned.class, - MakerVerifyMediatorSelection.class, MakerVerifyTakerAccount.class, MakerVerifyTakerFeePayment.class, MakerCreateAndSignContract.class, @@ -134,7 +131,6 @@ public void initialize() { FXCollections.observableArrayList(Arrays.asList( TakerVerifyMakerAccount.class, TakerVerifyMakerFeePayment.class, - TakerSelectArbitrator.class, TakerSelectMediator.class, CreateTakerFeeTx.class, SellerAsTakerCreatesDepositTxInputs.class, @@ -161,8 +157,6 @@ public void initialize() { )); addGroup("BuyerAsTakerProtocol", FXCollections.observableArrayList(Arrays.asList( - TakerSelectArbitrator.class, - TakerSelectMediator.class, TakerVerifyMakerAccount.class, TakerVerifyMakerFeePayment.class, CreateTakerFeeTx.class, @@ -188,7 +182,6 @@ public void initialize() { FXCollections.observableArrayList(Arrays.asList( MakerProcessPayDepositRequest.class, CheckIfPeerIsBanned.class, - MakerVerifyMediatorSelection.class, MakerVerifyTakerAccount.class, MakerVerifyTakerFeePayment.class, MakerCreateAndSignContract.class, diff --git a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java index 22b6a496bb8..0333776127c 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java @@ -35,7 +35,6 @@ import bisq.core.locale.TradeCurrency; import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; -import bisq.core.offer.availability.ArbitratorSelection; import bisq.core.user.Preferences; import bisq.network.p2p.NodeAddress; @@ -181,27 +180,23 @@ public void onCreateOffer(TradeCurrency tradeCurrency) { @Override public void onTakeOffer(Offer offer) { if (!takeOfferViewOpen) { - if (ArbitratorSelection.isNewRuleActivated()) { + List arbitratorNodeAddresses = offer.getArbitratorNodeAddresses(); + List arbitratorLanguages = arbitratorManager.getArbitratorLanguages(arbitratorNodeAddresses); + if (!arbitratorLanguages.isEmpty()) { + if (arbitratorLanguages.stream() + .noneMatch(languages -> languages.equals(preferences.getUserLanguage()))) { + showNoArbitratorForUserLocaleWarning(); + } openTakeOffer(offer); } else { - List arbitratorNodeAddresses = offer.getArbitratorNodeAddresses(); - List arbitratorLanguages = arbitratorManager.getArbitratorLanguages(arbitratorNodeAddresses); - if (!arbitratorLanguages.isEmpty()) { - if (arbitratorLanguages.stream() - .noneMatch(languages -> languages.equals(preferences.getUserLanguage()))) { - showNoArbitratorForUserLocaleWarning(); - } - openTakeOffer(offer); - } else { - // No need to translate that as this should only be a very temporary issue after 0.9 release. - String message = "There is no arbitrator available matching the offer's " + - "supported arbitrators list. That might happen if the arbitrators of the offer have " + - "revoked and the maker has not updated to version 0.9."; - log.warn(message + " offer.getArbitratorNodeAddresses()={}", arbitratorNodeAddresses); - new Popup<>().warning(message) - .closeButtonText(Res.get("shared.ok")) - .show(); - } + // No need to translate that as this should only be a very temporary issue after 0.9 release. + String message = "There is no arbitrator available matching the offer's " + + "supported arbitrators list. That might happen if the arbitrators of the offer have " + + "revoked and the maker has not updated to version 0.9."; + log.warn(message + " offer.getArbitratorNodeAddresses()={}", arbitratorNodeAddresses); + new Popup<>().warning(message) + .closeButtonText(Res.get("shared.ok")) + .show(); } } else { log.error("You have already a \"Take offer\" tab open."); From d7fe1dbeb3fa9f86708a4fd6fe08764d8091a28c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 24 Nov 2018 00:44:56 +0100 Subject: [PATCH 4/4] Handle edge cases with removed arbitrators --- .../java/bisq/core/offer/OpenOfferManager.java | 8 ++++---- .../java/bisq/desktop/main/offer/OfferView.java | 15 +++++---------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/bisq/core/offer/OpenOfferManager.java b/core/src/main/java/bisq/core/offer/OpenOfferManager.java index cadd983365b..d298b52e4d6 100644 --- a/core/src/main/java/bisq/core/offer/OpenOfferManager.java +++ b/core/src/main/java/bisq/core/offer/OpenOfferManager.java @@ -563,15 +563,15 @@ private void handleOfferAvailabilityRequest(OfferAvailabilityRequest request, No if (openOfferOptional.isPresent()) { OpenOffer openOffer = openOfferOptional.get(); if (openOffer.getState() == OpenOffer.State.AVAILABLE) { - final Offer offer = openOffer.getOffer(); + Offer offer = openOffer.getOffer(); if (preferences.getIgnoreTradersList().stream().noneMatch(hostName -> hostName.equals(peer.getHostName()))) { availabilityResult = AvailabilityResult.AVAILABLE; - arbitratorNodeAddress = ArbitratorSelection.getLeastUsedArbitrator(tradeStatisticsManager, arbitratorManager).getNodeAddress(); - openOffer.setArbitratorNodeAddress(arbitratorNodeAddress); - List acceptedArbitrators = user.getAcceptedArbitratorAddresses(); if (acceptedArbitrators != null && !acceptedArbitrators.isEmpty()) { + arbitratorNodeAddress = ArbitratorSelection.getLeastUsedArbitrator(tradeStatisticsManager, arbitratorManager).getNodeAddress(); + openOffer.setArbitratorNodeAddress(arbitratorNodeAddress); + // Check also tradePrice to avoid failures after taker fee is paid caused by a too big difference // in trade price between the peers. Also here poor connectivity might cause market price API connection // losses and therefore an outdated market price. diff --git a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java index 0333776127c..84313552c81 100644 --- a/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java +++ b/desktop/src/main/java/bisq/desktop/main/offer/OfferView.java @@ -182,21 +182,16 @@ public void onTakeOffer(Offer offer) { if (!takeOfferViewOpen) { List arbitratorNodeAddresses = offer.getArbitratorNodeAddresses(); List arbitratorLanguages = arbitratorManager.getArbitratorLanguages(arbitratorNodeAddresses); - if (!arbitratorLanguages.isEmpty()) { + if (arbitratorLanguages.isEmpty()) { + // In case we get an offer which has been created with arbitrators which are not available + // anymore we don't want to call the showNoArbitratorForUserLocaleWarning + openTakeOffer(offer); + } else { if (arbitratorLanguages.stream() .noneMatch(languages -> languages.equals(preferences.getUserLanguage()))) { showNoArbitratorForUserLocaleWarning(); } openTakeOffer(offer); - } else { - // No need to translate that as this should only be a very temporary issue after 0.9 release. - String message = "There is no arbitrator available matching the offer's " + - "supported arbitrators list. That might happen if the arbitrators of the offer have " + - "revoked and the maker has not updated to version 0.9."; - log.warn(message + " offer.getArbitratorNodeAddresses()={}", arbitratorNodeAddresses); - new Popup<>().warning(message) - .closeButtonText(Res.get("shared.ok")) - .show(); } } else { log.error("You have already a \"Take offer\" tab open.");