Cleanup state handling in domain

This commit is contained in:
Manfred Karrer 2015-03-26 01:10:46 +01:00
parent 77bf67e465
commit 9936dca851
30 changed files with 314 additions and 228 deletions

View file

@ -211,8 +211,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("takerTrade state = " + newValue); log.debug("takerTrade state = " + newValue);
String msg = ""; String msg = "";
if (newValue.getErrorMessage() != null) if (takerTrade.getErrorMessage() != null)
msg = "\nError message: " + newValue.getErrorMessage(); msg = "\nError message: " + takerTrade.getErrorMessage();
switch (newValue) { switch (newValue) {
case TAKE_OFFER_FEE_TX_CREATED: case TAKE_OFFER_FEE_TX_CREATED:
@ -235,7 +235,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
break; break;
case PAYOUT_PUBLISHED: case PAYOUT_PUBLISHED:
break; break;
case UNSPECIFIC_FAULT: case EXCEPTION:
errorMessage.set(msg); errorMessage.set(msg);
takeOfferRequested = false; takeOfferRequested = false;
break; break;

View file

@ -58,20 +58,13 @@ public class OffererTrade extends Trade implements Serializable {
public enum OffererProcessState implements ProcessState { public enum OffererProcessState implements ProcessState {
DEPOSIT_PUBLISHED, DEPOSIT_PUBLISHED,
DEPOSIT_CONFIRMED, DEPOSIT_CONFIRMED,
FIAT_PAYMENT_STARTED, FIAT_PAYMENT_STARTED,
PAYOUT_PUBLISHED, PAYOUT_PUBLISHED,
MESSAGE_SENDING_FAILED, MESSAGE_SENDING_FAILED,
UNSPECIFIC_FAULT; UNSPECIFIC_FAULT
protected String errorMessage;
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getErrorMessage() {
return errorMessage;
}
} }
protected OffererProcessState processState; protected OffererProcessState processState;

View file

@ -58,25 +58,17 @@ public class TakerTrade extends Trade implements Serializable {
TAKE_OFFER_FEE_TX_CREATED, TAKE_OFFER_FEE_TX_CREATED,
TAKE_OFFER_FEE_PUBLISHED, TAKE_OFFER_FEE_PUBLISHED,
TAKE_OFFER_FEE_PUBLISH_FAILED, TAKE_OFFER_FEE_PUBLISH_FAILED,
DEPOSIT_PUBLISHED, DEPOSIT_PUBLISHED,
DEPOSIT_CONFIRMED, DEPOSIT_CONFIRMED,
FIAT_PAYMENT_STARTED, FIAT_PAYMENT_STARTED,
FIAT_PAYMENT_RECEIVED, FIAT_PAYMENT_RECEIVED,
PAYOUT_PUBLISHED, PAYOUT_PUBLISHED,
MESSAGE_SENDING_FAILED, MESSAGE_SENDING_FAILED,
UNSPECIFIC_FAULT; EXCEPTION
protected String errorMessage;
@Override
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
@Override
public String getErrorMessage() {
return errorMessage;
}
} }
protected TakerProcessState processState; protected TakerProcessState processState;
@ -111,26 +103,32 @@ public class TakerTrade extends Trade implements Serializable {
// Setters // Setters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void setLifeCycleState(TakerLifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty.set(lifeCycleState);
}
public void setProcessState(TakerProcessState processState) { public void setProcessState(TakerProcessState processState) {
this.processState = processState; this.processState = processState;
processStateProperty.set(processState); processStateProperty.set(processState);
if (processState == TakerProcessState.UNSPECIFIC_FAULT) { if (processState == TakerProcessState.EXCEPTION) {
setLifeCycleState(TakerLifeCycleState.FAILED); setLifeCycleState(TakerLifeCycleState.FAILED);
disposeProtocol(); disposeProtocol();
} }
} }
public void setLifeCycleState(TakerLifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty.set(lifeCycleState);
}
public void setDepositTx(Transaction tx) { public void setDepositTx(Transaction tx) {
this.depositTx = tx; this.depositTx = tx;
setConfidenceListener(); setConfidenceListener();
} }
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
setProcessState(TakerTrade.TakerProcessState.EXCEPTION);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Getters // Getters

View file

@ -44,9 +44,8 @@ abstract public class Trade implements Serializable {
transient protected static final Logger log = LoggerFactory.getLogger(Trade.class); transient protected static final Logger log = LoggerFactory.getLogger(Trade.class);
public interface ProcessState { public interface ProcessState {
void setErrorMessage(String errorMessage);
String getErrorMessage();
} }
public interface LifeCycleState { public interface LifeCycleState {
@ -68,6 +67,8 @@ abstract public class Trade implements Serializable {
protected Peer tradingPeer; protected Peer tradingPeer;
protected int depthInBlocks = 0; protected int depthInBlocks = 0;
transient protected String errorMessage;
transient protected Throwable throwable;
transient protected ObjectProperty<Coin> tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount); transient protected ObjectProperty<Coin> tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
transient protected ObjectProperty<Fiat> tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume()); transient protected ObjectProperty<Fiat> tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
@ -159,6 +160,14 @@ abstract public class Trade implements Serializable {
this.payoutTx = tx; this.payoutTx = tx;
} }
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public void setThrowable(Throwable throwable) {
this.throwable = throwable;
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Getters // Getters
@ -216,6 +225,14 @@ abstract public class Trade implements Serializable {
return tradeVolumeProperty; return tradeVolumeProperty;
} }
public String getErrorMessage() {
return errorMessage;
}
public Throwable getThrowable() {
return throwable;
}
abstract public ReadOnlyObjectProperty<? extends ProcessState> processStateProperty(); abstract public ReadOnlyObjectProperty<? extends ProcessState> processStateProperty();
abstract public ReadOnlyObjectProperty<? extends LifeCycleState> lifeCycleStateProperty(); abstract public ReadOnlyObjectProperty<? extends LifeCycleState> lifeCycleStateProperty();

View file

@ -57,8 +57,9 @@ public class CreateAndSignPayoutTx extends Task<OffererAsBuyerModel> {
model.taker.payoutAmount = takerPayoutAmount; model.taker.payoutAmount = takerPayoutAmount;
complete(); complete();
} catch (Exception e) { } catch (Throwable t) {
failed(e); model.trade.setThrowable(t);
failed(t);
} }
} }
} }

