From 77bf67e465ce7181e2ab9f23c33817b934f6f7d8 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 26 Mar 2015 00:27:20 +0100 Subject: [PATCH] Refactor trade states --- .../io/bitsquare/gui/main/MainViewModel.java | 2 +- .../content/fiat/FiatAccountDataModel.java | 2 +- .../closed/ClosedTradesViewModel.java | 37 +++-- .../pending/PendingTradesListItem.java | 6 +- .../pending/PendingTradesViewModel.java | 76 +++++++--- .../createoffer/CreateOfferDataModel.java | 4 +- .../trade/offerbook/OfferBookDataModel.java | 10 +- .../trade/takeoffer/TakeOfferDataModel.java | 6 +- .../trade/takeoffer/TakeOfferViewModel.java | 16 +- .../io/bitsquare/gui/util/BSFormatter.java | 10 +- .../gui/util/validation/FiatValidator.java | 8 +- .../validation/OptionalFiatValidator.java | 8 +- .../java/io/bitsquare/offer/OfferBook.java | 6 +- .../offer/tomp2p/TomP2POfferBookService.java | 8 - .../java/io/bitsquare/trade/OffererTrade.java | 141 +++++++++++++++++ .../java/io/bitsquare/trade/TakerTrade.java | 130 ++++++++++++++++ .../main/java/io/bitsquare/trade/Trade.java | 142 +++--------------- .../java/io/bitsquare/trade/TradeManager.java | 121 ++++----------- ...ndler.java => TakeOfferResultHandler.java} | 6 +- .../CheckOfferAvailabilityProtocol.java | 1 + .../trade/offerer/OffererAsBuyerProtocol.java | 4 +- .../offerer/models/OffererAsBuyerModel.java | 6 +- .../ProcessPayoutTxPublishedMessage.java | 4 +- .../tasks/SendBankTransferStartedMessage.java | 8 +- .../tasks/SignAndPublishDepositTx.java | 4 +- .../trade/taker/TakerAsSellerProtocol.java | 4 +- .../taker/models/TakerAsSellerModel.java | 6 +- .../taker/tasks/BroadcastTakeOfferFeeTx.java | 8 +- .../taker/tasks/CreateTakeOfferFeeTx.java | 6 +- .../ProcessDepositTxPublishedMessage.java | 4 +- .../ProcessFiatTransferStartedMessage.java | 6 +- .../SendRequestDepositTxInputsMessage.java | 4 +- .../taker/tasks/SignAndPublishPayoutTx.java | 4 +- .../tasks/TakerCreatesAndSignsDepositTx.java | 4 +- .../src/main/java/io/bitsquare/user/User.java | 2 +- 35 files changed, 485 insertions(+), 329 deletions(-) rename core/src/main/java/io/bitsquare/trade/handlers/{TradeResultHandler.java => TakeOfferResultHandler.java} (86%) diff --git a/core/src/main/java/io/bitsquare/gui/main/MainViewModel.java b/core/src/main/java/io/bitsquare/gui/main/MainViewModel.java index 34b469578e..be0d3dc47f 100644 --- a/core/src/main/java/io/bitsquare/gui/main/MainViewModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/MainViewModel.java @@ -109,7 +109,7 @@ class MainViewModel implements ViewModel { updateProcess.state.addListener((observableValue, oldValue, newValue) -> applyUpdateState(newValue)); applyUpdateState(updateProcess.state.get()); - currentBankAccount.bind(user.currentFiatAccountPropertyProperty()); + currentBankAccount.bind(user.currentFiatAccountProperty()); user.fiatAccountsObservableList().addListener((ListChangeListener) change -> { bankAccountsComboBoxDisable.set(change.getList().isEmpty()); bankAccountsComboBoxPrompt.set(change.getList().isEmpty() ? "No accounts" : ""); diff --git a/core/src/main/java/io/bitsquare/gui/main/account/content/fiat/FiatAccountDataModel.java b/core/src/main/java/io/bitsquare/gui/main/account/content/fiat/FiatAccountDataModel.java index f463946675..037df574ac 100644 --- a/core/src/main/java/io/bitsquare/gui/main/account/content/fiat/FiatAccountDataModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/account/content/fiat/FiatAccountDataModel.java @@ -95,7 +95,7 @@ class FiatAccountDataModel implements Activatable, DataModel { } void removeBankAccount() { - user.removeFiatAccount(user.currentFiatAccountPropertyProperty().get()); + user.removeFiatAccount(user.currentFiatAccountProperty().get()); allFiatAccounts.setAll(user.fiatAccountsObservableList()); reset(); } diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/closed/ClosedTradesViewModel.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/closed/ClosedTradesViewModel.java index 4654dfd8d4..d771acf7a0 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/closed/ClosedTradesViewModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/closed/ClosedTradesViewModel.java @@ -20,6 +20,9 @@ package io.bitsquare.gui.main.portfolio.closed; import io.bitsquare.common.viewfx.model.ActivatableWithDataModel; import io.bitsquare.common.viewfx.model.ViewModel; import io.bitsquare.gui.util.BSFormatter; +import io.bitsquare.trade.OffererTrade; +import io.bitsquare.trade.TakerTrade; +import io.bitsquare.trade.Trade; import com.google.inject.Inject; @@ -67,17 +70,31 @@ class ClosedTradesViewModel extends ActivatableWithDataModel tradeAmountProperty() { + public ReadOnlyObjectProperty tradeAmountProperty() { return trade.tradeAmountProperty(); } - public ObjectProperty tradeVolumeProperty() { + public ReadOnlyObjectProperty tradeVolumeProperty() { return trade.tradeVolumeProperty(); } diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesViewModel.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesViewModel.java index 6673772abf..f18b074e21 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesViewModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesViewModel.java @@ -23,6 +23,8 @@ import io.bitsquare.common.viewfx.model.ViewModel; import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.validation.BtcAddressValidator; import io.bitsquare.locale.BSResources; +import io.bitsquare.trade.OffererTrade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.Trade; import org.bitcoinj.core.Coin; @@ -218,30 +220,56 @@ class PendingTradesViewModel extends ActivatableWithDataModel applyBankAccount(newValue)); + user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> applyBankAccount(newValue)); - applyBankAccount(user.currentFiatAccountPropertyProperty().get()); + applyBankAccount(user.currentFiatAccountProperty().get()); } if (accountSettings != null) diff --git a/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookDataModel.java b/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookDataModel.java index 9ae0142aa2..2decfdf69d 100644 --- a/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookDataModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookDataModel.java @@ -98,17 +98,17 @@ class OfferBookDataModel implements Activatable, DataModel { volumeAsFiat.set(null); offerBook.addClient(); - user.currentFiatAccountPropertyProperty().addListener(bankAccountChangeListener); + user.currentFiatAccountProperty().addListener(bankAccountChangeListener); btcCode.bind(preferences.btcDenominationProperty()); - setBankAccount(user.currentFiatAccountPropertyProperty().get()); + setBankAccount(user.currentFiatAccountProperty().get()); applyFilter(); } @Override public void deactivate() { offerBook.removeClient(); - user.currentFiatAccountPropertyProperty().removeListener(bankAccountChangeListener); + user.currentFiatAccountProperty().removeListener(bankAccountChangeListener); btcCode.unbind(); } @@ -148,7 +148,7 @@ class OfferBookDataModel implements Activatable, DataModel { boolean isTradable(Offer offer) { // if user has not registered yet we display all - FiatAccount currentFiatAccount = user.currentFiatAccountPropertyProperty().get(); + FiatAccount currentFiatAccount = user.currentFiatAccountProperty().get(); if (currentFiatAccount == null) return true; @@ -158,7 +158,7 @@ class OfferBookDataModel implements Activatable, DataModel { if (!countryResult) restrictionsInfo.set("This offer requires that the payments account resides in one of those countries:\n" + formatter.countryLocalesToString(offer.getAcceptedCountries()) + - "\n\nThe country of your payments account (" + user.currentFiatAccountPropertyProperty().get().country.name + + "\n\nThe country of your payments account (" + user.currentFiatAccountProperty().get().country.name + ") is not included in that list." + "\n\n Do you want to edit your preferences now?"); diff --git a/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferDataModel.java b/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferDataModel.java index 8927f97c68..434857f290 100644 --- a/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferDataModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferDataModel.java @@ -25,7 +25,7 @@ import io.bitsquare.common.viewfx.model.Activatable; import io.bitsquare.common.viewfx.model.DataModel; import io.bitsquare.offer.Offer; import io.bitsquare.trade.TradeManager; -import io.bitsquare.trade.handlers.TradeResultHandler; +import io.bitsquare.trade.handlers.TakeOfferResultHandler; import io.bitsquare.user.Preferences; import org.bitcoinj.core.Coin; @@ -124,8 +124,8 @@ class TakeOfferDataModel implements Activatable, DataModel { tradeManager.checkOfferAvailability(offer); } - void takeOffer(TradeResultHandler handler) { - tradeManager.requestTakeOffer(amountAsCoin.get(), offer, (trade) -> handler.handleTradeResult(trade)); + void takeOffer(TakeOfferResultHandler handler) { + tradeManager.requestTakeOffer(amountAsCoin.get(), offer, (trade) -> handler.handleResult(trade)); } void calculateVolume() { diff --git a/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferViewModel.java b/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferViewModel.java index d35c36920a..c8614b3b79 100644 --- a/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferViewModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferViewModel.java @@ -207,27 +207,25 @@ class TakeOfferViewModel extends ActivatableWithDataModel im isTakeOfferSpinnerVisible.set(true); - dataModel.takeOffer((trade) -> { - trade.processStateProperty().addListener((ov, oldValue, newValue) -> { - log.debug("trade state = " + newValue); + dataModel.takeOffer((takerTrade) -> { + takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { + log.debug("takerTrade state = " + newValue); String msg = ""; if (newValue.getErrorMessage() != null) msg = "\nError message: " + newValue.getErrorMessage(); switch (newValue) { - case INIT: - break; case TAKE_OFFER_FEE_TX_CREATED: break; case DEPOSIT_PUBLISHED: case DEPOSIT_CONFIRMED: - transactionId.set(trade.getDepositTx().getHashAsString()); + transactionId.set(takerTrade.getDepositTx().getHashAsString()); applyTakeOfferRequestResult(true); break; case FIAT_PAYMENT_STARTED: break; case TAKE_OFFER_FEE_PUBLISH_FAILED: - errorMessage.set("An error occurred when paying the trade fee." + msg); + errorMessage.set("An error occurred when paying the takerTrade fee." + msg); takeOfferRequested = false; break; case MESSAGE_SENDING_FAILED: @@ -237,12 +235,12 @@ class TakeOfferViewModel extends ActivatableWithDataModel im break; case PAYOUT_PUBLISHED: break; - case FAULT: + case UNSPECIFIC_FAULT: errorMessage.set(msg); takeOfferRequested = false; break; default: - log.warn("Unhandled trade state: " + newValue); + log.warn("Unhandled takerTrade state: " + newValue); break; } diff --git a/core/src/main/java/io/bitsquare/gui/util/BSFormatter.java b/core/src/main/java/io/bitsquare/gui/util/BSFormatter.java index f2d86e4401..ae5fbe4f87 100644 --- a/core/src/main/java/io/bitsquare/gui/util/BSFormatter.java +++ b/core/src/main/java/io/bitsquare/gui/util/BSFormatter.java @@ -79,12 +79,12 @@ public class BSFormatter { @Inject public BSFormatter(User user, ArbitrationRepository arbitrationRepository) { this.arbitrationRepository = arbitrationRepository; - if (user.currentFiatAccountPropertyProperty().get() == null) + if (user.currentFiatAccountProperty().get() == null) setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode()); - else if (user.currentFiatAccountPropertyProperty().get() != null) - setFiatCurrencyCode(user.currentFiatAccountPropertyProperty().get().currencyCode); + else if (user.currentFiatAccountProperty().get() != null) + setFiatCurrencyCode(user.currentFiatAccountProperty().get().currencyCode); - user.currentFiatAccountPropertyProperty().addListener((ov, oldValue, newValue) -> { + user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> { if (newValue != null) setFiatCurrencyCode(newValue.currencyCode); }); @@ -313,7 +313,7 @@ public class BSFormatter { } public String countryLocalesToString(List countries) { - return countries.stream().map(e-> e.name).collect(Collectors.joining(", ")); + return countries.stream().map(e -> e.name).collect(Collectors.joining(", ")); } public String arbitratorsToNames(List arbitrators) { diff --git a/core/src/main/java/io/bitsquare/gui/util/validation/FiatValidator.java b/core/src/main/java/io/bitsquare/gui/util/validation/FiatValidator.java index 3cdb67564b..11a4f327c3 100644 --- a/core/src/main/java/io/bitsquare/gui/util/validation/FiatValidator.java +++ b/core/src/main/java/io/bitsquare/gui/util/validation/FiatValidator.java @@ -39,12 +39,12 @@ public final class FiatValidator extends NumberValidator { @Inject public FiatValidator(User user) { if (user != null) { - if (user.currentFiatAccountPropertyProperty().get() == null) + if (user.currentFiatAccountProperty().get() == null) setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode()); - else if (user.currentFiatAccountPropertyProperty().get() != null) - setFiatCurrencyCode(user.currentFiatAccountPropertyProperty().get().currencyCode); + else if (user.currentFiatAccountProperty().get() != null) + setFiatCurrencyCode(user.currentFiatAccountProperty().get().currencyCode); - user.currentFiatAccountPropertyProperty().addListener((ov, oldValue, newValue) -> { + user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> { if (newValue != null) setFiatCurrencyCode(newValue.currencyCode); }); diff --git a/core/src/main/java/io/bitsquare/gui/util/validation/OptionalFiatValidator.java b/core/src/main/java/io/bitsquare/gui/util/validation/OptionalFiatValidator.java index 45001f3a2e..0fcb76ebdf 100644 --- a/core/src/main/java/io/bitsquare/gui/util/validation/OptionalFiatValidator.java +++ b/core/src/main/java/io/bitsquare/gui/util/validation/OptionalFiatValidator.java @@ -39,12 +39,12 @@ public final class OptionalFiatValidator extends NumberValidator { @Inject public OptionalFiatValidator(User user) { if (user != null) { - if (user.currentFiatAccountPropertyProperty().get() == null) + if (user.currentFiatAccountProperty().get() == null) setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode()); - else if (user.currentFiatAccountPropertyProperty().get() != null) - setFiatCurrencyCode(user.currentFiatAccountPropertyProperty().get().currencyCode); + else if (user.currentFiatAccountProperty().get() != null) + setFiatCurrencyCode(user.currentFiatAccountProperty().get().currencyCode); - user.currentFiatAccountPropertyProperty().addListener((ov, oldValue, newValue) -> { + user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> { if (newValue != null) setFiatCurrencyCode(newValue.currencyCode); }); diff --git a/core/src/main/java/io/bitsquare/offer/OfferBook.java b/core/src/main/java/io/bitsquare/offer/OfferBook.java index d2c11ef6e4..488e3f7e1b 100644 --- a/core/src/main/java/io/bitsquare/offer/OfferBook.java +++ b/core/src/main/java/io/bitsquare/offer/OfferBook.java @@ -150,14 +150,14 @@ public class OfferBook { private void addListeners() { log.debug("addListeners "); - user.currentFiatAccountPropertyProperty().addListener(bankAccountChangeListener); + user.currentFiatAccountProperty().addListener(bankAccountChangeListener); offerBookService.addListener(offerBookServiceListener); offerBookService.invalidationTimestampProperty().addListener(invalidationListener); } private void removeListeners() { log.debug("removeListeners "); - user.currentFiatAccountPropertyProperty().removeListener(bankAccountChangeListener); + user.currentFiatAccountProperty().removeListener(bankAccountChangeListener); offerBookService.removeListener(offerBookServiceListener); offerBookService.invalidationTimestampProperty().removeListener(invalidationListener); } @@ -180,7 +180,7 @@ public class OfferBook { // TODO Just temporary, will be removed later when we have a push solution private void startPolling() { addListeners(); - setBankAccount(user.currentFiatAccountPropertyProperty().get()); + setBankAccount(user.currentFiatAccountProperty().get()); pollingTimer = Utilities.setInterval(POLLING_INTERVAL, (animationTimer) -> { offerBookService.requestInvalidationTimeStampFromDHT(fiatCode); return null; diff --git a/core/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferBookService.java b/core/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferBookService.java index 48c5c880ac..fdc5926053 100644 --- a/core/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferBookService.java +++ b/core/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferBookService.java @@ -172,14 +172,6 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo try { Object offerDataObject = offerData.object(); if (offerDataObject instanceof Offer) { - - try { - Data offerData1 = new Data(offerDataObject); - log.trace("-------------------------- getOffers hash" + offerData1.hash().toString()); - } catch (IOException e) { - e.printStackTrace(); - } - offers.add((Offer) offerDataObject); } } catch (ClassNotFoundException | IOException e) { diff --git a/core/src/main/java/io/bitsquare/trade/OffererTrade.java b/core/src/main/java/io/bitsquare/trade/OffererTrade.java index 22971376ea..65a1e92169 100644 --- a/core/src/main/java/io/bitsquare/trade/OffererTrade.java +++ b/core/src/main/java/io/bitsquare/trade/OffererTrade.java @@ -20,8 +20,21 @@ package io.bitsquare.trade; import io.bitsquare.offer.Offer; import io.bitsquare.trade.protocol.trade.offerer.OffererAsBuyerProtocol; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionConfidence; + +import com.google.common.base.Throwables; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +import java.io.IOException; import java.io.Serializable; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.SimpleObjectProperty; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,13 +43,141 @@ public class OffererTrade extends Trade implements Serializable { private static final long serialVersionUID = 1L; transient private static final Logger log = LoggerFactory.getLogger(OffererTrade.class); + /////////////////////////////////////////////////////////////////////////////////////////// + // Enum + /////////////////////////////////////////////////////////////////////////////////////////// + + public enum OffererLifeCycleState implements LifeCycleState { + OPEN_OFFER, + OFFER_CANCELED, + PENDING, + COMPLETED, + FAILED + } + + public enum OffererProcessState implements ProcessState { + DEPOSIT_PUBLISHED, + DEPOSIT_CONFIRMED, + FIAT_PAYMENT_STARTED, + PAYOUT_PUBLISHED, + MESSAGE_SENDING_FAILED, + UNSPECIFIC_FAULT; + + protected String errorMessage; + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getErrorMessage() { + return errorMessage; + } + } + + protected OffererProcessState processState; + protected OffererLifeCycleState lifeCycleState; + + transient protected ObjectProperty processStateProperty = new SimpleObjectProperty<>(processState); + transient protected ObjectProperty lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState); + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + public OffererTrade(Offer offer) { super(offer); } + // Serialized object does not create our transient objects + private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + processStateProperty = new SimpleObjectProperty<>(processState); + lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState); + } + public void onFiatPaymentStarted() { ((OffererAsBuyerProtocol) protocol).onFiatPaymentStarted(); } + /////////////////////////////////////////////////////////////////////////////////////////// + // Setters + /////////////////////////////////////////////////////////////////////////////////////////// + + public void setProcessState(OffererProcessState processState) { + this.processState = processState; + processStateProperty.set(processState); + + switch (processState) { + case UNSPECIFIC_FAULT: + disposeProtocol(); + setLifeCycleState(OffererLifeCycleState.FAILED); + break; + } + } + + public void setLifeCycleState(OffererLifeCycleState lifeCycleState) { + switch (lifeCycleState) { + case FAILED: + disposeProtocol(); + break; + case COMPLETED: + disposeProtocol(); + break; + } + this.lifeCycleState = lifeCycleState; + lifeCycleStateProperty.set(lifeCycleState); + } + + public void setDepositTx(Transaction tx) { + this.depositTx = tx; + setConfidenceListener(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + + public OffererProcessState getProcessState() { + return processState; + } + + public OffererLifeCycleState getLifeCycleState() { + return lifeCycleState; + } + + public ReadOnlyObjectProperty processStateProperty() { + return processStateProperty; + } + + public ReadOnlyObjectProperty lifeCycleStateProperty() { + return lifeCycleStateProperty; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + protected void setConfidenceListener() { + TransactionConfidence transactionConfidence = depositTx.getConfidence(); + ListenableFuture future = transactionConfidence.getDepthFuture(1); + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(TransactionConfidence result) { + if (processState.ordinal() < OffererProcessState.DEPOSIT_CONFIRMED.ordinal()) + setProcessState(OffererProcessState.DEPOSIT_CONFIRMED); + } + + @Override + public void onFailure(Throwable t) { + t.printStackTrace(); + log.error(t.getMessage()); + Throwables.propagate(t); + } + }); + } } diff --git a/core/src/main/java/io/bitsquare/trade/TakerTrade.java b/core/src/main/java/io/bitsquare/trade/TakerTrade.java index 9753ef377e..150cdec774 100644 --- a/core/src/main/java/io/bitsquare/trade/TakerTrade.java +++ b/core/src/main/java/io/bitsquare/trade/TakerTrade.java @@ -20,8 +20,21 @@ package io.bitsquare.trade; import io.bitsquare.offer.Offer; import io.bitsquare.trade.protocol.trade.taker.TakerAsSellerProtocol; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionConfidence; + +import com.google.common.base.Throwables; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +import java.io.IOException; import java.io.Serializable; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.SimpleObjectProperty; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,11 +43,128 @@ public class TakerTrade extends Trade implements Serializable { private static final long serialVersionUID = 1L; transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Enum + /////////////////////////////////////////////////////////////////////////////////////////// + + public enum TakerLifeCycleState implements LifeCycleState { + PENDING, + COMPLETED, + FAILED + } + + public enum TakerProcessState implements ProcessState { + TAKE_OFFER_FEE_TX_CREATED, + TAKE_OFFER_FEE_PUBLISHED, + TAKE_OFFER_FEE_PUBLISH_FAILED, + DEPOSIT_PUBLISHED, + DEPOSIT_CONFIRMED, + FIAT_PAYMENT_STARTED, + FIAT_PAYMENT_RECEIVED, + PAYOUT_PUBLISHED, + MESSAGE_SENDING_FAILED, + UNSPECIFIC_FAULT; + + protected String errorMessage; + + @Override + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + @Override + public String getErrorMessage() { + return errorMessage; + } + } + + protected TakerProcessState processState; + protected TakerLifeCycleState lifeCycleState; + + transient protected ObjectProperty processStateProperty = new SimpleObjectProperty<>(processState); + transient protected ObjectProperty lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState); + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + public TakerTrade(Offer offer) { super(offer); } + // Serialized object does not create our transient objects + private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + processStateProperty = new SimpleObjectProperty<>(processState); + lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState); + } + public void onFiatPaymentReceived() { ((TakerAsSellerProtocol) protocol).onFiatPaymentReceived(); } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Setters + /////////////////////////////////////////////////////////////////////////////////////////// + + public void setProcessState(TakerProcessState processState) { + this.processState = processState; + processStateProperty.set(processState); + + if (processState == TakerProcessState.UNSPECIFIC_FAULT) { + setLifeCycleState(TakerLifeCycleState.FAILED); + disposeProtocol(); + } + } + + public void setLifeCycleState(TakerLifeCycleState lifeCycleState) { + this.lifeCycleState = lifeCycleState; + lifeCycleStateProperty.set(lifeCycleState); + } + + public void setDepositTx(Transaction tx) { + this.depositTx = tx; + setConfidenceListener(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + + public ReadOnlyObjectProperty processStateProperty() { + return processStateProperty; + } + + public ReadOnlyObjectProperty lifeCycleStateProperty() { + return lifeCycleStateProperty; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + protected void setConfidenceListener() { + TransactionConfidence transactionConfidence = depositTx.getConfidence(); + ListenableFuture future = transactionConfidence.getDepthFuture(1); + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(TransactionConfidence result) { + if (processState.ordinal() < TakerProcessState.DEPOSIT_CONFIRMED.ordinal()) + setProcessState(TakerProcessState.DEPOSIT_CONFIRMED); + } + + @Override + public void onFailure(Throwable t) { + t.printStackTrace(); + log.error(t.getMessage()); + Throwables.propagate(t); + } + }); + } } diff --git a/core/src/main/java/io/bitsquare/trade/Trade.java b/core/src/main/java/io/bitsquare/trade/Trade.java index 96dfdaa93f..b53df0933e 100644 --- a/core/src/main/java/io/bitsquare/trade/Trade.java +++ b/core/src/main/java/io/bitsquare/trade/Trade.java @@ -24,76 +24,39 @@ import io.bitsquare.trade.protocol.Protocol; import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionConfidence; import org.bitcoinj.utils.Fiat; -import com.google.common.base.Throwables; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - import java.io.IOException; import java.io.Serializable; import java.util.Date; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.SimpleObjectProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class Trade implements Serializable { +abstract public class Trade implements Serializable { // That object is saved to disc. We need to take care of changes to not break deserialization. private static final long serialVersionUID = 1L; transient protected static final Logger log = LoggerFactory.getLogger(Trade.class); - - /////////////////////////////////////////////////////////////////////////////////////////// - // Enum - /////////////////////////////////////////////////////////////////////////////////////////// - - public enum LifeCycleState { - OPEN_OFFER, - CANCELED, - PENDING, - COMPLETED, - FAILED + public interface ProcessState { + void setErrorMessage(String errorMessage); + String getErrorMessage(); } - public enum ProcessState { - INIT, - TAKE_OFFER_FEE_PUBLISH_FAILED, - TAKE_OFFER_FEE_TX_CREATED, - DEPOSIT_PUBLISHED, - TAKE_OFFER_FEE_PUBLISHED, - DEPOSIT_CONFIRMED, - FIAT_PAYMENT_STARTED, - FIAT_PAYMENT_RECEIVED, - PAYOUT_PUBLISHED, - MESSAGE_SENDING_FAILED, - FAULT; - - protected String errorMessage; - - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - public String getErrorMessage() { - return errorMessage; - } + public interface LifeCycleState { } transient protected Protocol protocol; - protected MailboxMessage mailboxMessage; protected final Offer offer; protected final Date date; - protected ProcessState processState; - protected LifeCycleState lifeCycleState; protected Coin tradeAmount; protected Contract contract; @@ -105,13 +68,8 @@ public class Trade implements Serializable { protected Peer tradingPeer; protected int depthInBlocks = 0; - // For changing values we use properties to get binding support in the UI (table) - // When serialized those transient properties are not instantiated, so we instantiate them in the getters at first - // access. Only use the accessor not the protected field. - transient protected ObjectProperty tradeAmountProperty; - transient protected ObjectProperty tradeVolumeProperty; - transient protected ObjectProperty processStateProperty; - transient protected ObjectProperty lifeCycleStateProperty; + transient protected ObjectProperty tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount); + transient protected ObjectProperty tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume()); /////////////////////////////////////////////////////////////////////////////////////////// @@ -121,18 +79,14 @@ public class Trade implements Serializable { public Trade(Offer offer) { this.offer = offer; date = new Date(); - - setProcessState(ProcessState.INIT); - log.debug("Trade "); } // Serialized object does not create our transient objects private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); + tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount); tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume()); - processStateProperty = new SimpleObjectProperty<>(processState); - lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState); } @@ -148,9 +102,10 @@ public class Trade implements Serializable { } public void disposeProtocol() { - if (protocol != null) + if (protocol != null) { protocol.cleanup(); - protocol = null; + protocol = null; + } } public void setMailboxMessage(MailboxMessage mailboxMessage) { @@ -164,6 +119,14 @@ public class Trade implements Serializable { // Setters /////////////////////////////////////////////////////////////////////////////////////////// + + public void setTradeAmount(Coin tradeAmount) { + this.tradeAmount = tradeAmount; + tradeAmountProperty.set(tradeAmount); + tradeVolumeProperty.set(getTradeVolume()); + } + + public void setTradingPeer(Peer tradingPeer) { this.tradingPeer = tradingPeer; } @@ -180,12 +143,6 @@ public class Trade implements Serializable { return tradeAmount; } - public void setTradeAmount(Coin tradeAmount) { - this.tradeAmount = tradeAmount; - tradeAmountProperty().set(tradeAmount); - tradeVolumeProperty().set(getTradeVolume()); - } - public Contract getContract() { return contract; } @@ -198,25 +155,10 @@ public class Trade implements Serializable { this.contract = contract; } - public void setDepositTx(Transaction tx) { - this.depositTx = tx; - setConfidenceListener(); - } - public void setPayoutTx(Transaction tx) { this.payoutTx = tx; } - public void setProcessState(ProcessState processState) { - this.processState = processState; - processStateProperty().set(processState); - } - - public void setLifeCycleState(LifeCycleState lifeCycleState) { - this.lifeCycleState = lifeCycleState; - lifeCycleStateProperty().set(lifeCycleState); - } - /////////////////////////////////////////////////////////////////////////////////////////// // Getters @@ -242,14 +184,6 @@ public class Trade implements Serializable { return payoutTx; } - public ProcessState getProcessState() { - return processState; - } - - public LifeCycleState getLifeCycleState() { - return lifeCycleState; - } - public Coin getSecurityDeposit() { return offer.getSecurityDeposit(); } @@ -274,45 +208,19 @@ public class Trade implements Serializable { return tradingPeer; } - public ObjectProperty tradeAmountProperty() { + public ReadOnlyObjectProperty tradeAmountProperty() { return tradeAmountProperty; } - public ObjectProperty tradeVolumeProperty() { + public ReadOnlyObjectProperty tradeVolumeProperty() { return tradeVolumeProperty; } - public ObjectProperty processStateProperty() { - return processStateProperty; - } + abstract public ReadOnlyObjectProperty processStateProperty(); - public ObjectProperty lifeCycleStateProperty() { - return lifeCycleStateProperty; - } + abstract public ReadOnlyObjectProperty lifeCycleStateProperty(); - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - - protected void setConfidenceListener() { - TransactionConfidence transactionConfidence = depositTx.getConfidence(); - ListenableFuture future = transactionConfidence.getDepthFuture(1); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(TransactionConfidence result) { - setProcessState(Trade.ProcessState.DEPOSIT_CONFIRMED); - } - - @Override - public void onFailure(Throwable t) { - t.printStackTrace(); - log.error(t.getMessage()); - Throwables.propagate(t); - } - }); - } - @Override public String toString() { return "Trade{" + @@ -320,8 +228,6 @@ public class Trade implements Serializable { ", mailboxMessage=" + mailboxMessage + ", offer=" + offer + ", date=" + date + - ", processState=" + processState + - ", lifeCycleState=" + lifeCycleState + ", tradeAmount=" + tradeAmount + ", contract=" + contract + ", contractAsJson='" + contractAsJson + '\'' + diff --git a/core/src/main/java/io/bitsquare/trade/TradeManager.java b/core/src/main/java/io/bitsquare/trade/TradeManager.java index 47c9d10fe5..1f60f32f2c 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/core/src/main/java/io/bitsquare/trade/TradeManager.java @@ -33,7 +33,7 @@ import io.bitsquare.p2p.MailboxMessage; import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MessageService; import io.bitsquare.p2p.Peer; -import io.bitsquare.trade.handlers.TradeResultHandler; +import io.bitsquare.trade.handlers.TakeOfferResultHandler; import io.bitsquare.trade.handlers.TransactionResultHandler; import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityModel; import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityProtocol; @@ -51,7 +51,6 @@ import org.bitcoinj.core.Coin; import org.bitcoinj.utils.Fiat; import java.io.File; -import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -63,8 +62,6 @@ import javax.inject.Named; import javafx.collections.ObservableList; -import net.tomp2p.storage.Data; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,15 +71,15 @@ public class TradeManager { private final User user; private final AccountSettings accountSettings; private final MessageService messageService; - private MailboxService mailboxService; + private final MailboxService mailboxService; private final AddressService addressService; private final BlockChainService blockChainService; private final WalletService walletService; private final SignatureService signatureService; - private EncryptionService encryptionService; + private final EncryptionService encryptionService; private final OfferBookService offerBookService; - private ArbitrationRepository arbitrationRepository; - private File storageDir; + private final ArbitrationRepository arbitrationRepository; + private final File storageDir; private final Map checkOfferAvailabilityProtocolMap = new HashMap<>(); @@ -124,20 +121,25 @@ public class TradeManager { /////////////////////////////////////////////////////////////////////////////////////////// // When all services are initialized we create the protocols for our open offers and persisted not completed pendingTrades - // BuyerAcceptsOfferProtocol listens for take offer requests, so we need to instantiate it early. + // OffererAsBuyerProtocol listens for take offer requests, so we need to instantiate it early. public void onAllServicesInitialized() { for (OffererTrade offererTrade : openOfferTrades) { - createOffererAsBuyerProtocol(offererTrade); + OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade); + offererTrade.setProtocol(protocol); } for (Trade trade : pendingTrades) { // We continue an interrupted trade. // TODO if the peer has changed its IP address, we need to make another findPeer request. At the moment we use the peer stored in trade to // continue the trade, but that might fail. if (trade instanceof OffererTrade) { - createOffererAsBuyerProtocol((OffererTrade) trade); + OffererTrade offererTrade = (OffererTrade) trade; + OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade); + offererTrade.setProtocol(protocol); } else if (trade instanceof TakerTrade) { - createTakerAsSellerProtocol((TakerTrade) trade); + TakerTrade takerTrade = (TakerTrade) trade; + TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(takerTrade); + takerTrade.setProtocol(sellerTakesOfferProtocol); } } @@ -148,10 +150,6 @@ public class TradeManager { }); } - public boolean isMyOffer(Offer offer) { - return offer.getP2PSigPubKey().equals(user.getP2PSigPubKey()); - } - /////////////////////////////////////////////////////////////////////////////////////////// // Offer @@ -165,7 +163,7 @@ public class TradeManager { TransactionResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { - FiatAccount currentFiatAccount = user.currentFiatAccountPropertyProperty().get(); + FiatAccount currentFiatAccount = user.currentFiatAccountProperty().get(); Offer offer = new Offer(id, user.getP2PSigPubKey(), direction, @@ -181,20 +179,13 @@ public class TradeManager { accountSettings.getAcceptedCountries(), accountSettings.getAcceptedLanguageLocaleCodes()); - try { - Data offerData = new Data(offer); - log.trace("-------------------------- placeOffer hash" + offerData.hash().toString()); - } catch (IOException e) { - e.printStackTrace(); - } - PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService); PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol( model, (transaction) -> { OffererTrade offererTrade = new OffererTrade(offer); - offererTrade.setLifeCycleState(Trade.LifeCycleState.OPEN_OFFER); + offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OPEN_OFFER); openOfferTrades.add(offererTrade); OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade); @@ -239,19 +230,20 @@ public class TradeManager { disposeCheckOfferAvailabilityRequest(offer); } - public void requestTakeOffer(Coin amount, Offer offer, TradeResultHandler tradeResultHandler) { + // First we check if offer is still available then we create the trade with the protocol + public void requestTakeOffer(Coin amount, Offer offer, TakeOfferResultHandler takeOfferResultHandler) { CheckOfferAvailabilityModel model = new CheckOfferAvailabilityModel(offer, messageService, addressService); - CheckOfferAvailabilityProtocol protocol = new CheckOfferAvailabilityProtocol(model, + CheckOfferAvailabilityProtocol availabilityProtocol = new CheckOfferAvailabilityProtocol(model, () -> { disposeCheckOfferAvailabilityRequest(offer); if (offer.getState() == Offer.State.AVAILABLE) { - Trade trade = takeAvailableOffer(amount, offer, model.getPeer()); - tradeResultHandler.handleTradeResult(trade); + TakerTrade trade = takeAvailableOffer(amount, offer, model.getPeer()); + takeOfferResultHandler.handleResult(trade); } }, (errorMessage) -> disposeCheckOfferAvailabilityRequest(offer)); - checkOfferAvailabilityProtocolMap.put(offer.getId(), protocol); - protocol.checkOfferAvailability(); + checkOfferAvailabilityProtocolMap.put(offer.getId(), availabilityProtocol); + availabilityProtocol.checkOfferAvailability(); } @@ -268,10 +260,13 @@ public class TradeManager { } public void onWithdrawAtTradeCompleted(Trade trade) { - trade.setLifeCycleState(Trade.LifeCycleState.COMPLETED); + if (trade instanceof OffererTrade) + ((OffererTrade) trade).setLifeCycleState(OffererTrade.OffererLifeCycleState.COMPLETED); + else + ((TakerTrade) trade).setLifeCycleState(TakerTrade.TakerLifeCycleState.COMPLETED); + pendingTrades.remove(trade); closedTrades.add(trade); - trade.disposeProtocol(); } @@ -305,10 +300,6 @@ public class TradeManager { // Private methods /////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////// - // Offer - /////////////////////////////////////////////////////////////////////////////////////////// - private void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler, @@ -322,7 +313,7 @@ public class TradeManager { openOfferTrades.remove(offererTrade); if (isCancelRequest) { - offererTrade.setLifeCycleState(Trade.LifeCycleState.CANCELED); + offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_CANCELED); closedTrades.add(offererTrade); offererTrade.disposeProtocol(); } @@ -335,16 +326,10 @@ public class TradeManager { (message, throwable) -> errorMessageHandler.handleErrorMessage(message)); } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Take offer - /////////////////////////////////////////////////////////////////////////////////////////// - private void disposeCheckOfferAvailabilityRequest(Offer offer) { if (checkOfferAvailabilityProtocolMap.containsKey(offer.getId())) { CheckOfferAvailabilityProtocol protocol = checkOfferAvailabilityProtocolMap.get(offer.getId()); protocol.cancel(); - protocol.cleanup(); checkOfferAvailabilityProtocolMap.remove(offer.getId()); } } @@ -354,11 +339,11 @@ public class TradeManager { // Trade /////////////////////////////////////////////////////////////////////////////////////////// - private Trade takeAvailableOffer(Coin amount, Offer offer, Peer peer) { + private TakerTrade takeAvailableOffer(Coin amount, Offer offer, Peer peer) { TakerTrade takerTrade = new TakerTrade(offer); takerTrade.setTradeAmount(amount); takerTrade.setTradingPeer(peer); - takerTrade.setLifeCycleState(Trade.LifeCycleState.PENDING); + takerTrade.setLifeCycleState(TakerTrade.TakerLifeCycleState.PENDING); pendingTrades.add(takerTrade); TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(takerTrade); @@ -370,30 +355,6 @@ public class TradeManager { private TakerAsSellerProtocol createTakerAsSellerProtocol(TakerTrade takerTrade) { - takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { - log.debug("takerTrade state = " + newValue); - switch (newValue) { - case INIT: - break; - case TAKE_OFFER_FEE_TX_CREATED: - case DEPOSIT_PUBLISHED: - case DEPOSIT_CONFIRMED: - case FIAT_PAYMENT_STARTED: - case FIAT_PAYMENT_RECEIVED: - case PAYOUT_PUBLISHED: - // persistPendingTrades(); - break; - case MESSAGE_SENDING_FAILED: - case FAULT: - takerTrade.setLifeCycleState(Trade.LifeCycleState.FAILED); - takerTrade.disposeProtocol(); - break; - default: - log.warn("Unhandled takerTrade state: " + newValue); - break; - } - }); - TakerAsSellerModel model = new TakerAsSellerModel( takerTrade, messageService, @@ -426,33 +387,15 @@ public class TradeManager { offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { log.debug("offererTrade state = " + newValue); switch (newValue) { - case INIT: - break; - case TAKE_OFFER_FEE_TX_CREATED: - // persistPendingTrades(); - break; case DEPOSIT_PUBLISHED: removeOpenOffer(offererTrade.getOffer(), () -> log.debug("remove offer was successful"), (message) -> log.error(message), false); - model.trade.setLifeCycleState(Trade.LifeCycleState.PENDING); + ((OffererTrade) model.trade).setLifeCycleState(OffererTrade.OffererLifeCycleState.PENDING); pendingTrades.add(offererTrade); break; - case DEPOSIT_CONFIRMED: - case FIAT_PAYMENT_STARTED: - case FIAT_PAYMENT_RECEIVED: - case PAYOUT_PUBLISHED: - // persistPendingTrades(); - break; - case TAKE_OFFER_FEE_PUBLISH_FAILED: - case MESSAGE_SENDING_FAILED: - case FAULT: - offererTrade.setLifeCycleState(Trade.LifeCycleState.FAILED); - offererTrade.disposeProtocol(); - break; default: - log.warn("Unhandled offererTrade state: " + newValue); break; } }); diff --git a/core/src/main/java/io/bitsquare/trade/handlers/TradeResultHandler.java b/core/src/main/java/io/bitsquare/trade/handlers/TakeOfferResultHandler.java similarity index 86% rename from core/src/main/java/io/bitsquare/trade/handlers/TradeResultHandler.java rename to core/src/main/java/io/bitsquare/trade/handlers/TakeOfferResultHandler.java index 3652b14d89..8802bf73b1 100644 --- a/core/src/main/java/io/bitsquare/trade/handlers/TradeResultHandler.java +++ b/core/src/main/java/io/bitsquare/trade/handlers/TakeOfferResultHandler.java @@ -17,9 +17,9 @@ package io.bitsquare.trade.handlers; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; -public interface TradeResultHandler { - void handleTradeResult(Trade trade); +public interface TakeOfferResultHandler { + void handleResult(TakerTrade trade); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/availability/CheckOfferAvailabilityProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/availability/CheckOfferAvailabilityProtocol.java index a0e14e52cb..a69d0472db 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/availability/CheckOfferAvailabilityProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/availability/CheckOfferAvailabilityProtocol.java @@ -88,6 +88,7 @@ public class CheckOfferAvailabilityProtocol { public void cancel() { isCanceled = true; taskRunner.cancel(); + cleanup(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/OffererAsBuyerProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/OffererAsBuyerProtocol.java index a6fe470fe4..3898c5a1c7 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/OffererAsBuyerProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/OffererAsBuyerProtocol.java @@ -23,7 +23,7 @@ import io.bitsquare.p2p.Message; import io.bitsquare.p2p.MessageHandler; import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.listener.SendMessageListener; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.OffererTrade; import io.bitsquare.trade.protocol.Protocol; import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage; import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage; @@ -107,7 +107,7 @@ public class OffererAsBuyerProtocol implements Protocol { // We don't store anything in the model as we might be in a trade process and receive that request from another peer who wants to take the offer // at the same time - boolean isOfferOpen = model.trade.getLifeCycleState() == Trade.LifeCycleState.OPEN_OFFER; + boolean isOfferOpen = model.trade.getLifeCycleState() == OffererTrade.OffererLifeCycleState.OPEN_OFFER; ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = new ReportOfferAvailabilityMessage(model.id, isOfferOpen); model.messageService.sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() { @Override diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/models/OffererAsBuyerModel.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/models/OffererAsBuyerModel.java index 0af51108a4..6e4e0bbee4 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/models/OffererAsBuyerModel.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/models/OffererAsBuyerModel.java @@ -24,7 +24,7 @@ import io.bitsquare.crypto.SignatureService; import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MessageService; import io.bitsquare.storage.Storage; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.OffererTrade; import io.bitsquare.trade.protocol.trade.SharedTradeModel; import io.bitsquare.user.User; @@ -41,7 +41,7 @@ public class OffererAsBuyerModel extends SharedTradeModel implements Serializabl transient private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerModel.class); transient private Storage storage; - transient public final Trade trade; + transient public final OffererTrade trade; public final Taker taker; public final Offerer offerer; @@ -49,7 +49,7 @@ public class OffererAsBuyerModel extends SharedTradeModel implements Serializabl // written by tasks private String takeOfferFeeTxId; - public OffererAsBuyerModel(Trade trade, + public OffererAsBuyerModel(OffererTrade trade, MessageService messageService, MailboxService mailboxService, WalletService walletService, diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/ProcessPayoutTxPublishedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/ProcessPayoutTxPublishedMessage.java index b397985162..5000367df7 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/ProcessPayoutTxPublishedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/ProcessPayoutTxPublishedMessage.java @@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.OffererTrade; import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage; import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; @@ -43,7 +43,7 @@ public class ProcessPayoutTxPublishedMessage extends Task { model.trade.setPayoutTx(checkNotNull(((PayoutTxPublishedMessage) model.getTradeMessage()).payoutTx)); - model.trade.setProcessState(Trade.ProcessState.PAYOUT_PUBLISHED); + model.trade.setProcessState(OffererTrade.OffererProcessState.PAYOUT_PUBLISHED); complete(); } catch (Throwable t) { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SendBankTransferStartedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SendBankTransferStartedMessage.java index e549acb874..b22e9f8c83 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SendBankTransferStartedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SendBankTransferStartedMessage.java @@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.p2p.listener.SendMessageListener; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.OffererTrade; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; @@ -50,19 +50,19 @@ public class SendBankTransferStartedMessage extends Task { @Override public void handleResult() { log.trace("Sending BankTransferInitedMessage succeeded."); - model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_STARTED); + model.trade.setProcessState(OffererTrade.OffererProcessState.FIAT_PAYMENT_STARTED); complete(); } @Override public void handleFault() { failed("Sending BankTransferInitedMessage failed."); - model.trade.setProcessState(Trade.ProcessState.FAULT); + model.trade.setProcessState(OffererTrade.OffererProcessState.UNSPECIFIC_FAULT); } }); } catch (Throwable t) { failed("Sending BankTransferInitedMessage failed."); - model.trade.setProcessState(Trade.ProcessState.FAULT); + model.trade.setProcessState(OffererTrade.OffererProcessState.UNSPECIFIC_FAULT); } } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SignAndPublishDepositTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SignAndPublishDepositTx.java index edf4357b3e..009497d911 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SignAndPublishDepositTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SignAndPublishDepositTx.java @@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks; import io.bitsquare.btc.FeePolicy; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.OffererTrade; import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; import org.bitcoinj.core.Coin; @@ -59,7 +59,7 @@ public class SignAndPublishDepositTx extends Task { log.trace("offererSignAndPublishTx succeeded " + transaction); model.trade.setDepositTx(transaction); - model.trade.setProcessState(Trade.ProcessState.DEPOSIT_PUBLISHED); + model.trade.setProcessState(OffererTrade.OffererProcessState.DEPOSIT_PUBLISHED); complete(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/TakerAsSellerProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/TakerAsSellerProtocol.java index ca7f0432bd..bc3578fa74 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/TakerAsSellerProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/TakerAsSellerProtocol.java @@ -22,7 +22,7 @@ import io.bitsquare.p2p.MailboxMessage; import io.bitsquare.p2p.Message; import io.bitsquare.p2p.MessageHandler; import io.bitsquare.p2p.Peer; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.Protocol; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; @@ -166,7 +166,7 @@ public class TakerAsSellerProtocol implements Protocol { // User clicked the "bank transfer received" button, so we release the funds for pay out public void onFiatPaymentReceived() { - model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_RECEIVED); + model.trade.setProcessState(TakerTrade.TakerProcessState.FIAT_PAYMENT_RECEIVED); TaskRunner taskRunner = new TaskRunner<>(model, () -> { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/models/TakerAsSellerModel.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/models/TakerAsSellerModel.java index ffe1d8fcf3..c3e8e0525d 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/models/TakerAsSellerModel.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/models/TakerAsSellerModel.java @@ -24,7 +24,7 @@ import io.bitsquare.crypto.SignatureService; import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MessageService; import io.bitsquare.storage.Storage; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.trade.SharedTradeModel; import io.bitsquare.user.User; @@ -43,7 +43,7 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable transient private static final Logger log = LoggerFactory.getLogger(TakerAsSellerModel.class); transient private Storage storage; - transient public final Trade trade; + transient public final TakerTrade trade; public final Taker taker; public final Offerer offerer; @@ -52,7 +52,7 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable private Transaction takeOfferFeeTx; private Transaction payoutTx; - public TakerAsSellerModel(Trade trade, + public TakerAsSellerModel(TakerTrade trade, MessageService messageService, MailboxService mailboxService, WalletService walletService, diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/BroadcastTakeOfferFeeTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/BroadcastTakeOfferFeeTx.java index 5c25c55c97..1a4970057b 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/BroadcastTakeOfferFeeTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/BroadcastTakeOfferFeeTx.java @@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import org.bitcoinj.core.Transaction; @@ -47,14 +47,14 @@ public class BroadcastTakeOfferFeeTx extends Task { public void onSuccess(Transaction transaction) { log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString()); - model.trade.setProcessState(Trade.ProcessState.TAKE_OFFER_FEE_PUBLISHED); + model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISHED); complete(); } @Override public void onFailure(@NotNull Throwable t) { - model.trade.setProcessState(Trade.ProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED); + model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED); failed(t); } @@ -63,7 +63,7 @@ public class BroadcastTakeOfferFeeTx extends Task { appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again."); appendToErrorMessage(e.getMessage()); - model.trade.setProcessState(Trade.ProcessState.FAULT); + model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT); failed(e); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/CreateTakeOfferFeeTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/CreateTakeOfferFeeTx.java index e55a7d9fdb..0b5ad100e2 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/CreateTakeOfferFeeTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/CreateTakeOfferFeeTx.java @@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import org.bitcoinj.core.Transaction; @@ -40,13 +40,13 @@ public class CreateTakeOfferFeeTx extends Task { Transaction createTakeOfferFeeTx = model.tradeWalletService.createTakeOfferFeeTx(model.taker.addressEntry); model.setTakeOfferFeeTx(createTakeOfferFeeTx); - model.trade.setProcessState(Trade.ProcessState.TAKE_OFFER_FEE_TX_CREATED); + model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_TX_CREATED); complete(); } catch (Exception e) { appendToErrorMessage(e.getMessage()); - model.trade.setProcessState(Trade.ProcessState.FAULT); + model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT); failed(e); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessDepositTxPublishedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessDepositTxPublishedMessage.java index a80d0341af..c243aa9876 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessDepositTxPublishedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessDepositTxPublishedMessage.java @@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; @@ -43,7 +43,7 @@ public class ProcessDepositTxPublishedMessage extends Task { DepositTxPublishedMessage message = (DepositTxPublishedMessage) model.getTradeMessage(); model.trade.setDepositTx(checkNotNull(message.depositTx)); - model.trade.setProcessState(Trade.ProcessState.DEPOSIT_PUBLISHED); + model.trade.setProcessState(TakerTrade.TakerProcessState.DEPOSIT_PUBLISHED); complete(); } catch (Throwable t) { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessFiatTransferStartedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessFiatTransferStartedMessage.java index 267e49a693..3dd47b6b0e 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessFiatTransferStartedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/ProcessFiatTransferStartedMessage.java @@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; @@ -46,11 +46,11 @@ public class ProcessFiatTransferStartedMessage extends Task model.offerer.payoutAmount = positiveCoinOf(nonZeroCoinOf(message.offererPayoutAmount)); model.taker.payoutAmount = positiveCoinOf(nonZeroCoinOf(message.takerPayoutAmount)); model.offerer.payoutAddressString = nonEmptyStringOf(message.offererPayoutAddress); - model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_STARTED); + model.trade.setProcessState(TakerTrade.TakerProcessState.FIAT_PAYMENT_STARTED); complete(); } catch (Throwable t) { - model.trade.setProcessState(Trade.ProcessState.FAULT); + model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT); failed(t); } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendRequestDepositTxInputsMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendRequestDepositTxInputsMessage.java index 2e213f4793..52951d2d95 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendRequestDepositTxInputsMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendRequestDepositTxInputsMessage.java @@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.p2p.listener.SendMessageListener; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; @@ -67,7 +67,7 @@ public class SendRequestDepositTxInputsMessage extends Task "connection. " + "We persisted the state of the trade, please try again later or cancel that trade."); - model.trade.setProcessState(Trade.ProcessState.MESSAGE_SENDING_FAILED); + model.trade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED); failed(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SignAndPublishPayoutTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SignAndPublishPayoutTx.java index 05c7058783..c68306a583 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SignAndPublishPayoutTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SignAndPublishPayoutTx.java @@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import org.bitcoinj.core.Transaction; @@ -55,7 +55,7 @@ public class SignAndPublishPayoutTx extends Task { @Override public void onSuccess(Transaction transaction) { model.setPayoutTx(transaction); - model.trade.setProcessState(Trade.ProcessState.PAYOUT_PUBLISHED); + model.trade.setProcessState(TakerTrade.TakerProcessState.PAYOUT_PUBLISHED); complete(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/TakerCreatesAndSignsDepositTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/TakerCreatesAndSignsDepositTx.java index cef02d4a12..bb02ea23fa 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/TakerCreatesAndSignsDepositTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/TakerCreatesAndSignsDepositTx.java @@ -21,7 +21,7 @@ import io.bitsquare.btc.FeePolicy; import io.bitsquare.btc.TradeWalletService; import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; +import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import org.bitcoinj.core.Coin; @@ -59,7 +59,7 @@ public class TakerCreatesAndSignsDepositTx extends Task { complete(); } catch (Exception e) { - Trade.ProcessState processState = Trade.ProcessState.FAULT; + TakerTrade.TakerProcessState processState = TakerTrade.TakerProcessState.UNSPECIFIC_FAULT; processState.setErrorMessage(errorMessage); model.trade.setProcessState(processState); diff --git a/core/src/main/java/io/bitsquare/user/User.java b/core/src/main/java/io/bitsquare/user/User.java index 3b0aba5181..53e47fc4cd 100644 --- a/core/src/main/java/io/bitsquare/user/User.java +++ b/core/src/main/java/io/bitsquare/user/User.java @@ -224,7 +224,7 @@ public class User implements Serializable { return currentFiatAccount; } - public ObjectProperty currentFiatAccountPropertyProperty() { + public ObjectProperty currentFiatAccountProperty() { return currentFiatAccountProperty; }