Fix bug with offer remove (arbitrator, locale)

This commit is contained in:
Manfred Karrer 2015-03-25 02:07:23 +01:00
parent 9cb029c21b
commit af5949540d
20 changed files with 292 additions and 320 deletions

View file

@ -30,7 +30,6 @@ import java.security.PublicKey;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import javax.inject.Inject; import javax.inject.Inject;
@ -83,7 +82,9 @@ public class Arbitrator implements Serializable {
// editable // editable
private ID_TYPE idType; private ID_TYPE idType;
private List<Locale> languages; // TODO languages breaks something in serialisation with TomP2P when uing Locale. cannot remove an offer
private List<String> languages;
private Coin fee; private Coin fee;
private List<METHOD> arbitrationMethods; private List<METHOD> arbitrationMethods;
private List<ID_VERIFICATION> idVerifications; private List<ID_VERIFICATION> idVerifications;
@ -119,7 +120,7 @@ public class Arbitrator implements Serializable {
this.p2pSigPubKey = user.getP2PSigPubKey(); this.p2pSigPubKey = user.getP2PSigPubKey();
this.name = "Manfred Karrer"; this.name = "Manfred Karrer";
this.idType = Arbitrator.ID_TYPE.REAL_LIFE_ID; 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.reputation = new Reputation();
this.fee = Coin.parseCoin("0.1"); this.fee = Coin.parseCoin("0.1");
this.arbitrationMethods = Arrays.asList(Arbitrator.METHOD.TLS_NOTARY); this.arbitrationMethods = Arrays.asList(Arbitrator.METHOD.TLS_NOTARY);
@ -181,7 +182,7 @@ public class Arbitrator implements Serializable {
doSave(); doSave();
} }
public void setLanguages(List<Locale> languages) { public void setLanguages(List<String> languages) {
this.languages = languages; this.languages = languages;
doSave(); doSave();
} }
@ -231,7 +232,7 @@ public class Arbitrator implements Serializable {
return idType; return idType;
} }
public List<Locale> getLanguages() { public List<String> getLanguages() {
return languages; return languages;
} }

View file