View file

@ -46,8 +46,9 @@ public class CreateOffererDepositTxInputs extends Task<OffererAsBuyerModel> {
model.offerer.outputs = result.getOutputs(); model.offerer.outputs = result.getOutputs();
complete(); complete();
} catch (Throwable e) { } catch (Throwable t) {
failed(e); model.trade.setThrowable(t);
failed(t);
} }
} }
} }

View file

@ -47,6 +47,7 @@ public class ProcessPayoutTxPublishedMessage extends Task<OffererAsBuyerModel> {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
model.trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -49,6 +49,7 @@ public class ProcessRequestDepositTxInputsMessage extends Task<OffererAsBuyerMod
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
model.trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -54,6 +54,7 @@ public class ProcessRequestOffererPublishDepositTxMessage extends Task<OffererAs
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
model.trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -20,6 +20,7 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage; import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel;
@ -35,27 +36,35 @@ public class RequestTakerDepositPayment extends Task<OffererAsBuyerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage( try {
model.id, RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage(
model.offerer.connectedOutputsForAllInputs, model.id,
model.offerer.outputs, model.offerer.connectedOutputsForAllInputs,
model.offerer.tradeWalletPubKey, model.offerer.outputs,
model.offerer.p2pSigPubKey, model.offerer.tradeWalletPubKey,
model.offerer.p2pEncryptPubKey, model.offerer.p2pSigPubKey,
model.offerer.fiatAccount, model.offerer.p2pEncryptPubKey,
model.offerer.accountId); model.offerer.fiatAccount,
model.offerer.accountId);
model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() { model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() {
@Override @Override
public void handleResult() { public void handleResult() {
log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer"); log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer");
complete(); complete();
} }
@Override @Override
public void handleFault() { public void handleFault() {
failed(); appendToErrorMessage("Sending RequestTakerDepositPaymentMessage failed");
} model.trade.setErrorMessage(errorMessage);
}); model.trade.setProcessState(OffererTrade.OffererProcessState.MESSAGE_SENDING_FAILED);
failed();
}
});
} catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -35,7 +35,7 @@ public class SendBankTransferStartedMessage extends Task<OffererAsBuyerModel> {
} }
@Override @Override
protected void doRun() { protected void doRun() {
try { try {
FiatTransferStartedMessage tradeMessage = new FiatTransferStartedMessage(model.id, FiatTransferStartedMessage tradeMessage = new FiatTransferStartedMessage(model.id,
model.offerer.payoutTxSignature, model.offerer.payoutTxSignature,
@ -49,20 +49,22 @@ public class SendBankTransferStartedMessage extends Task<OffererAsBuyerModel> {
new SendMessageListener() { new SendMessageListener() {
@Override @Override
public void handleResult() { public void handleResult() {
log.trace("Sending BankTransferInitedMessage succeeded."); log.trace("Sending FiatTransferStartedMessage succeeded.");
model.trade.setProcessState(OffererTrade.OffererProcessState.FIAT_PAYMENT_STARTED); model.trade.setProcessState(OffererTrade.OffererProcessState.FIAT_PAYMENT_STARTED);
complete(); complete();
} }
@Override @Override
public void handleFault() { public void handleFault() {
failed("Sending BankTransferInitedMessage failed."); appendToErrorMessage("Sending FiatTransferStartedMessage failed");
model.trade.setProcessState(OffererTrade.OffererProcessState.UNSPECIFIC_FAULT); model.trade.setErrorMessage(errorMessage);
model.trade.setProcessState(OffererTrade.OffererProcessState.MESSAGE_SENDING_FAILED);
failed();
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
failed("Sending BankTransferInitedMessage failed."); model.trade.setThrowable(t);
model.trade.setProcessState(OffererTrade.OffererProcessState.UNSPECIFIC_FAULT); failed(t);
} }
} }
} }

View file

@ -20,6 +20,7 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel;
@ -35,19 +36,27 @@ public class SendDepositTxToTaker extends Task<OffererAsBuyerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(model.id, model.trade.getDepositTx()); try {
DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(model.id, model.trade.getDepositTx());
model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() { model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() {
@Override @Override
public void handleResult() { public void handleResult() {
log.trace("DepositTxPublishedMessage successfully arrived at peer"); log.trace("DepositTxPublishedMessage successfully arrived at peer");
complete(); complete();
} }
@Override @Override
public void handleFault() { public void handleFault() {
failed("Sending DepositTxPublishedMessage failed."); appendToErrorMessage("Sending DepositTxPublishedMessage failed");
} model.trade.setErrorMessage(errorMessage);
}); model.trade.setProcessState(OffererTrade.OffererProcessState.MESSAGE_SENDING_FAILED);
failed();
}
});
} catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -66,11 +66,13 @@ public class SignAndPublishDepositTx extends Task<OffererAsBuyerModel> {
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
model.trade.setThrowable(t);
failed(t); failed(t);
} }
}); });
} catch (Exception e) { } catch (Throwable t) {
failed(e); model.trade.setThrowable(t);
failed(t);
} }
} }
} }

