Fix removal of orphan offer

This commit is contained in:
Manfred Karrer 2015-03-13 22:40:43 +01:00
parent c5967f1494
commit a198e4fcbb
10 changed files with 62 additions and 38 deletions

View file

@ -99,8 +99,8 @@ public class DebugView extends InitializableView {
PlaceOfferProtocol.class, PlaceOfferProtocol.class,
ValidateOffer.class, ValidateOffer.class,
CreateOfferFeeTx.class, CreateOfferFeeTx.class,
BroadcastCreateOfferFeeTx.class,
AddOfferToRemoteOfferBook.class, AddOfferToRemoteOfferBook.class,
BroadcastCreateOfferFeeTx.class,
Boolean.class, /* used as seperator*/ Boolean.class, /* used as seperator*/

View file

@ -24,14 +24,13 @@ import io.bitsquare.trade.TradeManager;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import io.bitsquare.util.handlers.ErrorMessageHandler; import io.bitsquare.util.handlers.ErrorMessageHandler;
import io.bitsquare.util.handlers.ResultHandler; import io.bitsquare.util.handlers.ResultHandler;
import io.bitsquare.viewfx.model.Activatable;
import io.bitsquare.viewfx.model.DataModel;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import io.bitsquare.viewfx.model.Activatable;
import io.bitsquare.viewfx.model.DataModel;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener; import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
@ -78,8 +77,8 @@ class OffersDataModel implements Activatable, DataModel {
tradeManager.getOpenOffers().removeListener(offerMapChangeListener); tradeManager.getOpenOffers().removeListener(offerMapChangeListener);
} }
void removeOpenOffer(String offerId, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
tradeManager.removeOpenOffer(offerId, resultHandler, errorMessageHandler); tradeManager.removeOpenOffer(offer, resultHandler, errorMessageHandler);
} }

View file

