Interrupted trade process working for both variants

This commit is contained in:
Manfred Karrer 2015-04-03 17:53:43 +02:00
parent a2aa0b40b4
commit d09fb97f8d
13 changed files with 161 additions and 50 deletions

View File

@ -54,6 +54,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
SELLER_WAIT_TX_CONF,
SELLER_WAIT_PAYMENT_STARTED,
SELLER_CONFIRM_RECEIVE_PAYMENT,
SELLER_PUBLISH_PAYOUT_TX,
SELLER_SEND_PUBLISHED_MSG,
SELLER_COMPLETED,
BUYER_WAIT_TX_CONF,
@ -287,7 +289,12 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
break;
case FIAT_PAYMENT_RECEIVED:
viewState.set(ViewState.SELLER_PUBLISH_PAYOUT_TX);
break;
case PAYOUT_PUBLISHED:
viewState.set(ViewState.SELLER_SEND_PUBLISHED_MSG);
break;
case PAYOUT_PUBLISHED_MSG_SENT:
viewState.set(ViewState.SELLER_COMPLETED);
break;
@ -324,7 +331,12 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
break;
case FIAT_PAYMENT_RECEIVED:
viewState.set(ViewState.SELLER_PUBLISH_PAYOUT_TX);
break;
case PAYOUT_PUBLISHED:
viewState.set(ViewState.SELLER_SEND_PUBLISHED_MSG);
break;
case PAYOUT_PUBLISHED_MSG_SENT:
viewState.set(ViewState.SELLER_COMPLETED);
break;

View File