View file

@ -36,26 +36,31 @@ public class VerifyAndSignContract extends Task<OffererAsBuyerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
Trade trade = model.trade; try {
Trade trade = model.trade;
Contract contract = new Contract( Contract contract = new Contract(
model.offer, model.offer,
trade.getTradeAmount(), trade.getTradeAmount(),
model.getTakeOfferFeeTxId(), model.getTakeOfferFeeTxId(),
model.offerer.accountId, model.offerer.accountId,
model.taker.accountId, model.taker.accountId,
model.offerer.fiatAccount, model.offerer.fiatAccount,
model.taker.fiatAccount, model.taker.fiatAccount,
model.offerer.p2pSigPubKey, model.offerer.p2pSigPubKey,
model.taker.p2pSigPublicKey); model.taker.p2pSigPublicKey);
String contractAsJson = Utilities.objectToJson(contract); String contractAsJson = Utilities.objectToJson(contract);
String signature = model.signatureService.signMessage(model.offerer.registrationKeyPair, contractAsJson); String signature = model.signatureService.signMessage(model.offerer.registrationKeyPair, contractAsJson);
trade.setContract(contract); trade.setContract(contract);
trade.setContractAsJson(contractAsJson); trade.setContractAsJson(contractAsJson);
trade.setOffererContractSignature(signature); trade.setOffererContractSignature(signature);
trade.setTakerContractSignature(model.taker.contractSignature); trade.setTakerContractSignature(model.taker.contractSignature);
complete(); complete();
} catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -33,12 +33,17 @@ public class VerifyTakeOfferFeePayment extends Task<OffererAsBuyerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
//TODO mocked yet, need a confidence listeners try {
int numOfPeersSeenTx = model.walletService.getNumOfPeersSeenTx(model.getTakeOfferFeeTxId()); //TODO mocked yet, need a confidence listeners
int numOfPeersSeenTx = model.walletService.getNumOfPeersSeenTx(model.getTakeOfferFeeTxId());
/* if (numOfPeersSeenTx > 2) { /* if (numOfPeersSeenTx > 2) {
resultHandler.handleResult(); resultHandler.handleResult();
}*/ }*/
complete(); complete();
} catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -33,18 +33,24 @@ public class VerifyTakerAccount extends Task<OffererAsBuyerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
//TODO mocked yet try {
if (model.blockChainService.verifyAccountRegistration()) { //TODO mocked yet
if (model.blockChainService.isAccountBlackListed(model.taker.accountId, model.taker.fiatAccount)) { if (model.blockChainService.verifyAccountRegistration()) {
log.error("Taker is blacklisted"); if (model.blockChainService.isAccountBlackListed(model.taker.accountId, model.taker.fiatAccount)) {
failed("Taker is blacklisted"); log.error("Taker is blacklisted");
failed("Taker is blacklisted");
}
else {
complete();
}
} }
else { else {
complete(); failed("Account registration validation for peer failed.");
} }
} } catch (Throwable t) {
else { model.trade.setThrowable(t);
failed("Account registration validation for peer failed."); failed(t);
} }
} }
} }

