Handle error cases in trade process

This commit is contained in:
Manfred Karrer 2015-03-14 10:04:17 +01:00
parent 1b883cf386
commit d1920b6e38
40 changed files with 65 additions and 42 deletions

View File

@ -41,6 +41,7 @@ public class Trade implements Serializable {
OPEN,
OFFERER_ACCEPTED,
OFFERER_REJECTED, /* For taker only*/
TAKE_OFFER_FEE_PAID,
DEPOSIT_PUBLISHED,
DEPOSIT_CONFIRMED,
FIAT_PAYMENT_STARTED,

View File

@ -55,7 +55,7 @@ public class GetPeerAddress extends Task<CheckOfferAvailabilityModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
model.getOffer().setState(Offer.State.OFFERER_OFFLINE);
}
}

View File

@ -51,7 +51,7 @@ public class ProcessReportOfferAvailabilityMessage extends Task<CheckOfferAvaila
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
model.getOffer().setState(Offer.State.AVAILABILITY_CHECK_FAILED);
}
}

View File

@ -52,7 +52,7 @@ public class RequestIsOfferAvailable extends Task<CheckOfferAvailabilityModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
if (model.getOffer().getState() != Offer.State.OFFERER_OFFLINE)
model.getOffer().setState(Offer.State.AVAILABILITY_CHECK_FAILED);
}

View File

@ -44,6 +44,7 @@ public class AddOfferToRemoteOfferBook extends Task<PlaceOfferModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
// do nothing
}
}

View File

@ -103,7 +103,7 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
}
}
protected void rollBackOnFault() {
protected void applyStateOnFault() {
if (!removeOfferFailed && !addOfferFailed) {
// If broadcast fails we need to remove offer from offerbook
model.getOfferBookService().removeOffer(model.getOffer(),

View File

@ -49,6 +49,7 @@ public class CreateOfferFeeTx extends Task<PlaceOfferModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
// do nothing
}
}

View File

@ -43,6 +43,7 @@ public class ValidateOffer extends Task<PlaceOfferModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
// do nothing
}
}

View File

@ -63,6 +63,6 @@ public class CreateDepositTx extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -55,6 +55,6 @@ public class ProcessPayoutTxPublishedMessage extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -58,6 +58,6 @@ public class ProcessRequestOffererPublishDepositTxMessage extends Task<BuyerAsOf
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -45,6 +45,7 @@ public class ProcessRequestTakeOfferMessage extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
// do nothing
}
}

View File

@ -54,6 +54,6 @@ public class ProcessTakeOfferFeePayedMessage extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -64,7 +64,7 @@ public class RespondToTakeOfferRequest extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
if (offerIsAvailable && model.getOpenOffer().getState() == OpenOffer.State.OFFER_ACCEPTED) {
model.getOpenOffer().setState(OpenOffer.State.OPEN);
model.setTrade(null);

View File

@ -58,6 +58,6 @@ public class SendBankTransferInitedMessage extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -55,6 +55,6 @@ public class SendDepositTxIdToTaker extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -58,6 +58,6 @@ public class SendTakerDepositPaymentRequest extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -57,6 +57,6 @@ public class SetupListenerForBlockChainConfirmation extends Task<BuyerAsOffererM
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -69,6 +69,6 @@ public class SignAndPublishDepositTx extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -64,7 +64,7 @@ public class SignPayoutTx extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -59,6 +59,6 @@ public class VerifyAndSignContract extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -43,6 +43,6 @@ public class VerifyTakeOfferFeePayment extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -49,6 +49,6 @@ public class VerifyTakerAccount extends Task<BuyerAsOffererModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -58,6 +58,6 @@ public class CreateAndSignContract extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -55,7 +55,7 @@ public class GetPeerAddress extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
if (model.getOffer().getState() != Offer.State.OFFERER_OFFLINE)
model.getOffer().setState(Offer.State.AVAILABILITY_CHECK_FAILED);
}

View File

@ -58,6 +58,6 @@ public class PayDeposit extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -47,6 +47,8 @@ public class PayTakeOfferFee extends Task<SellerAsTakerModel> {
public void onSuccess(Transaction transaction) {
log.debug("Take offer fee paid successfully. Transaction ID = " + transaction.getHashAsString());
model.getTrade().setTakeOfferFeeTxID(transaction.getHashAsString());
model.getTrade().setState(Trade.State.TAKE_OFFER_FEE_PAID);
complete();
}
@ -61,8 +63,10 @@ public class PayTakeOfferFee extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
// in error case take offer can be repeated so we reset the trade state
protected void applyStateOnFault() {
// As long as the take offer fee was not paid nothing critical happens.
// The take offer process can be repeated so we reset the trade state.
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again.");
model.getTrade().setState(Trade.State.OPEN);
}
}

View File

@ -55,6 +55,6 @@ public class ProcessBankTransferInitedMessage extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -49,6 +49,6 @@ public class ProcessDepositTxPublishedMessage extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -54,6 +54,7 @@ public class ProcessRespondToTakeOfferRequestMessage extends Task<SellerAsTakerM
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
// do nothing
}
}

View File

@ -53,6 +53,6 @@ public class ProcessTakerDepositPaymentRequestMessage extends Task<SellerAsTaker
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -52,7 +52,7 @@ public class RequestTakeOffer extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
if (model.getOffer().getState() != Offer.State.OFFERER_OFFLINE)
model.getOffer().setState(Offer.State.AVAILABILITY_CHECK_FAILED);
}

View File

@ -51,6 +51,6 @@ public class SendPayoutTxToOfferer extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -69,6 +69,6 @@ public class SendSignedTakerDepositTxAsHex extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -33,6 +33,8 @@ public class SendTakeOfferFeePayedMessage extends Task<SellerAsTakerModel> {
super(taskHandler, model);
}
public int retryCounter = 0;
@Override
protected void doRun() {
TakeOfferFeePayedMessage msg = new TakeOfferFeePayedMessage(
@ -43,6 +45,7 @@ public class SendTakeOfferFeePayedMessage extends Task<SellerAsTakerModel> {
);
model.getTradeMessageService().sendMessage(model.getPeer(), msg, new SendMessageListener() {
@Override
public void handleResult() {
log.trace("Sending TakeOfferFeePayedMessage succeeded.");
@ -51,12 +54,22 @@ public class SendTakeOfferFeePayedMessage extends Task<SellerAsTakerModel> {
@Override
public void handleFault() {
failed();
// 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++;
doRun();
}
else {
failed();
}
}
});
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
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.");
}
}

View File

@ -74,6 +74,6 @@ public class SignAndPublishPayoutTx extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -45,6 +45,6 @@ public class TakerCommitDepositTx extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -42,6 +42,6 @@ public class VerifyOfferFeePayment extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -47,6 +47,6 @@ public class VerifyOffererAccount extends Task<SellerAsTakerModel> {
}
@Override
protected void rollBackOnFault() {
protected void applyStateOnFault() {
}
}

View File

@ -47,7 +47,7 @@ public abstract class Task<T extends SharedModel> {
abstract protected void doRun();
abstract protected void rollBackOnFault();
abstract protected void applyStateOnFault();
private void interceptBeforeRun() {
if (getClass() == taskToInterceptBeforeRun)
@ -88,7 +88,7 @@ public abstract class Task<T extends SharedModel> {
}
protected void failed() {
rollBackOnFault();
applyStateOnFault();
taskHandler.handleErrorMessage(errorMessage);
}