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,
ValidateOffer.class,
CreateOfferFeeTx.class,
BroadcastCreateOfferFeeTx.class,
AddOfferToRemoteOfferBook.class,
BroadcastCreateOfferFeeTx.class,
Boolean.class, /* used as seperator*/

View File

@ -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);
}

View File

@ -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 {

View File

@ -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");

View File

@ -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() {

View File

@ -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)

View File

@ -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");

View File

@ -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);

View File

@ -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);
});
}
}
}

View File

@ -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();
}
}