diff --git a/core/src/main/java/haveno/core/app/DomainInitialisation.java b/core/src/main/java/haveno/core/app/DomainInitialisation.java index 7918ebc7..7ab65c70 100644 --- a/core/src/main/java/haveno/core/app/DomainInitialisation.java +++ b/core/src/main/java/haveno/core/app/DomainInitialisation.java @@ -34,7 +34,6 @@ import haveno.core.offer.OpenOfferManager; import haveno.core.offer.TriggerPriceService; import haveno.core.payment.AmazonGiftCardAccount; import haveno.core.payment.RevolutAccount; -import haveno.core.provider.mempool.MempoolService; import haveno.core.provider.price.PriceFeedService; import haveno.core.support.dispute.arbitration.ArbitrationManager; import haveno.core.support.dispute.arbitration.arbitrator.ArbitratorManager; @@ -93,7 +92,6 @@ public class DomainInitialisation { private final MarketAlerts marketAlerts; private final User user; private final TriggerPriceService triggerPriceService; - private final MempoolService mempoolService; private final MailboxMessageService mailboxMessageService; @Inject @@ -126,7 +124,6 @@ public class DomainInitialisation { MarketAlerts marketAlerts, User user, TriggerPriceService triggerPriceService, - MempoolService mempoolService, MailboxMessageService mailboxMessageService) { this.clockWatcher = clockWatcher; this.arbitrationManager = arbitrationManager; @@ -157,7 +154,6 @@ public class DomainInitialisation { this.marketAlerts = marketAlerts; this.user = user; this.triggerPriceService = triggerPriceService; - this.mempoolService = mempoolService; this.mailboxMessageService = mailboxMessageService; } @@ -215,7 +211,6 @@ public class DomainInitialisation { priceAlert.onAllServicesInitialized(); marketAlerts.onAllServicesInitialized(); triggerPriceService.onAllServicesInitialized(); - mempoolService.onAllServicesInitialized(); mailboxMessageService.onAllServicesInitialized(); diff --git a/core/src/main/java/haveno/core/offer/TriggerPriceService.java b/core/src/main/java/haveno/core/offer/TriggerPriceService.java index 37ebdaaf..8e323406 100644 --- a/core/src/main/java/haveno/core/offer/TriggerPriceService.java +++ b/core/src/main/java/haveno/core/offer/TriggerPriceService.java @@ -22,7 +22,6 @@ import haveno.core.locale.CurrencyUtil; import haveno.core.monetary.CryptoMoney; import haveno.core.monetary.Price; import haveno.core.monetary.TraditionalMoney; -import haveno.core.provider.mempool.MempoolService; import haveno.core.provider.price.MarketPrice; import haveno.core.provider.price.PriceFeedService; import haveno.network.p2p.BootstrapListener; @@ -47,18 +46,15 @@ import static haveno.common.util.MathUtils.scaleUpByPowerOf10; public class TriggerPriceService { private final P2PService p2PService; private final OpenOfferManager openOfferManager; - private final MempoolService mempoolService; private final PriceFeedService priceFeedService; private final Map> openOffersByCurrency = new HashMap<>(); @Inject public TriggerPriceService(P2PService p2PService, OpenOfferManager openOfferManager, - MempoolService mempoolService, PriceFeedService priceFeedService) { this.p2PService = p2PService; this.openOfferManager = openOfferManager; - this.mempoolService = mempoolService; this.priceFeedService = priceFeedService; } @@ -152,19 +148,7 @@ public class TriggerPriceService { }, errorMessage -> { }); } else if (openOffer.getState() == OpenOffer.State.AVAILABLE) { - // check the mempool if it has not been done before - if (openOffer.getMempoolStatus() < 0 && mempoolService.canRequestBeMade(openOffer.getOffer().getOfferPayload())) { - mempoolService.validateOfferMakerTx(openOffer.getOffer().getOfferPayload(), (txValidator -> { - openOffer.setMempoolStatus(txValidator.isFail() ? 0 : 1); - })); - } - // if the mempool indicated failure then deactivate the open offer - if (openOffer.getMempoolStatus() == 0) { - log.info("Deactivating open offer {} due to mempool validation", openOffer.getOffer().getShortId()); - openOfferManager.deactivateOpenOffer(openOffer, () -> { - }, errorMessage -> { - }); - } + // TODO: check if open offer's reserve tx is failed or double spend seen } } diff --git a/core/src/main/java/haveno/core/provider/mempool/MempoolRequest.java b/core/src/main/java/haveno/core/provider/mempool/MempoolRequest.java deleted file mode 100644 index ea2873f0..00000000 --- a/core/src/main/java/haveno/core/provider/mempool/MempoolRequest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of Haveno. - * - * Haveno 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. - * - * Haveno 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 Haveno. If not, see . - */ - -package haveno.core.provider.mempool; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import haveno.common.util.Utilities; -import haveno.core.provider.MempoolHttpClient; -import haveno.core.user.Preferences; -import haveno.network.Socks5ProxyProvider; -import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import static com.google.common.base.Preconditions.checkNotNull; - -@Slf4j -public class MempoolRequest { - private static final ListeningExecutorService executorService = Utilities.getListeningExecutorService("MempoolRequest", 3, 5, 10 * 60); - private final List txBroadcastServices = new ArrayList<>(); - private final MempoolHttpClient mempoolHttpClient; - - public MempoolRequest(Preferences preferences, Socks5ProxyProvider socks5ProxyProvider) { - this.txBroadcastServices.addAll(preferences.getDefaultTxBroadcastServices()); - this.mempoolHttpClient = new MempoolHttpClient(socks5ProxyProvider); - } - - public void getTxStatus(SettableFuture mempoolServiceCallback, String txId) { - mempoolHttpClient.setBaseUrl(getRandomServiceAddress(txBroadcastServices)); - ListenableFuture future = executorService.submit(() -> { - Thread.currentThread().setName("MempoolRequest @ " + mempoolHttpClient.getBaseUrl()); - log.info("Making http request for information on txId: {}", txId); - return mempoolHttpClient.getTxDetails(txId); - }); - - Futures.addCallback(future, new FutureCallback<>() { - public void onSuccess(String mempoolData) { - log.info("Received mempoolData of [{}] from provider", mempoolData); - mempoolServiceCallback.set(mempoolData); - } - public void onFailure(@NotNull Throwable throwable) { - mempoolServiceCallback.setException(throwable); - } - }, MoreExecutors.directExecutor()); - } - - public boolean switchToAnotherProvider() { - txBroadcastServices.remove(mempoolHttpClient.getBaseUrl()); - return txBroadcastServices.size() > 0; - } - - @Nullable - private static String getRandomServiceAddress(List txBroadcastServices) { - List list = checkNotNull(txBroadcastServices); - return !list.isEmpty() ? list.get(new Random().nextInt(list.size())) : null; - } -} - diff --git a/core/src/main/java/haveno/core/provider/mempool/MempoolService.java b/core/src/main/java/haveno/core/provider/mempool/MempoolService.java deleted file mode 100644 index d92dea00..00000000 --- a/core/src/main/java/haveno/core/provider/mempool/MempoolService.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * This file is part of Haveno. - * - * Haveno 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. - * - * Haveno 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 Haveno. If not, see . - */ - -package haveno.core.provider.mempool; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import com.google.inject.Inject; -import haveno.common.UserThread; -import haveno.common.config.Config; -import haveno.core.filter.FilterManager; -import haveno.core.offer.OfferPayload; -import haveno.core.trade.Trade; -import haveno.core.user.Preferences; -import haveno.network.Socks5ProxyProvider; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.bitcoinj.core.Coin; - -import javax.annotation.Nullable; -import javax.inject.Singleton; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.function.Consumer; - -@Slf4j -@Singleton -public class MempoolService { - private final Socks5ProxyProvider socks5ProxyProvider; - private final Config config; - private final Preferences preferences; - private final FilterManager filterManager; - private final List btcFeeReceivers = new ArrayList<>(); - @Getter - private int outstandingRequests = 0; - - @Inject - public MempoolService(Socks5ProxyProvider socks5ProxyProvider, - Config config, - Preferences preferences, - FilterManager filterManager) { - this.socks5ProxyProvider = socks5ProxyProvider; - this.config = config; - this.preferences = preferences; - this.filterManager = filterManager; - } - - public void onAllServicesInitialized() { - btcFeeReceivers.addAll(getAllBtcFeeReceivers()); - } - - public boolean canRequestBeMade() { - return outstandingRequests < 5; // limit max simultaneous lookups - } - - public boolean canRequestBeMade(OfferPayload offerPayload) { - // when validating a new offer, wait 1 block for the tx to propagate - return canRequestBeMade(); - } - - public void validateOfferMakerTx(OfferPayload offerPayload, Consumer resultHandler) { - validateOfferMakerTx(new TxValidator( offerPayload.getOfferFeeTxId(), Coin.valueOf(offerPayload.getAmount())), resultHandler); - } - - public void validateOfferMakerTx(TxValidator txValidator, Consumer resultHandler) { - if (!isServiceSupported()) { - UserThread.runAfter(() -> resultHandler.accept(txValidator.endResult("mempool request not supported, bypassing", true)), 1); - return; - } - MempoolRequest mempoolRequest = new MempoolRequest(preferences, socks5ProxyProvider); - validateOfferMakerTx(mempoolRequest, txValidator, resultHandler); - } - - public void validateOfferTakerTx(Trade trade, Consumer resultHandler) { - throw new RuntimeException("MempoolService.validateOfferTakerTx needs updated for XMR"); - //validateOfferTakerTx(new TxValidator( trade.getTakerFeeTxId(), trade.getTradeAmount(),resultHandler)); - } - - public void validateOfferTakerTx(TxValidator txValidator, Consumer resultHandler) { - if (!isServiceSupported()) { - UserThread.runAfter(() -> resultHandler.accept(txValidator.endResult("mempool request not supported, bypassing", true)), 1); - return; - } - MempoolRequest mempoolRequest = new MempoolRequest(preferences, socks5ProxyProvider); - validateOfferTakerTx(mempoolRequest, txValidator, resultHandler); - } - - public void checkTxIsConfirmed(String txId, Consumer resultHandler) { - TxValidator txValidator = new TxValidator(txId); - if (!isServiceSupported()) { - UserThread.runAfter(() -> resultHandler.accept(txValidator.endResult("mempool request not supported, bypassing", true)), 1); - return; - } - MempoolRequest mempoolRequest = new MempoolRequest(preferences, socks5ProxyProvider); - SettableFuture future = SettableFuture.create(); - Futures.addCallback(future, callbackForTxRequest(mempoolRequest, txValidator, resultHandler), MoreExecutors.directExecutor()); - mempoolRequest.getTxStatus(future, txId); - } - - // /////////////////////////// - - private void validateOfferMakerTx(MempoolRequest mempoolRequest, - TxValidator txValidator, - Consumer resultHandler) { - SettableFuture future = SettableFuture.create(); - Futures.addCallback(future, callbackForMakerTxValidation(mempoolRequest, txValidator, resultHandler), MoreExecutors.directExecutor()); - mempoolRequest.getTxStatus(future, txValidator.getTxId()); - } - - private void validateOfferTakerTx(MempoolRequest mempoolRequest, - TxValidator txValidator, - Consumer resultHandler) { - SettableFuture future = SettableFuture.create(); - Futures.addCallback(future, callbackForTakerTxValidation(mempoolRequest, txValidator, resultHandler), MoreExecutors.directExecutor()); - mempoolRequest.getTxStatus(future, txValidator.getTxId()); - } - - private FutureCallback callbackForMakerTxValidation(MempoolRequest theRequest, - TxValidator txValidator, - Consumer resultHandler) { - outstandingRequests++; - FutureCallback myCallback = new FutureCallback<>() { - @Override - public void onSuccess(@Nullable String jsonTxt) { - UserThread.execute(() -> { - outstandingRequests--; - resultHandler.accept(txValidator.endResult("onSuccess", true)); - }); - } - - @Override - public void onFailure(Throwable throwable) { - log.warn("onFailure - {}", throwable.toString()); - UserThread.execute(() -> { - outstandingRequests--; - if (theRequest.switchToAnotherProvider()) { - validateOfferMakerTx(theRequest, txValidator, resultHandler); - } else { - // exhausted all providers, let user know of failure - resultHandler.accept(txValidator.endResult("Tx not found", false)); - } - }); - } - }; - return myCallback; - } - - private FutureCallback callbackForTakerTxValidation(MempoolRequest theRequest, - TxValidator txValidator, - Consumer resultHandler) { - outstandingRequests++; - FutureCallback myCallback = new FutureCallback<>() { - @Override - public void onSuccess(@Nullable String jsonTxt) { - UserThread.execute(() -> { - outstandingRequests--; - resultHandler.accept(txValidator.endResult("onSuccess", true)); - }); - } - - @Override - public void onFailure(Throwable throwable) { - log.warn("onFailure - {}", throwable.toString()); - UserThread.execute(() -> { - outstandingRequests--; - if (theRequest.switchToAnotherProvider()) { - validateOfferTakerTx(theRequest, txValidator, resultHandler); - } else { - // exhausted all providers, let user know of failure - resultHandler.accept(txValidator.endResult("Tx not found", false)); - } - }); - } - }; - return myCallback; - } - - private FutureCallback callbackForTxRequest(MempoolRequest theRequest, - TxValidator txValidator, - Consumer resultHandler) { - outstandingRequests++; - FutureCallback myCallback = new FutureCallback<>() { - @Override - public void onSuccess(@Nullable String jsonTxt) { - UserThread.execute(() -> { - outstandingRequests--; - txValidator.setJsonTxt(jsonTxt); - resultHandler.accept(txValidator); - }); - } - - @Override - public void onFailure(Throwable throwable) { - log.warn("onFailure - {}", throwable.toString()); - UserThread.execute(() -> { - outstandingRequests--; - resultHandler.accept(txValidator.endResult("Tx not found", false)); - }); - - } - }; - return myCallback; - } - - // ///////////////////////////// - - private List getAllBtcFeeReceivers() { - List btcFeeReceivers = new ArrayList<>(); - // fee receivers from filter ref: bisq-network/bisq/pull/4294 - List feeReceivers = Optional.ofNullable(filterManager.getFilter()) - .flatMap(f -> Optional.ofNullable(f.getBtcFeeReceiverAddresses())) - .orElse(List.of()); - feeReceivers.forEach(e -> { - try { - btcFeeReceivers.add(e.split("#")[0]); // victim's receiver address - } catch (RuntimeException ignore) { - // If input format is not as expected we ignore entry - } - }); - log.info("Known BTC fee receivers: {}", btcFeeReceivers.toString()); - - return btcFeeReceivers; - } - - private boolean isServiceSupported() { - if (filterManager.getFilter() != null && filterManager.getFilter().isDisableMempoolValidation()) { - log.info("MempoolService bypassed by filter setting disableMempoolValidation=true"); - return false; - } - if (config.bypassMempoolValidation) { - log.info("MempoolService bypassed by config setting bypassMempoolValidation=true"); - return false; - } - if (!Config.baseCurrencyNetwork().isMainnet()) { - log.info("MempoolService only supports mainnet"); - return false; - } - return true; - } -} diff --git a/core/src/main/java/haveno/core/provider/mempool/TxValidator.java b/core/src/main/java/haveno/core/provider/mempool/TxValidator.java deleted file mode 100644 index ccba4ee6..00000000 --- a/core/src/main/java/haveno/core/provider/mempool/TxValidator.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Haveno. - * - * Haveno 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. - * - * Haveno 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 Haveno. If not, see . - */ - -package haveno.core.provider.mempool; - -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.bitcoinj.core.Coin; - -import java.util.ArrayList; -import java.util.List; - -@Slf4j -@Getter -public class TxValidator { - - private final List errorList; - private final String txId; - private Coin amount; - @Setter - private String jsonTxt; - - - public TxValidator(String txId, Coin amount) { - this.txId = txId; - this.amount = amount; - this.errorList = new ArrayList<>(); - this.jsonTxt = ""; - } - - public TxValidator(String txId) { - this.txId = txId; - this.errorList = new ArrayList<>(); - this.jsonTxt = ""; - } - - public TxValidator endResult(String title, boolean status) { - log.info("{} : {}", title, status ? "SUCCESS" : "FAIL"); - if (!status) { - errorList.add(title); - } - return this; - } - - public boolean isFail() { - return errorList.size() > 0; - } - - public boolean getResult() { - return errorList.size() == 0; - } - - public String errorSummary() { - return errorList.toString().substring(0, Math.min(85, errorList.toString().length())); - } - - @Override - public String toString() { - return errorList.toString(); - } -} diff --git a/core/src/test/java/haveno/core/provider/mempool/TxValidatorTest.java b/core/src/test/java/haveno/core/provider/mempool/TxValidatorTest.java deleted file mode 100644 index 490a0fc8..00000000 --- a/core/src/test/java/haveno/core/provider/mempool/TxValidatorTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of Haveno. - * - * Haveno 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. - * - * Haveno 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 Haveno. If not, see . - */ - -package haveno.core.provider.mempool; - -import com.google.gson.Gson; -import org.apache.commons.io.IOUtils; -import org.bitcoinj.core.Coin; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class TxValidatorTest { - private static final Logger log = LoggerFactory.getLogger(TxValidatorTest.class); - - private List btcFeeReceivers = new ArrayList<>(); - - public TxValidatorTest() { - btcFeeReceivers.add("1EKXx73oUhHaUh8JBimtiPGgHfwNmxYKAj"); - btcFeeReceivers.add("1HpvvMHcoXQsX85CjTsco5ZAAMoGu2Mze9"); - btcFeeReceivers.add("3EfRGckBQQuk7cpU7SwatPv8kFD1vALkTU"); - btcFeeReceivers.add("13sxMq8mTw7CTSqgGiMPfwo6ZDsVYrHLmR"); - btcFeeReceivers.add("19qA2BVPoyXDfHKVMovKG7SoxGY7xrBV8c"); - btcFeeReceivers.add("19BNi5EpZhgBBWAt5ka7xWpJpX2ZWJEYyq"); - btcFeeReceivers.add("38bZBj5peYS3Husdz7AH3gEUiUbYRD951t"); - btcFeeReceivers.add("3EtUWqsGThPtjwUczw27YCo6EWvQdaPUyp"); - btcFeeReceivers.add("1BVxNn3T12veSK6DgqwU4Hdn7QHcDDRag7"); - btcFeeReceivers.add("3A8Zc1XioE2HRzYfbb5P8iemCS72M6vRJV"); - btcFeeReceivers.add("34VLFgtFKAtwTdZ5rengTT2g2zC99sWQLC"); - log.warn("Known BTC fee receivers: {}", btcFeeReceivers.toString()); - } - - @Test - public void testMakerTx() throws InterruptedException { - String mempoolData, offerData; - } - - @Test - public void testTakerTx() throws InterruptedException { - String mempoolData, offerData; - } - - private void testOfferSet(Map offers, Map mempoolData, boolean expectedResult) { - Set knownValuesList = new HashSet<>(offers.values()); - knownValuesList.forEach(offerData -> { - TxValidator txValidator = createTxValidator(offerData); - log.warn("TESTING {}", txValidator.getTxId()); - String jsonTxt = mempoolData.get(txValidator.getTxId()); - if (jsonTxt == null || jsonTxt.isEmpty()) { - log.warn("{} was not found in the mempool", txValidator.getTxId()); - assertFalse(expectedResult); // tx was not found in explorer - } else { - //txValidator.parseJsonValidateMakerFeeTx(jsonTxt, btcFeeReceivers); - log.warn("expectedResult {}", expectedResult ); - log.warn("getResult {}", txValidator.getResult() ); - assertTrue(expectedResult == txValidator.getResult()); - } - }); - } - - private Map loadJsonTestData(String fileName) { - String json = ""; - try { - json = IOUtils.toString(this.getClass().getResourceAsStream(fileName), "UTF-8"); - } catch (IOException e) { - log.error(e.toString()); - } - Map map = new Gson().fromJson(json, Map.class); - return map; - } - - // initialize the TxValidator with offerData to be validated - private TxValidator createTxValidator(String offerData) { - try { - String[] y = offerData.split(","); - String txId = y[1]; - long amount = Long.parseLong(y[2]); - TxValidator txValidator = new TxValidator(txId, Coin.valueOf(amount)); - return txValidator; - } catch (RuntimeException ignore) { - // If input format is not as expected we ignore entry - } - return null; - } -} diff --git a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferDataModel.java b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferDataModel.java index 61745fb8..ef3b3359 100644 --- a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferDataModel.java +++ b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferDataModel.java @@ -31,7 +31,6 @@ import haveno.core.offer.OfferUtil; import haveno.core.payment.PaymentAccount; import haveno.core.payment.PaymentAccountUtil; import haveno.core.payment.payload.PaymentMethod; -import haveno.core.provider.mempool.MempoolService; import haveno.core.provider.price.PriceFeedService; import haveno.core.trade.HavenoUtils; import haveno.core.trade.TradeManager; @@ -48,13 +47,10 @@ import haveno.desktop.main.offer.offerbook.OfferBook; import haveno.desktop.main.overlays.popups.Popup; import haveno.desktop.util.GUIUtil; import haveno.network.p2p.P2PService; -import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty; -import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.ObservableList; -import lombok.Getter; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -73,7 +69,6 @@ class TakeOfferDataModel extends OfferDataModel { private final TradeManager tradeManager; private final OfferBook offerBook; private final User user; - private final MempoolService mempoolService; private final FilterManager filterManager; final Preferences preferences; private final PriceFeedService priceFeedService; @@ -94,10 +89,6 @@ class TakeOfferDataModel extends OfferDataModel { private PaymentAccount paymentAccount; private boolean isTabSelected; Price tradePrice; - @Getter - protected final IntegerProperty mempoolStatus = new SimpleIntegerProperty(); - @Getter - protected String mempoolStatusText; /////////////////////////////////////////////////////////////////////////////////////////// @@ -111,7 +102,6 @@ class TakeOfferDataModel extends OfferDataModel { OfferUtil offerUtil, XmrWalletService xmrWalletService, User user, - MempoolService mempoolService, FilterManager filterManager, Preferences preferences, PriceFeedService priceFeedService, @@ -124,7 +114,6 @@ class TakeOfferDataModel extends OfferDataModel { this.tradeManager = tradeManager; this.offerBook = offerBook; this.user = user; - this.mempoolService = mempoolService; this.filterManager = filterManager; this.preferences = preferences; this.priceFeedService = priceFeedService; @@ -192,15 +181,6 @@ class TakeOfferDataModel extends OfferDataModel { getBuyerSecurityDeposit() : getSellerSecurityDeposit(); - mempoolStatus.setValue(-1); - mempoolService.validateOfferMakerTx(offer.getOfferPayload(), (txValidator -> { - mempoolStatus.setValue(txValidator.isFail() ? 0 : 1); - if (txValidator.isFail()) { - mempoolStatusText = txValidator.toString(); - log.info("Mempool check of OfferFeeTxId returned errors: [{}]", mempoolStatusText); - } - })); - calculateVolume(); calculateTotalToPay(); diff --git a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferView.java b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferView.java index db6c39d8..ab4b9a08 100644 --- a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferView.java +++ b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferView.java @@ -813,20 +813,8 @@ public class TakeOfferView extends ActivatableViewAndModel cancelButton1.fire()) - .show(); - } else { - if (result == -1) { - log.warn("Fee check has not returned a result yet. We optimistically assume all is ok and continue."); - } - showNextStepAfterAmountIsSet(); - } + // TODO: pre-check if open offer's reserve tx is failed or double spend seen? + showNextStepAfterAmountIsSet(); } private void showNextStepAfterAmountIsSet() { diff --git a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java index 6063d459..ee24c3ef 100644 --- a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java +++ b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java @@ -116,7 +116,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel im private ChangeListener isWalletFundedListener; private ChangeListener tradeStateListener; private ChangeListener offerStateListener; - private ChangeListener getMempoolStatusListener; private ConnectionListener connectionListener; // private Subscription isFeeSufficientSubscription; private Runnable takeOfferResultHandler; @@ -449,7 +448,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel im boolean inputDataValid = isBtcInputValid(amount.get()).isValid && dataModel.isMinAmountLessOrEqualAmount() && !dataModel.isAmountLargerThanOfferAmount() - && dataModel.mempoolStatus.get() >= 0 // TODO do we want to block in case response is slow (tor can be slow)? && isOfferAvailable.get() && !dataModel.wouldCreateDustForMaker(); isNextButtonDisabled.set(!inputDataValid); @@ -491,12 +489,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel im tradeStateListener = (ov, oldValue, newValue) -> applyTradeState(); offerStateListener = (ov, oldValue, newValue) -> applyOfferState(newValue); - getMempoolStatusListener = (observable, oldValue, newValue) -> { - if (newValue.longValue() >= 0) { - updateButtonDisableState(); - } - }; - connectionListener = new ConnectionListener() { @Override public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection connection) { @@ -544,7 +536,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel im dataModel.getAmount().addListener(amountListener); dataModel.getIsXmrWalletFunded().addListener(isWalletFundedListener); - dataModel.getMempoolStatus().addListener(getMempoolStatusListener); p2PService.getNetworkNode().addConnectionListener(connectionListener); /* isFeeSufficientSubscription = EasyBind.subscribe(dataModel.isFeeFromFundingTxSufficient, newValue -> { updateButtonDisableState(); @@ -557,7 +548,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel im // Binding with Bindings.createObjectBinding does not work because of bi-directional binding dataModel.getAmount().removeListener(amountListener); - dataModel.getMempoolStatus().removeListener(getMempoolStatusListener); dataModel.getIsXmrWalletFunded().removeListener(isWalletFundedListener); if (offer != null) { @@ -717,10 +707,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel im offer.setErrorMessage(null); } - private CoinFormatter getFormatterForTakerFee() { - return xmrFormatter; - } - public Callback, ListCell> getPaymentAccountListCellFactory( ComboBox paymentAccountsComboBox) { return GUIUtil.getPaymentAccountListCellFactory(paymentAccountsComboBox, accountAgeWitnessService); diff --git a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java index e07dd2fd..793e531d 100644 --- a/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java +++ b/desktop/src/main/java/haveno/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java @@ -24,7 +24,6 @@ import haveno.core.account.witness.AccountAgeWitnessService; import haveno.core.network.MessageState; import haveno.core.offer.Offer; import haveno.core.offer.OfferUtil; -import haveno.core.provider.mempool.MempoolService; import haveno.core.trade.ArbitratorTrade; import haveno.core.trade.BuyerTrade; import haveno.core.trade.ClosedTradableManager; @@ -91,7 +90,6 @@ public class PendingTradesViewModel extends ActivatableWithDataModel