View file

@ -54,18 +54,16 @@ public class BroadcastTakeOfferFeeTx extends Task<TakerAsSellerModel> {
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again.");
model.trade.setErrorMessage(errorMessage);
model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED); model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED);
failed(t); failed(t);
} }
}); });
} catch (Exception e) { } catch (Throwable t) {
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again."); model.trade.setThrowable(t);
appendToErrorMessage(e.getMessage()); failed(t);
model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT);
failed(e);
} }
} }
} }

View file

@ -36,24 +36,29 @@ public class CreateAndSignContract extends Task<TakerAsSellerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
Trade trade = model.trade; try {
Contract contract = new Contract( Trade trade = model.trade;
model.offer, Contract contract = new Contract(
trade.getTradeAmount(), model.offer,
model.getTakeOfferFeeTx().getHashAsString(), trade.getTradeAmount(),
model.offerer.accountId, model.getTakeOfferFeeTx().getHashAsString(),
model.taker.accountId, model.offerer.accountId,
model.offerer.fiatAccount, model.taker.accountId,
model.taker.fiatAccount, model.offerer.fiatAccount,
model.offer.getP2PSigPubKey(), model.taker.fiatAccount,
model.taker.p2pSigPubKey); model.offer.getP2PSigPubKey(),
String contractAsJson = Utilities.objectToJson(contract); model.taker.p2pSigPubKey);
String signature = model.signatureService.signMessage(model.taker.registrationKeyPair, contractAsJson); String contractAsJson = Utilities.objectToJson(contract);
String signature = model.signatureService.signMessage(model.taker.registrationKeyPair, contractAsJson);
trade.setContract(contract); trade.setContract(contract);
trade.setContractAsJson(contractAsJson); trade.setContractAsJson(contractAsJson);
trade.setTakerContractSignature(signature); trade.setTakerContractSignature(signature);
complete(); complete();
} catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -43,12 +43,9 @@ public class CreateTakeOfferFeeTx extends Task<TakerAsSellerModel> {
model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_TX_CREATED); model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_TX_CREATED);
complete(); complete();
} catch (Exception e) { } catch (Throwable t) {
appendToErrorMessage(e.getMessage()); model.trade.setThrowable(t);
failed(t);
model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT);
failed(e);
} }
} }
} }

View file