@ -80,7 +80,7 @@ public class SellerSubView extends TradeSubView {
if (tradeStepDetailsView != null)
tradeStepDetailsView.deactivate();
switch (viewState) {
case UNDEFINED:
break;
@ -123,6 +123,12 @@ public class SellerSubView extends TradeSubView {
"your security deposit and the Bitcoin buyer receive the Bitcoin amount you sold.",
model.getCurrencyCode()));
break;
case SELLER_PUBLISH_PAYOUT_TX:
((ConfirmFiatReceivedView) tradeStepDetailsView).setStatusText("Publishing transaction...");
break;
case SELLER_SEND_PUBLISHED_MSG:
((ConfirmFiatReceivedView) tradeStepDetailsView).setStatusText("Sending message to trading partner...");
break;
case SELLER_COMPLETED:
waitTxInBlockchain.done();

View File

@ -38,6 +38,9 @@ public class ConfirmFiatReceivedView extends TradeStepDetailsView {
private Label infoLabel;
private InfoDisplay infoDisplay;
private final ChangeListener<String> txIdChangeListener;
private Button confirmFiatReceivedButton;
private Label statusLabel;
private ProgressIndicator statusProgressIndicator;
///////////////////////////////////////////////////////////////////////////////////////////
@ -74,6 +77,10 @@ public class ConfirmFiatReceivedView extends TradeStepDetailsView {
private void onPaymentReceived(ActionEvent actionEvent) {
log.debug("onPaymentReceived");
model.fiatPaymentReceived();
confirmFiatReceivedButton.setDisable(true);
statusProgressIndicator.setVisible(true);
statusProgressIndicator.setProgress(-1);
}
@ -91,6 +98,10 @@ public class ConfirmFiatReceivedView extends TradeStepDetailsView {
infoDisplay.setText(text);
}
public void setStatusText(String text) {
statusLabel.setText(text);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Build view
@ -104,8 +115,14 @@ public class ConfirmFiatReceivedView extends TradeStepDetailsView {
getAndAddTitledGroupBg(gridPane, gridRow, 1, "Information", Layout.GROUP_DISTANCE);
infoLabel = getAndAddInfoLabel(gridPane, gridRow++, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
getAndAddButton(gridPane, gridRow++, "Confirm payment receipt", this::onPaymentReceived);
ButtonWithProgressIndicatorAndLabelBucket bucket = getAndAddButtonWithStatus(gridPane, gridRow++, "Confirm payment receipt", this::onPaymentReceived);
confirmFiatReceivedButton = bucket.button;
statusProgressIndicator = bucket.progressIndicator;
statusLabel = bucket.label;
}
}

View File

@ -44,8 +44,10 @@ public class StartFiatView extends TradeStepDetailsView {
private TextFieldWithCopyIcon secondaryIdTextField;
private InfoDisplay paymentsInfoDisplay;
private Button paymentStartedButton;
private Label statusLabel;
private final ChangeListener<String> txIdChangeListener;
private ProgressIndicator statusProgressIndicator;
///////////////////////////////////////////////////////////////////////////////////////////
@ -102,6 +104,9 @@ public class StartFiatView extends TradeStepDetailsView {
log.debug("onPaymentStarted");
model.fiatPaymentStarted();
paymentStartedButton.setDisable(true);
statusProgressIndicator.setVisible(true);
statusProgressIndicator.setProgress(-1);
statusLabel.setText("Sending message to trading partner...");
}
@ -122,6 +127,9 @@ public class StartFiatView extends TradeStepDetailsView {
primaryIdTextField = getAndAddLabelTextFieldWithCopyIconPair(gridPane, gridRow++, "IBAN:").textFieldWithCopyIcon;
secondaryIdTextField = getAndAddLabelTextFieldWithCopyIconPair(gridPane, gridRow++, "BIC:").textFieldWithCopyIcon;
paymentsInfoDisplay = getAndAddInfoDisplay(gridPane, gridRow++, "infoDisplay", this::onOpenHelp);
paymentStartedButton = getAndAddButton(gridPane, gridRow++, "Payment started", this::onPaymentStarted);
ButtonWithProgressIndicatorAndLabelBucket bucket = getAndAddButtonWithStatus(gridPane, gridRow++, "Payment started", this::onPaymentStarted);
paymentStartedButton = bucket.button;
statusProgressIndicator = bucket.progressIndicator;
statusLabel = bucket.label;
}
}

View File

@ -195,6 +195,34 @@ public class ComponentBuilder {
return button;
}
public static ButtonWithProgressIndicatorAndLabelBucket getAndAddButtonWithStatus(GridPane gridPane,
int rowIndex,
String ButtonTitle,
EventHandler<ActionEvent> onActionHandler) {
HBox hBox = new HBox();
hBox.setSpacing(10);
Button button = new Button(ButtonTitle);
button.setDefaultButton(true);
button.setOnAction(onActionHandler);
ProgressIndicator progressIndicator = new ProgressIndicator(0);
progressIndicator.setPrefHeight(24);
progressIndicator.setPrefWidth(24);
progressIndicator.setVisible(false);
Label label = new Label();
label.setPadding(new Insets(5, 0, 0, 0));
hBox.getChildren().addAll(button, progressIndicator, label);
GridPane.setRowIndex(hBox, rowIndex);
GridPane.setColumnIndex(hBox, 1);
GridPane.setMargin(hBox, new Insets(15, 0, 40, 0));
gridPane.getChildren().add(hBox);
return new ButtonWithProgressIndicatorAndLabelBucket(button, progressIndicator, label);
}
public static class LabelTextFieldPair {
public Label label;
public TextField textField;
@ -235,4 +263,16 @@ public class ComponentBuilder {
}
}
public static class ButtonWithProgressIndicatorAndLabelBucket {
public Button button;
public ProgressIndicator progressIndicator;
public Label label;
public ButtonWithProgressIndicatorAndLabelBucket(Button button, ProgressIndicator progressIndicator, Label label) {
this.button = button;
this.progressIndicator = progressIndicator;
this.label = label;
}
}
}

View File

@ -175,19 +175,25 @@ public class FileManager<T> {
}
public void removeFile(String fileName) {
log.debug("removeFile" + fileName);
File file = new File(dir, fileName);
boolean result = file.delete();
if (!result)
log.warn("Could not delete file: " + file.toString());
lock.lock();
try {
boolean result = file.delete();
if (!result)
log.warn("Could not delete file: " + file.toString());
File backupDir = new File(Paths.get(dir.getAbsolutePath(), "backup").toString());
if (backupDir.exists()) {
File backupFile = new File(Paths.get(dir.getAbsolutePath(), "backup", fileName).toString());
if (backupFile.exists()) {
result = backupFile.delete();
if (!result)
log.warn("Could not delete backupFile: " + file.toString());
File backupDir = new File(Paths.get(dir.getAbsolutePath(), "backup").toString());
if (backupDir.exists()) {
File backupFile = new File(Paths.get(dir.getAbsolutePath(), "backup", fileName).toString());
if (backupFile.exists()) {
result = backupFile.delete();
if (!result)
log.warn("Could not delete backupFile: " + file.toString());
}
}
} finally {
lock.unlock();
}
}
@ -210,23 +216,33 @@ public class FileManager<T> {
}
public void removeAndBackupFile(String fileName) throws IOException {
File corruptedBackupDir = new File(Paths.get(dir.getAbsolutePath(), "corrupted").toString());
if (!corruptedBackupDir.exists())
if (!corruptedBackupDir.mkdir())
log.warn("make dir failed");
lock.lock();
try {
File corruptedBackupDir = new File(Paths.get(dir.getAbsolutePath(), "corrupted").toString());
if (!corruptedBackupDir.exists())
if (!corruptedBackupDir.mkdir())
log.warn("make dir failed");
File corruptedFile = new File(Paths.get(dir.getAbsolutePath(), "corrupted", fileName).toString());
renameTempFileToFile(storageFile, corruptedFile);
File corruptedFile = new File(Paths.get(dir.getAbsolutePath(), "corrupted", fileName).toString());
renameTempFileToFile(storageFile, corruptedFile);
} finally {
lock.unlock();
}
}
public void backupFile(String fileName) throws IOException {
File backupDir = new File(Paths.get(dir.getAbsolutePath(), "backup").toString());
if (!backupDir.exists())
if (!backupDir.mkdir())
log.warn("make dir failed");
lock.lock();
try {
File backupDir = new File(Paths.get(dir.getAbsolutePath(), "backup").toString());
if (!backupDir.exists())
if (!backupDir.mkdir())
log.warn("make dir failed");
File backupFile = new File(Paths.get(dir.getAbsolutePath(), "backup", fileName).toString());
Files.copy(storageFile, backupFile);
File backupFile = new File(Paths.get(dir.getAbsolutePath(), "backup", fileName).toString());
Files.copy(storageFile, backupFile);
} finally {
lock.unlock();
}
}
///////////////////////////////////////////////////////////////////////////////////////////
@ -258,8 +274,6 @@ public class FileManager<T> {
objectOutputStream = new ObjectOutputStream(fileOutputStream);
// TODO ConcurrentModificationException happens sometimes at that line
//log.debug("serializable " + serializable.toString());
log.debug("storageFile " + storageFile.toString());
objectOutputStream.writeObject(serializable);
// Attempt to force the bits to hit the disk. In reality the OS or hard disk itself may still decide
@ -274,6 +288,8 @@ public class FileManager<T> {
renameTempFileToFile(tempFile, storageFile);
} catch (Throwable t) {
log.debug("storageFile " + storageFile.toString());
log.debug("currentThread " + Thread.currentThread());
t.printStackTrace();
log.error("Error at saveToFile: " + t.getMessage());
} finally {

View File

@ -73,23 +73,15 @@ public class BuyerAsTakerProtocol implements TradeProtocol {
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void cleanup() {
log.debug("cleanup " + this);
processModel.getMessageService().removeMessageHandler(messageHandler);
}
public void setMailboxMessage(MailboxMessage mailboxMessage) {
log.debug("setMailboxMessage " + mailboxMessage);
// Might be called twice, so check that its only processed once
/* if (takerTradeProcessModel.getMailboxMessage() == null) {
takerTradeProcessModel.setMailboxMessage(mailboxMessage);
if (mailboxMessage instanceof FiatTransferStartedMessage) {
handleFiatTransferStartedMessage((FiatTransferStartedMessage) mailboxMessage);
if (processModel.getMailboxMessage() == null) {
processModel.setMailboxMessage(mailboxMessage);
if (mailboxMessage instanceof PayoutTxPublishedMessage) {
handle((PayoutTxPublishedMessage) mailboxMessage);
}
else if (mailboxMessage instanceof DepositTxPublishedMessage) {
handleDepositTxPublishedMessage((DepositTxPublishedMessage) mailboxMessage);
}
}*/
}
}
public void takeAvailableOffer() {
@ -106,6 +98,10 @@ public class BuyerAsTakerProtocol implements TradeProtocol {
taskRunner.run();
}
public void cleanup() {
log.debug("cleanup " + this);
processModel.getMessageService().removeMessageHandler(messageHandler);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Incoming message handling

View File

@ -77,12 +77,15 @@ public class SellerAsOffererProtocol implements TradeProtocol {
public void setMailboxMessage(MailboxMessage mailboxMessage) {
log.debug("setMailboxMessage " + mailboxMessage);
// Might be called twice, so check that its only processed once
/* if (offererTradeProcessModel.getMailboxMessage() == null) {
offererTradeProcessModel.setMailboxMessage(mailboxMessage);
if (mailboxMessage instanceof PayoutTxPublishedMessage) {
handlePayoutTxPublishedMessage((PayoutTxPublishedMessage) mailboxMessage);
if (processModel.getMailboxMessage() == null) {
processModel.setMailboxMessage(mailboxMessage);
if (mailboxMessage instanceof FiatTransferStartedMessage) {
handle((FiatTransferStartedMessage) mailboxMessage);
}
}*/
else if (mailboxMessage instanceof DepositTxPublishedMessage) {
handle((DepositTxPublishedMessage) mailboxMessage);
}
}
}
public void cleanup() {

View File

@ -75,11 +75,6 @@ public class SellerAsTakerProtocol implements TradeProtocol {
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void cleanup() {
log.debug("cleanup " + this);
processModel.getMessageService().removeMessageHandler(messageHandler);
}
public void setMailboxMessage(MailboxMessage mailboxMessage) {
log.debug("setMailboxMessage " + mailboxMessage);
// Might be called twice, so check that its only processed once
@ -107,6 +102,11 @@ public class SellerAsTakerProtocol implements TradeProtocol {
taskRunner.run();
}
public void cleanup() {
log.debug("cleanup " + this);
processModel.getMessageService().removeMessageHandler(messageHandler);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Incoming message handling

View File

@ -43,6 +43,7 @@ public class SendDepositTxPublishedMessage extends TradeTask {
@Override
public void handleResult() {
log.trace("DepositTxPublishedMessage successfully arrived at peer");
complete();
}

View File

@ -19,10 +19,14 @@ package io.bitsquare.trade.protocol.trade.tasks.seller;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.TradeTask;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.trade.states.OffererTradeState;
import io.bitsquare.trade.states.StateUtil;
import io.bitsquare.trade.states.TakerTradeState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -46,6 +50,12 @@ public class SendPayoutTxPublishedMessage extends TradeTask {
@Override
public void handleResult() {
log.trace("PayoutTxPublishedMessage successfully arrived at peer");
if (trade instanceof TakerTrade)
trade.setProcessState(TakerTradeState.ProcessState.PAYOUT_PUBLISHED_MSG_SENT);
else if (trade instanceof OffererTrade)
trade.setProcessState(OffererTradeState.ProcessState.PAYOUT_PUBLISHED_MSG_SENT);
complete();
}

View File

@ -41,6 +41,7 @@ public class OffererTradeState {
FIAT_PAYMENT_RECEIVED,
PAYOUT_PUBLISHED,
PAYOUT_PUBLISHED_MSG_SENT,
MESSAGE_SENDING_FAILED,
EXCEPTION

View File

@ -42,6 +42,7 @@ public class TakerTradeState {
FIAT_PAYMENT_RECEIVED,
PAYOUT_PUBLISHED,
PAYOUT_PUBLISHED_MSG_SENT,
MESSAGE_SENDING_FAILED,
EXCEPTION