From 5768b93cdf80dcc3ac27a74f549aa1b116587d9d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 21 Mar 2015 21:51:13 +0100 Subject: [PATCH] Improve state handling of trade --- .../io/bitsquare/btc/TradeWalletService.java | 6 +- .../main/portfolio/offer/OfferListItem.java | 5 +- .../main/portfolio/offer/OffersDataModel.java | 9 +- .../pending/PendingTradesDataModel.java | 12 +-- .../portfolio/pending/PendingTradesView.java | 1 + .../pending/PendingTradesViewModel.java | 10 +-- .../main/trade/offerbook/OfferBookView.java | 11 ++- .../trade/takeoffer/TakeOfferViewModel.java | 4 +- .../main/java/io/bitsquare/trade/Trade.java | 45 +++++++--- .../java/io/bitsquare/trade/TradeManager.java | 88 +++++++------------ .../trade/offerer/OffererAsBuyerProtocol.java | 62 +++---------- .../protocol/trade/offerer/models/Taker.java | 2 - .../ProcessPayoutTxPublishedMessage.java | 2 +- .../tasks/RequestTakerDepositPayment.java | 2 +- .../tasks/SendBankTransferStartedMessage.java | 8 +- .../offerer/tasks/SendDepositTxToTaker.java | 2 +- ...etupListenerForBlockChainConfirmation.java | 4 +- .../tasks/SignAndPublishDepositTx.java | 2 +- .../trade/taker/TakerAsSellerProtocol.java | 65 ++++---------- .../protocol/trade/taker/models/Offerer.java | 5 -- .../taker/models/TakerAsSellerModel.java | 4 - .../taker/tasks/BroadcastTakeOfferFeeTx.java | 6 +- .../taker/tasks/CreateTakeOfferFeeTx.java | 4 +- .../ProcessDepositTxPublishedMessage.java | 2 +- .../ProcessFiatTransferStartedMessage.java | 4 +- .../taker/tasks/SendPayoutTxToOfferer.java | 2 +- .../SendRequestDepositTxInputsMessage.java | 4 +- .../taker/tasks/SendSignedTakerDepositTx.java | 2 +- ...etupListenerForBlockChainConfirmation.java | 39 ++++---- .../taker/tasks/SignAndPublishPayoutTx.java | 2 +- .../taker/tasks/TakerCommitDepositTx.java | 8 +- .../tasks/TakerCreatesAndSignsDepositTx.java | 6 +- 32 files changed, 179 insertions(+), 249 deletions(-) diff --git a/core/src/main/java/io/bitsquare/btc/TradeWalletService.java b/core/src/main/java/io/bitsquare/btc/TradeWalletService.java index 40cc39cccb..1f3b6984ea 100644 --- a/core/src/main/java/io/bitsquare/btc/TradeWalletService.java +++ b/core/src/main/java/io/bitsquare/btc/TradeWalletService.java @@ -375,12 +375,13 @@ public class TradeWalletService { Futures.addCallback(broadcastComplete, callback); } - public void takerCommitsDepositTx(Transaction depositTx) throws WalletException { + // Returns local transaction which has a different state as the serialized depositTx we get from the offerer + public Transaction takerCommitsDepositTx(Transaction depositTx) throws WalletException { log.trace("takerCommitsDepositTx called"); log.trace("depositTx " + depositTx.toString()); // We need to recreate the tx we get a null pointer otherwise - depositTx = new Transaction(params, depositTx.bitcoinSerialize()); + Transaction localDepositTx = new Transaction(params, depositTx.bitcoinSerialize()); try { // TODO check if that is correct @@ -390,6 +391,7 @@ public class TradeWalletService { t.printStackTrace(); throw new WalletException(t); } + return localDepositTx; } public byte[] offererCreatesAndSignsPayoutTx(Transaction depositTx, diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OfferListItem.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OfferListItem.java index 51cec54090..85b7ed5a18 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OfferListItem.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OfferListItem.java @@ -18,6 +18,7 @@ package io.bitsquare.gui.main.portfolio.offer; import io.bitsquare.offer.Offer; +import io.bitsquare.trade.Trade; /** * We could remove that wrapper if it is not needed for additional UI only fields. @@ -26,8 +27,8 @@ class OfferListItem { private final Offer offer; - public OfferListItem(Offer offer) { - this.offer = offer; + public OfferListItem(Trade trade) { + this.offer = trade.getOffer(); } public Offer getOffer() { diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersDataModel.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersDataModel.java index 72920dbb09..2b87f7d999 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersDataModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersDataModel.java @@ -23,6 +23,7 @@ import io.bitsquare.common.viewfx.model.Activatable; import io.bitsquare.common.viewfx.model.DataModel; import io.bitsquare.offer.Direction; import io.bitsquare.offer.Offer; +import io.bitsquare.trade.Trade; import io.bitsquare.trade.TradeManager; import io.bitsquare.user.User; @@ -44,7 +45,7 @@ class OffersDataModel implements Activatable, DataModel { private final User user; private final ObservableList list = FXCollections.observableArrayList(); - private final MapChangeListener offerMapChangeListener; + private final MapChangeListener offerMapChangeListener; @Inject @@ -63,17 +64,17 @@ class OffersDataModel implements Activatable, DataModel { @Override public void activate() { list.clear(); - list.addAll(tradeManager.getOpenOffers().values().stream().map(OfferListItem::new).collect(Collectors.toList())); + list.addAll(tradeManager.getOpenOfferTrades().values().stream().map(OfferListItem::new).collect(Collectors.toList())); // we sort by date, earliest first list.sort((o1, o2) -> o2.getOffer().getCreationDate().compareTo(o1.getOffer().getCreationDate())); - tradeManager.getOpenOffers().addListener(offerMapChangeListener); + tradeManager.getOpenOfferTrades().addListener(offerMapChangeListener); } @Override public void deactivate() { - tradeManager.getOpenOffers().removeListener(offerMapChangeListener); + tradeManager.getOpenOfferTrades().removeListener(offerMapChangeListener); } void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesDataModel.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesDataModel.java index 603a0c6c44..1f2166812b 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesDataModel.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesDataModel.java @@ -66,11 +66,11 @@ class PendingTradesDataModel implements Activatable, DataModel { private boolean isOfferer; private Trade closedTrade; - private final ChangeListener tradeStateChangeListener; + private final ChangeListener tradeStateChangeListener; private final MapChangeListener mapChangeListener; final StringProperty txId = new SimpleStringProperty(); - final ObjectProperty tradeState = new SimpleObjectProperty<>(); + final ObjectProperty tradeState = new SimpleObjectProperty<>(); final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1); @Inject @@ -146,9 +146,9 @@ class PendingTradesDataModel implements Activatable, DataModel { isOfferer = getTrade().getOffer().getP2PSigPubKey().equals(user.getP2PSigPubKey()); Trade trade = getTrade(); - trade.stateProperty().addListener(tradeStateChangeListener); - tradeState.set(trade.stateProperty().get()); - log.trace("selectTrade trade.stateProperty().get() " + trade.stateProperty().get()); + trade.processStateProperty().addListener(tradeStateChangeListener); + tradeState.set(trade.processStateProperty().get()); + log.trace("selectTrade trade.stateProperty().get() " + trade.processStateProperty().get()); if (trade.getDepositTx() != null) txId.set(trade.getDepositTx().getHashAsString()); @@ -277,7 +277,7 @@ class PendingTradesDataModel implements Activatable, DataModel { private void cleanUpSelectedTrade() { if (selectedItem != null) { - selectedItem.getTrade().stateProperty().removeListener(tradeStateChangeListener); + selectedItem.getTrade().processStateProperty().removeListener(tradeStateChangeListener); } } diff --git a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.java b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.java index 635875208f..14ce3ea46a 100644 --- a/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.java +++ b/core/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.java @@ -181,6 +181,7 @@ public class PendingTradesView extends ActivatableViewAndModel im isTakeOfferSpinnerVisible.set(true); dataModel.takeOffer((trade) -> { - trade.stateProperty().addListener((ov, oldValue, newValue) -> { + trade.processStateProperty().addListener((ov, oldValue, newValue) -> { log.debug("trade state = " + newValue); String msg = ""; if (newValue.getErrorMessage() != null) msg = "\nError message: " + newValue.getErrorMessage(); switch (newValue) { - case OPEN: + case INIT: break; case TAKE_OFFER_FEE_TX_CREATED: break; diff --git a/core/src/main/java/io/bitsquare/trade/Trade.java b/core/src/main/java/io/bitsquare/trade/Trade.java index 624eb429ba..cf4873daae 100644 --- a/core/src/main/java/io/bitsquare/trade/Trade.java +++ b/core/src/main/java/io/bitsquare/trade/Trade.java @@ -18,6 +18,7 @@ package io.bitsquare.trade; import io.bitsquare.offer.Offer; +import io.bitsquare.p2p.Peer; import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; @@ -38,8 +39,16 @@ public class Trade implements Serializable { // Enum /////////////////////////////////////////////////////////////////////////////////////////// - public static enum State { - OPEN, + public static enum LifeCycleState { + OPEN_OFFER, + CANCELED, + PENDING, + COMPLETED, + FAILED + } + + public static enum ProcessState { + INIT, TAKE_OFFER_FEE_PUBLISH_FAILED, TAKE_OFFER_FEE_TX_CREATED, DEPOSIT_PUBLISHED, @@ -64,7 +73,7 @@ public class Trade implements Serializable { private final Offer offer; private final Date date; - private State state; + private ProcessState processState; private Coin tradeAmount; private Contract contract; private String contractAsJson; @@ -72,13 +81,14 @@ public class Trade implements Serializable { private String offererContractSignature; private Transaction depositTx; private Transaction payoutTx; + private Peer tradingPeer; // 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 private field. transient private ObjectProperty _tradeAmount; transient private ObjectProperty _tradeVolume; - transient private ObjectProperty _state; + transient private ObjectProperty _state; /////////////////////////////////////////////////////////////////////////////////////////// @@ -89,7 +99,7 @@ public class Trade implements Serializable { this.offer = offer; date = new Date(); - setState(State.OPEN); + setProcessState(ProcessState.INIT); } @@ -97,6 +107,10 @@ public class Trade implements Serializable { // Setters /////////////////////////////////////////////////////////////////////////////////////////// + public void setTradingPeer(Peer tradingPeer) { + this.tradingPeer = tradingPeer; + } + public void setTakerContractSignature(String takerSignature) { this.takerContractSignature = takerSignature; } @@ -135,9 +149,9 @@ public class Trade implements Serializable { this.payoutTx = tx; } - public void setState(State state) { - this.state = state; - stateProperty().set(state); + public void setProcessState(ProcessState processState) { + this.processState = processState; + processStateProperty().set(processState); } @@ -165,8 +179,8 @@ public class Trade implements Serializable { return payoutTx; } - public State getState() { - return state; + public ProcessState getProcessState() { + return processState; } public Coin getSecurityDeposit() { @@ -189,6 +203,11 @@ public class Trade implements Serializable { return date; } + public Peer getTradingPeer() { + return tradingPeer; + } + + // When serialized those transient properties are not instantiated, so we need to instantiate them at first access public ObjectProperty tradeAmountProperty() { if (_tradeAmount == null) @@ -204,9 +223,9 @@ public class Trade implements Serializable { return _tradeVolume; } - public ObjectProperty stateProperty() { + public ObjectProperty processStateProperty() { if (_state == null) - _state = new SimpleObjectProperty<>(state); + _state = new SimpleObjectProperty<>(processState); return _state; } @@ -216,7 +235,7 @@ public class Trade implements Serializable { return "Trade{" + "offer=" + offer + ", date=" + date + - ", state=" + state + + ", state=" + processState + ", 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 f55bd5a599..95dc36f0b8 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/core/src/main/java/io/bitsquare/trade/TradeManager.java @@ -90,7 +90,7 @@ public class TradeManager { private final Map offererAsBuyerProtocolMap = new HashMap<>(); private final Map checkOfferAvailabilityProtocolMap = new HashMap<>(); - private final ObservableMap openOffers = FXCollections.observableHashMap(); + private final ObservableMap openOfferTrades = FXCollections.observableHashMap(); private final ObservableMap pendingTrades = FXCollections.observableHashMap(); private final ObservableMap closedTrades = FXCollections.observableHashMap(); private final Map mailboxMessages = new HashMap<>(); @@ -119,9 +119,9 @@ public class TradeManager { this.encryptionService = encryptionService; this.offerBookService = offerBookService; - Serializable openOffersObject = persistence.read(this, "openOffers"); - if (openOffersObject instanceof Map) { - openOffers.putAll((Map) openOffersObject); + Serializable openOfferTradesObject = persistence.read(this, "openOfferTrades"); + if (openOfferTradesObject instanceof Map) { + openOfferTrades.putAll((Map) openOfferTradesObject); } Serializable pendingTradesObject = persistence.read(this, "pendingTrades"); @@ -143,33 +143,19 @@ 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. public void onAllServicesInitialized() { - for (Map.Entry entry : openOffers.entrySet()) { + for (Map.Entry entry : openOfferTrades.entrySet()) { createOffererAsBuyerProtocol(entry.getValue()); } for (Map.Entry entry : pendingTrades.entrySet()) { + // 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. Trade trade = entry.getValue(); - if (trade.getState() == Trade.State.FAULT) { - closeTrade(trade); + if (isMyOffer(trade.getOffer())) { + createOffererAsBuyerProtocol(trade); } else { - Offer offer = trade.getOffer(); - if (isMyOffer(offer)) { - createOffererAsBuyerProtocol(offer); - } - else { - CheckOfferAvailabilityModel model = new CheckOfferAvailabilityModel(offer, messageService, addressService); - CheckOfferAvailabilityProtocol protocol = new CheckOfferAvailabilityProtocol(model, - () -> { - disposeCheckOfferAvailabilityRequest(offer); - // TODO need to check that trade hijacking is not possible (taking trades form other peers) - if (offer.getState() == Offer.State.AVAILABLE || offer.getState() == Offer.State.RESERVED) { - createTakerAsSellerProtocol(trade, model.getPeer()); - } - }, - (errorMessage) -> disposeCheckOfferAvailabilityRequest(offer)); - checkOfferAvailabilityProtocolMap.put(offer.getId(), protocol); - protocol.checkOfferAvailability(); - } + createTakerAsSellerProtocol(trade); } } @@ -220,9 +206,10 @@ public class TradeManager { PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol( model, (transaction) -> { - openOffers.put(offer.getId(), offer); + Trade trade = new Trade(offer); + openOfferTrades.put(trade.getId(), trade); persistOpenOffers(); - createOffererAsBuyerProtocol(offer); + createOffererAsBuyerProtocol(trade); resultHandler.handleResult(transaction); }, (message) -> errorMessageHandler.handleErrorMessage(message) @@ -340,8 +327,8 @@ public class TradeManager { // Getters /////////////////////////////////////////////////////////////////////////////////////////// - public ObservableMap getOpenOffers() { - return openOffers; + public ObservableMap getOpenOfferTrades() { + return openOfferTrades; } public ObservableMap getPendingTrades() { @@ -372,8 +359,8 @@ public class TradeManager { String offerId = offer.getId(); offerBookService.removeOffer(offer, () -> { - if (openOffers.containsKey(offerId)) { - openOffers.remove(offerId); + if (openOfferTrades.containsKey(offerId)) { + openOfferTrades.remove(offerId); disposeCheckOfferAvailabilityRequest(offer); persistOpenOffers(); if (removeFromBuyerAcceptsOfferProtocolMap && offererAsBuyerProtocolMap.containsKey(offerId)) { @@ -413,8 +400,9 @@ public class TradeManager { private Trade takeAvailableOffer(Coin amount, Offer offer, Peer peer) { Trade trade = createTrade(offer); trade.setTradeAmount(amount); + trade.setTradingPeer(peer); - TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(trade, peer); + TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(trade); sellerTakesOfferProtocol.takeAvailableOffer(); return trade; } @@ -432,11 +420,11 @@ public class TradeManager { return trade; } - private TakerAsSellerProtocol createTakerAsSellerProtocol(Trade trade, Peer peer) { - trade.stateProperty().addListener((ov, oldValue, newValue) -> { + private TakerAsSellerProtocol createTakerAsSellerProtocol(Trade trade) { + trade.processStateProperty().addListener((ov, oldValue, newValue) -> { log.debug("trade state = " + newValue); switch (newValue) { - case OPEN: + case INIT: break; case TAKE_OFFER_FEE_TX_CREATED: case DEPOSIT_PUBLISHED: @@ -458,7 +446,6 @@ public class TradeManager { TakerAsSellerModel model = new TakerAsSellerModel( trade, - peer, messageService, mailboxService, walletService, @@ -478,17 +465,7 @@ public class TradeManager { } - private void createOffererAsBuyerProtocol(Offer offer) { - Trade trade; - if (pendingTrades.containsKey(offer.getId())) { - trade = pendingTrades.get(offer.getId()); - currentPendingTrade = trade; - } - else { - trade = new Trade(offer); - // don't save it in pendingTrades. It is only a potential trade - } - + private void createOffererAsBuyerProtocol(Trade trade) { OffererAsBuyerModel model = new OffererAsBuyerModel( trade, messageService, @@ -501,16 +478,16 @@ public class TradeManager { // TODO check, remove listener - trade.stateProperty().addListener((ov, oldValue, newValue) -> { + trade.processStateProperty().addListener((ov, oldValue, newValue) -> { log.debug("trade state = " + newValue); switch (newValue) { - case OPEN: + case INIT: break; case TAKE_OFFER_FEE_TX_CREATED: persistPendingTrades(); break; case DEPOSIT_PUBLISHED: - removeOpenOffer(offer, + removeOpenOffer(trade.getOffer(), () -> log.debug("remove offer was successful"), (message) -> log.error(message), false); @@ -531,7 +508,6 @@ public class TradeManager { case MESSAGE_SENDING_FAILED: case FAULT: closeTrade(trade); - offererAsBuyerProtocolMap.get(trade.getId()).cleanup(); break; default: log.warn("Unhandled trade state: " + newValue); @@ -540,7 +516,7 @@ public class TradeManager { }); OffererAsBuyerProtocol protocol = new OffererAsBuyerProtocol(model); - offererAsBuyerProtocolMap.put(offer.getId(), protocol); + offererAsBuyerProtocolMap.put(trade.getId(), protocol); if (mailboxMessages.containsKey(trade.getId())) { log.debug("OffererAsBuyerProtocol setMailboxMessage " + trade.getId()); protocol.setMailboxMessage(mailboxMessages.get(trade.getId())); @@ -612,13 +588,13 @@ public class TradeManager { } boolean isOfferOpen(String offerId) { - return openOffers.containsKey(offerId) - && (openOffers.get(offerId).getState() == Offer.State.UNKNOWN - || openOffers.get(offerId).getState() == Offer.State.AVAILABLE); + return openOfferTrades.containsKey(offerId) + && (openOfferTrades.get(offerId).getOffer().getState() == Offer.State.UNKNOWN + || openOfferTrades.get(offerId).getOffer().getState() == Offer.State.AVAILABLE); } private void persistOpenOffers() { - persistence.write(this, "openOffers", (Map) new HashMap<>(openOffers)); + persistence.write(this, "openOfferTrades", (Map) new HashMap<>(openOfferTrades)); } private void persistPendingTrades() { 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 c80e668d63..345036dbce 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 @@ -22,7 +22,6 @@ 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.protocol.trade.messages.PayoutTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage; import io.bitsquare.trade.protocol.trade.messages.RequestOffererPublishDepositTxMessage; @@ -42,8 +41,6 @@ import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract; import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment; import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount; -import org.bitcoinj.core.TransactionConfidence; - import javafx.application.Platform; import org.slf4j.Logger; @@ -57,8 +54,6 @@ public class OffererAsBuyerProtocol { private final OffererAsBuyerModel model; private final MessageHandler messageHandler; - private TransactionConfidence.Listener transactionConfidenceListener; - private TransactionConfidence transactionConfidence; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -87,18 +82,13 @@ public class OffererAsBuyerProtocol { } } } - + public void cleanup() { log.debug("cleanup " + this); // tradeMessageService and transactionConfidence use CopyOnWriteArrayList as listeners, but be safe and delay remove a bit. Platform.runLater(() -> { model.messageService.removeMessageHandler(messageHandler); - - if (transactionConfidence != null) { - if (!transactionConfidence.removeEventListener(transactionConfidenceListener)) - throw new RuntimeException("Remove transactionConfidenceListener failed at BuyerAsOffererProtocol."); - } }); } @@ -109,16 +99,11 @@ public class OffererAsBuyerProtocol { private void handleRequestDepositTxInputsMessage(RequestDepositTxInputsMessage tradeMessage, Peer taker) { checkTradeId(model.id, tradeMessage); model.setTradeMessage(tradeMessage); - model.taker.peer = taker; + model.trade.setTradingPeer(taker); TaskRunner taskRunner = new TaskRunner<>(model, - () -> { - log.debug("sequence at handleTakeOfferFeePayedMessage completed"); - }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + () -> log.debug("sequence at handleTakeOfferFeePayedMessage completed"), + (errorMessage) -> handleTaskRunnerFault(errorMessage)); taskRunner.addTasks( ProcessRequestDepositTxInputsMessage.class, CreateOffererDepositTxInputs.class, @@ -131,23 +116,8 @@ public class OffererAsBuyerProtocol { model.setTradeMessage(tradeMessage); TaskRunner taskRunner = new TaskRunner<>(model, - () -> { - log.debug("taskRunner at handleRequestOffererPublishDepositTxMessage completed"); - transactionConfidenceListener = (tx, reason) -> { - log.trace("onConfidenceChanged " + tx.getConfidence()); - if (reason == TransactionConfidence.Listener.ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence - .ConfidenceType.BUILDING) { - - model.trade.setState(Trade.State.DEPOSIT_CONFIRMED); - } - }; - transactionConfidence = model.trade.getDepositTx().getConfidence(); - transactionConfidence.addEventListener(transactionConfidenceListener); - }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + () -> log.debug("taskRunner at handleRequestOffererPublishDepositTxMessage completed"), + (errorMessage) -> handleTaskRunnerFault(errorMessage)); taskRunner.addTasks( ProcessRequestOffererPublishDepositTxMessage.class, VerifyTakerAccount.class, @@ -167,13 +137,8 @@ public class OffererAsBuyerProtocol { // User clicked the "bank transfer started" button public void onFiatPaymentStarted() { TaskRunner taskRunner = new TaskRunner<>(model, - () -> { - log.debug("sequence at handleBankTransferStartedUIEvent completed"); - }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + () -> log.debug("sequence at handleBankTransferStartedUIEvent completed"), + (errorMessage) -> handleTaskRunnerFault(errorMessage)); taskRunner.addTasks( CreateAndSignPayoutTx.class, VerifyTakeOfferFeePayment.class, @@ -193,14 +158,11 @@ public class OffererAsBuyerProtocol { TaskRunner taskRunner = new TaskRunner<>(model, () -> { log.debug("sequence at handlePayoutTxPublishedMessage completed"); - // we are done! model.onComplete(); }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + (errorMessage) -> handleTaskRunnerFault(errorMessage)); + taskRunner.addTasks(ProcessPayoutTxPublishedMessage.class); taskRunner.run(); } @@ -233,4 +195,8 @@ public class OffererAsBuyerProtocol { } } } + + private void handleTaskRunnerFault(String errorMessage) { + cleanup(); + } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/models/Taker.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/models/Taker.java index 810c41bf9f..ad5d0a5832 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/models/Taker.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/models/Taker.java @@ -18,7 +18,6 @@ package io.bitsquare.trade.protocol.trade.offerer.models; import io.bitsquare.fiat.FiatAccount; -import io.bitsquare.p2p.Peer; import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; @@ -34,7 +33,6 @@ public class Taker implements Serializable { private static final long serialVersionUID = 2660909397210346486L; // written by tasks - public Peer peer; public String accountId; public FiatAccount fiatAccount; public PublicKey p2pSigPublicKey; 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 7a0823c161..b397985162 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 @@ -43,7 +43,7 @@ public class ProcessPayoutTxPublishedMessage extends Task { model.trade.setPayoutTx(checkNotNull(((PayoutTxPublishedMessage) model.getTradeMessage()).payoutTx)); - model.trade.setState(Trade.State.PAYOUT_PUBLISHED); + model.trade.setProcessState(Trade.ProcessState.PAYOUT_PUBLISHED); complete(); } catch (Throwable t) { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/RequestTakerDepositPayment.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/RequestTakerDepositPayment.java index 96530ccf54..73359a65e6 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/RequestTakerDepositPayment.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/RequestTakerDepositPayment.java @@ -45,7 +45,7 @@ public class RequestTakerDepositPayment extends Task { model.offerer.fiatAccount, model.offerer.accountId); - model.messageService.sendMessage(model.taker.peer, tradeMessage, new SendMessageListener() { + model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() { @Override public void handleResult() { log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer"); 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 4aa1d8f42b..e549acb874 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 @@ -43,26 +43,26 @@ public class SendBankTransferStartedMessage extends Task { model.taker.payoutAmount, model.offerer.addressEntry.getAddressString()); - model.messageService.sendMessage(model.taker.peer, tradeMessage, + model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, model.taker.p2pSigPublicKey, model.taker.p2pEncryptPubKey, new SendMessageListener() { @Override public void handleResult() { log.trace("Sending BankTransferInitedMessage succeeded."); - model.trade.setState(Trade.State.FIAT_PAYMENT_STARTED); + model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_STARTED); complete(); } @Override public void handleFault() { failed("Sending BankTransferInitedMessage failed."); - model.trade.setState(Trade.State.FAULT); + model.trade.setProcessState(Trade.ProcessState.FAULT); } }); } catch (Throwable t) { failed("Sending BankTransferInitedMessage failed."); - model.trade.setState(Trade.State.FAULT); + model.trade.setProcessState(Trade.ProcessState.FAULT); } } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SendDepositTxToTaker.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SendDepositTxToTaker.java index 91b611af3a..017747e2d7 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SendDepositTxToTaker.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SendDepositTxToTaker.java @@ -37,7 +37,7 @@ public class SendDepositTxToTaker extends Task { protected void doRun() { DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(model.id, model.trade.getDepositTx()); - model.messageService.sendMessage(model.taker.peer, tradeMessage, new SendMessageListener() { + model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() { @Override public void handleResult() { log.trace("DepositTxPublishedMessage successfully arrived at peer"); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SetupListenerForBlockChainConfirmation.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SetupListenerForBlockChainConfirmation.java index 51f208ac6e..e1eb3780ff 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SetupListenerForBlockChainConfirmation.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SetupListenerForBlockChainConfirmation.java @@ -48,7 +48,7 @@ public class SetupListenerForBlockChainConfirmation extends Task removeEventListener()); @@ -62,6 +62,6 @@ public class SetupListenerForBlockChainConfirmation extends Task { log.trace("offererSignAndPublishTx succeeded " + transaction); model.trade.setDepositTx(transaction); - model.trade.setState(Trade.State.DEPOSIT_PUBLISHED); + model.trade.setProcessState(Trade.ProcessState.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 52462c588f..f2acb5b8bc 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 @@ -27,7 +27,7 @@ import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage; -import io.bitsquare.trade.protocol.trade.offerer.tasks.SetupListenerForBlockChainConfirmation; +import io.bitsquare.trade.protocol.trade.taker.tasks.SetupListenerForBlockChainConfirmation; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.tasks.BroadcastTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract; @@ -43,11 +43,6 @@ import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCommitDepositTx; import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesAndSignsDepositTx; import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment; import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount; -import io.bitsquare.util.Utilities; - -import java.util.function.Function; - -import javafx.animation.AnimationTimer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,11 +51,9 @@ import static io.bitsquare.util.Validator.nonEmptyStringOf; public class TakerAsSellerProtocol { private static final Logger log = LoggerFactory.getLogger(TakerAsSellerProtocol.class); - private static final int TIMEOUT_DELAY = 10000; private final TakerAsSellerModel model; private final MessageHandler messageHandler; - private AnimationTimer timeoutTimer; /////////////////////////////////////////////////////////////////////////////////////////// @@ -72,8 +65,6 @@ public class TakerAsSellerProtocol { this.model = model; messageHandler = this::handleMessage; model.messageService.addMessageHandler(messageHandler); - - } @@ -105,10 +96,8 @@ public class TakerAsSellerProtocol { () -> { log.debug("taskRunner at takeAvailableOffer completed"); }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + (errorMessage) -> handleTaskRunnerFault(errorMessage)); + taskRunner.addTasks( CreateTakeOfferFeeTx.class, BroadcastTakeOfferFeeTx.class, @@ -129,10 +118,8 @@ public class TakerAsSellerProtocol { () -> { log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"); }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + (errorMessage) -> handleTaskRunnerFault(errorMessage)); + taskRunner.addTasks( ProcessRequestTakerDepositPaymentMessage.class, VerifyOffererAccount.class, @@ -150,10 +137,8 @@ public class TakerAsSellerProtocol { () -> { log.debug("taskRunner at handleDepositTxPublishedMessage completed"); }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + (errorMessage) -> handleTaskRunnerFault(errorMessage)); + taskRunner.addTasks( ProcessDepositTxPublishedMessage.class, TakerCommitDepositTx.class, @@ -169,23 +154,21 @@ public class TakerAsSellerProtocol { () -> { log.debug("taskRunner at handleFiatTransferStartedMessage completed"); }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + (errorMessage) -> handleTaskRunnerFault(errorMessage)); + taskRunner.addTasks(ProcessFiatTransferStartedMessage.class); taskRunner.run(); } - + /////////////////////////////////////////////////////////////////////////////////////////// // Called from UI /////////////////////////////////////////////////////////////////////////////////////////// // User clicked the "bank transfer received" button, so we release the funds for pay out public void onFiatPaymentReceived() { - model.trade.setState(Trade.State.FIAT_PAYMENT_RECEIVED); - + model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_RECEIVED); + TaskRunner taskRunner = new TaskRunner<>(model, () -> { log.debug("taskRunner at handleFiatReceivedUIEvent completed"); @@ -193,10 +176,8 @@ public class TakerAsSellerProtocol { // we are done! model.onComplete(); }, - (errorMessage) -> { - log.error(errorMessage); - } - ); + (errorMessage) -> handleTaskRunnerFault(errorMessage)); + taskRunner.addTasks( SignAndPublishPayoutTx.class, VerifyOfferFeePayment.class, @@ -232,22 +213,8 @@ public class TakerAsSellerProtocol { } } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Timeout - /////////////////////////////////////////////////////////////////////////////////////////// - - private void startTimeout(Function callback) { - stopTimeout(); - timeoutTimer = Utilities.setTimeout(TIMEOUT_DELAY, callback); - timeoutTimer.start(); - } - - private void stopTimeout() { - if (timeoutTimer != null) { - timeoutTimer.stop(); - timeoutTimer = null; - } + private void handleTaskRunnerFault(String errorMessage) { + cleanup(); } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/models/Offerer.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/models/Offerer.java index 0d42064fab..3fb59a1278 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/models/Offerer.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/models/Offerer.java @@ -18,7 +18,6 @@ package io.bitsquare.trade.protocol.trade.taker.models; import io.bitsquare.fiat.FiatAccount; -import io.bitsquare.p2p.Peer; import org.bitcoinj.core.Coin; import org.bitcoinj.core.TransactionOutput; @@ -32,10 +31,6 @@ import java.util.List; public class Offerer implements Serializable { private static final long serialVersionUID = 1582902150121576205L; - // Those fields are set at constructor but not declared as final because constructor is not called in case model gets created from a persisted model - // Declared transient as they will be provided in any case at construction time - public Peer peer; - // written by tasks public byte[] tradeWalletPubKey; public Coin payoutAmount; 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 0a3da51fcb..5bf623c9d6 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 @@ -22,7 +22,6 @@ import io.bitsquare.btc.WalletService; import io.bitsquare.crypto.SignatureService; import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MessageService; -import io.bitsquare.p2p.Peer; import io.bitsquare.persistence.Persistence; import io.bitsquare.trade.Trade; import io.bitsquare.trade.protocol.trade.SharedTradeModel; @@ -48,7 +47,6 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable private Transaction payoutTx; public TakerAsSellerModel(Trade trade, - Peer offererPeer, MessageService messageService, MailboxService mailboxService, WalletService walletService, @@ -82,8 +80,6 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable offerer = new Offerer(); } - offerer.peer = offererPeer; - taker.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey(); taker.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair(); taker.addressEntry = walletService.getAddressEntry(id); 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 dd44a99221..5c25c55c97 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 @@ -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.setState(Trade.State.TAKE_OFFER_FEE_PUBLISHED); + model.trade.setProcessState(Trade.ProcessState.TAKE_OFFER_FEE_PUBLISHED); complete(); } @Override public void onFailure(@NotNull Throwable t) { - model.trade.setState(Trade.State.TAKE_OFFER_FEE_PUBLISH_FAILED); + model.trade.setProcessState(Trade.ProcessState.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.setState(Trade.State.FAULT); + model.trade.setProcessState(Trade.ProcessState.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 e251775677..e55a7d9fdb 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 @@ -40,13 +40,13 @@ public class CreateTakeOfferFeeTx extends Task { Transaction createTakeOfferFeeTx = model.tradeWalletService.createTakeOfferFeeTx(model.taker.addressEntry); model.setTakeOfferFeeTx(createTakeOfferFeeTx); - model.trade.setState(Trade.State.TAKE_OFFER_FEE_TX_CREATED); + model.trade.setProcessState(Trade.ProcessState.TAKE_OFFER_FEE_TX_CREATED); complete(); } catch (Exception e) { appendToErrorMessage(e.getMessage()); - model.trade.setState(Trade.State.FAULT); + model.trade.setProcessState(Trade.ProcessState.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 62b6b508dd..a80d0341af 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 @@ -43,7 +43,7 @@ public class ProcessDepositTxPublishedMessage extends Task { DepositTxPublishedMessage message = (DepositTxPublishedMessage) model.getTradeMessage(); model.trade.setDepositTx(checkNotNull(message.depositTx)); - model.trade.setState(Trade.State.DEPOSIT_PUBLISHED); + model.trade.setProcessState(Trade.ProcessState.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 dc50d23abf..267e49a693 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 @@ -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.setState(Trade.State.FIAT_PAYMENT_STARTED); + model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_STARTED); complete(); } catch (Throwable t) { - model.trade.setState(Trade.State.FAULT); + model.trade.setProcessState(Trade.ProcessState.FAULT); failed(t); } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendPayoutTxToOfferer.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendPayoutTxToOfferer.java index 61c1a61235..bf726859f6 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendPayoutTxToOfferer.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendPayoutTxToOfferer.java @@ -36,7 +36,7 @@ public class SendPayoutTxToOfferer extends Task { @Override protected void doRun() { PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(model.id, model.getPayoutTx()); - model.messageService.sendMessage(model.offerer.peer, + model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, model.offerer.p2pSigPublicKey, model.offerer.p2pEncryptPubKey, 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 6fef5ed61d..2e213f4793 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 @@ -47,7 +47,7 @@ public class SendRequestDepositTxInputsMessage extends Task model.taker.tradeWalletPubKey ); - model.messageService.sendMessage(model.offerer.peer, msg, new SendMessageListener() { + model.messageService.sendMessage(model.trade.getTradingPeer(), msg, new SendMessageListener() { @Override public void handleResult() { log.trace("Sending TakeOfferFeePayedMessage succeeded."); @@ -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.setState(Trade.State.MESSAGE_SENDING_FAILED); + model.trade.setProcessState(Trade.ProcessState.MESSAGE_SENDING_FAILED); failed(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendSignedTakerDepositTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendSignedTakerDepositTx.java index 010b256721..d54e489894 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendSignedTakerDepositTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SendSignedTakerDepositTx.java @@ -49,7 +49,7 @@ public class SendSignedTakerDepositTx extends Task { model.taker.outputs ); - model.messageService.sendMessage(model.offerer.peer, tradeMessage, new SendMessageListener() { + model.messageService.sendMessage(model.trade.getTradingPeer(), tradeMessage, new SendMessageListener() { @Override public void handleResult() { complete(); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SetupListenerForBlockChainConfirmation.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SetupListenerForBlockChainConfirmation.java index e083095ecd..2b6e8a413b 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SetupListenerForBlockChainConfirmation.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SetupListenerForBlockChainConfirmation.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.trade.Trade; -import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; +import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionConfidence; @@ -30,38 +30,43 @@ import javafx.application.Platform; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class SetupListenerForBlockChainConfirmation extends Task { +public class SetupListenerForBlockChainConfirmation extends Task { private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class); private TransactionConfidence.Listener transactionConfidenceListener; private TransactionConfidence transactionConfidence; - public SetupListenerForBlockChainConfirmation(TaskRunner taskHandler, OffererAsBuyerModel model) { + public SetupListenerForBlockChainConfirmation(TaskRunner taskHandler, TakerAsSellerModel model) { super(taskHandler, model); } @Override protected void doRun() { - transactionConfidence = model.trade.getDepositTx().getConfidence(); - transactionConfidenceListener = new TransactionConfidence.Listener() { - @Override - public void onConfidenceChanged(Transaction tx, ChangeReason reason) { - log.trace("onConfidenceChanged " + tx.getConfidence()); - if (reason == ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) { - model.trade.setState(Trade.State.DEPOSIT_CONFIRMED); + try { + transactionConfidence = model.trade.getDepositTx().getConfidence(); + transactionConfidenceListener = new TransactionConfidence.Listener() { + @Override + public void onConfidenceChanged(Transaction tx, ChangeReason reason) { + log.trace("onConfidenceChanged " + tx.getConfidence()); + if (reason == ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) { + model.trade.setProcessState(Trade.ProcessState.DEPOSIT_CONFIRMED); - // transactionConfidence use CopyOnWriteArrayList as listeners, but be safe and delay remove a bit. - Platform.runLater(() -> removeEventListener()); + // transactionConfidence use CopyOnWriteArrayList as listeners, but be safe and delay remove a bit. + Platform.runLater(() -> removeEventListener()); + } } - } - }; - transactionConfidence.addEventListener(transactionConfidenceListener); + }; + transactionConfidence.addEventListener(transactionConfidenceListener); - complete(); + complete(); + } catch (Throwable t) { + t.printStackTrace(); + log.error(t.getMessage()); + } } private void removeEventListener() { if (!transactionConfidence.removeEventListener(transactionConfidenceListener)) - throw new RuntimeException("Remove transactionConfidenceListener failed at SetupListenerForBlockChainConfirmation."); + log.error("Remove transactionConfidenceListener failed at SetupListenerForBlockChainConfirmation."); } } 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 db6d5a0dd8..05c7058783 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 @@ -55,7 +55,7 @@ public class SignAndPublishPayoutTx extends Task { @Override public void onSuccess(Transaction transaction) { model.setPayoutTx(transaction); - model.trade.setState(Trade.State.PAYOUT_PUBLISHED); + model.trade.setProcessState(Trade.ProcessState.PAYOUT_PUBLISHED); complete(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/TakerCommitDepositTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/TakerCommitDepositTx.java index a626b11605..052d86a90b 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/TakerCommitDepositTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/TakerCommitDepositTx.java @@ -21,6 +21,8 @@ import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; +import org.bitcoinj.core.Transaction; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,8 +36,10 @@ public class TakerCommitDepositTx extends Task { @Override protected void doRun() { try { - model.tradeWalletService.takerCommitsDepositTx(model.trade.getDepositTx()); - + // We need to put the tx into our wallet to have a fully setup tx + Transaction localDepositTx = model.tradeWalletService.takerCommitsDepositTx(model.trade.getDepositTx()); + model.trade.setDepositTx(localDepositTx); + complete(); } catch (Throwable t) { failed(t); 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 be945dc825..cef02d4a12 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 @@ -59,9 +59,9 @@ public class TakerCreatesAndSignsDepositTx extends Task { complete(); } catch (Exception e) { - Trade.State state = Trade.State.FAULT; - state.setErrorMessage(errorMessage); - model.trade.setState(state); + Trade.ProcessState processState = Trade.ProcessState.FAULT; + processState.setErrorMessage(errorMessage); + model.trade.setProcessState(processState); failed(e); }