@ -47,6 +47,7 @@ public class ProcessDepositTxPublishedMessage extends Task<TakerAsSellerModel> {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
model.trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -50,7 +50,7 @@ public class ProcessFiatTransferStartedMessage extends Task<TakerAsSellerModel>
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT); model.trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -52,6 +52,7 @@ public class ProcessRequestTakerDepositPaymentMessage extends Task<TakerAsSeller
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
model.trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -20,6 +20,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
@ -35,22 +36,30 @@ public class SendPayoutTxToOfferer extends Task<TakerAsSellerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(model.id, model.getPayoutTx()); try {
model.messageService.sendMessage(model.trade.getTradingPeer(), PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(model.id, model.getPayoutTx());
tradeMessage, model.messageService.sendMessage(model.trade.getTradingPeer(),
model.offerer.p2pSigPublicKey, tradeMessage,
model.offerer.p2pEncryptPubKey, model.offerer.p2pSigPublicKey,
new SendMessageListener() { model.offerer.p2pEncryptPubKey,
@Override new SendMessageListener() {
public void handleResult() { @Override
log.trace("PayoutTxPublishedMessage successfully arrived at peer"); public void handleResult() {
complete(); log.trace("PayoutTxPublishedMessage successfully arrived at peer");
} complete();
}
@Override @Override
public void handleFault() { public void handleFault() {
failed("Sending PayoutTxPublishedMessage failed."); appendToErrorMessage("Sending PayoutTxPublishedMessage failed");
} model.trade.setErrorMessage(errorMessage);
}); model.trade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED);
failed();
}
});
} catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -40,38 +40,44 @@ public class SendRequestDepositTxInputsMessage extends Task<TakerAsSellerModel>
@Override @Override
protected void doRun() { protected void doRun() {
RequestDepositTxInputsMessage msg = new RequestDepositTxInputsMessage( try {
model.id, RequestDepositTxInputsMessage msg = new RequestDepositTxInputsMessage(
model.getTakeOfferFeeTx().getHashAsString(), model.id,
model.trade.getTradeAmount(), model.getTakeOfferFeeTx().getHashAsString(),
model.taker.tradeWalletPubKey model.trade.getTradeAmount(),
); model.taker.tradeWalletPubKey);
model.messageService.sendMessage(model.trade.getTradingPeer(), msg, new SendMessageListener() { model.messageService.sendMessage(model.trade.getTradingPeer(), msg, new SendMessageListener() {
@Override @Override
public void handleResult() { public void handleResult() {
log.trace("Sending TakeOfferFeePayedMessage succeeded."); log.trace("Sending TakeOfferFeePayedMessage succeeded.");
complete(); complete();
}
@Override
public void handleFault() {
// Take offer fee is already paid, so we need to try to get that trade to succeed.
// We try to repeat once and if that fails as well we persist the state for a later retry.
if (retryCounter == 0) {
retryCounter++;
Platform.runLater(SendRequestDepositTxInputsMessage.this::doRun);
} }
else {
appendToErrorMessage("Sending TakeOfferFeePayedMessage to offerer failed. Maybe the network connection was lost or the offerer lost his " +
"connection. " +
"We persisted the state of the trade, please try again later or cancel that trade.");
model.trade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED); @Override
public void handleFault() {
log.warn("Sending TakeOfferFeePayedMessage failed. We try a second time.");
// Take offer fee is already paid, so we need to try to get that trade to succeed.
// We try to repeat once and if that fails as well we persist the state for a later retry.
if (retryCounter == 0) {
retryCounter++;
Platform.runLater(SendRequestDepositTxInputsMessage.this::doRun);
}
else {
appendToErrorMessage("Sending TakeOfferFeePayedMessage to offerer failed. Maybe the network connection was " +
"lost or the offerer lost his connection. We persisted the state of the trade, please try again later " +
"or cancel that trade.");
failed(); model.trade.setErrorMessage(errorMessage);
model.trade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED);
failed();
}
} }
} });
}); } catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -20,6 +20,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.messages.RequestOffererPublishDepositTxMessage; import io.bitsquare.trade.protocol.trade.messages.RequestOffererPublishDepositTxMessage;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
@ -35,30 +36,39 @@ public class SendSignedTakerDepositTx extends Task<TakerAsSellerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
RequestOffererPublishDepositTxMessage tradeMessage = new RequestOffererPublishDepositTxMessage( try {
model.id, RequestOffererPublishDepositTxMessage tradeMessage = new RequestOffererPublishDepositTxMessage(
model.taker.fiatAccount, model.id,
model.taker.accountId, model.taker.fiatAccount,
model.taker.p2pSigPubKey, model.taker.accountId,
model.taker.p2pEncryptPublicKey, model.taker.p2pSigPubKey,
model.trade.getContractAsJson(), model.taker.p2pEncryptPublicKey,
model.trade.getTakerContractSignature(), model.trade.getContractAsJson(),
model.taker.addressEntry.getAddressString(), model.trade.getTakerContractSignature(),
model.taker.preparedDepositTx, model.taker.addressEntry.getAddressString(),
model.taker.connectedOutputsForAllInputs, model.taker.preparedDepositTx,
model.taker.outputs model.taker.connectedOutputsForAllInputs,
); model.taker.outputs
);
model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() { model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() {
@Override @Override
public void handleResult() { public void handleResult() {
complete(); complete();
} }
@Override @Override
public void handleFault() { public void handleFault() {
failed("Sending RequestOffererDepositPublicationMessage failed"); appendToErrorMessage("Sending RequestOffererDepositPublicationMessage failed");
} model.trade.setErrorMessage(errorMessage);
}); model.trade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED);
failed();
}
});
} catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -62,11 +62,13 @@ public class SignAndPublishPayoutTx extends Task<TakerAsSellerModel> {
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
model.trade.setThrowable(t);
failed(t); failed(t);
} }
}); });
} catch (Throwable e) { } catch (Throwable t) {
failed(e); model.trade.setThrowable(t);
failed(t);
} }
} }
} }

