diff --git a/src/main/java/io/bitsquare/gui/MainController.java b/src/main/java/io/bitsquare/gui/MainController.java index fb8e5bce6c..8ed74829dd 100644 --- a/src/main/java/io/bitsquare/gui/MainController.java +++ b/src/main/java/io/bitsquare/gui/MainController.java @@ -166,6 +166,7 @@ public class MainController implements Initializable, NavigationController return childController; } + /////////////////////////////////////////////////////////////////////////////////////////// // Private methods /////////////////////////////////////////////////////////////////////////////////////////// @@ -173,7 +174,8 @@ public class MainController implements Initializable, NavigationController private void init() { messageFacade.init(); - messageFacade.addTakeOfferRequestListener(this::onTakeOfferRequested); + + trading.addTakeOfferRequestListener(this::onTakeOfferRequested); walletFacade.addDownloadListener(new WalletFacade.DownloadListener() { diff --git a/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookController.java b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookController.java index 75cdd6f49c..00261ba85d 100644 --- a/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookController.java +++ b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookController.java @@ -194,7 +194,7 @@ public class OrderBookController implements Initializable, ChildController private boolean isRegistered() { - return user.getAccountID() != null; + return user.getAccountId() != null; } private boolean areSettingsValid() diff --git a/src/main/java/io/bitsquare/gui/market/trade/TakerOfferController.java b/src/main/java/io/bitsquare/gui/market/trade/TakerOfferController.java index f7880d5439..e54c97c0e5 100644 --- a/src/main/java/io/bitsquare/gui/market/trade/TakerOfferController.java +++ b/src/main/java/io/bitsquare/gui/market/trade/TakerOfferController.java @@ -17,7 +17,8 @@ import io.bitsquare.msg.MessageFacade; import io.bitsquare.trade.Offer; import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trading; -import io.bitsquare.trade.payment.taker.TakerAsSellerProtocolListener; +import io.bitsquare.trade.protocol.taker.TakerAsSellerProtocol; +import io.bitsquare.trade.protocol.taker.TakerAsSellerProtocolListener; import java.math.BigInteger; import java.net.URL; import java.util.ResourceBundle; @@ -173,8 +174,6 @@ public class TakerOfferController implements Initializable, ChildController amountTextField.setEditable(false); trading.takeOffer(amount, offer, new TakerAsSellerProtocolListener() { - - @Override public void onDepositTxPublished(String depositTxId) { @@ -197,7 +196,7 @@ public class TakerOfferController implements Initializable, ChildController } @Override - public void onTradeCompleted(Trade trade, String payoutTxId) + public void onPayoutTxPublished(Trade trade, String payoutTxId) { accordion.setExpandedPane(summaryTitledPane); summaryPaidTextField.setText(BtcFormatter.formatSatoshis(trade.getTradeAmount())); @@ -207,10 +206,32 @@ public class TakerOfferController implements Initializable, ChildController summaryDepositTxIdTextField.setText(depositTxId); summaryPayoutTxIdTextField.setText(payoutTxId); } - }, (task) -> { - //log.trace(task.toString()); - }, throwable -> { - log.error(throwable.toString()); + + @Override + public void onFault(Throwable throwable, TakerAsSellerProtocol.State state) + { + log.error("Error while executing trade process at state: " + state + " / " + throwable); + Popups.openErrorPopup("Error while executing trade process", "Error while executing trade process at state: " + state + " / " + throwable); + } + + @Override + public void onWaitingForPeerResponse(TakerAsSellerProtocol.State state) + { + log.debug("Waiting for peers response at state " + state); + } + + @Override + public void onCompleted(TakerAsSellerProtocol.State state) + { + log.debug("Trade protocol completed at state " + state); + } + + @Override + public void onTakeOfferRequestRejected(Trade trade) + { + log.error("Take offer request rejected"); + Popups.openErrorPopup("Take offer request rejected", "Your take offer request has been rejected. It might be that the offerer got another request shortly before your request arrived."); + } } ); } @@ -220,7 +241,7 @@ public class TakerOfferController implements Initializable, ChildController @FXML public void onReceivedFiat() { - trading.releaseBTC(tradeId); + trading.onFiatReceived(tradeId); } @FXML diff --git a/src/main/java/io/bitsquare/gui/market/trade/TakerTradeController.java b/src/main/java/io/bitsquare/gui/market/trade/TakerTradeController.java index 34518514c7..c35b939c53 100644 --- a/src/main/java/io/bitsquare/gui/market/trade/TakerTradeController.java +++ b/src/main/java/io/bitsquare/gui/market/trade/TakerTradeController.java @@ -172,7 +172,7 @@ public class TakerTradeController implements Initializable, ChildController gridPane.add(isOnlineCheckerHolder, 2, row); //TODO - messageFacade.pingPeer(offer.getMessagePubKeyAsHex()); + // messageFacade.pingPeer(offer.getMessagePubKeyAsHex()); checkOnlineStatusTimer = Utilities.setTimeout(1000, (AnimationTimer animationTimer) -> { setIsOnlineStatus(true); //noinspection ReturnOfNull @@ -316,7 +316,7 @@ public class TakerTradeController implements Initializable, ChildController } @Override - public void onTradeCompleted(String hashAsString) + public void onPayoutTxPublished(String hashAsString) { showSummary(hashAsString); } @@ -359,7 +359,7 @@ public class TakerTradeController implements Initializable, ChildController private void releaseBTC() { processStepBar.next(); - trading.releaseBTC(trade.getId()); + trading.onFiatReceived(trade.getId()); nextButton.setText("Close"); nextButton.setOnAction(e -> close()); diff --git a/src/main/java/io/bitsquare/gui/orders/offer/OfferController.java b/src/main/java/io/bitsquare/gui/orders/offer/OfferController.java index cd6d5f6c96..16aa5d5ecb 100644 --- a/src/main/java/io/bitsquare/gui/orders/offer/OfferController.java +++ b/src/main/java/io/bitsquare/gui/orders/offer/OfferController.java @@ -7,7 +7,6 @@ import io.bitsquare.gui.NavigationController; import io.bitsquare.gui.util.Icons; import io.bitsquare.trade.Offer; import io.bitsquare.trade.Trading; -import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -110,13 +109,7 @@ public class OfferController implements Initializable, ChildController, Hibernat private void removeOffer(OfferListItem offerListItem) { - try - { - trading.removeOffer(offerListItem.getOffer()); - } catch (IOException e) - { - e.printStackTrace(); - } + trading.removeOffer(offerListItem.getOffer()); offerListItems.remove(offerListItem); } diff --git a/src/main/java/io/bitsquare/gui/orders/pending/PendingTradeController.java b/src/main/java/io/bitsquare/gui/orders/pending/PendingTradeController.java index cded2533ca..860bc2a527 100644 --- a/src/main/java/io/bitsquare/gui/orders/pending/PendingTradeController.java +++ b/src/main/java/io/bitsquare/gui/orders/pending/PendingTradeController.java @@ -152,20 +152,16 @@ public class PendingTradeController implements Initializable, ChildController, H } }); - trading.getNewTradeProperty().addListener(new ChangeListener() - { - @Override - public void changed(ObservableValue observableValue, String oldTradeUid, String newTradeUid) - { - Trade newTrade = trading.getTrades().get(newTradeUid); + trading.getNewTradeProperty().addListener((observableValue, oldTradeId, newTradeId) -> { + Trade newTrade = trading.getTrade(newTradeId); + if (newTrade != null) tradeItems.add(new PendingTradesListItem(newTrade)); - } }); initCopyIcons(); // select - Optional currentTradeItemOptional = tradeItems.stream().filter((e) -> e.getTrade().getId().equals(trading.getCurrentPendingTrade().getId())).findFirst(); + Optional currentTradeItemOptional = tradeItems.stream().filter((e) -> e.getTrade().getId().equals(trading.getPendingTrade().getId())).findFirst(); if (currentTradeItemOptional.isPresent()) openTradesTable.getSelectionModel().select(currentTradeItemOptional.get()); @@ -183,7 +179,7 @@ public class PendingTradeController implements Initializable, ChildController, H public void bankTransferInited() { - trading.onUIEventBankTransferInited(currentTrade.getId()); + trading.bankTransferInited(currentTrade.getId()); bankTransferInitedButton.setDisable(true); } diff --git a/src/main/java/io/bitsquare/msg/MessageFacade.java b/src/main/java/io/bitsquare/msg/MessageFacade.java index 27f4628633..837f27e1ea 100644 --- a/src/main/java/io/bitsquare/msg/MessageFacade.java +++ b/src/main/java/io/bitsquare/msg/MessageFacade.java @@ -4,14 +4,6 @@ import com.google.inject.Inject; import io.bitsquare.BitSquare; import io.bitsquare.msg.listeners.*; import io.bitsquare.trade.Offer; -import io.bitsquare.trade.payment.offerer.OffererAsBuyerProtocol; -import io.bitsquare.trade.payment.offerer.messages.*; -import io.bitsquare.trade.payment.taker.TakerAsSellerProtocol; -import io.bitsquare.trade.payment.taker.listeners.GetPeerAddressListener; -import io.bitsquare.trade.payment.taker.messages.PayoutTxPublishedMessage; -import io.bitsquare.trade.payment.taker.messages.RequestOffererPublishDepositTxMessage; -import io.bitsquare.trade.payment.taker.messages.RequestTakeOfferMessage; -import io.bitsquare.trade.payment.taker.messages.TakeOfferFeePayedMessage; import io.bitsquare.user.Arbitrator; import io.bitsquare.util.DSAKeyUtil; import io.bitsquare.util.FileUtil; @@ -29,7 +21,6 @@ import net.tomp2p.p2p.Peer; import net.tomp2p.p2p.PeerMaker; import net.tomp2p.peers.Number160; import net.tomp2p.peers.PeerAddress; -import net.tomp2p.rpc.ObjectDataReply; import net.tomp2p.storage.Data; import net.tomp2p.storage.StorageDisk; import net.tomp2p.utils.Utils; @@ -44,19 +35,18 @@ import org.slf4j.LoggerFactory; @SuppressWarnings({"EmptyMethod", "ConstantConditions"}) public class MessageFacade { - private static final String PING = "ping"; - private static final String PONG = "pong"; private static final Logger log = LoggerFactory.getLogger(MessageFacade.class); + // private static final String PING = "ping"; + // private static final String PONG = "pong"; private static final int MASTER_PEER_PORT = 5000; private final List orderBookListeners = new ArrayList<>(); - private final List takeOfferRequestListeners = new ArrayList<>(); private final List arbitratorListeners = new ArrayList<>(); - private final Map takerPaymentProtocols = new HashMap<>(); - private final Map offererAsBuyerProtocols = new HashMap<>(); + private final List incomingTradeMessageListeners = new ArrayList<>(); - private final List pingPeerListeners = new ArrayList<>(); + + // private final List pingPeerListeners = new ArrayList<>(); private final BooleanProperty isDirty = new SimpleBooleanProperty(false); private Peer myPeer; @@ -71,17 +61,9 @@ public class MessageFacade @Inject public MessageFacade() { - /* try - { - masterPeer = BootstrapMasterPeer.GET_INSTANCE(MASTER_PEER_PORT); - } catch (Exception e) - { - if (masterPeer != null) - masterPeer.shutdown(); - System.err.println("masterPeer already instantiated by another app. " + e.getMessage()); - } */ } + /////////////////////////////////////////////////////////////////////////////////////////// // Public Methods /////////////////////////////////////////////////////////////////////////////////////////// @@ -115,6 +97,146 @@ public class MessageFacade } + /////////////////////////////////////////////////////////////////////////////////////////// + // Find peer address + /////////////////////////////////////////////////////////////////////////////////////////// + + public void getPeerAddress(String pubKeyAsHex, GetPeerAddressListener listener) + { + final Number160 location = Number160.createHash(pubKeyAsHex); + final FutureDHT getPeerAddressFuture = myPeer.get(location).start(); + getPeerAddressFuture.addListener(new BaseFutureAdapter() + { + @Override + public void operationComplete(BaseFuture baseFuture) throws Exception + { + if (baseFuture.isSuccess() && getPeerAddressFuture.getData() != null) + { + final PeerAddress peerAddress = (PeerAddress) getPeerAddressFuture.getData().getObject(); + Platform.runLater(() -> listener.onResult(peerAddress)); + } + else + { + Platform.runLater(() -> listener.onFailed()); + } + } + }); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Publish offer + /////////////////////////////////////////////////////////////////////////////////////////// + + public void addOffer(Offer offer) throws IOException + { + log.trace("addOffer"); + Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode()); + final Number160 contentKey = Number160.createHash(offer.getId()); + final Data offerData = new Data(offer); + //offerData.setTTLSeconds(5); + final FutureDHT addFuture = myPeer.put(locationKey).setData(contentKey, offerData).start(); + //final FutureDHT addFuture = myPeer.add(locationKey).setData(offerData).start(); + addFuture.addListener(new BaseFutureAdapter() + { + @Override + public void operationComplete(BaseFuture future) throws Exception + { + Platform.runLater(() -> onOfferAdded(offerData, future.isSuccess(), locationKey)); + } + }); + } + + private void onOfferAdded(Data offerData, boolean success, Number160 locationKey) + { + log.trace("onOfferAdded"); + setDirty(locationKey); + orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOfferAdded(offerData, success)); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Get offers + /////////////////////////////////////////////////////////////////////////////////////////// + + public void getOffers(String currency) + { + log.trace("getOffers"); + final Number160 locationKey = Number160.createHash(currency); + final FutureDHT getOffersFuture = myPeer.get(locationKey).setAll().start(); + getOffersFuture.addListener(new BaseFutureAdapter() + { + @Override + public void operationComplete(BaseFuture future) throws Exception + { + final Map dataMap = getOffersFuture.getDataMap(); + Platform.runLater(() -> onOffersReceived(dataMap, future.isSuccess())); + } + }); + } + + private void onOffersReceived(Map dataMap, boolean success) + { + log.trace("onOffersReceived"); + orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOffersReceived(dataMap, success)); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Remove offer + /////////////////////////////////////////////////////////////////////////////////////////// + + public void removeOffer(Offer offer) + { + log.trace("removeOffer"); + Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode()); + Number160 contentKey = Number160.createHash(offer.getId()); + log.debug("removeOffer"); + FutureDHT removeFuture = myPeer.remove(locationKey).setReturnResults().setContentKey(contentKey).start(); + removeFuture.addListener(new BaseFutureAdapter() + { + @Override + public void operationComplete(BaseFuture future) throws Exception + { + Platform.runLater(() -> onOfferRemoved(removeFuture.getData(), future.isSuccess(), locationKey)); + } + }); + } + + private void onOfferRemoved(Data data, boolean success, Number160 locationKey) + { + log.trace("onOfferRemoved"); + setDirty(locationKey); + orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOfferRemoved(data, success)); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Trade process + /////////////////////////////////////////////////////////////////////////////////////////// + + public void sendTradeMessage(PeerAddress peerAddress, TradeMessage tradeMessage, OutgoingTradeMessageListener listener) + { + final PeerConnection peerConnection = myPeer.createPeerConnection(peerAddress, 10); + final FutureResponse sendFuture = myPeer.sendDirect(peerConnection).setObject(tradeMessage).start(); + sendFuture.addListener(new BaseFutureAdapter() + { + @Override + public void operationComplete(BaseFuture baseFuture) throws Exception + { + if (sendFuture.isSuccess()) + Platform.runLater(() -> listener.onResult()); + else + Platform.runLater(() -> listener.onFailed()); + } + } + ); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Reputation + /////////////////////////////////////////////////////////////////////////////////////////// + public void setupReputationRoot() throws IOException { String pubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(getPubKey()); // out message ID @@ -149,6 +271,7 @@ public class MessageFacade myPeer.put(locationKey).setData(contentKey, reputationData).start(); } + /////////////////////////////////////////////////////////////////////////////////////////// // Arbitrators /////////////////////////////////////////////////////////////////////////////////////////// @@ -199,100 +322,11 @@ public class MessageFacade arbitratorListener.onArbitratorsReceived(dataMap, success); } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Publish offer - /////////////////////////////////////////////////////////////////////////////////////////// - - //TODO use Offer and do proper serialisation here - public void addOffer(Offer offer) throws IOException - { - Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode()); - final Number160 contentKey = Number160.createHash(offer.getId()); - final Data offerData = new Data(offer); - //offerData.setTTLSeconds(5); - final FutureDHT addFuture = myPeer.put(locationKey).setData(contentKey, offerData).start(); - //final FutureDHT addFuture = myPeer.add(locationKey).setData(offerData).start(); - addFuture.addListener(new BaseFutureAdapter() - { - @Override - public void operationComplete(BaseFuture future) throws Exception - { - Platform.runLater(() -> onOfferAdded(offerData, future.isSuccess(), locationKey)); - } - }); - } - - private void onOfferAdded(Data offerData, boolean success, Number160 locationKey) - { - setDirty(locationKey); - - for (OrderBookListener orderBookListener : orderBookListeners) - orderBookListener.onOfferAdded(offerData, success); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Get offers - /////////////////////////////////////////////////////////////////////////////////////////// - - public void getOffers(String currency) - { - final Number160 locationKey = Number160.createHash(currency); - final FutureDHT getOffersFuture = myPeer.get(locationKey).setAll().start(); - getOffersFuture.addListener(new BaseFutureAdapter() - { - @Override - public void operationComplete(BaseFuture future) throws Exception - { - final Map dataMap = getOffersFuture.getDataMap(); - Platform.runLater(() -> onOffersReceived(dataMap, future.isSuccess())); - } - }); - } - - private void onOffersReceived(Map dataMap, boolean success) - { - for (OrderBookListener orderBookListener : orderBookListeners) - orderBookListener.onOffersReceived(dataMap, success); - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Remove offer - /////////////////////////////////////////////////////////////////////////////////////////// - - public void removeOffer(Offer offer) - { - Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode()); - Number160 contentKey = Number160.createHash(offer.getId()); - log.debug("removeOffer"); - FutureDHT removeFuture = myPeer.remove(locationKey).setReturnResults().setContentKey(contentKey).start(); - removeFuture.addListener(new BaseFutureAdapter() - { - @Override - public void operationComplete(BaseFuture future) throws Exception - { - Data data = removeFuture.getData(); - Platform.runLater(() -> onOfferRemoved(data, future.isSuccess(), locationKey)); - } - }); - } - - private void onOfferRemoved(Data data, boolean success, Number160 locationKey) - { - log.debug("onOfferRemoved"); - setDirty(locationKey); - - for (OrderBookListener orderBookListener : orderBookListeners) - orderBookListener.onOfferRemoved(data, success); - } - - /////////////////////////////////////////////////////////////////////////////////////////// // Check dirty flag for a location key /////////////////////////////////////////////////////////////////////////////////////////// - + // TODO just temp... public BooleanProperty getIsDirtyProperty() { return isDirty; @@ -312,11 +346,7 @@ public class MessageFacade { Object object = data.getObject(); if (object instanceof Long) - { - final long lastTimeStamp = (Long) object; - //System.out.println("getDirtyFlag " + lastTimeStamp); - Platform.runLater(() -> onGetDirtyFlag(lastTimeStamp)); - } + Platform.runLater(() -> onGetDirtyFlag((Long) object)); } } @@ -426,149 +456,12 @@ public class MessageFacade } */ - /////////////////////////////////////////////////////////////////////////////////////////// - // Find peer address - /////////////////////////////////////////////////////////////////////////////////////////// - - - public void getPeerAddress(String pubKeyAsHex, GetPeerAddressListener listener) - { - final Number160 location = Number160.createHash(pubKeyAsHex); - final FutureDHT getPeerAddressFuture = myPeer.get(location).start(); - getPeerAddressFuture.addListener(new BaseFutureAdapter() - { - @Override - public void operationComplete(BaseFuture baseFuture) throws Exception - { - if (baseFuture.isSuccess() && getPeerAddressFuture.getData() != null) - { - final PeerAddress peerAddress = (PeerAddress) getPeerAddressFuture.getData().getObject(); - Platform.runLater(() -> listener.onResult(peerAddress)); - } - else - { - Platform.runLater(() -> listener.onFailed()); - - } - } - }); - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Trade process - /////////////////////////////////////////////////////////////////////////////////////////// - - public void sendTradingMessage(final PeerAddress peerAddress, TradeMessage tradeMessage, TradeMessageListener listener) - { - final PeerConnection peerConnection = myPeer.createPeerConnection(peerAddress, 10); - final FutureResponse sendFuture = myPeer.sendDirect(peerConnection).setObject(tradeMessage).start(); - sendFuture.addListener(new BaseFutureAdapter() - { - @Override - public void operationComplete(BaseFuture baseFuture) throws Exception - { - if (sendFuture.isSuccess()) - { - Platform.runLater(() -> listener.onResult()); - } - else - { - Platform.runLater(() -> listener.onFailed()); - } - } - } - ); - } - - public void sendTradeMessage(PeerAddress peerAddress, TradeMessage tradeMessage, TradeMessageListener listener) - { - final PeerConnection peerConnection = myPeer.createPeerConnection(peerAddress, 10); - final FutureResponse sendFuture = myPeer.sendDirect(peerConnection).setObject(tradeMessage).start(); - sendFuture.addListener(new BaseFutureAdapter() - { - @Override - public void operationComplete(BaseFuture baseFuture) throws Exception - { - if (sendFuture.isSuccess()) - { - Platform.runLater(() -> onSendTradingMessageResult(listener)); - } - else - { - Platform.runLater(() -> onSendTradingMessageFailed(listener)); - } - } - } - ); - } - - private void onSendTradingMessageResult(TradeMessageListener listener) - { - listener.onResult(); - } - - private void onSendTradingMessageFailed(TradeMessageListener listener) - { - listener.onFailed(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Process incoming tradingMessage - /////////////////////////////////////////////////////////////////////////////////////////// - - private void processTradingMessage(TradeMessage tradeMessage, PeerAddress sender) - { - // log.trace("processTradingMessage TradeId " + tradeMessage.getTradeId()); - log.trace("processTradingMessage instance " + tradeMessage.getClass().getSimpleName()); - log.trace("processTradingMessage instance " + tradeMessage.getClass().getName()); - log.trace("processTradingMessage instance " + tradeMessage.getClass().getCanonicalName()); - log.trace("processTradingMessage instance " + tradeMessage.getClass().getTypeName()); - - if (tradeMessage instanceof RequestTakeOfferMessage) - { - takeOfferRequestListeners.stream().forEach(e -> e.onTakeOfferRequested(tradeMessage.getTradeId(), sender)); - } - else if (tradeMessage instanceof AcceptTakeOfferRequestMessage) - { - takerPaymentProtocols.get(tradeMessage.getTradeId()).onAcceptTakeOfferRequestMessage(); - } - else if (tradeMessage instanceof RejectTakeOfferRequestMessage) - { - takerPaymentProtocols.get(tradeMessage.getTradeId()).onRejectTakeOfferRequestMessage(); - } - else if (tradeMessage instanceof TakeOfferFeePayedMessage) - { - offererAsBuyerProtocols.get(tradeMessage.getTradeId()).onTakeOfferFeePayedMessage((TakeOfferFeePayedMessage) tradeMessage); - } - else if (tradeMessage instanceof RequestTakerDepositPaymentMessage) - { - takerPaymentProtocols.get(tradeMessage.getTradeId()).onRequestTakerDepositPaymentMessage((RequestTakerDepositPaymentMessage) tradeMessage); - } - else if (tradeMessage instanceof RequestOffererPublishDepositTxMessage) - { - offererAsBuyerProtocols.get(tradeMessage.getTradeId()).onRequestOffererPublishDepositTxMessage((RequestOffererPublishDepositTxMessage) tradeMessage); - } - else if (tradeMessage instanceof DepositTxPublishedMessage) - { - takerPaymentProtocols.get(tradeMessage.getTradeId()).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage); - } - else if (tradeMessage instanceof BankTransferInitedMessage) - { - takerPaymentProtocols.get(tradeMessage.getTradeId()).onBankTransferInitedMessage((BankTransferInitedMessage) tradeMessage); - } - else if (tradeMessage instanceof PayoutTxPublishedMessage) - { - offererAsBuyerProtocols.get(tradeMessage.getTradeId()).onPayoutTxPublishedMessage((PayoutTxPublishedMessage) tradeMessage); - } - } - /////////////////////////////////////////////////////////////////////////////////////////// // Ping peer /////////////////////////////////////////////////////////////////////////////////////////// //TODO not working anymore... - public void pingPeer(String publicKeyAsHex) + /* public void pingPeer(String publicKeyAsHex) { Number160 location = Number160.createHash(publicKeyAsHex); final FutureDHT getPeerAddressFuture = myPeer.get(location).start(); @@ -587,8 +480,7 @@ public class MessageFacade }); } - - private void onAddressFoundPingPeer(PeerAddress peerAddress) + private void onAddressFoundPingPeer(PeerAddress peerAddress) { try { @@ -626,16 +518,7 @@ public class MessageFacade for (PingPeerListener pingPeerListener : pingPeerListeners) pingPeerListener.onPingPeerResult(success); } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Misc - /////////////////////////////////////////////////////////////////////////////////////////// - - public PublicKey getPubKey() - { - return keyPair.getPublic(); - } + */ /////////////////////////////////////////////////////////////////////////////////////////// @@ -652,37 +535,7 @@ public class MessageFacade orderBookListeners.remove(listener); } - public void addTakeOfferRequestListener(TakeOfferRequestListener listener) - { - takeOfferRequestListeners.add(listener); - } - - public void removeTakeOfferRequestListener(TakeOfferRequestListener listener) - { - takeOfferRequestListeners.remove(listener); - } - - public void addTakerPaymentProtocol(TakerAsSellerProtocol protocol) - { - takerPaymentProtocols.put(protocol.getId(), protocol); - } - - public void removeTakerPaymentProtocol(TakerAsSellerProtocol protocol) - { - takerPaymentProtocols.remove(protocol); - } - - public void addOffererPaymentProtocol(OffererAsBuyerProtocol protocol) - { - offererAsBuyerProtocols.put(protocol.getId(), protocol); - } - - public void removeOffererPaymentProtocol(OffererAsBuyerProtocol protocol) - { - offererAsBuyerProtocols.remove(protocol); - } - - public void addPingPeerListener(PingPeerListener listener) + /* public void addPingPeerListener(PingPeerListener listener) { pingPeerListeners.add(listener); } @@ -690,7 +543,7 @@ public class MessageFacade public void removePingPeerListener(PingPeerListener listener) { pingPeerListeners.remove(listener); - } + } */ public void addArbitratorListener(ArbitratorListener listener) { @@ -702,6 +555,44 @@ public class MessageFacade arbitratorListeners.remove(listener); } + public void addIncomingTradeMessageListener(IncomingTradeMessageListener listener) + { + incomingTradeMessageListeners.add(listener); + } + + public void removeIncomingTradeMessageListener(IncomingTradeMessageListener listener) + { + incomingTradeMessageListeners.remove(listener); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + + public PublicKey getPubKey() + { + return keyPair.getPublic(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Incoming message handler + /////////////////////////////////////////////////////////////////////////////////////////// + + private void onMessage(Object request, PeerAddress sender) + { + if (request instanceof TradeMessage) + { + incomingTradeMessageListeners.stream().forEach(e -> e.onMessage((TradeMessage) request, sender)); + } + /* else + { + for (OrderBookListener orderBookListener : orderBookListeners) + orderBookListener.onMessage(request); + } */ + } + /////////////////////////////////////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////////////////////////////////// @@ -739,6 +630,18 @@ public class MessageFacade }); } + private void setupReplyHandler() + { + myPeer.setObjectDataReply((sender, request) -> { + if (!sender.equals(myPeer.getPeerAddress())) + Platform.runLater(() -> onMessage(request, sender)); + else + log.error("Received msg from myself. That should never happen."); + //noinspection ReturnOfNull + return null; + }); + } + private void setupStorage() { myPeer.getPeerBean().setStorage(new StorageDisk(FileUtil.getDirectory(BitSquare.ID + "_tomP2P").getAbsolutePath())); @@ -752,49 +655,4 @@ public class MessageFacade } - /////////////////////////////////////////////////////////////////////////////////////////// - // Incoming message handler - /////////////////////////////////////////////////////////////////////////////////////////// - - private void setupReplyHandler() - { - /* myPeer.setObjectDataReply((sender, request) -> { - if (!sender.equals(myPeer.getPeerAddress())) - { - Platform.runLater(() -> onMessage(request, sender)); - } - //noinspection ReturnOfNull - return null; - }); */ - - //noinspection Convert2Lambda - myPeer.setObjectDataReply(new ObjectDataReply() - { - - @Override - public Object reply(PeerAddress sender, Object request) throws Exception - { - if (!sender.equals(myPeer.getPeerAddress())) - { - Platform.runLater(() -> onMessage(request, sender)); - } - //noinspection ReturnOfNull - return null; - } - }); - } - - private void onMessage(Object request, PeerAddress sender) - { - if (request instanceof TradeMessage) - { - processTradingMessage((TradeMessage) request, sender); - } - /* else - { - for (OrderBookListener orderBookListener : orderBookListeners) - orderBookListener.onMessage(request); - } */ - } - } diff --git a/src/main/java/io/bitsquare/trade/payment/taker/listeners/GetPeerAddressListener.java b/src/main/java/io/bitsquare/msg/listeners/GetPeerAddressListener.java similarity index 74% rename from src/main/java/io/bitsquare/trade/payment/taker/listeners/GetPeerAddressListener.java rename to src/main/java/io/bitsquare/msg/listeners/GetPeerAddressListener.java index f46829c4e4..3ef6c45485 100644 --- a/src/main/java/io/bitsquare/trade/payment/taker/listeners/GetPeerAddressListener.java +++ b/src/main/java/io/bitsquare/msg/listeners/GetPeerAddressListener.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.taker.listeners; +package io.bitsquare.msg.listeners; import net.tomp2p.peers.PeerAddress; diff --git a/src/main/java/io/bitsquare/msg/listeners/IncomingTradeMessageListener.java b/src/main/java/io/bitsquare/msg/listeners/IncomingTradeMessageListener.java new file mode 100644 index 0000000000..e85fee55cd --- /dev/null +++ b/src/main/java/io/bitsquare/msg/listeners/IncomingTradeMessageListener.java @@ -0,0 +1,9 @@ +package io.bitsquare.msg.listeners; + +import io.bitsquare.msg.TradeMessage; +import net.tomp2p.peers.PeerAddress; + +public interface IncomingTradeMessageListener +{ + void onMessage(TradeMessage tradeMessage, PeerAddress sender); +} diff --git a/src/main/java/io/bitsquare/msg/listeners/TradeMessageListener.java b/src/main/java/io/bitsquare/msg/listeners/OutgoingTradeMessageListener.java similarity index 64% rename from src/main/java/io/bitsquare/msg/listeners/TradeMessageListener.java rename to src/main/java/io/bitsquare/msg/listeners/OutgoingTradeMessageListener.java index fb2d385a89..d0ed32c530 100644 --- a/src/main/java/io/bitsquare/msg/listeners/TradeMessageListener.java +++ b/src/main/java/io/bitsquare/msg/listeners/OutgoingTradeMessageListener.java @@ -1,6 +1,6 @@ package io.bitsquare.msg.listeners; -public interface TradeMessageListener +public interface OutgoingTradeMessageListener { void onFailed(); diff --git a/src/main/java/io/bitsquare/trade/Offer.java b/src/main/java/io/bitsquare/trade/Offer.java index 05e675e567..a342ac3c37 100644 --- a/src/main/java/io/bitsquare/trade/Offer.java +++ b/src/main/java/io/bitsquare/trade/Offer.java @@ -167,7 +167,7 @@ public class Offer implements Serializable return collateral; } - public String getBankAccountUID() + public String getBankAccountId() { return bankAccountUID; } diff --git a/src/main/java/io/bitsquare/trade/Trade.java b/src/main/java/io/bitsquare/trade/Trade.java index 864f3bc5bc..4007f773ee 100644 --- a/src/main/java/io/bitsquare/trade/Trade.java +++ b/src/main/java/io/bitsquare/trade/Trade.java @@ -6,7 +6,6 @@ import java.math.BigInteger; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleStringProperty; -@SuppressWarnings("SameParameterValue") public class Trade implements Serializable { private static final long serialVersionUID = -8275323072940974077L; @@ -22,7 +21,6 @@ public class Trade implements Serializable private String takerSignature; private Transaction depositTransaction; private Transaction payoutTransaction; - private State state = State.OPEN; public Trade(Offer offer) @@ -30,15 +28,16 @@ public class Trade implements Serializable this.offer = offer; } - public void setContractTakerSignature(String takerSignature) - { - this.takerSignature = takerSignature; - } /////////////////////////////////////////////////////////////////////////////////////////// // Setters /////////////////////////////////////////////////////////////////////////////////////////// + public void setContractTakerSignature(String takerSignature) + { + this.takerSignature = takerSignature; + } + public void setTakeOfferFeeTxID(String takeOfferFeeTxID) { this.takeOfferFeeTxID = takeOfferFeeTxID; diff --git a/src/main/java/io/bitsquare/trade/Trading.java b/src/main/java/io/bitsquare/trade/Trading.java index dec844f9df..e951f8ea3b 100644 --- a/src/main/java/io/bitsquare/trade/Trading.java +++ b/src/main/java/io/bitsquare/trade/Trading.java @@ -8,55 +8,61 @@ import io.bitsquare.btc.BlockChainFacade; import io.bitsquare.btc.WalletFacade; import io.bitsquare.crypto.CryptoFacade; import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.TradeMessage; +import io.bitsquare.msg.listeners.TakeOfferRequestListener; import io.bitsquare.storage.Storage; -import io.bitsquare.trade.payment.offerer.OffererAsBuyerProtocol; -import io.bitsquare.trade.payment.offerer.OffererAsBuyerProtocolListener; -import io.bitsquare.trade.payment.taker.TakerAsSellerProtocol; -import io.bitsquare.trade.payment.taker.TakerAsSellerProtocolListener; +import io.bitsquare.trade.protocol.messages.offerer.*; +import io.bitsquare.trade.protocol.messages.taker.PayoutTxPublishedMessage; +import io.bitsquare.trade.protocol.messages.taker.RequestOffererPublishDepositTxMessage; +import io.bitsquare.trade.protocol.messages.taker.RequestTakeOfferMessage; +import io.bitsquare.trade.protocol.messages.taker.TakeOfferFeePayedMessage; +import io.bitsquare.trade.protocol.offerer.OffererAsBuyerProtocol; +import io.bitsquare.trade.protocol.offerer.OffererAsBuyerProtocolListener; +import io.bitsquare.trade.protocol.taker.TakerAsSellerProtocol; +import io.bitsquare.trade.protocol.taker.TakerAsSellerProtocolListener; import io.bitsquare.user.User; -import io.nucleo.scheduler.worker.Worker; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; import java.io.IOException; import java.math.BigInteger; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import net.tomp2p.peers.PeerAddress; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * Represents trade domain. Keeps complexity of process apart from view controller - */ -@SuppressWarnings("EmptyMethod") public class Trading { private static final Logger log = LoggerFactory.getLogger(Trading.class); - private final Map takerPaymentProtocols = new HashMap<>(); - private final Map offererPaymentProtocols = new HashMap<>(); - private final String storageKey; - private final User user; + private final String storageKey = this.getClass().getName(); + + private final User user; private final Storage storage; private final MessageFacade messageFacade; private final BlockChainFacade blockChainFacade; private final WalletFacade walletFacade; private final CryptoFacade cryptoFacade; + + private final List takeOfferRequestListeners = new ArrayList<>(); + private final Map takerAsSellerProtocolMap = new HashMap<>(); + private final Map offererAsBuyerProtocolMap = new HashMap<>(); + private final StringProperty newTradeProperty = new SimpleStringProperty(); - private Map offers = new HashMap<>(); + private final Map offers; + private final Map trades; - private Map trades = new HashMap<>(); - private Trade currentPendingTrade; + private Trade pendingTrade; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////////////////// - @SuppressWarnings("unchecked") @Inject public Trading(User user, Storage storage, @@ -72,36 +78,55 @@ public class Trading this.walletFacade = walletFacade; this.cryptoFacade = cryptoFacade; - storageKey = this.getClass().getName(); - Object offersObject = storage.read(storageKey + ".offers"); if (offersObject instanceof HashMap) offers = (Map) offersObject; + else + offers = new HashMap<>(); Object tradesObject = storage.read(storageKey + ".trades"); if (tradesObject instanceof HashMap) trades = (Map) tradesObject; + else + trades = new HashMap<>(); - messageFacade.addTakeOfferRequestListener((offerId, sender) -> createOffererAsBuyerProtocol(offerId, sender)); + messageFacade.addIncomingTradeMessageListener(this::onIncomingTradeMessage); } + /////////////////////////////////////////////////////////////////////////////////////////// // Public Methods /////////////////////////////////////////////////////////////////////////////////////////// public void cleanup() { + messageFacade.removeIncomingTradeMessageListener(this::onIncomingTradeMessage); } - private void saveOffers() + + /////////////////////////////////////////////////////////////////////////////////////////// + // Event Listeners + /////////////////////////////////////////////////////////////////////////////////////////// + + public void addTakeOfferRequestListener(TakeOfferRequestListener listener) { - storage.write(storageKey + ".offers", offers); + takeOfferRequestListeners.add(listener); } + public void removeTakeOfferRequestListener(TakeOfferRequestListener listener) + { + takeOfferRequestListeners.remove(listener); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Manage offers + /////////////////////////////////////////////////////////////////////////////////////////// + public void addOffer(Offer offer) throws IOException { if (offers.containsKey(offer.getId())) - throw new IllegalStateException("offers contains already a offer with the ID " + offer.getId()); + throw new IllegalStateException("offers contains already an offer with the ID " + offer.getId()); offers.put(offer.getId(), offer); saveOffers(); @@ -109,22 +134,44 @@ public class Trading messageFacade.addOffer(offer); } - public void removeOffer(Offer offer) throws IOException + public void removeOffer(Offer offer) { + if (!offers.containsKey(offer.getId())) + throw new IllegalStateException("offers does not contain the offer with the ID " + offer.getId()); + offers.remove(offer.getId()); saveOffers(); messageFacade.removeOffer(offer); } + public Trade takeOffer(BigInteger amount, Offer offer, TakerAsSellerProtocolListener listener) + { + Trade trade = createTrade(offer); + trade.setTradeAmount(amount); + + TakerAsSellerProtocol takerAsSellerProtocol = new TakerAsSellerProtocol(trade, listener, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user); + takerAsSellerProtocolMap.put(trade.getId(), takerAsSellerProtocol); + takerAsSellerProtocol.start(); + + return trade; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Manage trades + /////////////////////////////////////////////////////////////////////////////////////////// public Trade createTrade(Offer offer) { + if (trades.containsKey(offer.getId())) + throw new IllegalStateException("trades contains already an trade with the ID " + offer.getId()); + Trade trade = new Trade(offer); trades.put(offer.getId(), trade); - //TODO for testing - //storage.write(storageKey + ".trades", trades); + saveTrades(); + // for updating UIs this.newTradeProperty.set(trade.getId()); return trade; @@ -132,39 +179,39 @@ public class Trading public void removeTrade(Trade trade) { + if (!trades.containsKey(trade.getId())) + throw new IllegalStateException("trades does not contain the trade with the ID " + trade.getId()); + trades.remove(trade.getId()); - storage.write(storageKey + ".trades", trades); + saveTrades(); + + // for updating UIs + this.newTradeProperty.set(null); } - public final StringProperty getNewTradeProperty() - { - return this.newTradeProperty; - } + /////////////////////////////////////////////////////////////////////////////////////////// + // Trading protocols + /////////////////////////////////////////////////////////////////////////////////////////// - public Trade takeOffer(BigInteger amount, Offer offer, TakerAsSellerProtocolListener listener, WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - Trade trade = createTrade(offer); - trade.setTradeAmount(amount); - - TakerAsSellerProtocol takerPaymentProtocol = new TakerAsSellerProtocol(trade, listener, resultHandler, faultHandler, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user); - takerPaymentProtocols.put(trade.getId(), takerPaymentProtocol); - - return trade; - } - - - public void createOffererAsBuyerProtocol(String offerId, PeerAddress sender) + private void createOffererAsBuyerProtocol(String offerId, PeerAddress sender) { log.trace("createOffererAsBuyerProtocol offerId = " + offerId); - Offer offer = offers.get(offerId); - if (offer != null && offers.containsKey(offer.getId())) + if (offers.containsKey(offerId)) { - offers.remove(offer); + Offer offer = offers.get(offerId); - currentPendingTrade = createTrade(offer); - OffererAsBuyerProtocolListener listener = new OffererAsBuyerProtocolListener() + Trade trade = createTrade(offer); + pendingTrade = trade; + + OffererAsBuyerProtocol offererAsBuyerProtocol = new OffererAsBuyerProtocol(trade, sender, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user, new OffererAsBuyerProtocolListener() { + @Override + public void onOfferAccepted(Offer offer) + { + removeOffer(offer); + } + @Override public void onDepositTxPublished(String depositTxID) { @@ -181,8 +228,8 @@ public class Trading public void onPayoutTxPublished(String payoutTxAsHex) { Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(), Utils.parseAsHexOrBase58(payoutTxAsHex)); - currentPendingTrade.setPayoutTransaction(payoutTx); - currentPendingTrade.setState(Trade.State.COMPLETED); + trade.setPayoutTransaction(payoutTx); + trade.setState(Trade.State.COMPLETED); log.debug("trading onPayoutTxPublishedMessage"); } @@ -192,27 +239,9 @@ public class Trading log.trace("trading onDepositTxConfirmedInBlockchain"); } - }; - - WorkerResultHandler resultHandler = new WorkerResultHandler() - { - @Override - public void onResult(Worker worker) - { - //log.trace("onResult " + worker.toString()); - } - }; - WorkerFaultHandler faultHandler = new WorkerFaultHandler() - { - @Override - public void onFault(Throwable throwable) - { - log.error("onFault " + throwable); - } - }; - - OffererAsBuyerProtocol offererAsBuyerProtocol = new OffererAsBuyerProtocol(currentPendingTrade, sender, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user, resultHandler, faultHandler, listener); - offererPaymentProtocols.put(currentPendingTrade.getId(), offererAsBuyerProtocol); + }); + this.offererAsBuyerProtocolMap.put(trade.getId(), offererAsBuyerProtocol); + offererAsBuyerProtocol.start(); } else { @@ -220,35 +249,89 @@ public class Trading } } - - public void onUIEventBankTransferInited(String tradeUID) + public void bankTransferInited(String tradeUID) { - offererPaymentProtocols.get(tradeUID).onUIEventBankTransferInited(); + offererAsBuyerProtocolMap.get(tradeUID).onUIEventBankTransferInited(); + } + + public void onFiatReceived(String tradeUID) + { + takerAsSellerProtocolMap.get(tradeUID).onUIEventFiatReceived(); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Process incoming tradeMessages + /////////////////////////////////////////////////////////////////////////////////////////// + + private void onIncomingTradeMessage(TradeMessage tradeMessage, PeerAddress sender) + { + // log.trace("processTradingMessage TradeId " + tradeMessage.getTradeId()); + log.trace("processTradingMessage instance " + tradeMessage.getClass().getSimpleName()); + log.trace("processTradingMessage instance " + tradeMessage.getClass().getName()); + log.trace("processTradingMessage instance " + tradeMessage.getClass().getCanonicalName()); + log.trace("processTradingMessage instance " + tradeMessage.getClass().getTypeName()); + + String tradeId = tradeMessage.getTradeId(); + + if (tradeMessage instanceof RequestTakeOfferMessage) + { + createOffererAsBuyerProtocol(tradeId, sender); + takeOfferRequestListeners.stream().forEach(e -> e.onTakeOfferRequested(tradeId, sender)); + } + else if (tradeMessage instanceof AcceptTakeOfferRequestMessage) + { + takerAsSellerProtocolMap.get(tradeId).onAcceptTakeOfferRequestMessage(); + } + else if (tradeMessage instanceof RejectTakeOfferRequestMessage) + { + takerAsSellerProtocolMap.get(tradeId).onRejectTakeOfferRequestMessage(); + } + else if (tradeMessage instanceof TakeOfferFeePayedMessage) + { + offererAsBuyerProtocolMap.get(tradeId).onTakeOfferFeePayedMessage((TakeOfferFeePayedMessage) tradeMessage); + } + else if (tradeMessage instanceof RequestTakerDepositPaymentMessage) + { + takerAsSellerProtocolMap.get(tradeId).onRequestTakerDepositPaymentMessage((RequestTakerDepositPaymentMessage) tradeMessage); + } + else if (tradeMessage instanceof RequestOffererPublishDepositTxMessage) + { + offererAsBuyerProtocolMap.get(tradeId).onRequestOffererPublishDepositTxMessage((RequestOffererPublishDepositTxMessage) tradeMessage); + } + else if (tradeMessage instanceof DepositTxPublishedMessage) + { + takerAsSellerProtocolMap.get(tradeId).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage); + } + else if (tradeMessage instanceof BankTransferInitedMessage) + { + takerAsSellerProtocolMap.get(tradeId).onBankTransferInitedMessage((BankTransferInitedMessage) tradeMessage); + } + else if (tradeMessage instanceof PayoutTxPublishedMessage) + { + offererAsBuyerProtocolMap.get(tradeId).onPayoutTxPublishedMessage((PayoutTxPublishedMessage) tradeMessage); + } } /////////////////////////////////////////////////////////////////////////////////////////// - // Trade process + // Utils /////////////////////////////////////////////////////////////////////////////////////////// - - // 6 - public void releaseBTC(String tradeUID) + public boolean isOfferAlreadyInTrades(Offer offer) { - takerPaymentProtocols.get(tradeUID).onUIEventFiatReceived(); + return trades.containsKey(offer.getId()); } + /////////////////////////////////////////////////////////////////////////////////////////// // Getters /////////////////////////////////////////////////////////////////////////////////////////// - public Map getTrades() { return trades; } - public Map getOffers() { return offers; @@ -259,14 +342,37 @@ public class Trading return offers.get(offerId); } - - public boolean isOfferAlreadyInTrades(Offer offer) + public Trade getPendingTrade() { - return trades.containsKey(offer.getId()); + return pendingTrade; } - public Trade getCurrentPendingTrade() + public final StringProperty getNewTradeProperty() { - return currentPendingTrade; + return this.newTradeProperty; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void saveOffers() + { + storage.write(storageKey + ".offers", offers); + } + + private void saveTrades() + { + storage.write(storageKey + ".trades", trades); + } + + @Nullable + public Trade getTrade(String tradeId) + { + if (trades.containsKey(tradeId)) + return trades.get(trades); + else + return null; } } diff --git a/src/main/java/io/bitsquare/trade/orderbook/OrderBook.java b/src/main/java/io/bitsquare/trade/orderbook/OrderBook.java index b451034457..998d9dca13 100644 --- a/src/main/java/io/bitsquare/trade/orderbook/OrderBook.java +++ b/src/main/java/io/bitsquare/trade/orderbook/OrderBook.java @@ -77,13 +77,7 @@ public class OrderBook implements OrderBookListener public void removeOffer(Offer offer) { - try - { - trading.removeOffer(offer); - } catch (IOException e) - { - e.printStackTrace(); - } + trading.removeOffer(offer); } public void applyFilter(OrderBookFilter orderBookFilter) diff --git a/src/main/java/io/bitsquare/trade/payment/PaymentModel.java b/src/main/java/io/bitsquare/trade/payment/PaymentModel.java deleted file mode 100644 index bb8bc70cf0..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/PaymentModel.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.bitsquare.trade.payment; - -import io.bitsquare.msg.MessageFacade; -import io.bitsquare.trade.Offer; -import io.bitsquare.trade.Trade; -import io.nucleo.scheduler.model.PropertyProviderModel; -import net.tomp2p.peers.PeerAddress; - -public class PaymentModel extends PropertyProviderModel -{ - public final MessageFacade messageFacade; - public final Offer offer; - public PeerAddress peerAddress; - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor - /////////////////////////////////////////////////////////////////////////////////////////// - - public PaymentModel(MessageFacade messageFacade, Trade trade) - { - this.messageFacade = messageFacade; - this.offer = trade.getOffer(); - } - - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/AbstractOffererAsBuyerTask.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/AbstractOffererAsBuyerTask.java deleted file mode 100644 index 31462112ae..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/AbstractOffererAsBuyerTask.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import io.bitsquare.trade.payment.offerer.OffererAsBuyerProtocol; -import io.nucleo.scheduler.tasks.AbstractTask; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractOffererAsBuyerTask extends AbstractTask -{ - private static final Logger log = LoggerFactory.getLogger(AbstractOffererAsBuyerTask.class); - - protected OffererAsBuyerProtocol sharedModel; - - public AbstractOffererAsBuyerTask(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - addResultHandlers(resultHandler); - addFaultHandlers(faultHandler); - } - - @Override - public void setModel(Object model) - { - sharedModel = (OffererAsBuyerProtocol) model; - super.setModel(model); - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/CreateDepositTx.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/CreateDepositTx.java deleted file mode 100644 index 1085d21fab..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/CreateDepositTx.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import com.google.bitcoin.core.InsufficientMoneyException; -import com.google.bitcoin.core.Transaction; -import com.google.bitcoin.core.Utils; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CreateDepositTx extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(CreateDepositTx.class); - - public CreateDepositTx(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - - try - { - sharedModel.setOffererPubKey(sharedModel.getWalletFacade().getAddressInfoByTradeID(sharedModel.getTrade().getId()).getPubKeyAsHexString()); - Transaction tx = sharedModel.getWalletFacade().offererCreatesMSTxAndAddPayment(sharedModel.getTrade().getCollateralAmount(), - sharedModel.getOffererPubKey(), - sharedModel.getTakerMultiSigPubKey(), - sharedModel.getTrade().getOffer().getArbitrator().getPubKeyAsHex(), - sharedModel.getTrade().getId()); - - sharedModel.setPreparedOffererDepositTxAsHex(Utils.bytesToHexString(tx.bitcoinSerialize())); - sharedModel.setOffererTxOutIndex(tx.getInput(0).getOutpoint().getIndex()); - complete(); - } catch (InsufficientMoneyException e) - { - log.error("Create deposit tx failed due InsufficientMoneyException " + e); - failed(new Exception("Create deposit tx failed due InsufficientMoneyException " + e)); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/HandleTakeOfferRequest.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/HandleTakeOfferRequest.java deleted file mode 100644 index e03396ff73..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/HandleTakeOfferRequest.java +++ /dev/null @@ -1,70 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import io.bitsquare.msg.listeners.TradeMessageListener; -import io.bitsquare.trade.Trade; -import io.bitsquare.trade.payment.offerer.messages.AcceptTakeOfferRequestMessage; -import io.bitsquare.trade.payment.offerer.messages.RejectTakeOfferRequestMessage; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class HandleTakeOfferRequest extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(HandleTakeOfferRequest.class); - - public HandleTakeOfferRequest(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - if (sharedModel.getTrade().getState() == Trade.State.OPEN) - { - AcceptTakeOfferRequestMessage msg = new AcceptTakeOfferRequestMessage(sharedModel.getTrade().getId()); - sharedModel.getMessageFacade().sendTradeMessage(sharedModel.peerAddress, msg, new TradeMessageListener() - { - @Override - public void onResult() - { - log.trace("AcceptTakeOfferRequestMessage successfully arrived at peer"); - sharedModel.getTrade().setState(Trade.State.ACCEPTED); - sharedModel.getMessageFacade().removeOffer(sharedModel.getTrade().getOffer()); - complete(); - } - - @Override - public void onFailed() - { - log.error("AcceptTakeOfferRequestMessage failed to arrive at peer"); - failed(new Exception("AcceptTakeOfferRequestMessage failed to arrive at peer")); - } - }); - } - else - { - RejectTakeOfferRequestMessage msg = new RejectTakeOfferRequestMessage(sharedModel.getTrade().getId()); - sharedModel.getMessageFacade().sendTradeMessage(sharedModel.peerAddress, msg, new TradeMessageListener() - { - @Override - public void onResult() - { - log.trace("RejectTakeOfferRequestMessage successfully arrived at peer"); - } - - @Override - public void onFailed() - { - log.error("RejectTakeOfferRequestMessage failed to arrive at peer"); - } - }); - - log.error("Offer not marked as open."); - failed(new Exception("Offer not marked as open.")); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/RequestTakerDepositPayment.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/RequestTakerDepositPayment.java deleted file mode 100644 index 16a1a7cc19..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/RequestTakerDepositPayment.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import io.bitsquare.msg.listeners.TradeMessageListener; -import io.bitsquare.trade.payment.offerer.messages.RequestTakerDepositPaymentMessage; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RequestTakerDepositPayment extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(RequestTakerDepositPayment.class); - - public RequestTakerDepositPayment(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - - RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage(sharedModel.getTrade().getId(), - sharedModel.getUser().getBankAccount(sharedModel.getTrade().getOffer().getBankAccountUID()), - sharedModel.getUser().getAccountID(), - sharedModel.getOffererPubKey(), - sharedModel.getPreparedOffererDepositTxAsHex(), - sharedModel.getOffererTxOutIndex()); - sharedModel.getMessageFacade().sendTradeMessage(sharedModel.peerAddress, tradeMessage, new TradeMessageListener() - { - @Override - public void onResult() - { - log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer"); - complete(); - } - - @Override - public void onFailed() - { - log.error("RequestTakerDepositPaymentMessage failed to arrive at peer"); - failed(new Exception("RequestTakerDepositPaymentMessage failed to arrive at peer")); - } - }); - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SendDepositTxIdToTaker.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SendDepositTxIdToTaker.java deleted file mode 100644 index 866cd4ac19..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SendDepositTxIdToTaker.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import com.google.bitcoin.core.Utils; -import io.bitsquare.msg.listeners.TradeMessageListener; -import io.bitsquare.trade.payment.offerer.messages.DepositTxPublishedMessage; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SendDepositTxIdToTaker extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(SendDepositTxIdToTaker.class); - - public SendDepositTxIdToTaker(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(sharedModel.getTrade().getId(), Utils.bytesToHexString(sharedModel.getTrade().getDepositTransaction().bitcoinSerialize())); - sharedModel.getMessageFacade().sendTradeMessage(sharedModel.peerAddress, tradeMessage, new TradeMessageListener() - { - @Override - public void onResult() - { - log.trace("DepositTxPublishedMessage successfully arrived at peer"); - complete(); - } - - @Override - public void onFailed() - { - log.error("DepositTxPublishedMessage failed to arrive at peer"); - failed(new Exception("DepositTxPublishedMessage failed to arrive at peer")); - } - }); - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SetupListenerForBlockChainConfirmation.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SetupListenerForBlockChainConfirmation.java deleted file mode 100644 index 51235f0685..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SetupListenerForBlockChainConfirmation.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import com.google.bitcoin.core.Transaction; -import com.google.bitcoin.core.TransactionConfidence; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SetupListenerForBlockChainConfirmation extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class); - - public SetupListenerForBlockChainConfirmation(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - //TODO - // sharedModel.offererPaymentProtocolListener.onDepositTxConfirmedInBlockchain(); - - Transaction tx = sharedModel.getTrade().getDepositTransaction(); - tx.getConfidence().addEventListener(new TransactionConfidence.Listener() - { - @Override - public void onConfidenceChanged(Transaction tx, ChangeReason reason) - { - log.trace("onConfidenceChanged " + tx.getConfidence()); - if (reason == ChangeReason.SEEN_PEERS) - { - sharedModel.getListener().onDepositTxConfirmedUpdate(tx.getConfidence()); - } - if (reason == ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) - { - sharedModel.getListener().onDepositTxConfirmedInBlockchain(); - tx.getConfidence().removeEventListener(this); - log.trace("Tx is in blockchain"); - complete(); - } - } - } - ); - } -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SignAndPublishDepositTx.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SignAndPublishDepositTx.java deleted file mode 100644 index ca5d7f2875..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SignAndPublishDepositTx.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import com.google.bitcoin.core.Transaction; -import com.google.common.util.concurrent.FutureCallback; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SignAndPublishDepositTx extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTx.class); - - public SignAndPublishDepositTx(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - try - { - sharedModel.getWalletFacade().offererSignAndPublishTx(sharedModel.getPreparedOffererDepositTxAsHex(), - sharedModel.getSignedTakerDepositTxAsHex(), - sharedModel.getTxConnOutAsHex(), - sharedModel.getTxScriptSigAsHex(), - sharedModel.getOffererTxOutIndex(), - sharedModel.getTakerTxOutIndex(), - new FutureCallback() - { - @Override - public void onSuccess(Transaction transaction) - { - log.trace("offererSignAndPublishTx succeeded " + transaction); - sharedModel.getTrade().setDepositTransaction(transaction); - sharedModel.getListener().onDepositTxPublished(transaction.getHashAsString()); - complete(); - } - - @Override - public void onFailure(Throwable t) - { - log.error("offererSignAndPublishTx failed:" + t); - failed(t); - } - }); - } catch (Exception e) - { - log.error("offererSignAndPublishTx failed:" + e); - failed(e); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyAndSignContract.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyAndSignContract.java deleted file mode 100644 index f9afeab59f..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyAndSignContract.java +++ /dev/null @@ -1,59 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import io.bitsquare.trade.Contract; -import io.bitsquare.util.Utilities; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class VerifyAndSignContract extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(VerifyAndSignContract.class); - - public VerifyAndSignContract(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - Contract contract = new Contract(sharedModel.getTrade().getOffer(), - sharedModel.getTrade().getTradeAmount(), - sharedModel.getTrade().getTakeOfferFeeTxId(), - sharedModel.getUser().getAccountID(), - sharedModel.getPeersAccountId(), - sharedModel.getUser().getCurrentBankAccount(), - sharedModel.getPeersBankAccount(), - sharedModel.getTrade().getOffer().getMessagePubKeyAsHex(), - sharedModel.getTakerMessagePubKey()); - - String contractAsJson = Utilities.objectToJson(contract); - // log.trace("Offerer contract created: " + contract); - // log.trace("Offerers contractAsJson: " + contractAsJson); - // log.trace("Takers contractAsJson: " + sharedModel.peersContractAsJson); - if (contractAsJson.equals(sharedModel.getPeersContractAsJson())) - { - log.trace("The 2 contracts as json does match"); - String signature = sharedModel.getCryptoFacade().signContract(sharedModel.getWalletFacade().getRegistrationAddressInfo().getKey(), contractAsJson); - sharedModel.getTrade().setContract(contract); - sharedModel.getTrade().setContractAsJson(contractAsJson); - sharedModel.getTrade().setContractTakerSignature(signature); - //log.trace("signature: " + signature); - - complete(); - } - else - { - // TODO use diff output as feedback ? - log.error("Contracts are not matching."); - log.error("Offerers contractAsJson: " + contractAsJson); - log.error("Takers contractAsJson: " + sharedModel.getPeersContractAsJson()); - - failed(new Exception("Contracts are not matching")); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyTakeOfferFeePayment.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyTakeOfferFeePayment.java deleted file mode 100644 index 45cd305564..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyTakeOfferFeePayment.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class VerifyTakeOfferFeePayment extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(VerifyTakeOfferFeePayment.class); - - public VerifyTakeOfferFeePayment(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - //TODO mocked yet, need a confidence listeners - int numOfPeersSeenTx = sharedModel.getWalletFacade().getNumOfPeersSeenTx(sharedModel.getTakeOfferFeeTxId()); - if (numOfPeersSeenTx > 2) - { - complete(); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyTakerAccount.java b/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyTakerAccount.java deleted file mode 100644 index 2c8dd6d9dc..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/VerifyTakerAccount.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.bitsquare.trade.payment.offerer.tasks; - -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class VerifyTakerAccount extends AbstractOffererAsBuyerTask -{ - private static final Logger log = LoggerFactory.getLogger(VerifyTakerAccount.class); - - public VerifyTakerAccount(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - //TODO mocked yet - if (sharedModel.getBlockChainFacade().verifyAccountRegistration()) - { - if (sharedModel.getBlockChainFacade().isAccountBlackListed(sharedModel.getPeersAccountId(), sharedModel.getPeersBankAccount())) - { - log.error("Taker is blacklisted"); - failed(new Exception("Taker is blacklisted")); - } - else - { - complete(); - } - } - else - { - log.error("Account registration validation for peer failed."); - failed(new Exception("Account registration validation for peer failed.")); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/TakerAsSellerProtocolListener.java b/src/main/java/io/bitsquare/trade/payment/taker/TakerAsSellerProtocolListener.java deleted file mode 100644 index ab36809c79..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/TakerAsSellerProtocolListener.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.bitsquare.trade.payment.taker; - -import io.bitsquare.trade.Trade; - -public interface TakerAsSellerProtocolListener -{ - void onDepositTxPublished(String depositTxId); - - void onBankTransferInited(String tradeId); - - void onTradeCompleted(Trade trade, String hashAsString); -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/AbstractTakerAsSellerTask.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/AbstractTakerAsSellerTask.java deleted file mode 100644 index f395e02ee7..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/AbstractTakerAsSellerTask.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import io.bitsquare.trade.payment.taker.TakerAsSellerProtocol; -import io.nucleo.scheduler.tasks.AbstractTask; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractTakerAsSellerTask extends AbstractTask -{ - private static final Logger log = LoggerFactory.getLogger(AbstractTakerAsSellerTask.class); - - protected TakerAsSellerProtocol sharedModel; - - public AbstractTakerAsSellerTask(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - addResultHandlers(resultHandler); - addFaultHandlers(faultHandler); - } - - @Override - public void setModel(Object model) - { - sharedModel = (TakerAsSellerProtocol) model; - super.setModel(model); - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/CreateAndSignContract.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/CreateAndSignContract.java deleted file mode 100644 index a2f87eadb9..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/CreateAndSignContract.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import io.bitsquare.trade.Contract; -import io.bitsquare.trade.Trade; -import io.bitsquare.util.Utilities; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CreateAndSignContract extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(CreateAndSignContract.class); - - public CreateAndSignContract(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - Trade trade = sharedModel.getTrade(); - Contract contract = new Contract(trade.getOffer(), - trade.getTradeAmount(), - trade.getTakeOfferFeeTxId(), - sharedModel.getPeersAccountId(), - sharedModel.getUser().getAccountID(), - sharedModel.getPeersBankAccount(), - sharedModel.getUser().getCurrentBankAccount(), - trade.getOffer().getMessagePubKeyAsHex(), - sharedModel.getUser().getMessagePubKeyAsHex() - ); - - String contractAsJson = Utilities.objectToJson(contract); - String signature = sharedModel.getCryptoFacade().signContract(sharedModel.getWalletFacade().getRegistrationAddressInfo().getKey(), contractAsJson); - //log.trace("contract: " + contract); - //log.debug("contractAsJson: " + contractAsJson); - //log.trace("contract signature: " + signature); - - trade.setContract(contract); - trade.setContractAsJson(contractAsJson); - trade.setContractTakerSignature(signature); - - complete(); - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/GetPeerAddress.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/GetPeerAddress.java deleted file mode 100644 index 2588400a5f..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/GetPeerAddress.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import io.bitsquare.trade.payment.taker.listeners.GetPeerAddressListener; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import net.tomp2p.peers.PeerAddress; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class GetPeerAddress extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(GetPeerAddress.class); - - public GetPeerAddress(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - sharedModel.getMessageFacade().getPeerAddress(sharedModel.getTrade().getOffer().getMessagePubKeyAsHex(), new GetPeerAddressListener() - { - @Override - public void onResult(PeerAddress address) - { - log.trace("Received address = " + address.toString()); - sharedModel.setPeerAddress(address); - complete(); - } - - @Override - public void onFailed() - { - log.error("Lookup for peer address failed."); - failed(new Exception("Lookup for peer address failed.")); - } - }); - - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/PayDeposit.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/PayDeposit.java deleted file mode 100644 index 6ef9fb75aa..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/PayDeposit.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import com.google.bitcoin.core.InsufficientMoneyException; -import io.bitsquare.trade.Trade; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import java.math.BigInteger; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PayDeposit extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(PayDeposit.class); - - public PayDeposit(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - try - { - Trade trade = sharedModel.getTrade(); - BigInteger collateralAmount = trade.getCollateralAmount(); - sharedModel.setSignedTakerDepositTx(sharedModel.getWalletFacade().takerAddPaymentAndSignTx(trade.getTradeAmount().add(collateralAmount), - trade.getTradeAmount().add(collateralAmount).add(collateralAmount), - sharedModel.getOffererPubKey(), - sharedModel.getWalletFacade().getAddressInfoByTradeID(trade.getId()).getPubKeyAsHexString(), - trade.getOffer().getArbitrator().getPubKeyAsHex(), - sharedModel.getPreparedOffererDepositTxAsHex(), - trade.getId())); - - log.trace("sharedModel.signedTakerDepositTx: " + sharedModel.getSignedTakerDepositTx()); - sharedModel.setTakerTxOutIndex(sharedModel.getSignedTakerDepositTx().getInput(1).getOutpoint().getIndex()); - - complete(); - } catch (InsufficientMoneyException e) - { - log.error("Pay deposit failed due InsufficientMoneyException " + e); - failed(new Exception("Pay deposit failed due InsufficientMoneyException " + e)); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/PayTakeOfferFee.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/PayTakeOfferFee.java deleted file mode 100644 index 4aeb76053f..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/PayTakeOfferFee.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import com.google.bitcoin.core.InsufficientMoneyException; -import com.google.bitcoin.core.Transaction; -import com.google.common.util.concurrent.FutureCallback; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PayTakeOfferFee extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(PayTakeOfferFee.class); - - public PayTakeOfferFee(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - try - { - sharedModel.getWalletFacade().payTakeOfferFee(sharedModel.getTrade().getId(), new FutureCallback() - { - @Override - public void onSuccess(Transaction transaction) - { - log.debug("Take offer fee paid successfully. Transaction ID = " + transaction.getHashAsString()); - sharedModel.getTrade().setTakeOfferFeeTxID(transaction.getHashAsString()); - complete(); - } - - @Override - public void onFailure(Throwable t) - { - log.error("Take offer fee paid failed with exception: " + t); - failed(new Exception("Take offer fee paid failed with exception: " + t)); - } - }); - } catch (InsufficientMoneyException e) - { - log.error("Take offer fee paid failed due InsufficientMoneyException " + e); - failed(new Exception("Take offer fee paid failed due InsufficientMoneyException " + e)); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/RequestTakeOffer.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/RequestTakeOffer.java deleted file mode 100644 index 613a1b1e45..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/RequestTakeOffer.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import io.bitsquare.msg.listeners.TradeMessageListener; -import io.bitsquare.trade.payment.taker.messages.RequestTakeOfferMessage; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RequestTakeOffer extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(RequestTakeOffer.class); - - public RequestTakeOffer(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - RequestTakeOfferMessage msg = new RequestTakeOfferMessage(sharedModel.getTrade().getId()); - sharedModel.getMessageFacade().sendTradingMessage(sharedModel.getPeerAddress(), msg, new TradeMessageListener() - { - @Override - public void onResult() - { - log.trace("RequestTakeOfferMessage successfully arrived at peer"); - complete(); - } - - @Override - public void onFailed() - { - log.error("RequestTakeOfferMessage failed to arrive at peer"); - failed(new Exception("RequestTakeOfferMessage failed to arrive at peer")); - } - }); - - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendPayoutTxToOfferer.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendPayoutTxToOfferer.java deleted file mode 100644 index edc42e8ee9..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendPayoutTxToOfferer.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import io.bitsquare.msg.listeners.TradeMessageListener; -import io.bitsquare.trade.payment.taker.messages.PayoutTxPublishedMessage; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SendPayoutTxToOfferer extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(SendPayoutTxToOfferer.class); - - public SendPayoutTxToOfferer(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(sharedModel.getTrade().getId(), sharedModel.getPayoutTxAsHex()); - sharedModel.getMessageFacade().sendTradeMessage(sharedModel.getPeerAddress(), tradeMessage, new TradeMessageListener() - { - @Override - public void onResult() - { - log.trace("PayoutTxPublishedMessage successfully arrived at peer"); - complete(); - } - - @Override - public void onFailed() - { - log.error("PayoutTxPublishedMessage failed to arrive at peer"); - failed(new Exception("PayoutTxPublishedMessage failed to arrive at peer")); - } - }); - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendSignedTakerDepositTxAsHex.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendSignedTakerDepositTxAsHex.java deleted file mode 100644 index fb00c5aa29..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendSignedTakerDepositTxAsHex.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import com.google.bitcoin.core.Utils; -import io.bitsquare.msg.listeners.TradeMessageListener; -import io.bitsquare.trade.payment.taker.messages.RequestOffererPublishDepositTxMessage; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SendSignedTakerDepositTxAsHex extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(SendSignedTakerDepositTxAsHex.class); - - public SendSignedTakerDepositTxAsHex(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - - RequestOffererPublishDepositTxMessage tradeMessage = new RequestOffererPublishDepositTxMessage(sharedModel.getTrade().getId(), - sharedModel.getUser().getCurrentBankAccount(), - sharedModel.getUser().getAccountID(), - sharedModel.getUser().getMessagePubKeyAsHex(), - Utils.bytesToHexString(sharedModel.getSignedTakerDepositTx().bitcoinSerialize()), - Utils.bytesToHexString(sharedModel.getSignedTakerDepositTx().getInput(1).getScriptBytes()), - Utils.bytesToHexString(sharedModel.getSignedTakerDepositTx().getInput(1).getConnectedOutput().getParentTransaction().bitcoinSerialize()), - sharedModel.getTrade().getContractAsJson(), - sharedModel.getTrade().getTakerSignature(), - sharedModel.getWalletFacade().getAddressInfoByTradeID(sharedModel.getTrade().getId()).getAddressString(), - sharedModel.getTakerTxOutIndex(), - sharedModel.getOffererTxOutIndex() - ); - sharedModel.getMessageFacade().sendTradeMessage(sharedModel.getPeerAddress(), tradeMessage, new TradeMessageListener() - { - @Override - public void onResult() - { - log.trace("RequestOffererDepositPublicationMessage successfully arrived at peer"); - complete(); - } - - @Override - public void onFailed() - { - log.error("RequestOffererDepositPublicationMessage failed to arrive at peer"); - failed(new Exception("RequestOffererDepositPublicationMessage failed to arrive at peer")); - } - }); - } -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendTakeOfferFeePayedTxId.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendTakeOfferFeePayedTxId.java deleted file mode 100644 index a10204932d..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/SendTakeOfferFeePayedTxId.java +++ /dev/null @@ -1,46 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import io.bitsquare.msg.listeners.TradeMessageListener; -import io.bitsquare.trade.payment.taker.messages.TakeOfferFeePayedMessage; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SendTakeOfferFeePayedTxId extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(SendTakeOfferFeePayedTxId.class); - - public SendTakeOfferFeePayedTxId(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - - TakeOfferFeePayedMessage msg = new TakeOfferFeePayedMessage(sharedModel.getTrade().getId(), - sharedModel.getTrade().getTakeOfferFeeTxId(), - sharedModel.getTrade().getTradeAmount(), - sharedModel.getWalletFacade().getAddressInfoByTradeID(sharedModel.getTrade().getId()).getPubKeyAsHexString()); - - sharedModel.getMessageFacade().sendTradeMessage(sharedModel.getPeerAddress(), msg, new TradeMessageListener() - { - @Override - public void onResult() - { - log.trace("TakeOfferFeePayedMessage successfully arrived at peer"); - complete(); - } - - @Override - public void onFailed() - { - log.error("TakeOfferFeePayedMessage failed to arrive at peer"); - failed(new Exception("TakeOfferFeePayedMessage failed to arrive at peer")); - } - }); - } -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/SignAndPublishPayoutTx.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/SignAndPublishPayoutTx.java deleted file mode 100644 index c3b5cd2ff0..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/SignAndPublishPayoutTx.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import com.google.bitcoin.core.Transaction; -import com.google.bitcoin.core.Utils; -import com.google.common.util.concurrent.FutureCallback; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import java.math.BigInteger; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SignAndPublishPayoutTx extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(SignAndPublishPayoutTx.class); - - public SignAndPublishPayoutTx(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - try - { - String depositTxAsHex = sharedModel.getDepositTxAsHex(); - String offererSignatureR = sharedModel.getOffererSignatureR(); - String offererSignatureS = sharedModel.getOffererSignatureS(); - BigInteger offererPaybackAmount = sharedModel.getOffererPaybackAmount(); - BigInteger takerPaybackAmount = sharedModel.getTakerPaybackAmount(); - String offererPayoutAddress = sharedModel.getOffererPayoutAddress(); - - sharedModel.getWalletFacade().takerSignsAndSendsTx(depositTxAsHex, - offererSignatureR, - offererSignatureS, - offererPaybackAmount, - takerPaybackAmount, - offererPayoutAddress, - sharedModel.getTrade().getId(), - new FutureCallback() - { - @Override - public void onSuccess(Transaction transaction) - { - log.debug("takerSignsAndSendsTx " + transaction); - sharedModel.getListener().onTradeCompleted(sharedModel.getTrade(), transaction.getHashAsString()); - sharedModel.setPayoutTxAsHex(Utils.bytesToHexString(transaction.bitcoinSerialize())); - complete(); - } - - @Override - public void onFailure(Throwable t) - { - log.error("Exception at takerSignsAndSendsTx " + t); - failed(t); - } - }); - } catch (Exception e) - { - log.error("Exception at takerSignsAndSendsTx " + e); - failed(e); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/taker/tasks/VerifyOffererAccount.java b/src/main/java/io/bitsquare/trade/payment/taker/tasks/VerifyOffererAccount.java deleted file mode 100644 index d4a958bfed..0000000000 --- a/src/main/java/io/bitsquare/trade/payment/taker/tasks/VerifyOffererAccount.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.bitsquare.trade.payment.taker.tasks; - -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class VerifyOffererAccount extends AbstractTakerAsSellerTask -{ - private static final Logger log = LoggerFactory.getLogger(VerifyOffererAccount.class); - - public VerifyOffererAccount(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) - { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - - //TODO mocked yet - if (sharedModel.getBlockChainFacade().verifyAccountRegistration()) - { - if (sharedModel.getBlockChainFacade().isAccountBlackListed(sharedModel.getPeersAccountId(), sharedModel.getPeersBankAccount())) - { - log.error("Offerer is blacklisted"); - failed(new Exception("Offerer is blacklisted")); - } - else - { - complete(); - } - } - else - { - log.error("Account Registration for peer failed."); - failed(new Exception("Account Registration for peer failed.")); - } - } - -} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/messages/AcceptTakeOfferRequestMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/AcceptTakeOfferRequestMessage.java similarity index 89% rename from src/main/java/io/bitsquare/trade/payment/offerer/messages/AcceptTakeOfferRequestMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/offerer/AcceptTakeOfferRequestMessage.java index a5c9e6cd2b..f4876bf212 100644 --- a/src/main/java/io/bitsquare/trade/payment/offerer/messages/AcceptTakeOfferRequestMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/AcceptTakeOfferRequestMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.offerer.messages; +package io.bitsquare.trade.protocol.messages.offerer; import io.bitsquare.msg.TradeMessage; import java.io.Serializable; diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/messages/BankTransferInitedMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/BankTransferInitedMessage.java similarity index 97% rename from src/main/java/io/bitsquare/trade/payment/offerer/messages/BankTransferInitedMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/offerer/BankTransferInitedMessage.java index b974a56862..c658da20bf 100644 --- a/src/main/java/io/bitsquare/trade/payment/offerer/messages/BankTransferInitedMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/BankTransferInitedMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.offerer.messages; +package io.bitsquare.trade.protocol.messages.offerer; import io.bitsquare.msg.TradeMessage; import java.io.Serializable; diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/messages/DepositTxPublishedMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/DepositTxPublishedMessage.java similarity index 92% rename from src/main/java/io/bitsquare/trade/payment/offerer/messages/DepositTxPublishedMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/offerer/DepositTxPublishedMessage.java index 89ea3acb5b..fbbc92d7d0 100644 --- a/src/main/java/io/bitsquare/trade/payment/offerer/messages/DepositTxPublishedMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/DepositTxPublishedMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.offerer.messages; +package io.bitsquare.trade.protocol.messages.offerer; import io.bitsquare.msg.TradeMessage; import java.io.Serializable; diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/messages/RejectTakeOfferRequestMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/RejectTakeOfferRequestMessage.java similarity index 89% rename from src/main/java/io/bitsquare/trade/payment/offerer/messages/RejectTakeOfferRequestMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/offerer/RejectTakeOfferRequestMessage.java index 1ddf96842e..78ee7255d5 100644 --- a/src/main/java/io/bitsquare/trade/payment/offerer/messages/RejectTakeOfferRequestMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/RejectTakeOfferRequestMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.offerer.messages; +package io.bitsquare.trade.protocol.messages.offerer; import io.bitsquare.msg.TradeMessage; import java.io.Serializable; diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/messages/RequestTakerDepositPaymentMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/RequestTakerDepositPaymentMessage.java similarity index 96% rename from src/main/java/io/bitsquare/trade/payment/offerer/messages/RequestTakerDepositPaymentMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/offerer/RequestTakerDepositPaymentMessage.java index 75ffef0818..8fc0366e30 100644 --- a/src/main/java/io/bitsquare/trade/payment/offerer/messages/RequestTakerDepositPaymentMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/offerer/RequestTakerDepositPaymentMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.offerer.messages; +package io.bitsquare.trade.protocol.messages.offerer; import io.bitsquare.bank.BankAccount; import io.bitsquare.msg.TradeMessage; diff --git a/src/main/java/io/bitsquare/trade/payment/taker/messages/PayoutTxPublishedMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/taker/PayoutTxPublishedMessage.java similarity index 92% rename from src/main/java/io/bitsquare/trade/payment/taker/messages/PayoutTxPublishedMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/taker/PayoutTxPublishedMessage.java index 9ab494d788..f758bf0c1a 100644 --- a/src/main/java/io/bitsquare/trade/payment/taker/messages/PayoutTxPublishedMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/taker/PayoutTxPublishedMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.taker.messages; +package io.bitsquare.trade.protocol.messages.taker; import io.bitsquare.msg.TradeMessage; import java.io.Serializable; diff --git a/src/main/java/io/bitsquare/trade/payment/taker/messages/RequestOffererPublishDepositTxMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/taker/RequestOffererPublishDepositTxMessage.java similarity index 98% rename from src/main/java/io/bitsquare/trade/payment/taker/messages/RequestOffererPublishDepositTxMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/taker/RequestOffererPublishDepositTxMessage.java index 2030d05c02..40405e2e8c 100644 --- a/src/main/java/io/bitsquare/trade/payment/taker/messages/RequestOffererPublishDepositTxMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/taker/RequestOffererPublishDepositTxMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.taker.messages; +package io.bitsquare.trade.protocol.messages.taker; import io.bitsquare.bank.BankAccount; import io.bitsquare.msg.TradeMessage; diff --git a/src/main/java/io/bitsquare/trade/payment/taker/messages/RequestTakeOfferMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/taker/RequestTakeOfferMessage.java similarity index 89% rename from src/main/java/io/bitsquare/trade/payment/taker/messages/RequestTakeOfferMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/taker/RequestTakeOfferMessage.java index f60d3997e3..df30ef586d 100644 --- a/src/main/java/io/bitsquare/trade/payment/taker/messages/RequestTakeOfferMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/taker/RequestTakeOfferMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.taker.messages; +package io.bitsquare.trade.protocol.messages.taker; import io.bitsquare.msg.TradeMessage; import java.io.Serializable; diff --git a/src/main/java/io/bitsquare/trade/payment/taker/messages/TakeOfferFeePayedMessage.java b/src/main/java/io/bitsquare/trade/protocol/messages/taker/TakeOfferFeePayedMessage.java similarity index 91% rename from src/main/java/io/bitsquare/trade/payment/taker/messages/TakeOfferFeePayedMessage.java rename to src/main/java/io/bitsquare/trade/protocol/messages/taker/TakeOfferFeePayedMessage.java index ee74602853..1974bb542c 100644 --- a/src/main/java/io/bitsquare/trade/payment/taker/messages/TakeOfferFeePayedMessage.java +++ b/src/main/java/io/bitsquare/trade/protocol/messages/taker/TakeOfferFeePayedMessage.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.taker.messages; +package io.bitsquare.trade.protocol.messages.taker; import io.bitsquare.msg.TradeMessage; import java.io.Serializable; @@ -32,7 +32,7 @@ public class TakeOfferFeePayedMessage implements Serializable, TradeMessage return tradeAmount; } - public String getTakeOfferFeeTxID() + public String getTakeOfferFeeTxId() { return takeOfferFeeTxID; } diff --git a/src/main/java/io/bitsquare/trade/payment/process/BuyOffererPaymentProcess.java b/src/main/java/io/bitsquare/trade/protocol/mock/BuyOffererPaymentProcess.java similarity index 95% rename from src/main/java/io/bitsquare/trade/payment/process/BuyOffererPaymentProcess.java rename to src/main/java/io/bitsquare/trade/protocol/mock/BuyOffererPaymentProcess.java index 9bf05ea20c..9acc86d0de 100644 --- a/src/main/java/io/bitsquare/trade/payment/process/BuyOffererPaymentProcess.java +++ b/src/main/java/io/bitsquare/trade/protocol/mock/BuyOffererPaymentProcess.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.process; +package io.bitsquare.trade.protocol.mock; //TODO not used but let it for reference until all use cases are impl. class BuyOffererPaymentProcess extends PaymentProcess diff --git a/src/main/java/io/bitsquare/trade/payment/process/BuyTakerPaymentProcess.java b/src/main/java/io/bitsquare/trade/protocol/mock/BuyTakerPaymentProcess.java similarity index 94% rename from src/main/java/io/bitsquare/trade/payment/process/BuyTakerPaymentProcess.java rename to src/main/java/io/bitsquare/trade/protocol/mock/BuyTakerPaymentProcess.java index 2c72772946..28c44db0f9 100644 --- a/src/main/java/io/bitsquare/trade/payment/process/BuyTakerPaymentProcess.java +++ b/src/main/java/io/bitsquare/trade/protocol/mock/BuyTakerPaymentProcess.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.process; +package io.bitsquare.trade.protocol.mock; //TODO not used but let it for reference until all use cases are impl. public class BuyTakerPaymentProcess extends PaymentProcess diff --git a/src/main/java/io/bitsquare/trade/payment/process/PaymentProcess.java b/src/main/java/io/bitsquare/trade/protocol/mock/PaymentProcess.java similarity index 99% rename from src/main/java/io/bitsquare/trade/payment/process/PaymentProcess.java rename to src/main/java/io/bitsquare/trade/protocol/mock/PaymentProcess.java index 6c1e14c2b5..078c838505 100644 --- a/src/main/java/io/bitsquare/trade/payment/process/PaymentProcess.java +++ b/src/main/java/io/bitsquare/trade/protocol/mock/PaymentProcess.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.process; +package io.bitsquare.trade.protocol.mock; import com.google.inject.Inject; import io.bitsquare.btc.BlockChainFacade; diff --git a/src/main/java/io/bitsquare/trade/payment/process/SellOffererPaymentProcess.java b/src/main/java/io/bitsquare/trade/protocol/mock/SellOffererPaymentProcess.java similarity index 95% rename from src/main/java/io/bitsquare/trade/payment/process/SellOffererPaymentProcess.java rename to src/main/java/io/bitsquare/trade/protocol/mock/SellOffererPaymentProcess.java index a1e94a39d0..e643a4f85f 100644 --- a/src/main/java/io/bitsquare/trade/payment/process/SellOffererPaymentProcess.java +++ b/src/main/java/io/bitsquare/trade/protocol/mock/SellOffererPaymentProcess.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.process; +package io.bitsquare.trade.protocol.mock; //TODO not used but let it for reference until all use cases are impl. class SellOffererPaymentProcess extends PaymentProcess diff --git a/src/main/java/io/bitsquare/trade/payment/process/SellTakerPaymentProcess.java b/src/main/java/io/bitsquare/trade/protocol/mock/SellTakerPaymentProcess.java similarity index 95% rename from src/main/java/io/bitsquare/trade/payment/process/SellTakerPaymentProcess.java rename to src/main/java/io/bitsquare/trade/protocol/mock/SellTakerPaymentProcess.java index 0c5ca27dcf..e265638f5d 100644 --- a/src/main/java/io/bitsquare/trade/payment/process/SellTakerPaymentProcess.java +++ b/src/main/java/io/bitsquare/trade/protocol/mock/SellTakerPaymentProcess.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.process; +package io.bitsquare.trade.protocol.mock; //TODO not used but let it for reference until all use cases are impl. class SellTakerPaymentProcess extends PaymentProcess diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/OffererAsBuyerProtocol.java b/src/main/java/io/bitsquare/trade/protocol/offerer/OffererAsBuyerProtocol.java similarity index 72% rename from src/main/java/io/bitsquare/trade/payment/offerer/OffererAsBuyerProtocol.java rename to src/main/java/io/bitsquare/trade/protocol/offerer/OffererAsBuyerProtocol.java index 8a1eb8e1b0..a003dc55de 100644 --- a/src/main/java/io/bitsquare/trade/payment/offerer/OffererAsBuyerProtocol.java +++ b/src/main/java/io/bitsquare/trade/protocol/offerer/OffererAsBuyerProtocol.java @@ -1,26 +1,27 @@ -package io.bitsquare.trade.payment.offerer; +package io.bitsquare.trade.protocol.offerer; +import com.google.bitcoin.core.ECKey; +import com.google.bitcoin.core.Transaction; import io.bitsquare.bank.BankAccount; import io.bitsquare.btc.BlockChainFacade; import io.bitsquare.btc.WalletFacade; import io.bitsquare.crypto.CryptoFacade; import io.bitsquare.msg.MessageFacade; +import io.bitsquare.trade.Contract; +import io.bitsquare.trade.Offer; import io.bitsquare.trade.Trade; -import io.bitsquare.trade.payment.offerer.tasks.*; -import io.bitsquare.trade.payment.taker.messages.PayoutTxPublishedMessage; -import io.bitsquare.trade.payment.taker.messages.RequestOffererPublishDepositTxMessage; -import io.bitsquare.trade.payment.taker.messages.TakeOfferFeePayedMessage; +import io.bitsquare.trade.protocol.messages.taker.PayoutTxPublishedMessage; +import io.bitsquare.trade.protocol.messages.taker.RequestOffererPublishDepositTxMessage; +import io.bitsquare.trade.protocol.messages.taker.TakeOfferFeePayedMessage; +import io.bitsquare.trade.protocol.tasks.offerer.*; import io.bitsquare.user.User; -import io.nucleo.scheduler.SequenceScheduler; -import io.nucleo.scheduler.worker.Worker; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import java.util.ArrayList; -import java.util.List; +import java.math.BigInteger; import net.tomp2p.peers.PeerAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static com.google.common.base.Preconditions.*; + //TODO refactor to process based pattern public class OffererAsBuyerProtocol { @@ -31,19 +32,22 @@ public class OffererAsBuyerProtocol private final String id; private final Trade trade; private final OffererAsBuyerProtocolListener listener; - private final WorkerResultHandler resultHandler; - private final WorkerFaultHandler faultHandler; private final MessageFacade messageFacade; private final WalletFacade walletFacade; private final BlockChainFacade blockChainFacade; private final CryptoFacade cryptoFacade; private final User user; + private final String tradeId; + private final Offer offer; + + // private - private final SequenceScheduler scheduler_1; + private State state; + // data written/read by tasks private String preparedOffererDepositTxAsHex; private long offererTxOutIndex; - private String offererPubKey; + // data written by messages, read by tasks private String takeOfferFeeTxId; private String takerMultiSigPubKey; @@ -56,14 +60,6 @@ public class OffererAsBuyerProtocol private String txConnOutAsHex; private String txScriptSigAsHex; private long takerTxOutIndex; - private SequenceScheduler scheduler_2; - private SequenceScheduler scheduler_3; - private SequenceScheduler scheduler_4; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor - /////////////////////////////////////////////////////////////////////////////////////////// public OffererAsBuyerProtocol(Trade trade, PeerAddress peerAddress, @@ -72,15 +68,11 @@ public class OffererAsBuyerProtocol BlockChainFacade blockChainFacade, CryptoFacade cryptoFacade, User user, - WorkerResultHandler resultHandler, - WorkerFaultHandler faultHandler, OffererAsBuyerProtocolListener listener) { this.trade = trade; this.peerAddress = peerAddress; this.listener = listener; - this.resultHandler = resultHandler; - this.faultHandler = faultHandler; this.messageFacade = messageFacade; this.walletFacade = walletFacade; this.blockChainFacade = blockChainFacade; @@ -89,43 +81,166 @@ public class OffererAsBuyerProtocol id = trade.getId(); - messageFacade.addOffererPaymentProtocol(this); + tradeId = trade.getId(); + offer = trade.getOffer(); - log.debug("OffererAsBuyerProtocol created"); + state = State.Start; + } - List tasks = new ArrayList<>(); - tasks.add(new HandleTakeOfferRequest(resultHandler, faultHandler)); - scheduler_1 = new SequenceScheduler(tasks, this); - scheduler_1.execute(); + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////// + // Instantiation is triggered by an incoming message from peer + /////////////////////////////////////////////////////////////////////////////////////////// + + public void start() + { + HandleTakeOfferRequest.run(this::onResultHandleTakeOfferRequest, this::onFaultHandleTakeOfferRequest, peerAddress, messageFacade, trade.getState(), tradeId); + state = State.HandleTakeOfferRequest; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultHandleTakeOfferRequest(Trade.State tradeState) + { + checkState(tradeState == Trade.State.ACCEPTED); + + listener.onOfferAccepted(offer); + trade.setState(tradeState); + + messageFacade.removeOffer(offer); + + // waiting for incoming msg from peer (-> onTakeOfferFeePayedMessage) + } + + public void onFaultHandleTakeOfferRequest(Throwable throwable) + { + // TODO } public void onTakeOfferFeePayedMessage(TakeOfferFeePayedMessage message) { log.debug("onTakeOfferFeePayedMessage"); - getTrade().setTakeOfferFeeTxID(message.getTakeOfferFeeTxID()); - getTrade().setTradeAmount(message.getTradeAmount()); - takeOfferFeeTxId = message.getTakeOfferFeeTxID(); - takerMultiSigPubKey = message.getTakerMultiSigPubKey(); + checkState(state == State.HandleTakeOfferRequest); - if (scheduler_1.getHasCompleted()) - { - List tasks = new ArrayList<>(); - tasks.add(new VerifyTakeOfferFeePayment(getResultHandler(), getFaultHandler())); - tasks.add(new CreateDepositTx(getResultHandler(), getFaultHandler())); - tasks.add(new RequestTakerDepositPayment(getResultHandler(), getFaultHandler())); - scheduler_2 = new SequenceScheduler(tasks, this); - scheduler_2.execute(); - } - else - { - log.error("scheduler_1 has not completed yet."); - } + String takeOfferFeeTxId = message.getTakeOfferFeeTxId(); + BigInteger tradeAmount = message.getTradeAmount(); + String takerMultiSigPubKey = message.getTakerMultiSigPubKey(); + + // validate input + checkNotNull(takeOfferFeeTxId); + checkArgument(takeOfferFeeTxId.length() > 0); + + checkNotNull(tradeAmount); + // TODO make validator for amounts with testing against trades amount range + //checkArgument(bigIntegerValidator.isValue(tradeAmount).inRangeOf(trade.getMinAmount(), trade.getAmount())); + + checkNotNull(takerMultiSigPubKey); + checkArgument(takerMultiSigPubKey.length() > 0); + + state = State.onTakeOfferFeePayedMessage; + + this.takeOfferFeeTxId = takeOfferFeeTxId; + this.takerMultiSigPubKey = takerMultiSigPubKey; + trade.setTakeOfferFeeTxID(takeOfferFeeTxId); + trade.setTradeAmount(tradeAmount); + + sequence2(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Incoming message from peer + /////////////////////////////////////////////////////////////////////////////////////////// + + private void sequence2() + { + VerifyTakeOfferFeePayment.run(this::onResultVerifyTakeOfferFeePayment, this::onFaultVerifyTakeOfferFeePayment, walletFacade, takeOfferFeeTxId); + state = State.VerifyTakeOfferFeePayment; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultVerifyTakeOfferFeePayment() + { + BigInteger collateralAmount = trade.getCollateralAmount(); + String arbitratorPubKeyAsHex = offer.getArbitrator().getPubKeyAsHex(); + + CreateDepositTx.run(this::onResultCreateDepositTx, + this::onFaultCreateDepositTx, + walletFacade, + tradeId, + collateralAmount, + takerMultiSigPubKey, + arbitratorPubKeyAsHex); + + state = State.CreateDepositTx; + } + + public void onFaultVerifyTakeOfferFeePayment(Throwable throwable) + { + // TODO + } + + public void onResultCreateDepositTx(String offererPubKey, String preparedOffererDepositTxAsHex, long offererTxOutIndex) + { + this.preparedOffererDepositTxAsHex = preparedOffererDepositTxAsHex; + this.offererTxOutIndex = offererTxOutIndex; + + BankAccount bankAccount = user.getBankAccount(trade.getOffer().getBankAccountId()); + String accountId = user.getAccountId(); + + RequestTakerDepositPayment.run(this::onResultRequestTakerDepositPayment, + this::onFaultRequestTakerDepositPayment, + peerAddress, + messageFacade, + tradeId, + bankAccount, + accountId, + offererPubKey, + preparedOffererDepositTxAsHex, + offererTxOutIndex); + + state = State.RequestTakerDepositPayment; + } + + public void onFaultCreateDepositTx(Throwable throwable) + { + // TODO + } + + public void onResultRequestTakerDepositPayment() + { + // waiting for incoming msg from peer (-> onRequestOffererPublishDepositTxMessage) + } + + public void onFaultRequestTakerDepositPayment(Throwable throwable) + { + // TODO } public void onRequestOffererPublishDepositTxMessage(RequestOffererPublishDepositTxMessage message) { log.debug("onRequestOffererPublishDepositTxMessage"); + + checkState(state == State.RequestTakerDepositPayment); + + checkNotNull(message); + + //TODO validation + + state = State.onRequestOffererPublishDepositTxMessage; + + //TODO takerPayoutAddress = message.getTakerPayoutAddress(); peersAccountId = message.getAccountId(); peersBankAccount = message.getBankAccount(); @@ -136,50 +251,172 @@ public class OffererAsBuyerProtocol txScriptSigAsHex = message.getTxScriptSigAsHex(); takerTxOutIndex = message.getTakerTxOutIndex(); - if (scheduler_2.getHasCompleted()) - { - List tasks = new ArrayList<>(); - tasks.add(new VerifyTakerAccount(getResultHandler(), getFaultHandler())); - tasks.add(new VerifyAndSignContract(getResultHandler(), getFaultHandler())); - tasks.add(new SignAndPublishDepositTx(getResultHandler(), getFaultHandler())); - tasks.add(new SendDepositTxIdToTaker(getResultHandler(), getFaultHandler())); - tasks.add(new SetupListenerForBlockChainConfirmation(getResultHandler(), getFaultHandler())); - scheduler_3 = new SequenceScheduler(tasks, this); - scheduler_3.execute(); - } - else - { - log.error("scheduler_2 has not completed yet."); - } + sequence3(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Incoming message from peer + /////////////////////////////////////////////////////////////////////////////////////////// + + public void sequence3() + { + VerifyTakerAccount.run(this::onResultVerifyTakerAccount, this::onFaultVerifyTakerAccount, blockChainFacade, peersAccountId, peersBankAccount); + state = State.VerifyTakerAccount; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultVerifyTakerAccount() + { + String accountId = user.getAccountId(); + BigInteger tradeAmount = trade.getTradeAmount(); + String messagePubKeyAsHex = user.getMessagePubKeyAsHex(); + BankAccount bankAccount = user.getBankAccount(offer.getBankAccountId()); + ECKey registrationKey = walletFacade.getRegistrationAddressInfo().getKey(); + + VerifyAndSignContract.run(this::onResultVerifyAndSignContract, + this::onFaultVerifyAndSignContract, + cryptoFacade, + accountId, + tradeAmount, + takeOfferFeeTxId, + messagePubKeyAsHex, + offer, + peersAccountId, + bankAccount, + peersBankAccount, + takerMessagePubKey, + peersContractAsJson, + registrationKey); + + state = State.VerifyAndSignContract; + } + + public void onFaultVerifyTakerAccount(Throwable throwable) + { + // TODO + } + + public void onResultVerifyAndSignContract(Contract contract, String contractAsJson, String signature) + { + trade.setContract(contract); + trade.setContractAsJson(contractAsJson); + trade.setContractTakerSignature(signature); + + SignAndPublishDepositTx.run(this::onResultSignAndPublishDepositTx, + this::onFaultSignAndPublishDepositTx, + walletFacade, + preparedOffererDepositTxAsHex, + signedTakerDepositTxAsHex, + txConnOutAsHex, + txScriptSigAsHex, + offererTxOutIndex, + takerTxOutIndex); + state = State.SignAndPublishDepositTx; + } + + public void onFaultVerifyAndSignContract(Throwable throwable) + { + // TODO + } + + public void onResultSignAndPublishDepositTx(Transaction transaction) + { + trade.setDepositTransaction(transaction); + listener.onDepositTxPublished(transaction.getHashAsString()); + + SendDepositTxIdToTaker.run(this::onResultSendDepositTxIdToTaker, this::onFaultSendDepositTxIdToTaker, peerAddress, messageFacade, trade); + state = State.SendDepositTxIdToTaker; + } + + public void onFaultSignAndPublishDepositTx(Throwable throwable) + { + // TODO + } + + public void onResultSendDepositTxIdToTaker() + { + SetupListenerForBlockChainConfirmation.run(this::onResultSetupListenerForBlockChainConfirmation, this::onFaultSetupListenerForBlockChainConfirmation, trade.getDepositTransaction(), listener); + state = State.SetupListenerForBlockChainConfirmation; + } + + public void onFaultSendDepositTxIdToTaker(Throwable throwable) + { + // TODO + } + + public void onResultSetupListenerForBlockChainConfirmation() + { + // waiting for UI event (-> bankTransferInited) + } + + public void onFaultSetupListenerForBlockChainConfirmation(Throwable throwable) + { + // TODO } // Triggered from UI event: Button click "Bank transfer inited" public void onUIEventBankTransferInited() { - log.debug("onUIEventBankTransferInited"); + log.debug("bankTransferInited"); - if (scheduler_3.getHasCompleted()) + + if (state == State.SetupListenerForBlockChainConfirmation) { - List tasks = new ArrayList<>(); - tasks.add(new SendSignedPayoutTx(getResultHandler(), getFaultHandler())); - scheduler_4 = new SequenceScheduler(tasks, this); - scheduler_4.execute(); + state = State.onUIEventBankTransferInited; + sequence4(); } else { - log.error("scheduler_3 has not completed yet."); + log.error("Invalid state. Actual state is: " + state); } } + /////////////////////////////////////////////////////////////////////////////////////////// + // UI event + /////////////////////////////////////////////////////////////////////////////////////////// + + public void sequence4() + { + SendSignedPayoutTx.run(this::onResultSendSignedPayoutTx, this::onFaultSendSignedPayoutTx, peerAddress, messageFacade, walletFacade, trade, takerPayoutAddress); + state = State.SendSignedPayoutTx; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultSendSignedPayoutTx() + { // waiting for incoming msg from peer (-> onPayoutTxPublishedMessage) + } + + public void onFaultSendSignedPayoutTx(Throwable throwable) + { + // TODO + } + public void onPayoutTxPublishedMessage(PayoutTxPublishedMessage tradeMessage) { log.debug("onPayoutTxPublishedMessage"); - listener.onPayoutTxPublished(tradeMessage.getPayoutTxAsHex()); + if (state == State.SendSignedPayoutTx) + { + state = State.onPayoutTxPublishedMessage; + listener.onPayoutTxPublished(tradeMessage.getPayoutTxAsHex()); + } + else + { + log.error("Invalid state. Actual state is: " + state); + } + } - /////////////////////////////////////////////////////////////////////////////////////////// - // Getters, Setters + // Incoming message from peer /////////////////////////////////////////////////////////////////////////////////////////// public String getId() @@ -187,134 +424,35 @@ public class OffererAsBuyerProtocol return id; } - public String getTakeOfferFeeTxId() - { - return takeOfferFeeTxId; - } - public String getTakerMultiSigPubKey() - { - return takerMultiSigPubKey; - } + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters, Setters + /////////////////////////////////////////////////////////////////////////////////////////// - public String getTakerPayoutAddress() + enum State { - return takerPayoutAddress; - } + Start, + HandleTakeOfferRequest, - public String getPeersAccountId() - { - return peersAccountId; - } + onTakeOfferFeePayedMessage, - public BankAccount getPeersBankAccount() - { - return peersBankAccount; - } + VerifyTakeOfferFeePayment, + CreateDepositTx, + RequestTakerDepositPayment, - public String getTakerMessagePubKey() - { - return takerMessagePubKey; - } + onRequestOffererPublishDepositTxMessage, - public String getPeersContractAsJson() - { - return peersContractAsJson; - } + VerifyTakerAccount, + VerifyAndSignContract, + SignAndPublishDepositTx, + SendDepositTxIdToTaker, + SetupListenerForBlockChainConfirmation, - public String getSignedTakerDepositTxAsHex() - { - return signedTakerDepositTxAsHex; - } + onUIEventBankTransferInited, - public String getTxConnOutAsHex() - { - return txConnOutAsHex; - } + SendSignedPayoutTx, - public String getTxScriptSigAsHex() - { - return txScriptSigAsHex; - } - - public long getTakerTxOutIndex() - { - return takerTxOutIndex; - } - - public String getPreparedOffererDepositTxAsHex() - { - return preparedOffererDepositTxAsHex; - } - - public void setPreparedOffererDepositTxAsHex(String preparedOffererDepositTxAsHex) - { - this.preparedOffererDepositTxAsHex = preparedOffererDepositTxAsHex; - } - - public long getOffererTxOutIndex() - { - return offererTxOutIndex; - } - - public void setOffererTxOutIndex(long offererTxOutIndex) - { - this.offererTxOutIndex = offererTxOutIndex; - } - - public String getOffererPubKey() - { - return offererPubKey; - } - - public void setOffererPubKey(String offererPubKey) - { - this.offererPubKey = offererPubKey; - } - - public Trade getTrade() - { - return trade; - } - - public OffererAsBuyerProtocolListener getListener() - { - return listener; - } - - public WorkerResultHandler getResultHandler() - { - return resultHandler; - } - - public WorkerFaultHandler getFaultHandler() - { - return faultHandler; - } - - public MessageFacade getMessageFacade() - { - return messageFacade; - } - - public WalletFacade getWalletFacade() - { - return walletFacade; - } - - public BlockChainFacade getBlockChainFacade() - { - return blockChainFacade; - } - - public CryptoFacade getCryptoFacade() - { - return cryptoFacade; - } - - public User getUser() - { - return user; + onPayoutTxPublishedMessage } @@ -506,7 +644,7 @@ public class OffererAsBuyerProtocol // offererPaymentProtocolListener.onProgress(getProgress()); - BankAccount bankAccount = user.getBankAccount(offer.getBankAccountUID()); + BankAccount bankAccount = user.getBankAccount(offer.getBankAccountId()); String accountID = user.getAccountId(); TradeMessageOld tradeMessage = new TradeMessageOld(TradeMessageType.REQUEST_TAKER_DEPOSIT_PAYMENT, trade.getId(), bankAccount, accountID, offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex); @@ -566,8 +704,8 @@ public class OffererAsBuyerProtocol Contract contract = new Contract(offer, trade.getTradeAmount(), trade.getTakeOfferFeeTxId(), - user.getAccountID(), - requestTradeMessage.getAccountID(), + user.getAccountId(), + requestTradeMessage.getAccountId(), user.getCurrentBankAccount(), requestTradeMessage.getBankAccount(), offer.getMessagePubKeyAsHex(), diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/OffererAsBuyerProtocolListener.java b/src/main/java/io/bitsquare/trade/protocol/offerer/OffererAsBuyerProtocolListener.java similarity index 73% rename from src/main/java/io/bitsquare/trade/payment/offerer/OffererAsBuyerProtocolListener.java rename to src/main/java/io/bitsquare/trade/protocol/offerer/OffererAsBuyerProtocolListener.java index 67c3712261..ebe45be1c1 100644 --- a/src/main/java/io/bitsquare/trade/payment/offerer/OffererAsBuyerProtocolListener.java +++ b/src/main/java/io/bitsquare/trade/protocol/offerer/OffererAsBuyerProtocolListener.java @@ -1,9 +1,12 @@ -package io.bitsquare.trade.payment.offerer; +package io.bitsquare.trade.protocol.offerer; import com.google.bitcoin.core.TransactionConfidence; +import io.bitsquare.trade.Offer; public interface OffererAsBuyerProtocolListener { + void onOfferAccepted(Offer offer); + void onDepositTxPublished(String depositTxID); void onDepositTxConfirmedInBlockchain(); diff --git a/src/main/java/io/bitsquare/trade/payment/taker/TakerAsSellerProtocol.java b/src/main/java/io/bitsquare/trade/protocol/taker/TakerAsSellerProtocol.java similarity index 74% rename from src/main/java/io/bitsquare/trade/payment/taker/TakerAsSellerProtocol.java rename to src/main/java/io/bitsquare/trade/protocol/taker/TakerAsSellerProtocol.java index 43b2739882..1b4491a89c 100644 --- a/src/main/java/io/bitsquare/trade/payment/taker/TakerAsSellerProtocol.java +++ b/src/main/java/io/bitsquare/trade/protocol/taker/TakerAsSellerProtocol.java @@ -1,4 +1,4 @@ -package io.bitsquare.trade.payment.taker; +package io.bitsquare.trade.protocol.taker; import com.google.bitcoin.core.Transaction; import io.bitsquare.bank.BankAccount; @@ -6,42 +6,36 @@ import io.bitsquare.btc.BlockChainFacade; import io.bitsquare.btc.WalletFacade; import io.bitsquare.crypto.CryptoFacade; import io.bitsquare.msg.MessageFacade; +import io.bitsquare.trade.Offer; import io.bitsquare.trade.Trade; -import io.bitsquare.trade.payment.offerer.messages.BankTransferInitedMessage; -import io.bitsquare.trade.payment.offerer.messages.DepositTxPublishedMessage; -import io.bitsquare.trade.payment.offerer.messages.RequestTakerDepositPaymentMessage; -import io.bitsquare.trade.payment.taker.tasks.*; +import io.bitsquare.trade.protocol.messages.offerer.BankTransferInitedMessage; +import io.bitsquare.trade.protocol.messages.offerer.DepositTxPublishedMessage; +import io.bitsquare.trade.protocol.messages.offerer.RequestTakerDepositPaymentMessage; +import io.bitsquare.trade.protocol.tasks.taker.*; import io.bitsquare.user.User; -import io.nucleo.scheduler.SequenceScheduler; -import io.nucleo.scheduler.worker.Worker; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; import net.tomp2p.peers.PeerAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -//TODO use states -@SuppressWarnings("ConstantConditions") +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.bitsquare.util.Validator.*; + public class TakerAsSellerProtocol { private static final Logger log = LoggerFactory.getLogger(TakerAsSellerProtocol.class); - // provided data - private final String id; private final Trade trade; private final TakerAsSellerProtocolListener listener; - private final WorkerResultHandler resultHandler; - private final WorkerFaultHandler faultHandler; private final MessageFacade messageFacade; private final WalletFacade walletFacade; private final BlockChainFacade blockChainFacade; private final CryptoFacade cryptoFacade; private final User user; - // private - private final SequenceScheduler scheduler_1; + private final String id; + private final Offer offer; + private final String tradeId; // written/read by task private String payoutTxAsHex; private PeerAddress peerAddress; @@ -59,20 +53,11 @@ public class TakerAsSellerProtocol private BigInteger offererPaybackAmount; private BigInteger takerPaybackAmount; private String offererPayoutAddress; - private int currentStep = 0; - private SequenceScheduler scheduler_2; - private SequenceScheduler scheduler_3; - private SequenceScheduler scheduler_4; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor - /////////////////////////////////////////////////////////////////////////////////////////// + //private + private State state; public TakerAsSellerProtocol(Trade trade, TakerAsSellerProtocolListener listener, - WorkerResultHandler resultHandler, - WorkerFaultHandler faultHandler, MessageFacade messageFacade, WalletFacade walletFacade, BlockChainFacade blockChainFacade, @@ -81,263 +66,301 @@ public class TakerAsSellerProtocol { this.trade = trade; this.listener = listener; - this.resultHandler = resultHandler; - this.faultHandler = faultHandler; this.messageFacade = messageFacade; this.walletFacade = walletFacade; this.blockChainFacade = blockChainFacade; this.cryptoFacade = cryptoFacade; this.user = user; + offer = trade.getOffer(); + tradeId = trade.getId(); + id = trade.getId(); + state = State.Init; + } - log.debug("TakerAsSellerProtocol created"); - messageFacade.addTakerPaymentProtocol(this); + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// - // start with first task sequence - List tasks = new ArrayList<>(); - tasks.add(new GetPeerAddress(resultHandler, faultHandler)); - tasks.add(new RequestTakeOffer(resultHandler, faultHandler)); - scheduler_1 = new SequenceScheduler(tasks, this); - scheduler_1.execute(); + // generic fault handler + public void onFault(Throwable throwable) + { + listener.onFault(throwable, state); + } + + public void start() + { + String messagePubKeyAsHex = validString(offer.getMessagePubKeyAsHex()); + + GetPeerAddress.run(this::onResultGetPeerAddress, this::onFault, messageFacade, messagePubKeyAsHex); + state = State.GetPeerAddress; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultGetPeerAddress(PeerAddress peerAddress) + { + this.peerAddress = validPeerAddress(peerAddress); + + RequestTakeOffer.run(this::onResultRequestTakeOffer, this::onFault, this.peerAddress, messageFacade, tradeId); + state = State.RequestTakeOffer; + } + + public void onResultRequestTakeOffer() + { + listener.onWaitingForPeerResponse(state); } public void onAcceptTakeOfferRequestMessage() { log.debug("onAcceptTakeOfferRequestMessage"); - if (scheduler_1.getHasCompleted()) - { - List tasks = new ArrayList<>(); - tasks.add(new PayTakeOfferFee(resultHandler, faultHandler)); - tasks.add(new SendTakeOfferFeePayedTxId(resultHandler, faultHandler)); - scheduler_2 = new SequenceScheduler(tasks, this); - scheduler_2.execute(); - } - else - { - log.error("scheduler_1 has not completed yet."); - } + checkState(state == State.RequestTakeOffer); + + PayTakeOfferFee.run(this::onResultPayTakeOfferFee, this::onFault, walletFacade, tradeId); + state = State.PayTakeOfferFee; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Incoming message from peer + /////////////////////////////////////////////////////////////////////////////////////////// + + // OR public void onRejectTakeOfferRequestMessage() { log.debug("onRejectTakeOfferRequestMessage"); - if (scheduler_1.getHasCompleted()) - { - //TODO - } - else - { - log.error("scheduler_1 has not completed yet."); - } + checkState(state == State.RequestTakeOffer); + + state = State.onRejectTakeOfferRequestMessage; + listener.onTakeOfferRequestRejected(trade); + } + + public void onResultPayTakeOfferFee(Transaction transaction) + { + checkNotNull(transaction); + String transactionId = validString(transaction.getHashAsString()); + + trade.setTakeOfferFeeTxID(transactionId); + + String takeOfferFeeTxId = trade.getTakeOfferFeeTxId(); + BigInteger tradeAmount = trade.getTradeAmount(); + String pubKeyAsHexString = walletFacade.getAddressInfoByTradeID(tradeId).getPubKeyAsHexString(); + + SendTakeOfferFeePayedTxId.run(this::onResultSendTakeOfferFeePayedTxId, + this::onFault, + peerAddress, + messageFacade, + tradeId, + takeOfferFeeTxId, + tradeAmount, + pubKeyAsHexString); + state = State.SendTakeOfferFeePayedTxId; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultSendTakeOfferFeePayedTxId() + { + listener.onWaitingForPeerResponse(state); } public void onRequestTakerDepositPaymentMessage(RequestTakerDepositPaymentMessage message) { log.debug("onRequestTakerDepositPaymentMessage"); - peersAccountId = message.getAccountID(); - peersBankAccount = message.getBankAccount(); - offererPubKey = message.getOffererPubKey(); - preparedOffererDepositTxAsHex = message.getPreparedOffererDepositTxAsHex(); - offererTxOutIndex = message.getOffererTxOutIndex(); - if (scheduler_2.getHasCompleted()) - { - List tasks = new ArrayList<>(); - tasks.add(new VerifyOffererAccount(resultHandler, faultHandler)); - tasks.add(new CreateAndSignContract(resultHandler, faultHandler)); - tasks.add(new PayDeposit(resultHandler, faultHandler)); - tasks.add(new SendSignedTakerDepositTxAsHex(resultHandler, faultHandler)); - scheduler_3 = new SequenceScheduler(tasks, this); - scheduler_3.execute(); - } - else - { - log.error("scheduler_2 has not completed yet."); - } + checkState(state == State.SendTakeOfferFeePayedTxId); + + peersAccountId = validString(message.getAccountID()); + peersBankAccount = checkNotNull(message.getBankAccount()); + offererPubKey = validString(message.getOffererPubKey()); + preparedOffererDepositTxAsHex = validString(message.getPreparedOffererDepositTxAsHex()); + offererTxOutIndex = validNonNegativeLong(message.getOffererTxOutIndex()); + + VerifyOffererAccount.run(this::onResultVerifyOffererAccount, + this::onFault, + blockChainFacade, + peersAccountId, + peersBankAccount); + state = State.VerifyOffererAccount; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Incoming message from peer + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultVerifyOffererAccount() + { + CreateAndSignContract.run(this::onResultCreateAndSignContract, + this::onFault, + cryptoFacade, + trade, + user, + peersAccountId, + peersBankAccount, + walletFacade.getRegistrationAddressInfo().getKey()); + state = State.CreateAndSignContract; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultCreateAndSignContract() + { + PayDeposit.run(this::onResultPayDeposit, this::onFault, walletFacade, trade, offererPubKey, preparedOffererDepositTxAsHex); + state = State.PayDeposit; + } + + public void onResultPayDeposit(Transaction signedTakerDepositTx, long takerTxOutIndex) + { + SendSignedTakerDepositTxAsHex.run(this::onResultSendSignedTakerDepositTxAsHex, + this::onFault, + peerAddress, + messageFacade, + walletFacade, + trade, + user, + signedTakerDepositTx, + takerTxOutIndex, + offererTxOutIndex); + state = State.SendSignedTakerDepositTxAsHex; + } + + public void onResultSendSignedTakerDepositTxAsHex() + { + listener.onWaitingForPeerResponse(state); } // informational, does only trigger UI feedback/update public void onDepositTxPublishedMessage(DepositTxPublishedMessage message) { log.debug("onDepositTxPublishedMessage"); - String txID = getWalletFacade().takerCommitDepositTx(message.getDepositTxAsHex()); - listener.onDepositTxPublished(txID); + if (state.ordinal() > State.SendSignedTakerDepositTxAsHex.ordinal() && state.ordinal() < State.SignAndPublishPayoutTx.ordinal()) + { + state = State.onDepositTxPublishedMessage; + + listener.onDepositTxPublished(walletFacade.takerCommitDepositTx(message.getDepositTxAsHex())); + } + else + { + log.error("Invalid state. Actual state is: " + state); + } } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Incoming message from peer + /////////////////////////////////////////////////////////////////////////////////////////// + // informational, store data for later, does only trigger UI feedback/update public void onBankTransferInitedMessage(BankTransferInitedMessage tradeMessage) { log.debug("onBankTransferInitedMessage"); - depositTxAsHex = tradeMessage.getDepositTxAsHex(); - offererSignatureR = tradeMessage.getOffererSignatureR(); - offererSignatureS = tradeMessage.getOffererSignatureS(); - offererPaybackAmount = tradeMessage.getOffererPaybackAmount(); - takerPaybackAmount = tradeMessage.getTakerPaybackAmount(); - offererPayoutAddress = tradeMessage.getOffererPayoutAddress(); + if (state.ordinal() > State.SendSignedTakerDepositTxAsHex.ordinal() && state.ordinal() < State.SignAndPublishPayoutTx.ordinal()) + { + state = State.onBankTransferInitedMessage; - listener.onBankTransferInited(tradeMessage.getTradeId()); + depositTxAsHex = tradeMessage.getDepositTxAsHex(); + offererSignatureR = tradeMessage.getOffererSignatureR(); + offererSignatureS = tradeMessage.getOffererSignatureS(); + offererPaybackAmount = tradeMessage.getOffererPaybackAmount(); + takerPaybackAmount = tradeMessage.getTakerPaybackAmount(); + offererPayoutAddress = tradeMessage.getOffererPayoutAddress(); + + listener.onBankTransferInited(tradeMessage.getTradeId()); + } + else + { + log.error("Invalid state. Actual state is: " + state); + } } // User clicked the "bank transfer received" button, so we release the funds for pay out public void onUIEventFiatReceived() { log.debug("onUIEventFiatReceived"); - if (scheduler_3.getHasCompleted()) + + if (state.ordinal() > State.SendSignedTakerDepositTxAsHex.ordinal() && state.ordinal() < State.SignAndPublishPayoutTx.ordinal()) { - List tasks = new ArrayList<>(); - tasks.add(new SignAndPublishPayoutTx(resultHandler, faultHandler)); - tasks.add(new SendPayoutTxToOfferer(resultHandler, faultHandler)); - scheduler_4 = new SequenceScheduler(tasks, this); - scheduler_4.execute(); + state = State.onUIEventFiatReceived; + + SignAndPublishPayoutTx.run(this::onResultSignAndPublishPayoutTx, + this::onFault, + walletFacade, + trade, + depositTxAsHex, + offererSignatureR, + offererSignatureS, + offererPaybackAmount, + takerPaybackAmount, + offererPayoutAddress); + state = State.SignAndPublishPayoutTx; } else { - log.error("scheduler_3 has not completed yet."); + log.error("Invalid state. Actual state is: " + state); } } + public void onResultSignAndPublishPayoutTx(Transaction transaction, String payoutTxAsHex) + { + listener.onPayoutTxPublished(trade, transaction.getHashAsString()); + + SendPayoutTxToOfferer.run(this::onResultSendPayoutTxToOfferer, this::onFault, peerAddress, messageFacade, trade, payoutTxAsHex); + state = State.SendPayoutTxToOfferer; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + public void onResultSendPayoutTxToOfferer() + { + checkState(state == State.SendPayoutTxToOfferer); + listener.onCompleted(state); + } + + public String getId() + { + return id; + } + /////////////////////////////////////////////////////////////////////////////////////////// // Getters, Setters /////////////////////////////////////////////////////////////////////////////////////////// - public String getId() + public enum State { - return id; + Init, + GetPeerAddress, + RequestTakeOffer, + PayTakeOfferFee, + onRejectTakeOfferRequestMessage, + SendTakeOfferFeePayedTxId, + VerifyOffererAccount, + CreateAndSignContract, + PayDeposit, + SendSignedTakerDepositTxAsHex, + onDepositTxPublishedMessage, + onBankTransferInitedMessage, + onUIEventFiatReceived, + SignAndPublishPayoutTx, + SendPayoutTxToOfferer } - public Trade getTrade() - { - return trade; - } - - public TakerAsSellerProtocolListener getListener() - { - return listener; - } - - public MessageFacade getMessageFacade() - { - return messageFacade; - } - - public WalletFacade getWalletFacade() - { - return walletFacade; - } - - public BlockChainFacade getBlockChainFacade() - { - return blockChainFacade; - } - - public CryptoFacade getCryptoFacade() - { - return cryptoFacade; - } - - public User getUser() - { - return user; - } - - public PeerAddress getPeerAddress() - { - return peerAddress; - } - - public void setPeerAddress(PeerAddress peerAddress) - { - this.peerAddress = peerAddress; - } - - public Transaction getSignedTakerDepositTx() - { - return signedTakerDepositTx; - } - - public void setSignedTakerDepositTx(Transaction signedTakerDepositTx) - { - this.signedTakerDepositTx = signedTakerDepositTx; - } - - public long getTakerTxOutIndex() - { - return takerTxOutIndex; - } - - public void setTakerTxOutIndex(long takerTxOutIndex) - { - this.takerTxOutIndex = takerTxOutIndex; - } - - public String getPeersAccountId() - { - return peersAccountId; - } - - public BankAccount getPeersBankAccount() - { - return peersBankAccount; - } - - public String getOffererPubKey() - { - return offererPubKey; - } - - public String getPreparedOffererDepositTxAsHex() - { - return preparedOffererDepositTxAsHex; - } - - public long getOffererTxOutIndex() - { - return offererTxOutIndex; - } - - public String getDepositTxAsHex() - { - return depositTxAsHex; - } - - public String getOffererSignatureR() - { - return offererSignatureR; - } - - public String getOffererSignatureS() - { - return offererSignatureS; - } - - public BigInteger getOffererPaybackAmount() - { - return offererPaybackAmount; - } - - public BigInteger getTakerPaybackAmount() - { - return takerPaybackAmount; - } - - public String getOffererPayoutAddress() - { - return offererPayoutAddress; - } - - public String getPayoutTxAsHex() - { - return payoutTxAsHex; - } - - public void setPayoutTxAsHex(String payoutTxAsHex) - { - this.payoutTxAsHex = payoutTxAsHex; - } /////////////////////////////////////////////////////////////////////////////////////////// // Step 1.1 @@ -774,7 +797,7 @@ public class TakerAsSellerProtocol { System.out.println("######### 3.12 onSuccess walletFacade.takerSignsAndSendsTx " + transaction); log.debug("3.12 onSuccess walletFacade.takerSignsAndSendsTx " + transaction); - listener.onTradeCompleted(transaction.getHashAsString()); + listener.onPayoutTxPublished(transaction.getHashAsString()); sendPayoutTxToOfferer(Utils.bytesToHexString(transaction.bitcoinSerialize())); } diff --git a/src/main/java/io/bitsquare/trade/protocol/taker/TakerAsSellerProtocolListener.java b/src/main/java/io/bitsquare/trade/protocol/taker/TakerAsSellerProtocolListener.java new file mode 100644 index 0000000000..20f75789e6 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/taker/TakerAsSellerProtocolListener.java @@ -0,0 +1,20 @@ +package io.bitsquare.trade.protocol.taker; + +import io.bitsquare.trade.Trade; + +public interface TakerAsSellerProtocolListener +{ + void onDepositTxPublished(String depositTxId); + + void onBankTransferInited(String tradeId); + + void onPayoutTxPublished(Trade trade, String hashAsString); + + void onFault(Throwable throwable, TakerAsSellerProtocol.State state); + + void onWaitingForPeerResponse(TakerAsSellerProtocol.State state); + + void onCompleted(TakerAsSellerProtocol.State state); + + void onTakeOfferRequestRejected(Trade trade); +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/FaultHandler.java b/src/main/java/io/bitsquare/trade/protocol/tasks/FaultHandler.java new file mode 100644 index 0000000000..f2d4a6ce2d --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/FaultHandler.java @@ -0,0 +1,6 @@ +package io.bitsquare.trade.protocol.tasks; + +public interface FaultHandler +{ + void onFault(Throwable throwable); +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/ResultHandler.java b/src/main/java/io/bitsquare/trade/protocol/tasks/ResultHandler.java new file mode 100644 index 0000000000..9d9670e880 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/ResultHandler.java @@ -0,0 +1,6 @@ +package io.bitsquare.trade.protocol.tasks; + +public interface ResultHandler +{ + void onResult(); +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/CreateDepositTx.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/CreateDepositTx.java new file mode 100644 index 0000000000..19711509e1 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/CreateDepositTx.java @@ -0,0 +1,49 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import com.google.bitcoin.core.InsufficientMoneyException; +import com.google.bitcoin.core.Transaction; +import com.google.bitcoin.core.Utils; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import java.math.BigInteger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CreateDepositTx +{ + private static final Logger log = LoggerFactory.getLogger(CreateDepositTx.class); + + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + WalletFacade walletFacade, + String tradeId, + BigInteger collateralAmount, + String takerMultiSigPubKey, + String arbitratorPubKeyAsHex) + { + try + { + String offererPubKey = walletFacade.getAddressInfoByTradeID(tradeId).getPubKeyAsHexString(); + Transaction transaction = walletFacade.offererCreatesMSTxAndAddPayment(collateralAmount, + offererPubKey, + takerMultiSigPubKey, + arbitratorPubKeyAsHex, + tradeId); + + String preparedOffererDepositTxAsHex = Utils.bytesToHexString(transaction.bitcoinSerialize()); + long offererTxOutIndex = transaction.getInput(0).getOutpoint().getIndex(); + + resultHandler.onResult(offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex); + } catch (InsufficientMoneyException e) + { + log.error("Create deposit tx faultHandler.onFault due InsufficientMoneyException " + e); + faultHandler.onFault(new Exception("Create deposit tx faultHandler.onFault due InsufficientMoneyException " + e)); + } + } + + public interface ResultHandler + { + void onResult(String offererPubKey, String preparedOffererDepositTxAsHex, long offererTxOutIndex); + } + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/HandleTakeOfferRequest.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/HandleTakeOfferRequest.java new file mode 100644 index 0000000000..08fff63d62 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/HandleTakeOfferRequest.java @@ -0,0 +1,65 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.OutgoingTradeMessageListener; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.messages.offerer.AcceptTakeOfferRequestMessage; +import io.bitsquare.trade.protocol.messages.offerer.RejectTakeOfferRequestMessage; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HandleTakeOfferRequest +{ + private static final Logger log = LoggerFactory.getLogger(HandleTakeOfferRequest.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, PeerAddress peerAddress, MessageFacade messageFacade, Trade.State tradeState, String tradeId) + { + if (tradeState == Trade.State.OPEN) + { + messageFacade.sendTradeMessage(peerAddress, new AcceptTakeOfferRequestMessage(tradeId), new OutgoingTradeMessageListener() + { + @Override + public void onResult() + { + log.trace("AcceptTakeOfferRequestMessage successfully arrived at peer"); + resultHandler.onResult(Trade.State.ACCEPTED); + } + + @Override + public void onFailed() + { + log.error("AcceptTakeOfferRequestMessage faultHandler.onFault to arrive at peer"); + faultHandler.onFault(new Exception("AcceptTakeOfferRequestMessage faultHandler.onFault to arrive at peer")); + } + }); + } + else + { + RejectTakeOfferRequestMessage msg = new RejectTakeOfferRequestMessage(tradeId); + messageFacade.sendTradeMessage(peerAddress, msg, new OutgoingTradeMessageListener() + { + @Override + public void onResult() + { + log.trace("RejectTakeOfferRequestMessage successfully arrived at peer"); + } + + @Override + public void onFailed() + { + log.error("RejectTakeOfferRequestMessage faultHandler.onFault to arrive at peer"); + } + }); + + log.error("Offer not marked as open."); + faultHandler.onFault(new Exception("Offer not marked as open.")); + } + } + + public interface ResultHandler + { + void onResult(Trade.State tradeState); + } +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/RequestTakerDepositPayment.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/RequestTakerDepositPayment.java new file mode 100644 index 0000000000..888b2e846f --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/RequestTakerDepositPayment.java @@ -0,0 +1,52 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import io.bitsquare.bank.BankAccount; +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.OutgoingTradeMessageListener; +import io.bitsquare.trade.protocol.messages.offerer.RequestTakerDepositPaymentMessage; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RequestTakerDepositPayment +{ + private static final Logger log = LoggerFactory.getLogger(RequestTakerDepositPayment.class); + + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + PeerAddress peerAddress, + MessageFacade messageFacade, + String tradeId, + BankAccount bankAccount, + String accountId, + String offererPubKey, + String preparedOffererDepositTxAsHex, + long offererTxOutIndex) + { + RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage(tradeId, + bankAccount, + accountId, + offererPubKey, + preparedOffererDepositTxAsHex, + offererTxOutIndex); + messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() + { + @Override + public void onResult() + { + log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer"); + resultHandler.onResult(); + } + + @Override + public void onFailed() + { + log.error("RequestTakerDepositPaymentMessage faultHandler.onFault to arrive at peer"); + faultHandler.onFault(new Exception("RequestTakerDepositPaymentMessage faultHandler.onFault to arrive at peer")); + } + }); + } + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SendDepositTxIdToTaker.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SendDepositTxIdToTaker.java new file mode 100644 index 0000000000..4e814e0d95 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SendDepositTxIdToTaker.java @@ -0,0 +1,39 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import com.google.bitcoin.core.Utils; +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.OutgoingTradeMessageListener; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.messages.offerer.DepositTxPublishedMessage; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SendDepositTxIdToTaker +{ + private static final Logger log = LoggerFactory.getLogger(SendDepositTxIdToTaker.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, PeerAddress peerAddress, MessageFacade messageFacade, Trade trade) + { + DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(trade.getId(), Utils.bytesToHexString(trade.getDepositTransaction().bitcoinSerialize())); + messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() + { + @Override + public void onResult() + { + log.trace("DepositTxPublishedMessage successfully arrived at peer"); + resultHandler.onResult(); + } + + @Override + public void onFailed() + { + log.error("DepositTxPublishedMessage faultHandler.onFault to arrive at peer"); + faultHandler.onFault(new Exception("DepositTxPublishedMessage faultHandler.onFault to arrive at peer")); + } + }); + } + +} diff --git a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SendSignedPayoutTx.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SendSignedPayoutTx.java similarity index 52% rename from src/main/java/io/bitsquare/trade/payment/offerer/tasks/SendSignedPayoutTx.java rename to src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SendSignedPayoutTx.java index 2cacf6c06d..540fe268c0 100644 --- a/src/main/java/io/bitsquare/trade/payment/offerer/tasks/SendSignedPayoutTx.java +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SendSignedPayoutTx.java @@ -1,55 +1,57 @@ -package io.bitsquare.trade.payment.offerer.tasks; +package io.bitsquare.trade.protocol.tasks.offerer; import com.google.bitcoin.core.ECKey; import com.google.bitcoin.core.Transaction; -import io.bitsquare.msg.listeners.TradeMessageListener; -import io.bitsquare.trade.payment.offerer.messages.BankTransferInitedMessage; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.OutgoingTradeMessageListener; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.messages.offerer.BankTransferInitedMessage; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; import java.math.BigInteger; import javafx.util.Pair; +import net.tomp2p.peers.PeerAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class SendSignedPayoutTx extends AbstractOffererAsBuyerTask +public class SendSignedPayoutTx { private static final Logger log = LoggerFactory.getLogger(SendSignedPayoutTx.class); - public SendSignedPayoutTx(WorkerResultHandler resultHandler, WorkerFaultHandler faultHandler) + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + PeerAddress peerAddress, + MessageFacade messageFacade, + WalletFacade walletFacade, + Trade trade, + String takerPayoutAddress) { - super(resultHandler, faultHandler); - } - - @Override - public void execute() - { - log.trace("execute"); - try { - Transaction depositTransaction = sharedModel.getTrade().getDepositTransaction(); - BigInteger collateral = sharedModel.getTrade().getCollateralAmount(); - BigInteger offererPaybackAmount = sharedModel.getTrade().getTradeAmount().add(collateral); + Transaction depositTransaction = trade.getDepositTransaction(); + BigInteger collateral = trade.getCollateralAmount(); + BigInteger offererPaybackAmount = trade.getTradeAmount().add(collateral); BigInteger takerPaybackAmount = collateral; log.trace("offererPaybackAmount " + offererPaybackAmount); log.trace("takerPaybackAmount " + takerPaybackAmount); log.trace("depositTransaction.getHashAsString() " + depositTransaction.getHashAsString()); - log.trace("takerPayoutAddress " + sharedModel.getTakerPayoutAddress()); + log.trace("takerPayoutAddress " + takerPayoutAddress); - Pair result = sharedModel.getWalletFacade().offererCreatesAndSignsPayoutTx(depositTransaction.getHashAsString(), + Pair result = walletFacade.offererCreatesAndSignsPayoutTx(depositTransaction.getHashAsString(), offererPaybackAmount, takerPaybackAmount, - sharedModel.getTakerPayoutAddress(), - sharedModel.getTrade().getId()); + takerPayoutAddress, + trade.getId()); ECKey.ECDSASignature offererSignature = result.getKey(); String offererSignatureR = offererSignature.r.toString(); String offererSignatureS = offererSignature.s.toString(); String depositTxAsHex = result.getValue(); - String offererPayoutAddress = sharedModel.getWalletFacade().getAddressInfoByTradeID(sharedModel.getTrade().getId()).getAddressString(); + String offererPayoutAddress = walletFacade.getAddressInfoByTradeID(trade.getId()).getAddressString(); - BankTransferInitedMessage tradeMessage = new BankTransferInitedMessage(sharedModel.getTrade().getId(), + BankTransferInitedMessage tradeMessage = new BankTransferInitedMessage(trade.getId(), depositTxAsHex, offererSignatureR, offererSignatureS, @@ -64,28 +66,27 @@ public class SendSignedPayoutTx extends AbstractOffererAsBuyerTask log.trace("takerPaybackAmount " + takerPaybackAmount); log.trace("offererPayoutAddress " + offererPayoutAddress); - sharedModel.getMessageFacade().sendTradeMessage(sharedModel.peerAddress, tradeMessage, new TradeMessageListener() + messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() { @Override public void onResult() { log.trace("BankTransferInitedMessage successfully arrived at peer"); - complete(); + resultHandler.onResult(); } @Override public void onFailed() { - log.error("BankTransferInitedMessage failed to arrive at peer"); - failed(new Exception("BankTransferInitedMessage failed to arrive at peer")); + log.error("BankTransferInitedMessage faultHandler.onFault to arrive at peer"); + faultHandler.onFault(new Exception("BankTransferInitedMessage faultHandler.onFault to arrive at peer")); } }); } catch (Exception e) { log.error("Exception at OffererCreatesAndSignsPayoutTx " + e); - failed(e); + faultHandler.onFault(e); } } - } diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SetupListenerForBlockChainConfirmation.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SetupListenerForBlockChainConfirmation.java new file mode 100644 index 0000000000..0ba260a5fe --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SetupListenerForBlockChainConfirmation.java @@ -0,0 +1,40 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import com.google.bitcoin.core.Transaction; +import com.google.bitcoin.core.TransactionConfidence; +import io.bitsquare.trade.protocol.offerer.OffererAsBuyerProtocolListener; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SetupListenerForBlockChainConfirmation +{ + private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, Transaction depositTransaction, OffererAsBuyerProtocolListener listener) + { //TODO + // sharedModel.offererPaymentProtocolListener.onDepositTxConfirmedInBlockchain(); + + depositTransaction.getConfidence().addEventListener(new TransactionConfidence.Listener() + { + @Override + public void onConfidenceChanged(Transaction tx, ChangeReason reason) + { + log.trace("onConfidenceChanged " + tx.getConfidence()); + if (reason == ChangeReason.SEEN_PEERS) + { + listener.onDepositTxConfirmedUpdate(tx.getConfidence()); + } + if (reason == ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) + { + listener.onDepositTxConfirmedInBlockchain(); + depositTransaction.getConfidence().removeEventListener(this); + log.trace("Tx is in blockchain"); + resultHandler.onResult(); + } + } + } + ); + } +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SignAndPublishDepositTx.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SignAndPublishDepositTx.java new file mode 100644 index 0000000000..02cb1478b4 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/SignAndPublishDepositTx.java @@ -0,0 +1,60 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import com.google.bitcoin.core.Transaction; +import com.google.common.util.concurrent.FutureCallback; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SignAndPublishDepositTx +{ + private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTx.class); + + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + WalletFacade walletFacade, + String preparedOffererDepositTxAsHex, + String signedTakerDepositTxAsHex, + String txConnOutAsHex, + String txScriptSigAsHex, + long offererTxOutIndex, + long takerTxOutIndex) + { + try + { + walletFacade.offererSignAndPublishTx(preparedOffererDepositTxAsHex, + signedTakerDepositTxAsHex, + txConnOutAsHex, + txScriptSigAsHex, + offererTxOutIndex, + takerTxOutIndex, + new FutureCallback() + { + @Override + public void onSuccess(Transaction transaction) + { + log.trace("offererSignAndPublishTx succeeded " + transaction); + resultHandler.onResult(transaction); + } + + @Override + public void onFailure(Throwable t) + { + log.error("offererSignAndPublishTx faultHandler.onFault:" + t); + faultHandler.onFault(t); + } + }); + } catch (Exception e) + { + log.error("offererSignAndPublishTx faultHandler.onFault:" + e); + faultHandler.onFault(e); + } + } + + public interface ResultHandler + { + void onResult(Transaction transaction); + } + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyAndSignContract.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyAndSignContract.java new file mode 100644 index 0000000000..284f4d2ba0 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyAndSignContract.java @@ -0,0 +1,70 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import com.google.bitcoin.core.ECKey; +import io.bitsquare.bank.BankAccount; +import io.bitsquare.crypto.CryptoFacade; +import io.bitsquare.trade.Contract; +import io.bitsquare.trade.Offer; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.util.Utilities; +import java.math.BigInteger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VerifyAndSignContract +{ + private static final Logger log = LoggerFactory.getLogger(VerifyAndSignContract.class); + + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + CryptoFacade cryptoFacade, + String accountId, + BigInteger tradeAmount, + String takeOfferFeeTxId, + String messagePubKeyAsHex, + Offer offer, + String peersAccountId, + BankAccount bankAccount, + BankAccount peersBankAccount, + String takerMessagePubKey, + String peersContractAsJson, + ECKey registrationKey) + { + Contract contract = new Contract(offer, + tradeAmount, + takeOfferFeeTxId, + accountId, + peersAccountId, + bankAccount, + peersBankAccount, + messagePubKeyAsHex, + takerMessagePubKey); + + String contractAsJson = Utilities.objectToJson(contract); + // log.trace("Offerer contract created: " + contract); + // log.trace("Offerers contractAsJson: " + contractAsJson); + // log.trace("Takers contractAsJson: " + sharedModel.peersContractAsJson); + if (contractAsJson.equals(peersContractAsJson)) + { + log.trace("The 2 contracts as json does match"); + String signature = cryptoFacade.signContract(registrationKey, contractAsJson); + //log.trace("signature: " + signature); + + resultHandler.onResult(contract, contractAsJson, signature); + } + else + { + // TODO use diff output as feedback ? + log.error("Contracts are not matching."); + log.error("Offerers contractAsJson: " + contractAsJson); + log.error("Takers contractAsJson: " + peersContractAsJson); + + faultHandler.onFault(new Exception("Contracts are not matching")); + } + } + + public interface ResultHandler + { + void onResult(Contract contract, String contractAsJson, String signature); + } +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyTakeOfferFeePayment.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyTakeOfferFeePayment.java new file mode 100644 index 0000000000..d6923290cb --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyTakeOfferFeePayment.java @@ -0,0 +1,22 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VerifyTakeOfferFeePayment +{ + private static final Logger log = LoggerFactory.getLogger(VerifyTakeOfferFeePayment.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, WalletFacade walletFacade, String takeOfferFeeTxId) + { //TODO mocked yet, need a confidence listeners + int numOfPeersSeenTx = walletFacade.getNumOfPeersSeenTx(takeOfferFeeTxId); + if (numOfPeersSeenTx > 2) + { + resultHandler.onResult(); + } + } + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyTakerAccount.java b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyTakerAccount.java new file mode 100644 index 0000000000..44f19ff4de --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/offerer/VerifyTakerAccount.java @@ -0,0 +1,36 @@ +package io.bitsquare.trade.protocol.tasks.offerer; + +import io.bitsquare.bank.BankAccount; +import io.bitsquare.btc.BlockChainFacade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VerifyTakerAccount +{ + private static final Logger log = LoggerFactory.getLogger(VerifyTakerAccount.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, BlockChainFacade blockChainFacade, String peersAccountId, BankAccount peersBankAccount) + { + //TODO mocked yet + if (blockChainFacade.verifyAccountRegistration()) + { + if (blockChainFacade.isAccountBlackListed(peersAccountId, peersBankAccount)) + { + log.error("Taker is blacklisted"); + faultHandler.onFault(new Exception("Taker is blacklisted")); + } + else + { + resultHandler.onResult(); + } + } + else + { + log.error("Account registration validation for peer faultHandler.onFault."); + faultHandler.onFault(new Exception("Account registration validation for peer faultHandler.onFault.")); + } + } + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/CreateAndSignContract.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/CreateAndSignContract.java new file mode 100644 index 0000000000..ce4c71d89f --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/CreateAndSignContract.java @@ -0,0 +1,60 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import com.google.bitcoin.core.ECKey; +import io.bitsquare.bank.BankAccount; +import io.bitsquare.crypto.CryptoFacade; +import io.bitsquare.trade.Contract; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import io.bitsquare.user.User; +import io.bitsquare.util.Utilities; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CreateAndSignContract +{ + private static final Logger log = LoggerFactory.getLogger(CreateAndSignContract.class); + + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + CryptoFacade cryptoFacade, + Trade trade, + User user, + String peersAccountId, + BankAccount peersBankAccount, + ECKey registrationKey) + { + try + { + Contract contract = new Contract(trade.getOffer(), + trade.getTradeAmount(), + trade.getTakeOfferFeeTxId(), + peersAccountId, + user.getAccountId(), + peersBankAccount, + user.getCurrentBankAccount(), + trade.getOffer().getMessagePubKeyAsHex(), + user.getMessagePubKeyAsHex() + ); + + String contractAsJson = Utilities.objectToJson(contract); + String signature = cryptoFacade.signContract(registrationKey, contractAsJson); + //log.trace("contract: " + contract); + //log.debug("contractAsJson: " + contractAsJson); + //log.trace("contract signature: " + signature); + + trade.setContract(contract); + trade.setContractAsJson(contractAsJson); + trade.setContractTakerSignature(signature); + + resultHandler.onResult(); + } catch (Throwable t) + { + log.error("Exception at sign contract " + t); + faultHandler.onFault(t); + } + } + + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/GetPeerAddress.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/GetPeerAddress.java new file mode 100644 index 0000000000..7738ad5cee --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/GetPeerAddress.java @@ -0,0 +1,39 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.GetPeerAddressListener; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GetPeerAddress +{ + private static final Logger log = LoggerFactory.getLogger(GetPeerAddress.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, MessageFacade messageFacade, String messagePubKeyAsHex) + { + messageFacade.getPeerAddress(messagePubKeyAsHex, new GetPeerAddressListener() + { + @Override + public void onResult(PeerAddress peerAddress) + { + log.trace("Received address = " + peerAddress.toString()); + resultHandler.onResult(peerAddress); + } + + @Override + public void onFailed() + { + log.error("Lookup for peer address faultHandler.onFault."); + faultHandler.onFault(new Exception("Lookup for peer address faultHandler.onFault.")); + } + }); + } + + public interface ResultHandler + { + void onResult(PeerAddress peerAddress); + } +} + diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/PayDeposit.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/PayDeposit.java new file mode 100644 index 0000000000..5e67be8f73 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/PayDeposit.java @@ -0,0 +1,46 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import com.google.bitcoin.core.InsufficientMoneyException; +import com.google.bitcoin.core.Transaction; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import java.math.BigInteger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PayDeposit +{ + private static final Logger log = LoggerFactory.getLogger(PayDeposit.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, WalletFacade walletFacade, Trade trade, String offererPubKey, String preparedOffererDepositTxAsHex) + { + try + { + BigInteger collateralAmount = trade.getCollateralAmount(); + Transaction signedTakerDepositTx = walletFacade.takerAddPaymentAndSignTx(trade.getTradeAmount().add(collateralAmount), + trade.getTradeAmount().add(collateralAmount).add(collateralAmount), + offererPubKey, + walletFacade.getAddressInfoByTradeID(trade.getId()).getPubKeyAsHexString(), + trade.getOffer().getArbitrator().getPubKeyAsHex(), + preparedOffererDepositTxAsHex, + trade.getId()); + + log.trace("sharedModel.signedTakerDepositTx: " + signedTakerDepositTx); + long takerTxOutIndex = signedTakerDepositTx.getInput(1).getOutpoint().getIndex(); + + resultHandler.onResult(signedTakerDepositTx, takerTxOutIndex); + } catch (InsufficientMoneyException e) + { + log.error("Pay deposit faultHandler.onFault due InsufficientMoneyException " + e); + faultHandler.onFault(new Exception("Pay deposit faultHandler.onFault due InsufficientMoneyException " + e)); + } + } + + public interface ResultHandler + { + void onResult(Transaction signedTakerDepositTx, long takerTxOutIndex); + } + + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/PayTakeOfferFee.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/PayTakeOfferFee.java new file mode 100644 index 0000000000..7078d1fd72 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/PayTakeOfferFee.java @@ -0,0 +1,48 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import com.google.bitcoin.core.InsufficientMoneyException; +import com.google.bitcoin.core.Transaction; +import com.google.common.util.concurrent.FutureCallback; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PayTakeOfferFee +{ + private static final Logger log = LoggerFactory.getLogger(PayTakeOfferFee.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, WalletFacade walletFacade, String tradeId) + { + log.trace("execute"); + try + { + walletFacade.payTakeOfferFee(tradeId, new FutureCallback() + { + @Override + public void onSuccess(Transaction transaction) + { + log.debug("Take offer fee paid successfully. Transaction ID = " + transaction.getHashAsString()); + resultHandler.onResult(transaction); + } + + @Override + public void onFailure(Throwable t) + { + log.error("Take offer fee paid faultHandler.onFault with exception: " + t); + faultHandler.onFault(new Exception("Take offer fee paid faultHandler.onFault with exception: " + t)); + } + }); + } catch (InsufficientMoneyException e) + { + log.error("Take offer fee paid faultHandler.onFault due InsufficientMoneyException " + e); + faultHandler.onFault(new Exception("Take offer fee paid faultHandler.onFault due InsufficientMoneyException " + e)); + } + } + + public interface ResultHandler + { + void onResult(Transaction transaction); + } + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/RequestTakeOffer.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/RequestTakeOffer.java new file mode 100644 index 0000000000..6814d09d24 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/RequestTakeOffer.java @@ -0,0 +1,35 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.OutgoingTradeMessageListener; +import io.bitsquare.trade.protocol.messages.taker.RequestTakeOfferMessage; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RequestTakeOffer +{ + private static final Logger log = LoggerFactory.getLogger(RequestTakeOffer.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, PeerAddress peerAddress, MessageFacade messageFacade, String tradeId) + { + messageFacade.sendTradeMessage(peerAddress, new RequestTakeOfferMessage(tradeId), new OutgoingTradeMessageListener() + { + @Override + public void onResult() + { + log.trace("RequestTakeOfferMessage successfully arrived at peer"); + resultHandler.onResult(); + } + + @Override + public void onFailed() + { + log.error("RequestTakeOfferMessage faultHandler.onFault to arrive at peer"); + faultHandler.onFault(new Exception("RequestTakeOfferMessage faultHandler.onFault to arrive at peer")); + } + }); + } +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendPayoutTxToOfferer.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendPayoutTxToOfferer.java new file mode 100644 index 0000000000..987a29bee4 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendPayoutTxToOfferer.java @@ -0,0 +1,39 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.OutgoingTradeMessageListener; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.messages.taker.PayoutTxPublishedMessage; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SendPayoutTxToOfferer +{ + private static final Logger log = LoggerFactory.getLogger(SendPayoutTxToOfferer.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, PeerAddress peerAddress, MessageFacade messageFacade, Trade trade, String payoutTxAsHex) + { + PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(trade.getId(), payoutTxAsHex); + messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() + { + @Override + public void onResult() + { + log.trace("PayoutTxPublishedMessage successfully arrived at peer"); + resultHandler.onResult(); + } + + @Override + public void onFailed() + { + log.error("PayoutTxPublishedMessage faultHandler.onFault to arrive at peer"); + faultHandler.onFault(new Exception("PayoutTxPublishedMessage faultHandler.onFault to arrive at peer")); + } + }); + + } + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendSignedTakerDepositTxAsHex.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendSignedTakerDepositTxAsHex.java new file mode 100644 index 0000000000..38e4bc30a0 --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendSignedTakerDepositTxAsHex.java @@ -0,0 +1,61 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import com.google.bitcoin.core.Transaction; +import com.google.bitcoin.core.Utils; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.OutgoingTradeMessageListener; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.messages.taker.RequestOffererPublishDepositTxMessage; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import io.bitsquare.user.User; +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SendSignedTakerDepositTxAsHex +{ + private static final Logger log = LoggerFactory.getLogger(SendSignedTakerDepositTxAsHex.class); + + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + PeerAddress peerAddress, + MessageFacade messageFacade, + WalletFacade walletFacade, + Trade trade, + User user, + Transaction signedTakerDepositTx, + long takerTxOutIndex, + long offererTxOutIndex) + { + RequestOffererPublishDepositTxMessage tradeMessage = new RequestOffererPublishDepositTxMessage(trade.getId(), + user.getCurrentBankAccount(), + user.getAccountId(), + user.getMessagePubKeyAsHex(), + Utils.bytesToHexString(signedTakerDepositTx.bitcoinSerialize()), + Utils.bytesToHexString(signedTakerDepositTx.getInput(1).getScriptBytes()), + Utils.bytesToHexString(signedTakerDepositTx.getInput(1).getConnectedOutput().getParentTransaction().bitcoinSerialize()), + trade.getContractAsJson(), + trade.getTakerSignature(), + walletFacade.getAddressInfoByTradeID(trade.getId()).getAddressString(), + takerTxOutIndex, + offererTxOutIndex); + messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() + { + @Override + public void onResult() + { + log.trace("RequestOffererDepositPublicationMessage successfully arrived at peer"); + resultHandler.onResult(); + } + + @Override + public void onFailed() + { + log.error("RequestOffererDepositPublicationMessage faultHandler.onFault to arrive at peer"); + faultHandler.onFault(new Exception("RequestOffererDepositPublicationMessage faultHandler.onFault to arrive at peer")); + } + }); + } +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendTakeOfferFeePayedTxId.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendTakeOfferFeePayedTxId.java new file mode 100644 index 0000000000..02aef821ca --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SendTakeOfferFeePayedTxId.java @@ -0,0 +1,48 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import io.bitsquare.msg.MessageFacade; +import io.bitsquare.msg.listeners.OutgoingTradeMessageListener; +import io.bitsquare.trade.protocol.messages.taker.TakeOfferFeePayedMessage; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import java.math.BigInteger; +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SendTakeOfferFeePayedTxId +{ + private static final Logger log = LoggerFactory.getLogger(SendTakeOfferFeePayedTxId.class); + + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + PeerAddress peerAddress, + MessageFacade messageFacade, + String tradeId, + String takeOfferFeeTxId, + BigInteger tradeAmount, + String pubKeyAsHexString) + { + TakeOfferFeePayedMessage msg = new TakeOfferFeePayedMessage(tradeId, + takeOfferFeeTxId, + tradeAmount, + pubKeyAsHexString); + + messageFacade.sendTradeMessage(peerAddress, msg, new OutgoingTradeMessageListener() + { + @Override + public void onResult() + { + log.trace("TakeOfferFeePayedMessage successfully arrived at peer"); + resultHandler.onResult(); + } + + @Override + public void onFailed() + { + log.error("TakeOfferFeePayedMessage faultHandler.onFault to arrive at peer"); + faultHandler.onFault(new Exception("TakeOfferFeePayedMessage faultHandler.onFault to arrive at peer")); + } + }); + } +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SignAndPublishPayoutTx.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SignAndPublishPayoutTx.java new file mode 100644 index 0000000000..ef342a303f --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/SignAndPublishPayoutTx.java @@ -0,0 +1,68 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import com.google.bitcoin.core.Transaction; +import com.google.bitcoin.core.Utils; +import com.google.common.util.concurrent.FutureCallback; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import java.math.BigInteger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SignAndPublishPayoutTx +{ + private static final Logger log = LoggerFactory.getLogger(SignAndPublishPayoutTx.class); + + public static void run(ResultHandler resultHandler, + FaultHandler faultHandler, + WalletFacade walletFacade, + Trade trade, + String depositTxAsHex, + String offererSignatureR, + String offererSignatureS, + BigInteger offererPaybackAmount, + BigInteger takerPaybackAmount, + String offererPayoutAddress + ) + { + try + { + + walletFacade.takerSignsAndSendsTx(depositTxAsHex, + offererSignatureR, + offererSignatureS, + offererPaybackAmount, + takerPaybackAmount, + offererPayoutAddress, + trade.getId(), + new FutureCallback() + { + @Override + public void onSuccess(Transaction transaction) + { + log.debug("takerSignsAndSendsTx " + transaction); + String payoutTxAsHex = Utils.bytesToHexString(transaction.bitcoinSerialize()); + resultHandler.onResult(transaction, payoutTxAsHex); + } + + @Override + public void onFailure(Throwable t) + { + log.error("Exception at takerSignsAndSendsTx " + t); + faultHandler.onFault(t); + } + }); + } catch (Exception e) + { + log.error("Exception at takerSignsAndSendsTx " + e); + faultHandler.onFault(e); + } + } + + public interface ResultHandler + { + void onResult(Transaction transaction, String payoutTxAsHex); + } + +} diff --git a/src/main/java/io/bitsquare/trade/protocol/tasks/taker/VerifyOffererAccount.java b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/VerifyOffererAccount.java new file mode 100644 index 0000000000..f4ce650d6f --- /dev/null +++ b/src/main/java/io/bitsquare/trade/protocol/tasks/taker/VerifyOffererAccount.java @@ -0,0 +1,35 @@ +package io.bitsquare.trade.protocol.tasks.taker; + +import io.bitsquare.bank.BankAccount; +import io.bitsquare.btc.BlockChainFacade; +import io.bitsquare.trade.protocol.tasks.FaultHandler; +import io.bitsquare.trade.protocol.tasks.ResultHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VerifyOffererAccount +{ + private static final Logger log = LoggerFactory.getLogger(VerifyOffererAccount.class); + + public static void run(ResultHandler resultHandler, FaultHandler faultHandler, BlockChainFacade blockChainFacade, String peersAccountId, BankAccount peersBankAccount) + { + //TODO mocked yet + if (blockChainFacade.verifyAccountRegistration()) + { + if (blockChainFacade.isAccountBlackListed(peersAccountId, peersBankAccount)) + { + log.error("Offerer is blacklisted"); + faultHandler.onFault(new Exception("Offerer is blacklisted")); + } + else + { + resultHandler.onResult(); + } + } + else + { + log.error("Account Registration for peer faultHandler.onFault."); + faultHandler.onFault(new Exception("Account Registration for peer faultHandler.onFault.")); + } + } +} diff --git a/src/main/java/io/bitsquare/user/User.java b/src/main/java/io/bitsquare/user/User.java index c9917a835a..a2ca1d9195 100644 --- a/src/main/java/io/bitsquare/user/User.java +++ b/src/main/java/io/bitsquare/user/User.java @@ -35,7 +35,7 @@ public class User implements Serializable { if (savedUser != null) { - accountID = savedUser.getAccountID(); + accountID = savedUser.getAccountId(); messagePubKeyAsHex = savedUser.getMessagePubKeyAsHex(); isOnline = savedUser.getIsOnline(); bankAccounts = savedUser.getBankAccounts(); @@ -92,7 +92,7 @@ public class User implements Serializable } - public String getAccountID() + public String getAccountId() { return accountID; } diff --git a/src/main/java/io/bitsquare/util/Validator.java b/src/main/java/io/bitsquare/util/Validator.java new file mode 100644 index 0000000000..51b135d055 --- /dev/null +++ b/src/main/java/io/bitsquare/util/Validator.java @@ -0,0 +1,34 @@ +package io.bitsquare.util; + +import net.tomp2p.peers.PeerAddress; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public class Validator +{ + private static final Logger log = LoggerFactory.getLogger(Validator.class); + + public static String validString(String value) + { + checkNotNull(value); + checkArgument(value.length() > 0); + return value; + } + + public static long validNonNegativeLong(long value) + { + checkArgument(value >= 0); + return value; + } + + public static PeerAddress validPeerAddress(PeerAddress value) + { + checkNotNull(value); + return value; + } + + +} diff --git a/src/main/java/io/nucleo/scheduler/AbstractScheduler.java b/src/main/java/io/nucleo/scheduler/AbstractScheduler.java deleted file mode 100644 index 35c48496d2..0000000000 --- a/src/main/java/io/nucleo/scheduler/AbstractScheduler.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.nucleo.scheduler; - -import com.sun.istack.internal.NotNull; -import io.nucleo.scheduler.worker.AbstractWorker; -import io.nucleo.scheduler.worker.Worker; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import java.util.ArrayList; -import java.util.List; - -public abstract class AbstractScheduler extends AbstractWorker implements WorkerResultHandler, WorkerFaultHandler -{ - protected List workerElements = new ArrayList<>(); - - public void setWorkers(@NotNull List workerElements) - { - this.workerElements = workerElements; - } - - protected void executeWorker(Worker worker) - { - ((AbstractWorker) worker).setModel(model); - worker.addResultHandlers(this); - worker.addFaultHandlers(this); - worker.execute(); - } - - public void onResult() - { - } - - public void onFault(Throwable throwable) - { - failed(throwable); - } - -} diff --git a/src/main/java/io/nucleo/scheduler/DependencyManagedScheduler.java b/src/main/java/io/nucleo/scheduler/DependencyManagedScheduler.java deleted file mode 100644 index aaacf075da..0000000000 --- a/src/main/java/io/nucleo/scheduler/DependencyManagedScheduler.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.nucleo.scheduler; - -import io.nucleo.scheduler.tasks.AbstractDependencyManagedTask; -import io.nucleo.scheduler.worker.AbstractWorker; -import io.nucleo.scheduler.worker.Worker; -import java.util.function.Predicate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Not tested yet as not used... - */ -public class DependencyManagedScheduler extends AbstractScheduler -{ - private static final Logger log = LoggerFactory.getLogger(DependencyManagedScheduler.class); - - @Override - public void execute() - { - if (workerElements.size() > 0) - workerElements.stream().forEach(this::executeWorker); - else - complete(); - } - - @Override - protected void executeWorker(Worker worker) - { - ((AbstractWorker) worker).setModel(model); - if (((AbstractDependencyManagedTask) worker).areAllDependenciesAvailable()) - { - worker.addResultHandlers(this); - worker.addFaultHandlers(this); - worker.execute(); - } - } - - @Override - public void onResult(Worker worker) - { - Predicate notCompleted = w -> !w.getHasCompleted(); - if (workerElements.stream().filter(notCompleted).count() == 0) - complete(); - else - execute(); - } -} diff --git a/src/main/java/io/nucleo/scheduler/ParallelScheduler.java b/src/main/java/io/nucleo/scheduler/ParallelScheduler.java deleted file mode 100644 index 11a8a050a0..0000000000 --- a/src/main/java/io/nucleo/scheduler/ParallelScheduler.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.nucleo.scheduler; - -import io.nucleo.scheduler.worker.Worker; -import java.util.function.Predicate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Not tested yet as not used... - */ -public class ParallelScheduler extends AbstractScheduler -{ - private static final Logger log = LoggerFactory.getLogger(ParallelScheduler.class); - private long numberOfChildrenCompleted; - - - @Override - public void execute() - { - if (workerElements.size() > 0) - workerElements.stream().forEach(this::executeWorker); - else - complete(); - } - - @Override - public void onResult(Worker worker) - { - Predicate notCompleted = w -> !w.getHasCompleted(); - if (workerElements.stream().filter(notCompleted).count() == 0) - complete(); - } - -} diff --git a/src/main/java/io/nucleo/scheduler/SequenceScheduler.java b/src/main/java/io/nucleo/scheduler/SequenceScheduler.java deleted file mode 100644 index 166f297203..0000000000 --- a/src/main/java/io/nucleo/scheduler/SequenceScheduler.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.nucleo.scheduler; - -import com.sun.istack.internal.NotNull; -import io.nucleo.scheduler.worker.Worker; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -public class SequenceScheduler extends AbstractScheduler -{ - private Iterator workerIterator; - - public SequenceScheduler(List workerElements, Object model) - { - setWorkers(workerElements); - setModel(model); - } - - public SequenceScheduler() - { - } - - @Override - public void setWorkers(@NotNull List workerElements) - { - workerIterator = new LinkedList<>(workerElements).iterator(); - } - - @Override - public void execute() - { - if (workerIterator != null && workerIterator.hasNext()) - executeWorker(workerIterator.next()); - else - complete(); - } - - @Override - public void onResult(Worker worker) - { - execute(); - } - -} diff --git a/src/main/java/io/nucleo/scheduler/example/ExamplePropertyProviderModel.java b/src/main/java/io/nucleo/scheduler/example/ExamplePropertyProviderModel.java deleted file mode 100644 index 82daeaa7d0..0000000000 --- a/src/main/java/io/nucleo/scheduler/example/ExamplePropertyProviderModel.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.nucleo.scheduler.example; - -import io.nucleo.scheduler.model.PropertyProviderModel; - -public class ExamplePropertyProviderModel extends PropertyProviderModel -{ - public final Object flashVars; - public Object user; - - public ExamplePropertyProviderModel(Object flashVars) - { - this.flashVars = flashVars; - } - -} diff --git a/src/main/java/io/nucleo/scheduler/example/SchedulerTestRunner.java b/src/main/java/io/nucleo/scheduler/example/SchedulerTestRunner.java deleted file mode 100644 index 0b6ec9ef26..0000000000 --- a/src/main/java/io/nucleo/scheduler/example/SchedulerTestRunner.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.nucleo.scheduler.example; - -import io.nucleo.scheduler.worker.Worker; -import io.nucleo.scheduler.worker.WorkerFaultHandler; -import io.nucleo.scheduler.worker.WorkerResultHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SchedulerTestRunner implements WorkerResultHandler, WorkerFaultHandler -{ - private static final Logger log = LoggerFactory.getLogger(SchedulerTestRunner.class); - private static SchedulerTestRunner schedulerTestRunner; - - public SchedulerTestRunner() - { - /* Map flashVars = new HashMap<>(); - flashVars.put("userName", "bully"); - - Object model = new ExamplePropertyProviderModel(flashVars); - ExampleAS3Scheduler exampleScheduler = new ExampleAS3Scheduler(); - - exampleScheduler.setModel(model); - exampleScheduler.setResultHandler(() -> { - log.debug("setResultHandler "); - }); - exampleScheduler.setFaultHandler((throwable) -> { - log.debug("setFaultHandler "); - }); - exampleScheduler.execute(); */ - } - - public static void main(String[] args) - { - schedulerTestRunner = new SchedulerTestRunner(); - } - - @Override - public void onFault(Throwable throwable) - { - log.debug("onFault " + this); - } - - @Override - public void onResult(Worker worker) - { - log.debug("onResult " + this); - } -} diff --git a/src/main/java/io/nucleo/scheduler/model/PropertyProviderModel.java b/src/main/java/io/nucleo/scheduler/model/PropertyProviderModel.java deleted file mode 100644 index bbdd3b9780..0000000000 --- a/src/main/java/io/nucleo/scheduler/model/PropertyProviderModel.java +++ /dev/null @@ -1,54 +0,0 @@ -package io.nucleo.scheduler.model; - -import java.lang.reflect.Field; -import java.util.List; -import java.util.function.Predicate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class PropertyProviderModel -{ - private static final Logger log = LoggerFactory.getLogger(PropertyProviderModel.class); - - public PropertyProviderModel() - { - } - - public boolean areAllDependenciesAvailable(List propertyNames) - { - Predicate isPropertyNotNull = (propertyName) -> read(propertyName) != null; - return propertyNames.stream().allMatch(isPropertyNotNull); - } - - public Object read(String key) - { - try - { - return getField(key).get(this); - } catch (IllegalAccessException e) - { - e.printStackTrace(); - return null; - } - } - - - // ------------------------------------------------------------------- - // Private - // ------------------------------------------------------------------- - - private Field getField(String key) - { - Class clazz = this.getClass(); - try - { - Field field = clazz.getDeclaredField(key); - field.setAccessible(true); // make sure a private field is accessible for reflection - return field; - } catch (Exception e) - { - e.printStackTrace(); - return null; - } - } -} diff --git a/src/main/java/io/nucleo/scheduler/tasks/AbstractDependencyManagedTask.java b/src/main/java/io/nucleo/scheduler/tasks/AbstractDependencyManagedTask.java deleted file mode 100644 index 6e39fb1d13..0000000000 --- a/src/main/java/io/nucleo/scheduler/tasks/AbstractDependencyManagedTask.java +++ /dev/null @@ -1,68 +0,0 @@ -package io.nucleo.scheduler.tasks; - -import io.nucleo.scheduler.model.PropertyProviderModel; -import java.util.ArrayList; -import java.util.List; - -/** - * The base class for all tasks using a IPropertyProviderModel instance as a shared model. - */ -public abstract class AbstractDependencyManagedTask extends AbstractTask -{ - private PropertyProviderModel propertyProviderModel; - private List readDependencyKeys = new ArrayList<>(); - - public AbstractDependencyManagedTask() - { - - } - - - // ------------------------------------------------------------------- - // IRunnable implementation - // ------------------------------------------------------------------- - - @Override - public void setModel(Object model) - { - propertyProviderModel = (PropertyProviderModel) model; - - super.setModel(model); - - initReadDependencies(); - } - - - // ------------------------------------------------------------------- - // Abstract Methods - // ------------------------------------------------------------------- - - /** - * To be overwritten in subclasses - * Used to read the needed data objects for the task. - * Typically stored as instance variable in the task. - */ - protected void initReadDependencies() - { - // user = read(IUser); - // channel = read("channel"); - } - - - // ------------------------------------------------------------------- - // Final protected - // ------------------------------------------------------------------- - - final protected Object read(String key) - { - readDependencyKeys.add(key); - - return propertyProviderModel.read(key); - } - - public boolean areAllDependenciesAvailable() - { - return propertyProviderModel.areAllDependenciesAvailable(readDependencyKeys); - } - -} diff --git a/src/main/java/io/nucleo/scheduler/tasks/AbstractTask.java b/src/main/java/io/nucleo/scheduler/tasks/AbstractTask.java deleted file mode 100644 index 8d669bb845..0000000000 --- a/src/main/java/io/nucleo/scheduler/tasks/AbstractTask.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.nucleo.scheduler.tasks; - -import io.nucleo.scheduler.worker.AbstractWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The base class for all tasks. - */ -public abstract class AbstractTask extends AbstractWorker -{ - private static final Logger log = LoggerFactory.getLogger(AbstractTask.class); -} diff --git a/src/main/java/io/nucleo/scheduler/worker/AbstractWorker.java b/src/main/java/io/nucleo/scheduler/worker/AbstractWorker.java deleted file mode 100644 index 138f43b2f5..0000000000 --- a/src/main/java/io/nucleo/scheduler/worker/AbstractWorker.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.nucleo.scheduler.worker; - -import java.util.ArrayList; -import java.util.List; - -public abstract class AbstractWorker implements Worker -{ - protected List resultHandlers = new ArrayList<>(); - protected List faultHandlers = new ArrayList<>(); - protected Object model; - protected boolean hasFailed; - protected boolean hasCompleted; - - @Override - abstract public void execute(); - - @Override - public void addResultHandlers(WorkerResultHandler resultHandler) - { - resultHandlers.add(resultHandler); - } - - @Override - public void addFaultHandlers(WorkerFaultHandler faultHandler) - { - faultHandlers.add(faultHandler); - } - - public void setModel(Object model) - { - this.model = model; - } - - @Override - public boolean getHasCompleted() - { - return hasCompleted; - } - - protected void complete() - { - hasCompleted = true; - resultHandlers.stream().forEach(e -> e.onResult(this)); - } - - protected void failed(Throwable throwable) - { - hasFailed = true; - faultHandlers.stream().forEach(e -> e.onFault(throwable)); - } - - protected void destroy() - { - } -} diff --git a/src/main/java/io/nucleo/scheduler/worker/Worker.java b/src/main/java/io/nucleo/scheduler/worker/Worker.java deleted file mode 100644 index b971760186..0000000000 --- a/src/main/java/io/nucleo/scheduler/worker/Worker.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.nucleo.scheduler.worker; - -/** - * The base interface for all runnable objects (tasks, schedulers) - */ -public interface Worker -{ - /** - * Starts the execution. - */ - void execute(); - - void addResultHandlers(WorkerResultHandler resultHandler); - - void addFaultHandlers(WorkerFaultHandler faultHandler); - - boolean getHasCompleted(); - -} diff --git a/src/main/java/io/nucleo/scheduler/worker/WorkerFaultHandler.java b/src/main/java/io/nucleo/scheduler/worker/WorkerFaultHandler.java deleted file mode 100644 index 944307afb9..0000000000 --- a/src/main/java/io/nucleo/scheduler/worker/WorkerFaultHandler.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.nucleo.scheduler.worker; - -public interface WorkerFaultHandler -{ - void onFault(Throwable throwable); -} diff --git a/src/main/java/io/nucleo/scheduler/worker/WorkerResultHandler.java b/src/main/java/io/nucleo/scheduler/worker/WorkerResultHandler.java deleted file mode 100644 index 8e3eb016db..0000000000 --- a/src/main/java/io/nucleo/scheduler/worker/WorkerResultHandler.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.nucleo.scheduler.worker; - -public interface WorkerResultHandler -{ - void onResult(Worker worker); -} diff --git a/src/test/java/io/bitsquare/BitSquareTestSuite.java b/src/test/java/io/bitsquare/BitSquareTestSuite.java index c8f78861fa..1d67032b68 100644 --- a/src/test/java/io/bitsquare/BitSquareTestSuite.java +++ b/src/test/java/io/bitsquare/BitSquareTestSuite.java @@ -3,7 +3,6 @@ package io.bitsquare; import io.bitsquare.btc.BtcValidatorTest; import io.bitsquare.gui.util.BitSquareConverterTest; import io.bitsquare.gui.util.BitSquareValidatorTest; -import io.nucleo.scheduler.SequenceSchedulerTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -12,7 +11,6 @@ import org.junit.runners.Suite; BtcValidatorTest.class, BitSquareConverterTest.class, BitSquareValidatorTest.class, - SequenceSchedulerTest.class }) public class BitSquareTestSuite diff --git a/src/test/java/io/nucleo/scheduler/SequenceSchedulerTest.java b/src/test/java/io/nucleo/scheduler/SequenceSchedulerTest.java deleted file mode 100644 index f4539889d5..0000000000 --- a/src/test/java/io/nucleo/scheduler/SequenceSchedulerTest.java +++ /dev/null @@ -1,228 +0,0 @@ -package io.nucleo.scheduler; - -import io.nucleo.scheduler.tasks.SyncWorker1; -import io.nucleo.scheduler.tasks.SyncWorker2; -import io.nucleo.scheduler.worker.Worker; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.*; - -public class SequenceSchedulerTest -{ - private final boolean[] hasCompleted = new boolean[1]; - private final boolean[] hasFailed = new boolean[1]; - private final boolean[] worker1HasCompleted = new boolean[1]; - private final boolean[] worker1HasFailed = new boolean[1]; - private final boolean[] worker2HasCompleted = new boolean[1]; - private final boolean[] worker2HasFailed = new boolean[1]; - private SequenceScheduler sequenceScheduler; - private Map model = new HashMap<>(); - private List workerList = new ArrayList<>(); - private Throwable worker1Throwable; - - @Before - public void setUp() - { - sequenceScheduler = new SequenceScheduler(); - sequenceScheduler.addResultHandlers((worker) -> { - hasCompleted[0] = true; - }); - sequenceScheduler.addFaultHandlers(throwable -> { - hasFailed[0] = true; - }); - } - - @After - public void tearDown() throws Exception - { - hasCompleted[0] = false; - hasFailed[0] = false; - workerList.clear(); - model.clear(); - worker1Throwable = null; - } - - @Test - public void testEmpty() - { - sequenceScheduler.execute(); - assertTrue(sequenceScheduler.getHasCompleted()); - assertTrue(hasCompleted[0]); - assertFalse(hasFailed[0]); - } - - @Test - public void testEmpty2() - { - sequenceScheduler.setWorkers(workerList); - sequenceScheduler.execute(); - assertTrue(sequenceScheduler.getHasCompleted()); - assertTrue(hasCompleted[0]); - assertFalse(hasFailed[0]); - } - - - @Test - public void testOneWithCompleted() - { - Worker worker1 = getWorker1(false); - workerList.add(worker1); - sequenceScheduler.setWorkers(workerList); - sequenceScheduler.execute(); - - assertTrue(sequenceScheduler.getHasCompleted()); - assertTrue(hasCompleted[0]); - assertFalse(hasFailed[0]); - - assertTrue(worker1.getHasCompleted()); - assertTrue(worker1HasCompleted[0]); - assertFalse(worker1HasFailed[0]); - } - - @Test - public void testOneWithFailed() - { - Worker worker1 = getWorker1(true); - workerList.add(worker1); - sequenceScheduler.setWorkers(workerList); - sequenceScheduler.execute(); - - assertFalse(sequenceScheduler.getHasCompleted()); - assertFalse(hasCompleted[0]); - assertTrue(hasFailed[0]); - - assertFalse(worker1.getHasCompleted()); - assertFalse(worker1HasCompleted[0]); - assertTrue(worker1HasFailed[0]); - assertEquals(SyncWorker1.ERR_MSG, worker1Throwable.getMessage()); - } - - // @Test - public void testTwoCompleted() - { - Worker worker1 = getWorker1(false); - Worker worker2 = getWorker2(false); - workerList.add(worker1); - workerList.add(worker2); - sequenceScheduler.setWorkers(workerList); - sequenceScheduler.execute(); - - assertTrue(sequenceScheduler.getHasCompleted()); - assertTrue(hasCompleted[0]); - assertFalse(hasFailed[0]); - - assertTrue(worker1.getHasCompleted()); - assertTrue(worker1HasCompleted[0]); - assertFalse(worker1HasFailed[0]); - - assertTrue(worker2.getHasCompleted()); - assertTrue(worker2HasCompleted[0]); - assertFalse(worker2HasFailed[0]); - } - - @Test - public void testTwoReverseOrder() - { - model.put("worker1State", ""); - model.put("worker2State", ""); - Worker worker1 = getWorker1(false); - Worker worker2 = getWorker2(false); - workerList.add(worker2); - workerList.add(worker1); - sequenceScheduler.setWorkers(workerList); - sequenceScheduler.setModel(model); - sequenceScheduler.execute(); - - assertEquals(SyncWorker1.STATE, model.get("worker1State")); - assertEquals(SyncWorker2.STATE, model.get("worker2State")); - - assertTrue(sequenceScheduler.getHasCompleted()); - assertTrue(hasCompleted[0]); - assertFalse(hasFailed[0]); - - assertTrue(worker1.getHasCompleted()); - assertTrue(worker1HasCompleted[0]); - assertFalse(worker1HasFailed[0]); - - assertTrue(worker2.getHasCompleted()); - assertTrue(worker2HasCompleted[0]); - assertFalse(worker2HasFailed[0]); - } - - @Test - public void testTwoFirstFailed() - { - Worker worker1 = getWorker1(true); - Worker worker2 = getWorker2(false); - workerList.add(worker1); - workerList.add(worker2); - sequenceScheduler.setWorkers(workerList); - sequenceScheduler.execute(); - - assertFalse(sequenceScheduler.getHasCompleted()); - assertFalse(hasCompleted[0]); - assertTrue(hasFailed[0]); - - assertFalse(worker1.getHasCompleted()); - assertFalse(worker1HasCompleted[0]); - assertTrue(worker1HasFailed[0]); - - assertFalse(worker2.getHasCompleted()); - assertFalse(worker2HasCompleted[0]); - assertFalse(worker2HasFailed[0]); // second has not been executed and is not failed! - } - - @Test - public void testTwoSecondFailed() - { - Worker worker1 = getWorker1(false); - Worker worker2 = getWorker2(true); - workerList.add(worker1); - workerList.add(worker2); - sequenceScheduler.setWorkers(workerList); - sequenceScheduler.execute(); - - assertFalse(sequenceScheduler.getHasCompleted()); - assertFalse(hasCompleted[0]); - assertTrue(hasFailed[0]); - - assertTrue(worker1.getHasCompleted()); - assertTrue(worker1HasCompleted[0]); - assertFalse(worker1HasFailed[0]); - - assertFalse(worker2.getHasCompleted()); - assertFalse(worker2HasCompleted[0]); - assertTrue(worker2HasFailed[0]); // second has not been executed and is not failed! - } - - private Worker getWorker1(boolean letItFail) - { - Worker worker1 = new SyncWorker1(letItFail); - worker1.addResultHandlers((worker) -> { - worker1HasCompleted[0] = true; - }); - worker1.addFaultHandlers(throwable -> { - worker1HasFailed[0] = true; - worker1Throwable = throwable; - }); - return worker1; - } - - private Worker getWorker2(boolean letItFail) - { - Worker worker2 = new SyncWorker2(letItFail); - worker2.addResultHandlers((worker) -> { - worker2HasCompleted[0] = true; - }); - worker2.addFaultHandlers(throwable -> { - worker2HasFailed[0] = true; - }); - return worker2; - } -} diff --git a/src/test/java/io/nucleo/scheduler/tasks/SyncWorker1.java b/src/test/java/io/nucleo/scheduler/tasks/SyncWorker1.java deleted file mode 100644 index cf0029b209..0000000000 --- a/src/test/java/io/nucleo/scheduler/tasks/SyncWorker1.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.nucleo.scheduler.tasks; - -import java.util.Map; - -public class SyncWorker1 extends AbstractTask -{ - - public static String ERR_MSG = "Failure message"; - public static String STATE = "ok"; - private boolean letItFail; - - public SyncWorker1(boolean letItFail) - { - - this.letItFail = letItFail; - } - - @Override - public void execute() - { - System.out.println("execute " + this); - if (model != null) ((Map) model).put("worker1State", STATE); - if (letItFail) - failed(new Exception(ERR_MSG)); - else - complete(); - } - -} diff --git a/src/test/java/io/nucleo/scheduler/tasks/SyncWorker2.java b/src/test/java/io/nucleo/scheduler/tasks/SyncWorker2.java deleted file mode 100644 index 2f59630bec..0000000000 --- a/src/test/java/io/nucleo/scheduler/tasks/SyncWorker2.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.nucleo.scheduler.tasks; - -import java.util.Map; - -public class SyncWorker2 extends AbstractTask -{ - public static String ERR_MSG = "Failure message"; - public static String STATE = "ok"; - private boolean letItFail; - - public SyncWorker2(boolean letItFail) - { - this.letItFail = letItFail; - } - - @Override - public void execute() - { - System.out.println("execute " + this); - if (model != null) ((Map) model).put("worker2State", STATE); - if (letItFail) - failed(new Exception(ERR_MSG)); - else - complete(); - } - -}