diff --git a/core/src/main/java/io/bitsquare/gui/main/debug/DebugView.java b/core/src/main/java/io/bitsquare/gui/main/debug/DebugView.java index e5080528f1..3aa7affda3 100644 --- a/core/src/main/java/io/bitsquare/gui/main/debug/DebugView.java +++ b/core/src/main/java/io/bitsquare/gui/main/debug/DebugView.java @@ -99,8 +99,8 @@ public class DebugView extends InitializableView { PlaceOfferProtocol.class, ValidateOffer.class, CreateOfferFeeTx.class, - BroadcastCreateOfferFeeTx.class, AddOfferToRemoteOfferBook.class, + BroadcastCreateOfferFeeTx.class, Boolean.class, /* used as seperator*/ diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersDataModel.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersDataModel.java index fa2774d432..d9fbe5e3d8 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersDataModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersDataModel.java @@ -24,14 +24,13 @@ import io.bitsquare.trade.TradeManager; import io.bitsquare.user.User; import io.bitsquare.util.handlers.ErrorMessageHandler; import io.bitsquare.util.handlers.ResultHandler; +import io.bitsquare.viewfx.model.Activatable; +import io.bitsquare.viewfx.model.DataModel; import com.google.inject.Inject; import java.util.stream.Collectors; -import io.bitsquare.viewfx.model.Activatable; -import io.bitsquare.viewfx.model.DataModel; - import javafx.collections.FXCollections; import javafx.collections.MapChangeListener; import javafx.collections.ObservableList; @@ -78,8 +77,8 @@ class OffersDataModel implements Activatable, DataModel { tradeManager.getOpenOffers().removeListener(offerMapChangeListener); } - void removeOpenOffer(String offerId, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { - tradeManager.removeOpenOffer(offerId, resultHandler, errorMessageHandler); + void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { + tradeManager.removeOpenOffer(offer, resultHandler, errorMessageHandler); } diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersView.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersView.java index 1d5eaa02c3..7563197a15 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersView.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersView.java @@ -18,13 +18,13 @@ package io.bitsquare.gui.main.portfolio.offer; import io.bitsquare.gui.components.Popups; +import io.bitsquare.offer.Offer; import io.bitsquare.util.Utilities; +import io.bitsquare.viewfx.view.ActivatableViewAndModel; +import io.bitsquare.viewfx.view.FxmlView; import javax.inject.Inject; -import io.bitsquare.viewfx.view.FxmlView; -import io.bitsquare.viewfx.view.ActivatableViewAndModel; - import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.fxml.FXML; import javafx.scene.control.*; @@ -63,8 +63,8 @@ public class OffersView extends ActivatableViewAndModel<GridPane, OffersViewMode table.setItems(model.getList()); } - private void removeOpenOffer(String offerId) { - model.removeOpenOffer(offerId); + private void removeOpenOffer(Offer offer) { + model.removeOpenOffer(offer); } private void openOfferDetails(OpenOfferListItem item) { @@ -233,7 +233,7 @@ public class OffersView extends ActivatableViewAndModel<GridPane, OffersViewMode super.updateItem(item, empty); if (item != null) { - button.setOnAction(event -> removeOpenOffer(item.getOpenOffer().getId())); + button.setOnAction(event -> removeOpenOffer(item.getOpenOffer().getOffer())); setGraphic(button); } else { diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersViewModel.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersViewModel.java index 18bb939589..3acc046307 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersViewModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersViewModel.java @@ -19,12 +19,12 @@ package io.bitsquare.gui.main.portfolio.offer; import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.util.BSFormatter; +import io.bitsquare.offer.Offer; +import io.bitsquare.viewfx.model.ActivatableWithDataModel; +import io.bitsquare.viewfx.model.ViewModel; import com.google.inject.Inject; -import io.bitsquare.viewfx.model.ViewModel; -import io.bitsquare.viewfx.model.ActivatableWithDataModel; - import javafx.collections.ObservableList; import org.slf4j.Logger; @@ -44,8 +44,8 @@ class OffersViewModel extends ActivatableWithDataModel<OffersDataModel> implemen } - void removeOpenOffer(String offerId) { - dataModel.removeOpenOffer(offerId, + void removeOpenOffer(Offer offer) { + dataModel.removeOpenOffer(offer, () -> { // visual feedback? log.debug("Remove offer was successful"); diff --git a/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookDataModel.java b/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookDataModel.java index 8d65394ee9..92d1e576e9 100644 --- a/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookDataModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookDataModel.java @@ -114,8 +114,8 @@ class OfferBookDataModel implements Activatable, DataModel { btcCode.unbind(); } - void removeOpenOffer(String offerId, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { - tradeManager.removeOpenOffer(offerId, resultHandler, errorMessageHandler); + void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { + tradeManager.removeOpenOffer(offer, resultHandler, errorMessageHandler); } void calculateVolume() { diff --git a/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookView.java b/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookView.java index 9d48bd8e9e..919ee8146c 100644 --- a/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookView.java +++ b/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookView.java @@ -471,7 +471,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi iconView.setId("image-remove"); title = "Remove"; button.setOnAction(event -> model.removeOpenOffer(item - .getOffer().getId())); + .getOffer())); } else { if (offer.getDirection() == Direction.SELL) diff --git a/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookViewModel.java b/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookViewModel.java index bdb93d2c04..bb054f2e04 100644 --- a/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookViewModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookViewModel.java @@ -103,8 +103,8 @@ class OfferBookViewModel extends ActivatableWithDataModel<OfferBookDataModel> im (newValue))); } - void removeOpenOffer(String offerId) { - dataModel.removeOpenOffer(offerId, + void removeOpenOffer(Offer offer) { + dataModel.removeOpenOffer(offer, () -> { // visual feedback? log.debug("Remove offer was successful"); diff --git a/core/src/main/java/io/bitsquare/trade/TradeManager.java b/core/src/main/java/io/bitsquare/trade/TradeManager.java index a8317a8656..cc334c5ddf 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/core/src/main/java/io/bitsquare/trade/TradeManager.java @@ -191,8 +191,8 @@ public class TradeManager { placeOfferProtocol.placeOffer(); } - public void removeOpenOffer(String offerId, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { - removeOpenOffer(offerId, resultHandler, errorMessageHandler, true); + public void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { + removeOpenOffer(offer, resultHandler, errorMessageHandler, true); } public Trade takeOffer(Coin amount, Offer offer) { @@ -304,11 +304,12 @@ public class TradeManager { return openOffer; } - private void removeOpenOffer(String offerId, + private void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler, boolean removeFromOffererAsBuyerProtocolMap) { - offerBookService.removeOffer(openOffers.get(offerId).getOffer(), + String offerId = offer.getId(); + offerBookService.removeOffer(offer, () -> { if (openOffers.containsKey(offerId)) { OpenOffer openOffer = openOffers.remove(offerId); @@ -357,7 +358,7 @@ public class TradeManager { case OPEN: break; case OFFER_ACCEPTED: - removeOpenOffer(openOffer.getId(), + removeOpenOffer(openOffer.getOffer(), () -> log.debug("remove offer was successful"), (message) -> log.error(message), false); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/placeoffer/tasks/BroadcastCreateOfferFeeTx.java b/core/src/main/java/io/bitsquare/trade/protocol/placeoffer/tasks/BroadcastCreateOfferFeeTx.java index 9719797a7f..584515ea85 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/placeoffer/tasks/BroadcastCreateOfferFeeTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/placeoffer/tasks/BroadcastCreateOfferFeeTx.java @@ -31,6 +31,9 @@ import org.slf4j.LoggerFactory; public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> { private static final Logger log = LoggerFactory.getLogger(BroadcastCreateOfferFeeTx.class); + private boolean removeOfferFailed; + private boolean addOfferFailed; + public BroadcastCreateOfferFeeTx(TaskRunner taskHandler, PlaceOfferModel model) { super(taskHandler, model); @@ -41,6 +44,8 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> { @Override protected void doRun() { model.getWalletService().broadcastCreateOfferFeeTx(model.getTransaction(), new FutureCallback<Transaction>() { + + @Override public void onSuccess(Transaction transaction) { log.info("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString()); @@ -64,11 +69,13 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> { }, (message, throwable) -> { log.error("addOffer failed"); + addOfferFailed = true; failed(throwable); }); }, (message, throwable) -> { log.error("removeOffer failed"); + removeOfferFailed = true; failed(throwable); }); } @@ -84,4 +91,19 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> { } }); } + + protected void applyErrorState() { + if (!removeOfferFailed && !addOfferFailed) { + // If broadcast fails we need to remove offer from offerbook + model.getOfferBookService().removeOffer(model.getOffer(), + () -> { + log.info("Offer removed from offerbook because broadcast failed."); + }, + (message, throwable) -> { + log.error("removeOffer failed"); + failed(throwable); + }); + } + } + } diff --git a/core/src/main/java/io/bitsquare/util/taskrunner/TaskRunner.java b/core/src/main/java/io/bitsquare/util/taskrunner/TaskRunner.java index 968a55019c..1118acf58b 100644 --- a/core/src/main/java/io/bitsquare/util/taskrunner/TaskRunner.java +++ b/core/src/main/java/io/bitsquare/util/taskrunner/TaskRunner.java @@ -54,18 +54,20 @@ public class TaskRunner<T extends SharedModel> { } protected void next() { - if (!failed && !isCanceled && tasks.size() > 0) { - try { - currentTask = tasks.poll(); - log.trace("Run task: " + currentTask.getSimpleName()); - currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run(); - } catch (Throwable throwable) { - throwable.printStackTrace(); - handleErrorMessage("Error at taskRunner: " + throwable.getMessage()); + if (!failed && !isCanceled) { + if (tasks.size() > 0) { + try { + currentTask = tasks.poll(); + log.trace("Run task: " + currentTask.getSimpleName()); + currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + handleErrorMessage("Error at taskRunner: " + throwable.getMessage()); + } + } + else { + resultHandler.handleResult(); } - } - else { - resultHandler.handleResult(); } }