View file

@ -22,7 +22,6 @@ import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.VerificationException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -43,7 +42,8 @@ public class TakerCommitDepositTx extends Task<TakerAsSellerModel> {
model.trade.setDepositTx(depositTx); model.trade.setDepositTx(depositTx);
complete(); complete();
} catch (VerificationException t) { } catch (Throwable t) {
model.trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -21,7 +21,6 @@ import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.TradeWalletService; import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -58,12 +57,9 @@ public class TakerCreatesAndSignsDepositTx extends Task<TakerAsSellerModel> {
model.taker.preparedDepositTx = result.getDepositTx(); model.taker.preparedDepositTx = result.getDepositTx();
complete(); complete();
} catch (Exception e) { } catch (Throwable t) {
TakerTrade.TakerProcessState processState = TakerTrade.TakerProcessState.UNSPECIFIC_FAULT; model.trade.setThrowable(t);
processState.setErrorMessage(errorMessage); failed(t);
model.trade.setProcessState(processState);
failed(e);
} }
} }
} }

View file

@ -33,11 +33,16 @@ public class VerifyOfferFeePayment extends Task<TakerAsSellerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
//TODO impl. missing try {
int numOfPeersSeenTx = model.walletService.getNumOfPeersSeenTx(model.getTakeOfferFeeTx().getHashAsString()); //TODO impl. missing
int numOfPeersSeenTx = model.walletService.getNumOfPeersSeenTx(model.getTakeOfferFeeTx().getHashAsString());
/* if (numOfPeersSeenTx > 2) { /* if (numOfPeersSeenTx > 2) {
resultHandler.handleResult(); resultHandler.handleResult();
}*/ }*/
complete(); complete();
} catch (Throwable t) {
model.trade.setThrowable(t);
failed(t);
}
} }
} }

View file

@ -33,16 +33,21 @@ public class VerifyOffererAccount extends Task<TakerAsSellerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
if (model.blockChainService.verifyAccountRegistration()) { try {
if (model.blockChainService.isAccountBlackListed(model.offerer.accountId, model.offerer.fiatAccount)) { if (model.blockChainService.verifyAccountRegistration()) {
failed("Taker is blacklisted."); if (model.blockChainService.isAccountBlackListed(model.offerer.accountId, model.offerer.fiatAccount)) {
failed("Taker is blacklisted.");
}
else {
complete();
}
} }
else { else {
complete(); failed("Account registration validation for peer faultHandler.onFault.");
} }
} } catch (Throwable t) {
else { model.trade.setThrowable(t);
failed("Account registration validation for peer faultHandler.onFault."); failed(t);
} }
} }
} }