From af5949540d6abfedda8ea6d1c16d9e6fabcf762e Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 25 Mar 2015 02:07:23 +0100 Subject: [PATCH] Fix bug with offer remove (arbitrator, locale) --- .../io/bitsquare/arbitration/Arbitrator.java | 11 +- .../java/io/bitsquare/btc/AddressEntry.java | 6 - .../profile/ArbitratorProfileView.java | 2 +- .../ArbitratorRegistrationView.java | 6 +- .../bitsquare/gui/main/debug/DebugView.java | 2 - .../pending/PendingTradesDataModel.java | 4 +- .../main/java/io/bitsquare/offer/Offer.java | 12 +- .../offer/tomp2p/TomP2POfferBookService.java | 10 ++ .../p2p/tomp2p/TomP2PDHTService.java | 7 +- .../java/io/bitsquare/trade/OffererTrade.java | 42 +++++ .../java/io/bitsquare/trade/TakerTrade.java | 39 ++++ .../main/java/io/bitsquare/trade/Trade.java | 130 ++++++++------ .../java/io/bitsquare/trade/TradeList.java | 8 +- .../java/io/bitsquare/trade/TradeManager.java | 170 +++++++----------- .../io/bitsquare/trade/protocol/Protocol.java | 26 +++ .../protocol/trade/SharedTradeModel.java | 1 + .../trade/offerer/OffererAsBuyerProtocol.java | 5 +- ...etupListenerForBlockChainConfirmation.java | 62 ------- .../trade/taker/TakerAsSellerProtocol.java | 7 +- ...etupListenerForBlockChainConfirmation.java | 62 ------- 20 files changed, 292 insertions(+), 320 deletions(-) create mode 100644 core/src/main/java/io/bitsquare/trade/OffererTrade.java create mode 100644 core/src/main/java/io/bitsquare/trade/TakerTrade.java create mode 100644 core/src/main/java/io/bitsquare/trade/protocol/Protocol.java delete mode 100644 core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SetupListenerForBlockChainConfirmation.java delete mode 100644 core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SetupListenerForBlockChainConfirmation.java diff --git a/core/src/main/java/io/bitsquare/arbitration/Arbitrator.java b/core/src/main/java/io/bitsquare/arbitration/Arbitrator.java index 87e9668a64..1c9ad38beb 100644 --- a/core/src/main/java/io/bitsquare/arbitration/Arbitrator.java +++ b/core/src/main/java/io/bitsquare/arbitration/Arbitrator.java @@ -30,7 +30,6 @@ import java.security.PublicKey; import java.util.Arrays; import java.util.List; -import java.util.Locale; import java.util.Objects; import javax.inject.Inject; @@ -83,7 +82,9 @@ public class Arbitrator implements Serializable { // editable private ID_TYPE idType; - private List languages; + // TODO languages breaks something in serialisation with TomP2P when uing Locale. cannot remove an offer + private List languages; + private Coin fee; private List arbitrationMethods; private List idVerifications; @@ -119,7 +120,7 @@ public class Arbitrator implements Serializable { this.p2pSigPubKey = user.getP2PSigPubKey(); this.name = "Manfred Karrer"; this.idType = Arbitrator.ID_TYPE.REAL_LIFE_ID; - this.languages = Arrays.asList(LanguageUtil.getDefaultLanguageLocale()); + this.languages = Arrays.asList(LanguageUtil.getDefaultLanguageLocale().getISO3Language()); this.reputation = new Reputation(); this.fee = Coin.parseCoin("0.1"); this.arbitrationMethods = Arrays.asList(Arbitrator.METHOD.TLS_NOTARY); @@ -181,7 +182,7 @@ public class Arbitrator implements Serializable { doSave(); } - public void setLanguages(List languages) { + public void setLanguages(List languages) { this.languages = languages; doSave(); } @@ -231,7 +232,7 @@ public class Arbitrator implements Serializable { return idType; } - public List getLanguages() { + public List getLanguages() { return languages; } diff --git a/core/src/main/java/io/bitsquare/btc/AddressEntry.java b/core/src/main/java/io/bitsquare/btc/AddressEntry.java index ada686630c..963a96a2d8 100644 --- a/core/src/main/java/io/bitsquare/btc/AddressEntry.java +++ b/core/src/main/java/io/bitsquare/btc/AddressEntry.java @@ -23,8 +23,6 @@ import org.bitcoinj.crypto.DeterministicKey; import java.io.Serializable; -import java.util.Arrays; - /** * Is a minimalistic wallet abstraction used to separate transactions between different activities like: * Registration, trade and arbiter deposit. @@ -96,10 +94,6 @@ public class AddressEntry implements Serializable { return "AddressEntry{" + "offerId='" + offerId + ", addressContext=" + context + - ", keyPair=" + keyPair + - ", pubKey=" + Arrays.toString(pubKey) + - ", pubKeyHash=" + Arrays.toString(pubKeyHash) + - ", params=" + params + '}'; } } diff --git a/core/src/main/java/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileView.java b/core/src/main/java/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileView.java index 0a2d4d6535..d484d9e47c 100644 --- a/core/src/main/java/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileView.java +++ b/core/src/main/java/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileView.java @@ -59,7 +59,7 @@ public class ArbitratorProfileView extends AbstractView { nameLabel.setText(name); nameTextField.setText(arbitrator.getName()); - languagesTextField.setText(formatter.languageLocalesToString(arbitrator.getLanguages())); + // languagesTextField.setText(formatter.languageLocalesToString(arbitrator.getLanguages())); reputationTextField.setText(arbitrator.getReputation().toString()); feeTextField.setText(String.valueOf(arbitrator.getFee() + " BTC")); methodsTextField.setText(formatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods())); diff --git a/core/src/main/java/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationView.java b/core/src/main/java/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationView.java index 52bfdd3b74..9deba56694 100644 --- a/core/src/main/java/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationView.java +++ b/core/src/main/java/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationView.java @@ -249,7 +249,7 @@ public class ArbitratorRegistrationView extends ActivatableView stateProperty; + transient private ObjectProperty stateProperty = new SimpleObjectProperty<>(State.UNKNOWN); /////////////////////////////////////////////////////////////////////////////////////////// @@ -137,6 +135,9 @@ public class Offer implements Serializable { stateProperty().set(state); } + public void setOfferFeePaymentTxID(String offerFeePaymentTxID) { + this.offerFeePaymentTxID = offerFeePaymentTxID; + } /////////////////////////////////////////////////////////////////////////////////////////// // Getters @@ -205,10 +206,6 @@ public class Offer implements Serializable { return offerFeePaymentTxID; } - public void setOfferFeePaymentTxID(String offerFeePaymentTxID) { - this.offerFeePaymentTxID = offerFeePaymentTxID; - } - public List getArbitrators() { return arbitrators; } @@ -277,7 +274,6 @@ public class Offer implements Serializable { ", fiatPrice=" + fiatPrice + ", amount=" + amount + ", minAmount=" + minAmount + - ", p2pSigPubKey=" + p2pSigPubKey + ", fiatAccountType=" + fiatAccountType + ", bankAccountCountry=" + bankAccountCountry + ", securityDeposit=" + securityDeposit + diff --git a/core/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferBookService.java b/core/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferBookService.java index d167dc98a3..d7ea97ac24 100644 --- a/core/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferBookService.java +++ b/core/src/main/java/io/bitsquare/offer/tomp2p/TomP2POfferBookService.java @@ -64,6 +64,7 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo @Override public void addOffer(Offer offer, ResultHandler resultHandler, FaultHandler faultHandler) { + log.debug("addOffer " + offer); Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode()); try { final Data offerData = new Data(offer); @@ -108,6 +109,7 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo } public void removeOffer(Offer offer, ResultHandler resultHandler, FaultHandler faultHandler) { + log.debug("removeOffer " + offer); Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode()); try { final Data offerData = new Data(offer); @@ -170,6 +172,14 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo try { Object offerDataObject = offerData.object(); if (offerDataObject instanceof Offer) { + + try { + Data offerData1 = new Data(offerDataObject); + log.trace("-------------------------- getOffers hash" + offerData1.hash().toString()); + } catch (IOException e) { + e.printStackTrace(); + } + offers.add((Offer) offerDataObject); } } catch (ClassNotFoundException | IOException e) { diff --git a/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PDHTService.java b/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PDHTService.java index d07de72440..7361fca1e6 100644 --- a/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PDHTService.java +++ b/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PDHTService.java @@ -163,9 +163,10 @@ public class TomP2PDHTService extends TomP2PService implements DHTService { * @return */ public FuturePut addProtectedDataToMap(Number160 locationKey, Data data) { - log.trace("addProtectedDataToMap"); + log.trace("addProtectedDataToMap locationKey = " + locationKey); data.protectEntry(keyPair); log.trace("addProtectedDataToMap with contentKey " + data.hash().toString()); + return peerDHT.add(locationKey).data(data).keyPair(keyPair).start(); } @@ -178,7 +179,7 @@ public class TomP2PDHTService extends TomP2PService implements DHTService { * @return */ public FutureRemove removeProtectedDataFromMap(Number160 locationKey, Data data) { - log.trace("removeProtectedDataFromMap"); + log.trace("removeProtectedDataFromMap locationKey = " + locationKey); Number160 contentKey = data.hash(); log.trace("removeProtectedDataFromMap with contentKey " + contentKey.toString()); return peerDHT.remove(locationKey).contentKey(contentKey).keyPair(keyPair).start(); @@ -247,7 +248,7 @@ public class TomP2PDHTService extends TomP2PService implements DHTService { log.trace("getDataFromMapOfMyProtectedDomain"); return peerDHT.get(locationKey).all().domainKey(pubKeyHashForMyDomain).start(); } - + /** * Remove all data from map for given locationKey. * Access: Only the domain owner. diff --git a/core/src/main/java/io/bitsquare/trade/OffererTrade.java b/core/src/main/java/io/bitsquare/trade/OffererTrade.java new file mode 100644 index 0000000000..33b6ca2b06 --- /dev/null +++ b/core/src/main/java/io/bitsquare/trade/OffererTrade.java @@ -0,0 +1,42 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.trade; + +import io.bitsquare.offer.Offer; +import io.bitsquare.trade.protocol.trade.offerer.OffererAsBuyerProtocol; + +import java.io.Serializable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OffererTrade extends Trade implements Serializable { + private static final long serialVersionUID = 1; + transient private static final Logger log = LoggerFactory.getLogger(OffererTrade.class); + + + public OffererTrade(Offer offer) { + super(offer); + } + + public void onFiatPaymentStarted() { + ((OffererAsBuyerProtocol) protocol).onFiatPaymentStarted(); + } + + +} diff --git a/core/src/main/java/io/bitsquare/trade/TakerTrade.java b/core/src/main/java/io/bitsquare/trade/TakerTrade.java new file mode 100644 index 0000000000..c8ceee5ee9 --- /dev/null +++ b/core/src/main/java/io/bitsquare/trade/TakerTrade.java @@ -0,0 +1,39 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.trade; + +import io.bitsquare.offer.Offer; +import io.bitsquare.trade.protocol.trade.taker.TakerAsSellerProtocol; + +import java.io.Serializable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TakerTrade extends Trade implements Serializable { + private static final long serialVersionUID = 1; + transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class); + + public TakerTrade(Offer offer) { + super(offer); + } + + public void onFiatPaymentReceived() { + ((TakerAsSellerProtocol) protocol).onFiatPaymentReceived(); + } +} diff --git a/core/src/main/java/io/bitsquare/trade/Trade.java b/core/src/main/java/io/bitsquare/trade/Trade.java index df5aec9ccb..70ad34de39 100644 --- a/core/src/main/java/io/bitsquare/trade/Trade.java +++ b/core/src/main/java/io/bitsquare/trade/Trade.java @@ -18,7 +18,9 @@ package io.bitsquare.trade; import io.bitsquare.offer.Offer; +import io.bitsquare.p2p.MailboxMessage; import io.bitsquare.p2p.Peer; +import io.bitsquare.trade.protocol.Protocol; import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; @@ -30,7 +32,6 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import java.io.IOException; import java.io.Serializable; import java.util.Date; @@ -42,8 +43,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Trade implements Serializable { - private static final long serialVersionUID = -8275323072940974077L; - private static final Logger log = LoggerFactory.getLogger(Trade.class); + protected static final long serialVersionUID = 1; + protected static final Logger log = LoggerFactory.getLogger(Trade.class); /////////////////////////////////////////////////////////////////////////////////////////// @@ -71,7 +72,7 @@ public class Trade implements Serializable { MESSAGE_SENDING_FAILED, FAULT; - private String errorMessage; + protected String errorMessage; public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; @@ -82,28 +83,32 @@ public class Trade implements Serializable { } } - private final Offer offer; - private final Date date; - private ProcessState processState; - private LifeCycleState lifeCycleState; + transient protected Protocol protocol; - private Coin tradeAmount; - private Contract contract; - private String contractAsJson; - private String takerContractSignature; - private String offererContractSignature; - private Transaction depositTx; - private Transaction payoutTx; - private Peer tradingPeer; - private int depthInBlocks = 0; + protected MailboxMessage mailboxMessage; + + protected final Offer offer; + protected final Date date; + protected ProcessState processState; + protected LifeCycleState lifeCycleState; + + protected Coin tradeAmount; + protected Contract contract; + protected String contractAsJson; + protected String takerContractSignature; + protected String offererContractSignature; + protected Transaction depositTx; + protected Transaction payoutTx; + protected Peer tradingPeer; + protected int depthInBlocks = 0; // For changing values we use properties to get binding support in the UI (table) // When serialized those transient properties are not instantiated, so we instantiate them in the getters at first - // access. Only use the accessor not the private field. - transient private ObjectProperty _tradeAmount; - transient private ObjectProperty _tradeVolume; - transient private ObjectProperty _processState; - transient private ObjectProperty _lifeCycleState; + // access. Only use the accessor not the protected field. + transient protected ObjectProperty _tradeAmount; + transient protected ObjectProperty _tradeVolume; + transient protected ObjectProperty _processState; + transient protected ObjectProperty _lifeCycleState; /////////////////////////////////////////////////////////////////////////////////////////// @@ -118,47 +123,36 @@ public class Trade implements Serializable { log.debug("Trade "); } - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - log.debug("Trade writeObject"); - out.defaultWriteObject(); - log.debug("Trade writeObject"); + /////////////////////////////////////////////////////////////////////////////////////////// + // Methods + /////////////////////////////////////////////////////////////////////////////////////////// + + + public void disposeProtocol() { + if (protocol != null) + protocol.cleanup(); + protocol = null; } - private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { - log.debug("Trade readObject"); - in.defaultReadObject(); - //TODO cannot call yet as persistence need to be refactored first. cann be called only after bitcoinJ is initialized as serialized tx objects throw - // exceptions - //setConfidenceListener(); - log.debug("Trade readObject"); + public void setMailboxMessage(MailboxMessage mailboxMessage) { + this.mailboxMessage = mailboxMessage; + if (protocol != null) + protocol.setMailboxMessage(mailboxMessage); } - private void setConfidenceListener() { - // log.debug("setConfidenceListener called. depthInBlocks=" + depthInBlocks + " / depositTx != null ? " + (depositTx.toString() != null)); - if (depositTx != null && depthInBlocks == 0) { - TransactionConfidence transactionConfidence = depositTx.getConfidence(); - ListenableFuture future = transactionConfidence.getDepthFuture(1); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(TransactionConfidence result) { - setProcessState(Trade.ProcessState.DEPOSIT_CONFIRMED); - } + public void setProtocol(Protocol protocol) { + this.protocol = protocol; - @Override - public void onFailure(Throwable t) { - t.printStackTrace(); - log.error(t.getMessage()); - Throwables.propagate(t); - } - }); - } + if (mailboxMessage != null) + protocol.setMailboxMessage(mailboxMessage); } - + /////////////////////////////////////////////////////////////////////////////////////////// // Setters /////////////////////////////////////////////////////////////////////////////////////////// + public void setTradingPeer(Peer tradingPeer) { this.tradingPeer = tradingPeer; } @@ -298,12 +292,38 @@ public class Trade implements Serializable { return _lifeCycleState; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + protected void setConfidenceListener() { + TransactionConfidence transactionConfidence = depositTx.getConfidence(); + ListenableFuture future = transactionConfidence.getDepthFuture(1); + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(TransactionConfidence result) { + setProcessState(Trade.ProcessState.DEPOSIT_CONFIRMED); + } + + @Override + public void onFailure(Throwable t) { + t.printStackTrace(); + log.error(t.getMessage()); + Throwables.propagate(t); + } + }); + } + @Override public String toString() { return "Trade{" + - "offer=" + offer + + "protocol=" + protocol + + ", mailboxMessage=" + mailboxMessage + + ", offer=" + offer + ", date=" + date + - ", state=" + processState + + ", processState=" + processState + + ", lifeCycleState=" + lifeCycleState + ", tradeAmount=" + tradeAmount + ", contract=" + contract + ", contractAsJson='" + contractAsJson + '\'' + @@ -311,6 +331,8 @@ public class Trade implements Serializable { ", offererContractSignature='" + offererContractSignature + '\'' + ", depositTx=" + depositTx + ", payoutTx=" + payoutTx + + ", tradingPeer=" + tradingPeer + + ", depthInBlocks=" + depthInBlocks + '}'; } } diff --git a/core/src/main/java/io/bitsquare/trade/TradeList.java b/core/src/main/java/io/bitsquare/trade/TradeList.java index 37b3a1d93d..8f09809cc6 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeList.java +++ b/core/src/main/java/io/bitsquare/trade/TradeList.java @@ -30,12 +30,12 @@ import javafx.collections.ObservableList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class TradeList extends ArrayList implements Serializable { +public class TradeList extends ArrayList implements Serializable { private static final long serialVersionUID = 1L; transient private static final Logger log = LoggerFactory.getLogger(TradeList.class); transient final private Storage storage; - transient private ObservableList observableList; + transient private ObservableList observableList; public TradeList(File storageDir, String fileName) { this.storage = new Storage<>(storageDir); @@ -51,7 +51,7 @@ public class TradeList extends ArrayList implements Serializable { } @Override - public boolean add(Trade trade) { + public boolean add(T trade) { boolean result = super.add(trade); observableList.add(trade); storage.save(); @@ -66,7 +66,7 @@ public class TradeList extends ArrayList implements Serializable { return result; } - public ObservableList getObservableList() { + public ObservableList getObservableList() { return observableList; } diff --git a/core/src/main/java/io/bitsquare/trade/TradeManager.java b/core/src/main/java/io/bitsquare/trade/TradeManager.java index 6c3dd6dc84..0b67e719f4 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/core/src/main/java/io/bitsquare/trade/TradeManager.java @@ -51,6 +51,7 @@ import org.bitcoinj.core.Coin; import org.bitcoinj.utils.Fiat; import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -62,6 +63,8 @@ import javax.inject.Named; import javafx.collections.ObservableList; +import net.tomp2p.storage.Data; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -80,14 +83,11 @@ public class TradeManager { private final OfferBookService offerBookService; private File storageDir; - private final Map takerAsSellerProtocolMap = new HashMap<>(); - private final Map offererAsBuyerProtocolMap = new HashMap<>(); private final Map checkOfferAvailabilityProtocolMap = new HashMap<>(); - private final TradeList openOfferTrades; - private final TradeList pendingTrades; - private final TradeList closedTrades; - private final Map mailboxMessages = new HashMap<>(); + private final TradeList openOfferTrades; + private final TradeList pendingTrades; + private final TradeList closedTrades; /////////////////////////////////////////////////////////////////////////////////////////// @@ -111,9 +111,9 @@ public class TradeManager { this.offerBookService = offerBookService; this.storageDir = storageDir; - this.openOfferTrades = new TradeList(storageDir, "OpenOfferTrades"); - this.pendingTrades = new TradeList(storageDir, "PendingTrades"); - this.closedTrades = new TradeList(storageDir, "ClosedTrades"); + this.openOfferTrades = new TradeList<>(storageDir, "OpenOfferTrades"); + this.pendingTrades = new TradeList<>(storageDir, "PendingTrades"); + this.closedTrades = new TradeList<>(storageDir, "ClosedTrades"); } @@ -124,18 +124,18 @@ public class TradeManager { // When all services are initialized we create the protocols for our open offers and persisted not completed pendingTrades // BuyerAcceptsOfferProtocol listens for take offer requests, so we need to instantiate it early. public void onAllServicesInitialized() { - for (Trade trade : openOfferTrades) { - createOffererAsBuyerProtocol(trade); + for (OffererTrade offererTrade : openOfferTrades) { + createOffererAsBuyerProtocol(offererTrade); } for (Trade trade : pendingTrades) { // We continue an interrupted trade. // TODO if the peer has changed its IP address, we need to make another findPeer request. At the moment we use the peer stored in trade to // continue the trade, but that might fail. - if (isMyOffer(trade.getOffer())) { - createOffererAsBuyerProtocol(trade); + if (trade instanceof OffererTrade) { + createOffererAsBuyerProtocol((OffererTrade) trade); } - else { - createTakerAsSellerProtocol(trade); + else if (trade instanceof TakerTrade) { + createTakerAsSellerProtocol((TakerTrade) trade); } } @@ -179,16 +179,24 @@ public class TradeManager { accountSettings.getAcceptedCountries(), accountSettings.getAcceptedLanguageLocales()); + try { + Data offerData = new Data(offer); + log.trace("-------------------------- placeOffer hash" + offerData.hash().toString()); + } catch (IOException e) { + e.printStackTrace(); + } + PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService); PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol( model, (transaction) -> { - Trade trade = new Trade(offer); - trade.setLifeCycleState(Trade.LifeCycleState.OPEN_OFFER); - openOfferTrades.add(trade); + OffererTrade offererTrade = new OffererTrade(offer); + offererTrade.setLifeCycleState(Trade.LifeCycleState.OPEN_OFFER); + openOfferTrades.add(offererTrade); - createOffererAsBuyerProtocol(trade); + OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade); + offererTrade.setProtocol(protocol); resultHandler.handleResult(transaction); }, (message) -> errorMessageHandler.handleErrorMessage(message) @@ -249,23 +257,19 @@ public class TradeManager { // Trade /////////////////////////////////////////////////////////////////////////////////////////// - public void onFiatPaymentStarted(String tradeId) { - // TODO remove if check when persistence is impl. - if (offererAsBuyerProtocolMap.containsKey(tradeId)) { - offererAsBuyerProtocolMap.get(tradeId).onFiatPaymentStarted(); - // persistPendingTrades(); - } + public void onFiatPaymentStarted(Trade trade) { + ((OffererTrade) trade).onFiatPaymentStarted(); } - public void onFiatPaymentReceived(String tradeId) { - takerAsSellerProtocolMap.get(tradeId).onFiatPaymentReceived(); + public void onFiatPaymentReceived(Trade trade) { + ((TakerTrade) trade).onFiatPaymentReceived(); } public void onWithdrawAtTradeCompleted(Trade trade) { trade.setLifeCycleState(Trade.LifeCycleState.COMPLETED); pendingTrades.remove(trade); closedTrades.add(trade); - removeFromProtocolMap(trade); + trade.disposeProtocol(); } @@ -282,7 +286,7 @@ public class TradeManager { // Getters /////////////////////////////////////////////////////////////////////////////////////////// - public ObservableList getOpenOfferTrades() { + public ObservableList getOpenOfferTrades() { return openOfferTrades.getObservableList(); } @@ -310,24 +314,19 @@ public class TradeManager { offerBookService.removeOffer(offer, () -> { offer.setState(Offer.State.REMOVED); - - Optional result = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny(); - if (result.isPresent()) { - Trade trade = result.get(); - openOfferTrades.remove(trade); + Optional offererTradeOptional = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny(); + if (offererTradeOptional.isPresent()) { + OffererTrade offererTrade = offererTradeOptional.get(); + openOfferTrades.remove(offererTrade); if (isCancelRequest) { - trade.setLifeCycleState(Trade.LifeCycleState.CANCELED); - closedTrades.add(trade); + offererTrade.setLifeCycleState(Trade.LifeCycleState.CANCELED); + closedTrades.add(offererTrade); + offererTrade.disposeProtocol(); } } disposeCheckOfferAvailabilityRequest(offer); - String offerId = offer.getId(); - if (isCancelRequest && offererAsBuyerProtocolMap.containsKey(offerId)) { - offererAsBuyerProtocolMap.get(offerId).cleanup(); - offererAsBuyerProtocolMap.remove(offerId); - } resultHandler.handleResult(); }, @@ -354,23 +353,23 @@ public class TradeManager { /////////////////////////////////////////////////////////////////////////////////////////// private Trade takeAvailableOffer(Coin amount, Offer offer, Peer peer) { - Trade trade = new Trade(offer); - trade.setTradeAmount(amount); - trade.setTradingPeer(peer); - trade.setLifeCycleState(Trade.LifeCycleState.PENDING); - pendingTrades.add(trade); + TakerTrade takerTrade = new TakerTrade(offer); + takerTrade.setTradeAmount(amount); + takerTrade.setTradingPeer(peer); + takerTrade.setLifeCycleState(Trade.LifeCycleState.PENDING); + pendingTrades.add(takerTrade); - TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(trade); - //trade.setProtocol(sellerTakesOfferProtocol); + TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(takerTrade); + takerTrade.setProtocol(sellerTakesOfferProtocol); sellerTakesOfferProtocol.takeAvailableOffer(); - return trade; + return takerTrade; } - private TakerAsSellerProtocol createTakerAsSellerProtocol(Trade trade) { - trade.processStateProperty().addListener((ov, oldValue, newValue) -> { - log.debug("trade state = " + newValue); + private TakerAsSellerProtocol createTakerAsSellerProtocol(TakerTrade takerTrade) { + takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { + log.debug("takerTrade state = " + newValue); switch (newValue) { case INIT: break; @@ -384,17 +383,17 @@ public class TradeManager { break; case MESSAGE_SENDING_FAILED: case FAULT: - trade.setLifeCycleState(Trade.LifeCycleState.FAILED); - removeFromProtocolMap(trade); + takerTrade.setLifeCycleState(Trade.LifeCycleState.FAILED); + takerTrade.disposeProtocol(); break; default: - log.warn("Unhandled trade state: " + newValue); + log.warn("Unhandled takerTrade state: " + newValue); break; } }); TakerAsSellerModel model = new TakerAsSellerModel( - trade, + takerTrade, messageService, mailboxService, walletService, @@ -403,20 +402,13 @@ public class TradeManager { user, storageDir); - TakerAsSellerProtocol protocol = new TakerAsSellerProtocol(model); - takerAsSellerProtocolMap.put(trade.getId(), protocol); - - if (mailboxMessages.containsKey(trade.getId())) { - log.debug("TakerAsSellerProtocol setMailboxMessage " + trade.getId()); - protocol.setMailboxMessage(mailboxMessages.get(trade.getId())); - } - return protocol; + return new TakerAsSellerProtocol(model); } - private void createOffererAsBuyerProtocol(Trade trade) { + private OffererAsBuyerProtocol createOffererAsBuyerProtocol(OffererTrade offererTrade) { OffererAsBuyerModel model = new OffererAsBuyerModel( - trade, + offererTrade, messageService, mailboxService, walletService, @@ -427,8 +419,8 @@ public class TradeManager { // TODO check, remove listener - trade.processStateProperty().addListener((ov, oldValue, newValue) -> { - log.debug("trade state = " + newValue); + offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { + log.debug("offererTrade state = " + newValue); switch (newValue) { case INIT: break; @@ -436,12 +428,12 @@ public class TradeManager { // persistPendingTrades(); break; case DEPOSIT_PUBLISHED: - removeOpenOffer(trade.getOffer(), + removeOpenOffer(offererTrade.getOffer(), () -> log.debug("remove offer was successful"), (message) -> log.error(message), false); model.trade.setLifeCycleState(Trade.LifeCycleState.PENDING); - pendingTrades.add(trade); + pendingTrades.add(offererTrade); break; case DEPOSIT_CONFIRMED: case FIAT_PAYMENT_STARTED: @@ -452,32 +444,16 @@ public class TradeManager { case TAKE_OFFER_FEE_PUBLISH_FAILED: case MESSAGE_SENDING_FAILED: case FAULT: - trade.setLifeCycleState(Trade.LifeCycleState.FAILED); - removeFromProtocolMap(trade); + offererTrade.setLifeCycleState(Trade.LifeCycleState.FAILED); + offererTrade.disposeProtocol(); break; default: - log.warn("Unhandled trade state: " + newValue); + log.warn("Unhandled offererTrade state: " + newValue); break; } }); - OffererAsBuyerProtocol protocol = new OffererAsBuyerProtocol(model); - offererAsBuyerProtocolMap.put(trade.getId(), protocol); - if (mailboxMessages.containsKey(trade.getId())) { - log.debug("OffererAsBuyerProtocol setMailboxMessage " + trade.getId()); - protocol.setMailboxMessage(mailboxMessages.get(trade.getId())); - } - } - - private void removeFromProtocolMap(Trade trade) { - if (takerAsSellerProtocolMap.containsKey(trade.getId())) { - takerAsSellerProtocolMap.get(trade.getId()).cleanup(); - takerAsSellerProtocolMap.remove(trade.getId()); - } - else if (offererAsBuyerProtocolMap.containsKey(trade.getId())) { - offererAsBuyerProtocolMap.get(trade.getId()).cleanup(); - offererAsBuyerProtocolMap.remove(trade.getId()); - } + return new OffererAsBuyerProtocol(model); } @@ -493,23 +469,15 @@ public class TradeManager { if (mailboxMessage instanceof TradeMessage) { String tradeId = ((TradeMessage) mailboxMessage).tradeId; - mailboxMessages.put(tradeId, mailboxMessage); - log.trace("added mailboxMessage with tradeID " + tradeId); - if (takerAsSellerProtocolMap.containsKey(tradeId)) { - takerAsSellerProtocolMap.get(tradeId).setMailboxMessage(mailboxMessage); - log.trace("sellerAsTakerProtocol exist with tradeID " + tradeId); - } - if (offererAsBuyerProtocolMap.containsKey(tradeId)) { - offererAsBuyerProtocolMap.get(tradeId).setMailboxMessage(mailboxMessage); - log.trace("buyerAcceptsOfferProtocol exist with tradeID " + tradeId); - } + Optional tradeOptional = pendingTrades.stream().filter(e -> e.getId().equals(tradeId)).findAny(); + if (tradeOptional.isPresent()) + tradeOptional.get().setMailboxMessage(mailboxMessage); } } catch (Throwable e) { e.printStackTrace(); log.error(e.getMessage()); } } - log.trace("mailboxMessages.size=" + mailboxMessages.size()); } private void emptyMailbox() { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/Protocol.java b/core/src/main/java/io/bitsquare/trade/protocol/Protocol.java new file mode 100644 index 0000000000..4f083b56a5 --- /dev/null +++ b/core/src/main/java/io/bitsquare/trade/protocol/Protocol.java @@ -0,0 +1,26 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.trade.protocol; + +import io.bitsquare.p2p.MailboxMessage; + +public interface Protocol { + void cleanup(); + + void setMailboxMessage(MailboxMessage mailboxMessage); +} diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/SharedTradeModel.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/SharedTradeModel.java index 69a38e24f1..e397fec035 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/SharedTradeModel.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/SharedTradeModel.java @@ -71,6 +71,7 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable { id = offer.getId(); tradeWalletService = walletService.getTradeWalletService(); //TODO use default arbitrator for now + arbitratorPubKey = offer.getArbitrators().get(0).getPubKey(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/OffererAsBuyerProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/OffererAsBuyerProtocol.java index 2d8d41694f..1339648b3e 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/OffererAsBuyerProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/OffererAsBuyerProtocol.java @@ -24,6 +24,7 @@ import io.bitsquare.p2p.MessageHandler; import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.Protocol; import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage; import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage; import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage; @@ -39,7 +40,6 @@ import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestOffererPubl import io.bitsquare.trade.protocol.trade.offerer.tasks.RequestTakerDepositPayment; import io.bitsquare.trade.protocol.trade.offerer.tasks.SendBankTransferStartedMessage; import io.bitsquare.trade.protocol.trade.offerer.tasks.SendDepositTxToTaker; -import io.bitsquare.trade.protocol.trade.offerer.tasks.SetupListenerForBlockChainConfirmation; import io.bitsquare.trade.protocol.trade.offerer.tasks.SignAndPublishDepositTx; import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract; import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment; @@ -52,7 +52,7 @@ import org.slf4j.LoggerFactory; import static io.bitsquare.util.Validator.*; -public class OffererAsBuyerProtocol { +public class OffererAsBuyerProtocol implements Protocol { private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerProtocol.class); private final OffererAsBuyerModel model; @@ -156,7 +156,6 @@ public class OffererAsBuyerProtocol { VerifyTakerAccount.class, VerifyAndSignContract.class, SignAndPublishDepositTx.class, - SetupListenerForBlockChainConfirmation.class, SendDepositTxToTaker.class ); taskRunner.run(); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SetupListenerForBlockChainConfirmation.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SetupListenerForBlockChainConfirmation.java deleted file mode 100644 index 60cc0ddbee..0000000000 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/offerer/tasks/SetupListenerForBlockChainConfirmation.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Bitsquare. - * - * Bitsquare is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bitsquare is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bitsquare. If not, see . - */ - -package io.bitsquare.trade.protocol.trade.offerer.tasks; - -import io.bitsquare.common.taskrunner.Task; -import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; -import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; - -import org.bitcoinj.core.TransactionConfidence; - -import com.google.common.base.Throwables; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SetupListenerForBlockChainConfirmation extends Task { - private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class); - - public SetupListenerForBlockChainConfirmation(TaskRunner taskHandler, OffererAsBuyerModel model) { - super(taskHandler, model); - } - - @Override - protected void doRun() { - TransactionConfidence transactionConfidence = model.trade.getDepositTx().getConfidence(); - ListenableFuture future = transactionConfidence.getDepthFuture(1); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(TransactionConfidence result) { - model.trade.setProcessState(Trade.ProcessState.DEPOSIT_CONFIRMED); - } - - @Override - public void onFailure(Throwable t) { - t.printStackTrace(); - log.error(t.getMessage()); - Throwables.propagate(t); - } - }); - - complete(); - } -} diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/TakerAsSellerProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/TakerAsSellerProtocol.java index f2acb5b8bc..ca7f0432bd 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/TakerAsSellerProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/TakerAsSellerProtocol.java @@ -23,11 +23,11 @@ import io.bitsquare.p2p.Message; import io.bitsquare.p2p.MessageHandler; import io.bitsquare.p2p.Peer; import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.Protocol; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage; -import io.bitsquare.trade.protocol.trade.taker.tasks.SetupListenerForBlockChainConfirmation; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.tasks.BroadcastTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract; @@ -49,7 +49,7 @@ import org.slf4j.LoggerFactory; import static io.bitsquare.util.Validator.nonEmptyStringOf; -public class TakerAsSellerProtocol { +public class TakerAsSellerProtocol implements Protocol { private static final Logger log = LoggerFactory.getLogger(TakerAsSellerProtocol.class); private final TakerAsSellerModel model; @@ -141,8 +141,7 @@ public class TakerAsSellerProtocol { taskRunner.addTasks( ProcessDepositTxPublishedMessage.class, - TakerCommitDepositTx.class, - SetupListenerForBlockChainConfirmation.class + TakerCommitDepositTx.class ); taskRunner.run(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SetupListenerForBlockChainConfirmation.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SetupListenerForBlockChainConfirmation.java deleted file mode 100644 index d0293ad76f..0000000000 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/taker/tasks/SetupListenerForBlockChainConfirmation.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Bitsquare. - * - * Bitsquare is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bitsquare is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bitsquare. If not, see . - */ - -package io.bitsquare.trade.protocol.trade.taker.tasks; - -import io.bitsquare.common.taskrunner.Task; -import io.bitsquare.common.taskrunner.TaskRunner; -import io.bitsquare.trade.Trade; -import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; - -import org.bitcoinj.core.TransactionConfidence; - -import com.google.common.base.Throwables; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SetupListenerForBlockChainConfirmation extends Task { - private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class); - - public SetupListenerForBlockChainConfirmation(TaskRunner taskHandler, TakerAsSellerModel model) { - super(taskHandler, model); - } - - @Override - protected void doRun() { - TransactionConfidence transactionConfidence = model.trade.getDepositTx().getConfidence(); - ListenableFuture future = transactionConfidence.getDepthFuture(1); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(TransactionConfidence result) { - model.trade.setProcessState(Trade.ProcessState.DEPOSIT_CONFIRMED); - } - - @Override - public void onFailure(Throwable t) { - t.printStackTrace(); - log.error(t.getMessage()); - Throwables.propagate(t); - } - }); - - complete(); - } -}