@ -23,8 +23,6 @@ import org.bitcoinj.crypto.DeterministicKey;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays;
/** /**
* Is a minimalistic wallet abstraction used to separate transactions between different activities like: * Is a minimalistic wallet abstraction used to separate transactions between different activities like:
* Registration, trade and arbiter deposit. * Registration, trade and arbiter deposit.
@ -96,10 +94,6 @@ public class AddressEntry implements Serializable {
return "AddressEntry{" + return "AddressEntry{" +
"offerId='" + offerId + "offerId='" + offerId +
", addressContext=" + context + ", addressContext=" + context +
", keyPair=" + keyPair +
", pubKey=" + Arrays.toString(pubKey) +
", pubKeyHash=" + Arrays.toString(pubKeyHash) +
", params=" + params +
'}'; '}';
} }
} }

View file

@ -59,7 +59,7 @@ public class ArbitratorProfileView extends AbstractView {
nameLabel.setText(name); nameLabel.setText(name);
nameTextField.setText(arbitrator.getName()); nameTextField.setText(arbitrator.getName());
languagesTextField.setText(formatter.languageLocalesToString(arbitrator.getLanguages())); // languagesTextField.setText(formatter.languageLocalesToString(arbitrator.getLanguages()));
reputationTextField.setText(arbitrator.getReputation().toString()); reputationTextField.setText(arbitrator.getReputation().toString());
feeTextField.setText(String.valueOf(arbitrator.getFee() + " BTC")); feeTextField.setText(String.valueOf(arbitrator.getFee() + " BTC"));
methodsTextField.setText(formatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods())); methodsTextField.setText(formatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods()));

View file

@ -249,7 +249,7 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
arbitrator.setFee(formatter.parseToCoin(arbitrationFeeTextField.getText())); arbitrator.setFee(formatter.parseToCoin(arbitrationFeeTextField.getText()));
arbitrator.setIdType(idType); arbitrator.setIdType(idType);
arbitrator.setIdVerifications(idVerificationList); arbitrator.setIdVerifications(idVerificationList);
arbitrator.setLanguages(languageList); // arbitrator.setLanguages(languageList);
arbitrator.setArbitrationMethods(methodList); arbitrator.setArbitrationMethods(methodList);
arbitrator.setSaveOnEveryUpdate(true); arbitrator.setSaveOnEveryUpdate(true);
@ -346,7 +346,7 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
nameTextField.setText(arbitrator.getName()); nameTextField.setText(arbitrator.getName());
idTypeTextField.setText(BSResources.get(arbitrator.getIdType().toString())); idTypeTextField.setText(BSResources.get(arbitrator.getIdType().toString()));
languagesTextField.setText(formatter.languageLocalesToString(arbitrator.getLanguages())); // languagesTextField.setText(formatter.languageLocalesToString(arbitrator.getLanguages()));
arbitrationFeeTextField.setText(String.valueOf(arbitrator.getFee())); arbitrationFeeTextField.setText(String.valueOf(arbitrator.getFee()));
methodsTextField.setText(formatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods())); methodsTextField.setText(formatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods()));
idVerificationsTextField.setText( idVerificationsTextField.setText(
@ -355,7 +355,7 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
descriptionTextArea.setText(arbitrator.getDescription()); descriptionTextArea.setText(arbitrator.getDescription());
idType = arbitrator.getIdType(); idType = arbitrator.getIdType();
languageList = arbitrator.getLanguages(); // languageList = arbitrator.getLanguages();
methodList = arbitrator.getArbitrationMethods(); methodList = arbitrator.getArbitrationMethods();
idVerificationList = arbitrator.getIdVerifications(); idVerificationList = arbitrator.getIdVerifications();
} }

View file

@ -37,7 +37,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.RequestTakerDepositPayment;
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendBankTransferStartedMessage; 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.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.SignAndPublishDepositTx;
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract; import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract;
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment; import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment;
@ -110,7 +109,6 @@ public class DebugView extends InitializableView {
VerifyTakerAccount.class, VerifyTakerAccount.class,
VerifyAndSignContract.class, VerifyAndSignContract.class,
SignAndPublishDepositTx.class, SignAndPublishDepositTx.class,
SetupListenerForBlockChainConfirmation.class,
SendDepositTxToTaker.class, SendDepositTxToTaker.class,
CreateAndSignPayoutTx.class, CreateAndSignPayoutTx.class,

View file

@ -139,11 +139,11 @@ class PendingTradesDataModel implements Activatable, DataModel {
} }
void fiatPaymentStarted() { void fiatPaymentStarted() {
tradeManager.onFiatPaymentStarted(getTrade().getId()); tradeManager.onFiatPaymentStarted(getTrade());
} }
void fiatPaymentReceived() { void fiatPaymentReceived() {
tradeManager.onFiatPaymentReceived(getTrade().getId()); tradeManager.onFiatPaymentReceived(getTrade());
} }
void withdraw(String toAddress) { void withdraw(String toAddress) {

View file

@ -43,8 +43,6 @@ import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.*; import static com.google.common.base.Preconditions.*;
//TODO flatten down?
public class Offer implements Serializable { public class Offer implements Serializable {
private static final long serialVersionUID = -971164804305475826L; private static final long serialVersionUID = -971164804305475826L;
private transient static final Logger log = LoggerFactory.getLogger(Offer.class); private transient static final Logger log = LoggerFactory.getLogger(Offer.class);
@ -86,7 +84,7 @@ public class Offer implements Serializable {
// Those state properties are transient and only used at runtime! // Those state properties are transient and only used at runtime!
// don't access directly as it might be null; use getStateProperty() which creates an object if not instantiated // don't access directly as it might be null; use getStateProperty() which creates an object if not instantiated
private transient ObjectProperty<State> stateProperty; transient private ObjectProperty<State> stateProperty = new SimpleObjectProperty<>(State.UNKNOWN);
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -137,6 +135,9 @@ public class Offer implements Serializable {
stateProperty().set(state); stateProperty().set(state);
} }
public void setOfferFeePaymentTxID(String offerFeePaymentTxID) {
this.offerFeePaymentTxID = offerFeePaymentTxID;
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Getters // Getters
@ -205,10 +206,6 @@ public class Offer implements Serializable {
return offerFeePaymentTxID; return offerFeePaymentTxID;
} }
public void setOfferFeePaymentTxID(String offerFeePaymentTxID) {
this.offerFeePaymentTxID = offerFeePaymentTxID;
}
public List<Arbitrator> getArbitrators() { public List<Arbitrator> getArbitrators() {
return arbitrators; return arbitrators;
} }
@ -277,7 +274,6 @@ public class Offer implements Serializable {
", fiatPrice=" + fiatPrice + ", fiatPrice=" + fiatPrice +
", amount=" + amount + ", amount=" + amount +
", minAmount=" + minAmount + ", minAmount=" + minAmount +
", p2pSigPubKey=" + p2pSigPubKey +
", fiatAccountType=" + fiatAccountType + ", fiatAccountType=" + fiatAccountType +
", bankAccountCountry=" + bankAccountCountry + ", bankAccountCountry=" + bankAccountCountry +
", securityDeposit=" + securityDeposit + ", securityDeposit=" + securityDeposit +

View file

@ -64,6 +64,7 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
@Override @Override
public void addOffer(Offer offer, ResultHandler resultHandler, FaultHandler faultHandler) { public void addOffer(Offer offer, ResultHandler resultHandler, FaultHandler faultHandler) {
log.debug("addOffer " + offer);
Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode()); Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
try { try {
final Data offerData = new Data(offer); 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) { public void removeOffer(Offer offer, ResultHandler resultHandler, FaultHandler faultHandler) {
log.debug("removeOffer " + offer);
Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode()); Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
try { try {
final Data offerData = new Data(offer); final Data offerData = new Data(offer);
@ -170,6 +172,14 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
try { try {
Object offerDataObject = offerData.object(); Object offerDataObject = offerData.object();
if (offerDataObject instanceof Offer) { 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); offers.add((Offer) offerDataObject);
} }
} catch (ClassNotFoundException | IOException e) { } catch (ClassNotFoundException | IOException e) {

View file

@ -163,9 +163,10 @@ public class TomP2PDHTService extends TomP2PService implements DHTService {
* @return * @return
*/ */
public FuturePut addProtectedDataToMap(Number160 locationKey, Data data) { public FuturePut addProtectedDataToMap(Number160 locationKey, Data data) {
log.trace("addProtectedDataToMap"); log.trace("addProtectedDataToMap locationKey = " + locationKey);
data.protectEntry(keyPair); data.protectEntry(keyPair);
log.trace("addProtectedDataToMap with contentKey " + data.hash().toString()); log.trace("addProtectedDataToMap with contentKey " + data.hash().toString());
return peerDHT.add(locationKey).data(data).keyPair(keyPair).start(); return peerDHT.add(locationKey).data(data).keyPair(keyPair).start();
} }
@ -178,7 +179,7 @@ public class TomP2PDHTService extends TomP2PService implements DHTService {
* @return * @return
*/ */
public FutureRemove removeProtectedDataFromMap(Number160 locationKey, Data data) { public FutureRemove removeProtectedDataFromMap(Number160 locationKey, Data data) {
log.trace("removeProtectedDataFromMap"); log.trace("removeProtectedDataFromMap locationKey = " + locationKey);
Number160 contentKey = data.hash(); Number160 contentKey = data.hash();
log.trace("removeProtectedDataFromMap with contentKey " + contentKey.toString()); log.trace("removeProtectedDataFromMap with contentKey " + contentKey.toString());
return peerDHT.remove(locationKey).contentKey(contentKey).keyPair(keyPair).start(); return peerDHT.remove(locationKey).contentKey(contentKey).keyPair(keyPair).start();

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
}
}

View file

@ -18,7 +18,9 @@
package io.bitsquare.trade; package io.bitsquare.trade;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.protocol.Protocol;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction; 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.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
@ -42,8 +43,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class Trade implements Serializable { public class Trade implements Serializable {
private static final long serialVersionUID = -8275323072940974077L; protected static final long serialVersionUID = 1;
private static final Logger log = LoggerFactory.getLogger(Trade.class); protected static final Logger log = LoggerFactory.getLogger(Trade.class);
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -71,7 +72,7 @@ public class Trade implements Serializable {
MESSAGE_SENDING_FAILED, MESSAGE_SENDING_FAILED,
FAULT; FAULT;
private String errorMessage; protected String errorMessage;
public void setErrorMessage(String errorMessage) { public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage; this.errorMessage = errorMessage;
@ -82,28 +83,32 @@ public class Trade implements Serializable {
} }
} }
private final Offer offer; transient protected Protocol protocol;
private final Date date;
private ProcessState processState;
private LifeCycleState lifeCycleState;
private Coin tradeAmount; protected MailboxMessage mailboxMessage;
private Contract contract;
private String contractAsJson; protected final Offer offer;
private String takerContractSignature; protected final Date date;
private String offererContractSignature; protected ProcessState processState;
private Transaction depositTx; protected LifeCycleState lifeCycleState;
private Transaction payoutTx;
private Peer tradingPeer; protected Coin tradeAmount;
private int depthInBlocks = 0; 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) // 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 // 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. // access. Only use the accessor not the protected field.
transient private ObjectProperty<Coin> _tradeAmount; transient protected ObjectProperty<Coin> _tradeAmount;
transient private ObjectProperty<Fiat> _tradeVolume; transient protected ObjectProperty<Fiat> _tradeVolume;
transient private ObjectProperty<ProcessState> _processState; transient protected ObjectProperty<ProcessState> _processState;
transient private ObjectProperty<LifeCycleState> _lifeCycleState; transient protected ObjectProperty<LifeCycleState> _lifeCycleState;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -118,40 +123,28 @@ public class Trade implements Serializable {
log.debug("Trade "); log.debug("Trade ");
} }
private void writeObject(java.io.ObjectOutputStream out) throws IOException { ///////////////////////////////////////////////////////////////////////////////////////////
log.debug("Trade writeObject"); // Methods
out.defaultWriteObject(); ///////////////////////////////////////////////////////////////////////////////////////////
log.debug("Trade writeObject");
public void disposeProtocol() {
if (protocol != null)
protocol.cleanup();
protocol = null;
} }
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { public void setMailboxMessage(MailboxMessage mailboxMessage) {
log.debug("Trade readObject"); this.mailboxMessage = mailboxMessage;
in.defaultReadObject(); if (protocol != null)
//TODO cannot call yet as persistence need to be refactored first. cann be called only after bitcoinJ is initialized as serialized tx objects throw protocol.setMailboxMessage(mailboxMessage);
// exceptions
//setConfidenceListener();
log.debug("Trade readObject");
} }
private void setConfidenceListener() { public void setProtocol(Protocol protocol) {
// log.debug("setConfidenceListener called. depthInBlocks=" + depthInBlocks + " / depositTx != null ? " + (depositTx.toString() != null)); this.protocol = protocol;
if (depositTx != null && depthInBlocks == 0) {
TransactionConfidence transactionConfidence = depositTx.getConfidence();
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@Override
public void onSuccess(TransactionConfidence result) {
setProcessState(Trade.ProcessState.DEPOSIT_CONFIRMED);
}
@Override if (mailboxMessage != null)
public void onFailure(Throwable t) { protocol.setMailboxMessage(mailboxMessage);
t.printStackTrace();
log.error(t.getMessage());
Throwables.propagate(t);
}
});
}
} }
@ -159,6 +152,7 @@ public class Trade implements Serializable {
// Setters // Setters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void setTradingPeer(Peer tradingPeer) { public void setTradingPeer(Peer tradingPeer) {
this.tradingPeer = tradingPeer; this.tradingPeer = tradingPeer;
} }
@ -298,12 +292,38 @@ public class Trade implements Serializable {
return _lifeCycleState; return _lifeCycleState;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
protected void setConfidenceListener() {
TransactionConfidence transactionConfidence = depositTx.getConfidence();
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@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 @Override
public String toString() { public String toString() {
return "Trade{" + return "Trade{" +
"offer=" + offer + "protocol=" + protocol +
", mailboxMessage=" + mailboxMessage +
", offer=" + offer +
", date=" + date + ", date=" + date +
", state=" + processState + ", processState=" + processState +
", lifeCycleState=" + lifeCycleState +
", tradeAmount=" + tradeAmount + ", tradeAmount=" + tradeAmount +
", contract=" + contract + ", contract=" + contract +
", contractAsJson='" + contractAsJson + '\'' + ", contractAsJson='" + contractAsJson + '\'' +
@ -311,6 +331,8 @@ public class Trade implements Serializable {
", offererContractSignature='" + offererContractSignature + '\'' + ", offererContractSignature='" + offererContractSignature + '\'' +
", depositTx=" + depositTx + ", depositTx=" + depositTx +
", payoutTx=" + payoutTx + ", payoutTx=" + payoutTx +
", tradingPeer=" + tradingPeer +
", depthInBlocks=" + depthInBlocks +
'}'; '}';
} }
} }

View file

@ -30,12 +30,12 @@ import javafx.collections.ObservableList;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class TradeList extends ArrayList<Trade> implements Serializable { public class TradeList<T> extends ArrayList<T> implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(TradeList.class); transient private static final Logger log = LoggerFactory.getLogger(TradeList.class);
transient final private Storage<TradeList> storage; transient final private Storage<TradeList> storage;
transient private ObservableList<Trade> observableList; transient private ObservableList<T> observableList;
public TradeList(File storageDir, String fileName) { public TradeList(File storageDir, String fileName) {
this.storage = new Storage<>(storageDir); this.storage = new Storage<>(storageDir);
@ -51,7 +51,7 @@ public class TradeList extends ArrayList<Trade> implements Serializable {
} }
@Override @Override
public boolean add(Trade trade) { public boolean add(T trade) {
boolean result = super.add(trade); boolean result = super.add(trade);
observableList.add(trade); observableList.add(trade);
storage.save(); storage.save();
@ -66,7 +66,7 @@ public class TradeList extends ArrayList<Trade> implements Serializable {
return result; return result;
} }
public ObservableList<Trade> getObservableList() { public ObservableList<T> getObservableList() {
return observableList; return observableList;
} }

View file

@ -51,6 +51,7 @@ import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.Fiat; import org.bitcoinj.utils.Fiat;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -62,6 +63,8 @@ import javax.inject.Named;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import net.tomp2p.storage.Data;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -80,14 +83,11 @@ public class TradeManager {
private final OfferBookService offerBookService; private final OfferBookService offerBookService;
private File storageDir; private File storageDir;
private final Map<String, TakerAsSellerProtocol> takerAsSellerProtocolMap = new HashMap<>();
private final Map<String, OffererAsBuyerProtocol> offererAsBuyerProtocolMap = new HashMap<>();
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>(); private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
private final TradeList openOfferTrades; private final TradeList<OffererTrade> openOfferTrades;
private final TradeList pendingTrades; private final TradeList<Trade> pendingTrades;
private final TradeList closedTrades; private final TradeList<Trade> closedTrades;
private final Map<String, MailboxMessage> mailboxMessages = new HashMap<>();
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -111,9 +111,9 @@ public class TradeManager {
this.offerBookService = offerBookService; this.offerBookService = offerBookService;
this.storageDir = storageDir; this.storageDir = storageDir;
this.openOfferTrades = new TradeList(storageDir, "OpenOfferTrades"); this.openOfferTrades = new TradeList<>(storageDir, "OpenOfferTrades");
this.pendingTrades = new TradeList(storageDir, "PendingTrades"); this.pendingTrades = new TradeList<>(storageDir, "PendingTrades");
this.closedTrades = new TradeList(storageDir, "ClosedTrades"); 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 // 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. // BuyerAcceptsOfferProtocol listens for take offer requests, so we need to instantiate it early.
public void onAllServicesInitialized() { public void onAllServicesInitialized() {
for (Trade trade : openOfferTrades) { for (OffererTrade offererTrade : openOfferTrades) {
createOffererAsBuyerProtocol(trade); createOffererAsBuyerProtocol(offererTrade);
} }
for (Trade trade : pendingTrades) { for (Trade trade : pendingTrades) {
// We continue an interrupted trade. // 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 // 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. // continue the trade, but that might fail.
if (isMyOffer(trade.getOffer())) { if (trade instanceof OffererTrade) {
createOffererAsBuyerProtocol(trade); createOffererAsBuyerProtocol((OffererTrade) trade);
} }
else { else if (trade instanceof TakerTrade) {
createTakerAsSellerProtocol(trade); createTakerAsSellerProtocol((TakerTrade) trade);
} }
} }
@ -179,16 +179,24 @@ public class TradeManager {
accountSettings.getAcceptedCountries(), accountSettings.getAcceptedCountries(),
accountSettings.getAcceptedLanguageLocales()); 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); PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService);
PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol( PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol(
model, model,
(transaction) -> { (transaction) -> {
Trade trade = new Trade(offer); OffererTrade offererTrade = new OffererTrade(offer);
trade.setLifeCycleState(Trade.LifeCycleState.OPEN_OFFER); offererTrade.setLifeCycleState(Trade.LifeCycleState.OPEN_OFFER);
openOfferTrades.add(trade); openOfferTrades.add(offererTrade);
createOffererAsBuyerProtocol(trade); OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade);
offererTrade.setProtocol(protocol);
resultHandler.handleResult(transaction); resultHandler.handleResult(transaction);
}, },
(message) -> errorMessageHandler.handleErrorMessage(message) (message) -> errorMessageHandler.handleErrorMessage(message)
@ -249,23 +257,19 @@ public class TradeManager {
// Trade // Trade
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void onFiatPaymentStarted(String tradeId) { public void onFiatPaymentStarted(Trade trade) {
// TODO remove if check when persistence is impl. ((OffererTrade) trade).onFiatPaymentStarted();
if (offererAsBuyerProtocolMap.containsKey(tradeId)) {
offererAsBuyerProtocolMap.get(tradeId).onFiatPaymentStarted();
// persistPendingTrades();
}
} }
public void onFiatPaymentReceived(String tradeId) { public void onFiatPaymentReceived(Trade trade) {
takerAsSellerProtocolMap.get(tradeId).onFiatPaymentReceived(); ((TakerTrade) trade).onFiatPaymentReceived();
} }
public void onWithdrawAtTradeCompleted(Trade trade) { public void onWithdrawAtTradeCompleted(Trade trade) {
trade.setLifeCycleState(Trade.LifeCycleState.COMPLETED); trade.setLifeCycleState(Trade.LifeCycleState.COMPLETED);
pendingTrades.remove(trade); pendingTrades.remove(trade);
closedTrades.add(trade); closedTrades.add(trade);
removeFromProtocolMap(trade); trade.disposeProtocol();
} }
@ -282,7 +286,7 @@ public class TradeManager {
// Getters // Getters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public ObservableList<Trade> getOpenOfferTrades() { public ObservableList<OffererTrade> getOpenOfferTrades() {
return openOfferTrades.getObservableList(); return openOfferTrades.getObservableList();
} }
@ -310,24 +314,19 @@ public class TradeManager {
offerBookService.removeOffer(offer, offerBookService.removeOffer(offer,
() -> { () -> {
offer.setState(Offer.State.REMOVED); offer.setState(Offer.State.REMOVED);
Optional<OffererTrade> offererTradeOptional = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny();
Optional<Trade> result = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny(); if (offererTradeOptional.isPresent()) {
if (result.isPresent()) { OffererTrade offererTrade = offererTradeOptional.get();
Trade trade = result.get(); openOfferTrades.remove(offererTrade);
openOfferTrades.remove(trade);
if (isCancelRequest) { if (isCancelRequest) {
trade.setLifeCycleState(Trade.LifeCycleState.CANCELED); offererTrade.setLifeCycleState(Trade.LifeCycleState.CANCELED);
closedTrades.add(trade); closedTrades.add(offererTrade);
offererTrade.disposeProtocol();
} }
} }
disposeCheckOfferAvailabilityRequest(offer); disposeCheckOfferAvailabilityRequest(offer);
String offerId = offer.getId();
if (isCancelRequest && offererAsBuyerProtocolMap.containsKey(offerId)) {
offererAsBuyerProtocolMap.get(offerId).cleanup();
offererAsBuyerProtocolMap.remove(offerId);
}
resultHandler.handleResult(); resultHandler.handleResult();
}, },
@ -354,23 +353,23 @@ public class TradeManager {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
private Trade takeAvailableOffer(Coin amount, Offer offer, Peer peer) { private Trade takeAvailableOffer(Coin amount, Offer offer, Peer peer) {
Trade trade = new Trade(offer); TakerTrade takerTrade = new TakerTrade(offer);
trade.setTradeAmount(amount); takerTrade.setTradeAmount(amount);
trade.setTradingPeer(peer); takerTrade.setTradingPeer(peer);
trade.setLifeCycleState(Trade.LifeCycleState.PENDING); takerTrade.setLifeCycleState(Trade.LifeCycleState.PENDING);
pendingTrades.add(trade); pendingTrades.add(takerTrade);
TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(trade); TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(takerTrade);
//trade.setProtocol(sellerTakesOfferProtocol); takerTrade.setProtocol(sellerTakesOfferProtocol);
sellerTakesOfferProtocol.takeAvailableOffer(); sellerTakesOfferProtocol.takeAvailableOffer();
return trade; return takerTrade;
} }
private TakerAsSellerProtocol createTakerAsSellerProtocol(Trade trade) { private TakerAsSellerProtocol createTakerAsSellerProtocol(TakerTrade takerTrade) {
trade.processStateProperty().addListener((ov, oldValue, newValue) -> { takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("trade state = " + newValue); log.debug("takerTrade state = " + newValue);
switch (newValue) { switch (newValue) {
case INIT: case INIT:
break; break;
@ -384,17 +383,17 @@ public class TradeManager {
break; break;
case MESSAGE_SENDING_FAILED: case MESSAGE_SENDING_FAILED:
case FAULT: case FAULT:
trade.setLifeCycleState(Trade.LifeCycleState.FAILED); takerTrade.setLifeCycleState(Trade.LifeCycleState.FAILED);
removeFromProtocolMap(trade); takerTrade.disposeProtocol();
break; break;
default: default:
log.warn("Unhandled trade state: " + newValue); log.warn("Unhandled takerTrade state: " + newValue);
break; break;
} }
}); });
TakerAsSellerModel model = new TakerAsSellerModel( TakerAsSellerModel model = new TakerAsSellerModel(
trade, takerTrade,
messageService, messageService,
mailboxService, mailboxService,
walletService, walletService,
@ -403,20 +402,13 @@ public class TradeManager {
user, user,
storageDir); storageDir);
TakerAsSellerProtocol protocol = new TakerAsSellerProtocol(model); return 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;
} }
private void createOffererAsBuyerProtocol(Trade trade) { private OffererAsBuyerProtocol createOffererAsBuyerProtocol(OffererTrade offererTrade) {
OffererAsBuyerModel model = new OffererAsBuyerModel( OffererAsBuyerModel model = new OffererAsBuyerModel(
trade, offererTrade,
messageService, messageService,
mailboxService, mailboxService,
walletService, walletService,
@ -427,8 +419,8 @@ public class TradeManager {
// TODO check, remove listener // TODO check, remove listener
trade.processStateProperty().addListener((ov, oldValue, newValue) -> { offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("trade state = " + newValue); log.debug("offererTrade state = " + newValue);
switch (newValue) { switch (newValue) {
case INIT: case INIT:
break; break;
@ -436,12 +428,12 @@ public class TradeManager {
// persistPendingTrades(); // persistPendingTrades();
break; break;
case DEPOSIT_PUBLISHED: case DEPOSIT_PUBLISHED:
removeOpenOffer(trade.getOffer(), removeOpenOffer(offererTrade.getOffer(),
() -> log.debug("remove offer was successful"), () -> log.debug("remove offer was successful"),
(message) -> log.error(message), (message) -> log.error(message),
false); false);
model.trade.setLifeCycleState(Trade.LifeCycleState.PENDING); model.trade.setLifeCycleState(Trade.LifeCycleState.PENDING);
pendingTrades.add(trade); pendingTrades.add(offererTrade);
break; break;
case DEPOSIT_CONFIRMED: case DEPOSIT_CONFIRMED:
case FIAT_PAYMENT_STARTED: case FIAT_PAYMENT_STARTED:
@ -452,32 +444,16 @@ public class TradeManager {
case TAKE_OFFER_FEE_PUBLISH_FAILED: case TAKE_OFFER_FEE_PUBLISH_FAILED:
case MESSAGE_SENDING_FAILED: case MESSAGE_SENDING_FAILED:
case FAULT: case FAULT:
trade.setLifeCycleState(Trade.LifeCycleState.FAILED); offererTrade.setLifeCycleState(Trade.LifeCycleState.FAILED);
removeFromProtocolMap(trade); offererTrade.disposeProtocol();
break; break;
default: default:
log.warn("Unhandled trade state: " + newValue); log.warn("Unhandled offererTrade state: " + newValue);
break; break;
} }
}); });
OffererAsBuyerProtocol protocol = new OffererAsBuyerProtocol(model); return 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());
}
} }
@ -493,23 +469,15 @@ public class TradeManager {
if (mailboxMessage instanceof TradeMessage) { if (mailboxMessage instanceof TradeMessage) {
String tradeId = ((TradeMessage) mailboxMessage).tradeId; String tradeId = ((TradeMessage) mailboxMessage).tradeId;
mailboxMessages.put(tradeId, mailboxMessage); Optional<Trade> tradeOptional = pendingTrades.stream().filter(e -> e.getId().equals(tradeId)).findAny();
log.trace("added mailboxMessage with tradeID " + tradeId); if (tradeOptional.isPresent())
if (takerAsSellerProtocolMap.containsKey(tradeId)) { tradeOptional.get().setMailboxMessage(mailboxMessage);
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);
}
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
log.error(e.getMessage()); log.error(e.getMessage());
} }
} }
log.trace("mailboxMessages.size=" + mailboxMessages.size());
} }
private void emptyMailbox() { private void emptyMailbox() {

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.trade.protocol;
import io.bitsquare.p2p.MailboxMessage;
public interface Protocol {
void cleanup();
void setMailboxMessage(MailboxMessage mailboxMessage);
}

View file

@ -71,6 +71,7 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable {
id = offer.getId(); id = offer.getId();
tradeWalletService = walletService.getTradeWalletService(); tradeWalletService = walletService.getTradeWalletService();
//TODO use default arbitrator for now //TODO use default arbitrator for now
arbitratorPubKey = offer.getArbitrators().get(0).getPubKey(); arbitratorPubKey = offer.getArbitrators().get(0).getPubKey();
} }

View file

@ -24,6 +24,7 @@ import io.bitsquare.p2p.MessageHandler;
import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.Peer;
import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.Trade; 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.ReportOfferAvailabilityMessage;
import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage; import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage; 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.RequestTakerDepositPayment;
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendBankTransferStartedMessage; 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.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.SignAndPublishDepositTx;
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract; import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract;
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment; import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment;
@ -52,7 +52,7 @@ import org.slf4j.LoggerFactory;
import static io.bitsquare.util.Validator.*; import static io.bitsquare.util.Validator.*;
public class OffererAsBuyerProtocol { public class OffererAsBuyerProtocol implements Protocol {
private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerProtocol.class); private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerProtocol.class);
private final OffererAsBuyerModel model; private final OffererAsBuyerModel model;
@ -156,7 +156,6 @@ public class OffererAsBuyerProtocol {
VerifyTakerAccount.class, VerifyTakerAccount.class,
VerifyAndSignContract.class, VerifyAndSignContract.class,
SignAndPublishDepositTx.class, SignAndPublishDepositTx.class,
SetupListenerForBlockChainConfirmation.class,
SendDepositTxToTaker.class SendDepositTxToTaker.class
); );
taskRunner.run(); taskRunner.run();

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
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<OffererAsBuyerModel> {
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<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@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();
}
}

View file

@ -23,11 +23,11 @@ import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.MessageHandler; import io.bitsquare.p2p.MessageHandler;
import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.Trade; 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.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage; import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage; 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.models.TakerAsSellerModel;
import io.bitsquare.trade.protocol.trade.taker.tasks.BroadcastTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.taker.tasks.BroadcastTakeOfferFeeTx;
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract; import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract;
@ -49,7 +49,7 @@ import org.slf4j.LoggerFactory;
import static io.bitsquare.util.Validator.nonEmptyStringOf; 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 static final Logger log = LoggerFactory.getLogger(TakerAsSellerProtocol.class);
private final TakerAsSellerModel model; private final TakerAsSellerModel model;
@ -141,8 +141,7 @@ public class TakerAsSellerProtocol {
taskRunner.addTasks( taskRunner.addTasks(
ProcessDepositTxPublishedMessage.class, ProcessDepositTxPublishedMessage.class,
TakerCommitDepositTx.class, TakerCommitDepositTx.class
SetupListenerForBlockChainConfirmation.class
); );
taskRunner.run(); taskRunner.run();
} }

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
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<TakerAsSellerModel> {
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<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@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();
}
}