@ -18,13 +18,13 @@
package io.bitsquare.gui.main.portfolio.offer; package io.bitsquare.gui.main.portfolio.offer;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.offer.Offer;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;
import io.bitsquare.viewfx.view.ActivatableViewAndModel;
import io.bitsquare.viewfx.view.FxmlView;
import javax.inject.Inject; import javax.inject.Inject;
import io.bitsquare.viewfx.view.FxmlView;
import io.bitsquare.viewfx.view.ActivatableViewAndModel;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
@ -63,8 +63,8 @@ public class OffersView extends ActivatableViewAndModel<GridPane, OffersViewMode
table.setItems(model.getList()); table.setItems(model.getList());
} }
private void removeOpenOffer(String offerId) { private void removeOpenOffer(Offer offer) {
model.removeOpenOffer(offerId); model.removeOpenOffer(offer);
} }
private void openOfferDetails(OpenOfferListItem item) { private void openOfferDetails(OpenOfferListItem item) {
@ -233,7 +233,7 @@ public class OffersView extends ActivatableViewAndModel<GridPane, OffersViewMode
super.updateItem(item, empty); super.updateItem(item, empty);
if (item != null) { if (item != null) {
button.setOnAction(event -> removeOpenOffer(item.getOpenOffer().getId())); button.setOnAction(event -> removeOpenOffer(item.getOpenOffer().getOffer()));
setGraphic(button); setGraphic(button);
} }
else { else {

View file

@ -19,12 +19,12 @@ package io.bitsquare.gui.main.portfolio.offer;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.util.BSFormatter; 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 com.google.inject.Inject;
import io.bitsquare.viewfx.model.ViewModel;
import io.bitsquare.viewfx.model.ActivatableWithDataModel;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -44,8 +44,8 @@ class OffersViewModel extends ActivatableWithDataModel<OffersDataModel> implemen
} }
void removeOpenOffer(String offerId) { void removeOpenOffer(Offer offer) {
dataModel.removeOpenOffer(offerId, dataModel.removeOpenOffer(offer,
() -> { () -> {
// visual feedback? // visual feedback?
log.debug("Remove offer was successful"); log.debug("Remove offer was successful");

View file

@ -114,8 +114,8 @@ class OfferBookDataModel implements Activatable, DataModel {
btcCode.unbind(); btcCode.unbind();
} }
void removeOpenOffer(String offerId, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
tradeManager.removeOpenOffer(offerId, resultHandler, errorMessageHandler); tradeManager.removeOpenOffer(offer, resultHandler, errorMessageHandler);
} }
void calculateVolume() { void calculateVolume() {

View file

@ -471,7 +471,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
iconView.setId("image-remove"); iconView.setId("image-remove");
title = "Remove"; title = "Remove";
button.setOnAction(event -> model.removeOpenOffer(item button.setOnAction(event -> model.removeOpenOffer(item
.getOffer().getId())); .getOffer()));
} }
else { else {
if (offer.getDirection() == Direction.SELL) if (offer.getDirection() == Direction.SELL)

View file

@ -103,8 +103,8 @@ class OfferBookViewModel extends ActivatableWithDataModel<OfferBookDataModel> im
(newValue))); (newValue)));
} }
void removeOpenOffer(String offerId) { void removeOpenOffer(Offer offer) {
dataModel.removeOpenOffer(offerId, dataModel.removeOpenOffer(offer,
() -> { () -> {
// visual feedback? // visual feedback?
log.debug("Remove offer was successful"); log.debug("Remove offer was successful");

View file

@ -191,8 +191,8 @@ public class TradeManager {
placeOfferProtocol.placeOffer(); placeOfferProtocol.placeOffer();
} }
public void removeOpenOffer(String offerId, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { public void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
removeOpenOffer(offerId, resultHandler, errorMessageHandler, true); removeOpenOffer(offer, resultHandler, errorMessageHandler, true);
} }
public Trade takeOffer(Coin amount, Offer offer) { public Trade takeOffer(Coin amount, Offer offer) {
@ -304,11 +304,12 @@ public class TradeManager {
return openOffer; return openOffer;
} }
private void removeOpenOffer(String offerId, private void removeOpenOffer(Offer offer,
ResultHandler resultHandler, ResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler, ErrorMessageHandler errorMessageHandler,
boolean removeFromOffererAsBuyerProtocolMap) { boolean removeFromOffererAsBuyerProtocolMap) {
offerBookService.removeOffer(openOffers.get(offerId).getOffer(), String offerId = offer.getId();
offerBookService.removeOffer(offer,
() -> { () -> {
if (openOffers.containsKey(offerId)) { if (openOffers.containsKey(offerId)) {
OpenOffer openOffer = openOffers.remove(offerId); OpenOffer openOffer = openOffers.remove(offerId);
@ -357,7 +358,7 @@ public class TradeManager {
case OPEN: case OPEN:
break; break;
case OFFER_ACCEPTED: case OFFER_ACCEPTED:
removeOpenOffer(openOffer.getId(), removeOpenOffer(openOffer.getOffer(),
() -> log.debug("remove offer was successful"), () -> log.debug("remove offer was successful"),
(message) -> log.error(message), (message) -> log.error(message),
false); false);

View file

@ -31,6 +31,9 @@ import org.slf4j.LoggerFactory;
public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> { public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
private static final Logger log = LoggerFactory.getLogger(BroadcastCreateOfferFeeTx.class); private static final Logger log = LoggerFactory.getLogger(BroadcastCreateOfferFeeTx.class);
private boolean removeOfferFailed;
private boolean addOfferFailed;
public BroadcastCreateOfferFeeTx(TaskRunner taskHandler, PlaceOfferModel model) { public BroadcastCreateOfferFeeTx(TaskRunner taskHandler, PlaceOfferModel model) {
super(taskHandler, model); super(taskHandler, model);
@ -41,6 +44,8 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
@Override @Override
protected void doRun() { protected void doRun() {
model.getWalletService().broadcastCreateOfferFeeTx(model.getTransaction(), new FutureCallback<Transaction>() { model.getWalletService().broadcastCreateOfferFeeTx(model.getTransaction(), new FutureCallback<Transaction>() {
@Override @Override
public void onSuccess(Transaction transaction) { public void onSuccess(Transaction transaction) {
log.info("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString()); log.info("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString());
@ -64,11 +69,13 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
}, },
(message, throwable) -> { (message, throwable) -> {
log.error("addOffer failed"); log.error("addOffer failed");
addOfferFailed = true;
failed(throwable); failed(throwable);
}); });
}, },
(message, throwable) -> { (message, throwable) -> {
log.error("removeOffer failed"); log.error("removeOffer failed");
removeOfferFailed = true;
failed(throwable); 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);
});
}
}
} }

View file

@ -54,18 +54,20 @@ public class TaskRunner<T extends SharedModel> {
} }
protected void next() { protected void next() {
if (!failed && !isCanceled && tasks.size() > 0) { if (!failed && !isCanceled) {
try { if (tasks.size() > 0) {
currentTask = tasks.poll(); try {
log.trace("Run task: " + currentTask.getSimpleName()); currentTask = tasks.poll();
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run(); log.trace("Run task: " + currentTask.getSimpleName());
} catch (Throwable throwable) { currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run();
throwable.printStackTrace(); } catch (Throwable throwable) {
handleErrorMessage("Error at taskRunner: " + throwable.getMessage()); throwable.printStackTrace();
handleErrorMessage("Error at taskRunner: " + throwable.getMessage());
}
}
else {
resultHandler.handleResult();
} }
}
else {
resultHandler.handleResult();
} }
} }