Merge pull request #1958 from ManfredKarrer/improve-backward-compatibility-with-new-arb-selection

Improve backward compatibility with new arb selection
This commit is contained in:
Christoph Atteneder 2018-11-26 11:25:26 +01:00 committed by GitHub
commit c7c20fb2ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 123 additions and 179 deletions

View File

@ -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 class GenesisTxInfo {
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 class GenesisTxInfo {
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;
}

View File

@ -563,15 +563,15 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
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<NodeAddress> 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.

View File

@ -24,13 +24,9 @@ import bisq.core.trade.statistics.TradeStatisticsManager;
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.Set;
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) {

View File

@ -19,6 +19,7 @@ package bisq.core.offer.availability;
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() {

View File

@ -19,15 +19,26 @@ package bisq.core.offer.availability.tasks;
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;
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 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<OfferAvailabilityModel> {
public ProcessOfferAvailabilityResponse(TaskRunner taskHandler, OfferAvailabilityModel model) {
super(taskHandler, model);
@ -35,29 +46,61 @@ public class ProcessOfferAvailabilityResponse extends Task<OfferAvailabilityMode
@Override
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 (model.getOffer().getState() != Offer.State.REMOVED) {
if (offerAvailabilityResponse.getAvailabilityResult() == AvailabilityResult.AVAILABLE) {
model.getOffer().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
model.setSelectedArbitrator(selectedArbitrator);
}
} else {
model.getOffer().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;
}
complete();
offer.setState(Offer.State.AVAILABLE);
NodeAddress selectedArbitrator = offerAvailabilityResponse.getArbitrator();
if (selectedArbitrator != null) {
model.setSelectedArbitrator(selectedArbitrator);
complete();
return;
}
// 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<NodeAddress> userArbitratorAddresses = model.getUser().getAcceptedArbitratorAddresses();
checkNotNull(userArbitratorAddresses, "model.getUser().getAcceptedArbitratorAddresses() must not be null");
List<NodeAddress> offerArbitratorNodeAddresses = offer.getArbitratorNodeAddresses();
List<NodeAddress> 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) {
model.getOffer().setErrorMessage("An error occurred.\n" +
offer.setErrorMessage("An error occurred.\n" +
"Error message:\n"
+ t.getMessage());

View File

@ -30,7 +30,6 @@ import bisq.core.monetary.Volume;
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 abstract class Trade implements Tradable, Model {
useSavingsWallet,
fundsNeededForTrade);
if (ArbitratorSelection.isNewRuleActivated()) {
Optional<Arbitrator> optionalArbitrator = processModel.getArbitratorManager().getArbitratorByNodeAddress(arbitratorNodeAddress);
if (optionalArbitrator.isPresent()) {
Arbitrator arbitrator = optionalArbitrator.get();
arbitratorBtcPubKey = arbitrator.getBtcPubKey();
arbitratorPubKeyRing = arbitrator.getPubKeyRing();
UserThread.runAfter(() -> this.persist(), 1);
}
Optional<Arbitrator> optionalArbitrator = processModel.getArbitratorManager().getArbitratorByNodeAddress(arbitratorNodeAddress);
if (optionalArbitrator.isPresent()) {
Arbitrator arbitrator = optionalArbitrator.get();
arbitratorBtcPubKey = arbitrator.getBtcPubKey();
arbitratorPubKeyRing = arbitrator.getPubKeyRing();
UserThread.runAfter(this::persist, 1);
}
createTradeProtocol();

View File

@ -473,7 +473,8 @@ public class TradeManager implements PersistedDataHost {
return new OfferAvailabilityModel(
offer,
keyRing.getPubKeyRing(),
p2PService);
p2PService,
user);
}

View File

@ -36,7 +36,6 @@ import bisq.core.trade.protocol.tasks.maker.MakerProcessDepositTxPublishedMessag
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 class BuyerAsMakerProtocol extends TradeProtocol implements BuyerProtocol
taskRunner.addTasks(
MakerProcessPayDepositRequest.class,
CheckIfPeerIsBanned.class,
MakerVerifyMediatorSelection.class,
MakerVerifyTakerAccount.class,
VerifyPeersAccountAgeWitness.class,
MakerVerifyTakerFeePayment.class,

View File

@ -34,7 +34,6 @@ import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerCreatesDepositT
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 class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
this::handleTaskRunnerFault);
taskRunner.addTasks(
TakerSelectArbitrator.class,
TakerSelectMediator.class,
TakerVerifyMakerAccount.class,
TakerVerifyMakerFeePayment.class,

View File

@ -32,7 +32,6 @@ import bisq.core.trade.protocol.tasks.maker.MakerProcessDepositTxPublishedMessag
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 class SellerAsMakerProtocol extends TradeProtocol implements SellerProtoc
taskRunner.addTasks(
MakerProcessPayDepositRequest.class,
CheckIfPeerIsBanned.class,
MakerVerifyMediatorSelection.class,
MakerVerifyTakerAccount.class,
VerifyPeersAccountAgeWitness.class,
MakerVerifyTakerFeePayment.class,

View File

@ -34,7 +34,6 @@ import bisq.core.trade.protocol.tasks.seller_as_taker.SellerAsTakerCreatesDeposi
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 class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
taskRunner.addTasks(
TakerVerifyMakerAccount.class,
TakerVerifyMakerFeePayment.class,
TakerSelectArbitrator.class,
TakerSelectMediator.class,
CreateTakerFeeTx.class,
SellerAsTakerCreatesDepositTxInputs.class,

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}

View File

@ -21,10 +21,17 @@ 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 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 class TakerSelectMediator extends TradeTask {
protected void run() {
try {
runInterceptHook();
List<NodeAddress> 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);

View File

@ -39,7 +39,6 @@ import bisq.core.trade.protocol.tasks.maker.MakerProcessDepositTxPublishedMessag
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.SellerAsTakerCreatesDeposi
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 class DebugView extends InitializableView<GridPane, Void> {
FXCollections.observableArrayList(Arrays.asList(
MakerProcessPayDepositRequest.class,
CheckIfPeerIsBanned.class,
MakerVerifyMediatorSelection.class,
MakerVerifyTakerAccount.class,
MakerVerifyTakerFeePayment.class,
MakerCreateAndSignContract.class,
@ -134,7 +131,6 @@ public class DebugView extends InitializableView<GridPane, Void> {
FXCollections.observableArrayList(Arrays.asList(
TakerVerifyMakerAccount.class,
TakerVerifyMakerFeePayment.class,
TakerSelectArbitrator.class,
TakerSelectMediator.class,
CreateTakerFeeTx.class,
SellerAsTakerCreatesDepositTxInputs.class,
@ -161,8 +157,6 @@ public class DebugView extends InitializableView<GridPane, Void> {
));
addGroup("BuyerAsTakerProtocol",
FXCollections.observableArrayList(Arrays.asList(
TakerSelectArbitrator.class,
TakerSelectMediator.class,
TakerVerifyMakerAccount.class,
TakerVerifyMakerFeePayment.class,
CreateTakerFeeTx.class,
@ -188,7 +182,6 @@ public class DebugView extends InitializableView<GridPane, Void> {
FXCollections.observableArrayList(Arrays.asList(
MakerProcessPayDepositRequest.class,
CheckIfPeerIsBanned.class,
MakerVerifyMediatorSelection.class,
MakerVerifyTakerAccount.class,
MakerVerifyTakerFeePayment.class,
MakerCreateAndSignContract.class,

View File

@ -37,6 +37,8 @@ import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
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 +166,8 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
@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 +180,19 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
@Override
public void onTakeOffer(Offer offer) {
if (!takeOfferViewOpen) {
if (!arbitratorManager.getArbitratorLanguages(offer.getArbitratorNodeAddresses()).stream()
.anyMatch(languages -> languages.equals(preferences.getUserLanguage()))) {
showNoArbitratorForUserLocaleWarning();
List<NodeAddress> arbitratorNodeAddresses = offer.getArbitratorNodeAddresses();
List<String> arbitratorLanguages = arbitratorManager.getArbitratorLanguages(arbitratorNodeAddresses);
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);
}
openTakeOffer(offer);
} else {
log.error("You have already a \"Take offer\" tab open.");
}