Refactor trade states

This commit is contained in:
Manfred Karrer 2015-03-26 00:27:20 +01:00
parent 180b5ad0f0
commit 77bf67e465
35 changed files with 485 additions and 329 deletions

View file

@ -109,7 +109,7 @@ class MainViewModel implements ViewModel {
updateProcess.state.addListener((observableValue, oldValue, newValue) -> applyUpdateState(newValue)); updateProcess.state.addListener((observableValue, oldValue, newValue) -> applyUpdateState(newValue));
applyUpdateState(updateProcess.state.get()); applyUpdateState(updateProcess.state.get());
currentBankAccount.bind(user.currentFiatAccountPropertyProperty()); currentBankAccount.bind(user.currentFiatAccountProperty());
user.fiatAccountsObservableList().addListener((ListChangeListener<FiatAccount>) change -> { user.fiatAccountsObservableList().addListener((ListChangeListener<FiatAccount>) change -> {
bankAccountsComboBoxDisable.set(change.getList().isEmpty()); bankAccountsComboBoxDisable.set(change.getList().isEmpty());
bankAccountsComboBoxPrompt.set(change.getList().isEmpty() ? "No accounts" : ""); bankAccountsComboBoxPrompt.set(change.getList().isEmpty() ? "No accounts" : "");

View file

@ -95,7 +95,7 @@ class FiatAccountDataModel implements Activatable, DataModel {
} }
void removeBankAccount() { void removeBankAccount() {
user.removeFiatAccount(user.currentFiatAccountPropertyProperty().get()); user.removeFiatAccount(user.currentFiatAccountProperty().get());
allFiatAccounts.setAll(user.fiatAccountsObservableList()); allFiatAccounts.setAll(user.fiatAccountsObservableList());
reset(); reset();
} }

View file

@ -20,6 +20,9 @@ package io.bitsquare.gui.main.portfolio.closed;
import io.bitsquare.common.viewfx.model.ActivatableWithDataModel; import io.bitsquare.common.viewfx.model.ActivatableWithDataModel;
import io.bitsquare.common.viewfx.model.ViewModel; import io.bitsquare.common.viewfx.model.ViewModel;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.Trade;
import com.google.inject.Inject; import com.google.inject.Inject;
@ -67,8 +70,20 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
String getState(ClosedTradesListItem item) { String getState(ClosedTradesListItem item) {
if (item != null && item.getTrade() != null) { if (item != null && item.getTrade() != null) {
switch (item.getTrade().getLifeCycleState()) { Trade.LifeCycleState lifeCycleState = item.getTrade().lifeCycleStateProperty().get();
case CANCELED: if (lifeCycleState instanceof TakerTrade.TakerLifeCycleState) {
switch ((TakerTrade.TakerLifeCycleState) lifeCycleState) {
case COMPLETED:
return "Completed";
case FAILED:
return "Failed";
case PENDING:
throw new RuntimeException("Wrong state: " + lifeCycleState);
}
}
else if (lifeCycleState instanceof OffererTrade.OffererLifeCycleState) {
switch ((OffererTrade.OffererLifeCycleState) lifeCycleState) {
case OFFER_CANCELED:
return "Canceled"; return "Canceled";
case COMPLETED: case COMPLETED:
return "Completed"; return "Completed";
@ -76,8 +91,10 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
return "Failed"; return "Failed";
case OPEN_OFFER: case OPEN_OFFER:
case PENDING: case PENDING:
throw new RuntimeException("Wrong state: " + item.getTrade().getLifeCycleState()); throw new RuntimeException("Wrong state: " + lifeCycleState);
} }
}
return "Undefined"; return "Undefined";
} }
else { else {

View file

@ -24,7 +24,7 @@ import org.bitcoinj.utils.Fiat;
import java.util.Date; import java.util.Date;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty;
/** /**
* We could remove that wrapper if it is not needed for additional UI only fields. * We could remove that wrapper if it is not needed for additional UI only fields.
@ -50,11 +50,11 @@ public class PendingTradesListItem {
return trade; return trade;
} }
public ObjectProperty<Coin> tradeAmountProperty() { public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
return trade.tradeAmountProperty(); return trade.tradeAmountProperty();
} }
public ObjectProperty<Fiat> tradeVolumeProperty() { public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
return trade.tradeVolumeProperty(); return trade.tradeVolumeProperty();
} }

View file

@ -23,6 +23,8 @@ import io.bitsquare.common.viewfx.model.ViewModel;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.BtcAddressValidator; import io.bitsquare.gui.util.validation.BtcAddressValidator;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -218,10 +220,11 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
private void updateState() { private void updateState() {
Trade.ProcessState tradeProcessState = dataModel.tradeState.get(); Trade.ProcessState processState = dataModel.tradeState.get();
log.trace("tradeState " + tradeProcessState); log.trace("tradeState " + processState);
if (tradeProcessState != null) { if (processState != null) {
switch (tradeProcessState) { if (processState instanceof TakerTrade.TakerProcessState) {
switch ((TakerTrade.TakerProcessState) processState) {
case DEPOSIT_PUBLISHED: case DEPOSIT_PUBLISHED:
state.set(dataModel.isOfferer() ? State.OFFERER_BUYER_WAIT_TX_CONF : State.TAKER_SELLER_WAIT_TX_CONF); state.set(dataModel.isOfferer() ? State.OFFERER_BUYER_WAIT_TX_CONF : State.TAKER_SELLER_WAIT_TX_CONF);
break; break;
@ -240,10 +243,35 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
// TODO error states not implemented yet // TODO error states not implemented yet
break; break;
default: default:
log.warn("unhandled state " + tradeProcessState); log.warn("unhandled state " + processState);
break; break;
} }
} }
else if (processState instanceof OffererTrade.OffererProcessState) {
switch ((OffererTrade.OffererProcessState) processState) {
case DEPOSIT_PUBLISHED:
state.set(dataModel.isOfferer() ? State.OFFERER_BUYER_WAIT_TX_CONF : State.TAKER_SELLER_WAIT_TX_CONF);
break;
case DEPOSIT_CONFIRMED:
state.set(dataModel.isOfferer() ? State.OFFERER_BUYER_START_PAYMENT :
State.TAKER_SELLER_WAIT_PAYMENT_STARTED);
break;
case FIAT_PAYMENT_STARTED:
state.set(dataModel.isOfferer() ? State.OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED :
State.TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT);
break;
case PAYOUT_PUBLISHED:
state.set(dataModel.isOfferer() ? State.OFFERER_BUYER_COMPLETED : State.TAKER_SELLER_COMPLETED);
break;
case MESSAGE_SENDING_FAILED:
// TODO error states not implemented yet
break;
default:
log.warn("unhandled state " + processState);
break;
}
}
}
else { else {
state.set(null); state.set(null);
} }

View file

@ -133,9 +133,9 @@ class CreateOfferDataModel implements Activatable, DataModel {
} }
if (user != null) { if (user != null) {
user.currentFiatAccountPropertyProperty().addListener((ov, oldValue, newValue) -> applyBankAccount(newValue)); user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> applyBankAccount(newValue));
applyBankAccount(user.currentFiatAccountPropertyProperty().get()); applyBankAccount(user.currentFiatAccountProperty().get());
} }
if (accountSettings != null) if (accountSettings != null)

View file

@ -98,17 +98,17 @@ class OfferBookDataModel implements Activatable, DataModel {
volumeAsFiat.set(null); volumeAsFiat.set(null);
offerBook.addClient(); offerBook.addClient();
user.currentFiatAccountPropertyProperty().addListener(bankAccountChangeListener); user.currentFiatAccountProperty().addListener(bankAccountChangeListener);
btcCode.bind(preferences.btcDenominationProperty()); btcCode.bind(preferences.btcDenominationProperty());
setBankAccount(user.currentFiatAccountPropertyProperty().get()); setBankAccount(user.currentFiatAccountProperty().get());
applyFilter(); applyFilter();
} }
@Override @Override
public void deactivate() { public void deactivate() {
offerBook.removeClient(); offerBook.removeClient();
user.currentFiatAccountPropertyProperty().removeListener(bankAccountChangeListener); user.currentFiatAccountProperty().removeListener(bankAccountChangeListener);
btcCode.unbind(); btcCode.unbind();
} }
@ -148,7 +148,7 @@ class OfferBookDataModel implements Activatable, DataModel {
boolean isTradable(Offer offer) { boolean isTradable(Offer offer) {
// if user has not registered yet we display all // if user has not registered yet we display all
FiatAccount currentFiatAccount = user.currentFiatAccountPropertyProperty().get(); FiatAccount currentFiatAccount = user.currentFiatAccountProperty().get();
if (currentFiatAccount == null) if (currentFiatAccount == null)
return true; return true;
@ -158,7 +158,7 @@ class OfferBookDataModel implements Activatable, DataModel {
if (!countryResult) if (!countryResult)
restrictionsInfo.set("This offer requires that the payments account resides in one of those countries:\n" + restrictionsInfo.set("This offer requires that the payments account resides in one of those countries:\n" +
formatter.countryLocalesToString(offer.getAcceptedCountries()) + formatter.countryLocalesToString(offer.getAcceptedCountries()) +
"\n\nThe country of your payments account (" + user.currentFiatAccountPropertyProperty().get().country.name + "\n\nThe country of your payments account (" + user.currentFiatAccountProperty().get().country.name +
") is not included in that list." + ") is not included in that list." +
"\n\n Do you want to edit your preferences now?"); "\n\n Do you want to edit your preferences now?");

View file

@ -25,7 +25,7 @@ import io.bitsquare.common.viewfx.model.Activatable;
import io.bitsquare.common.viewfx.model.DataModel; import io.bitsquare.common.viewfx.model.DataModel;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.trade.TradeManager; import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.handlers.TradeResultHandler; import io.bitsquare.trade.handlers.TakeOfferResultHandler;
import io.bitsquare.user.Preferences; import io.bitsquare.user.Preferences;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -124,8 +124,8 @@ class TakeOfferDataModel implements Activatable, DataModel {
tradeManager.checkOfferAvailability(offer); tradeManager.checkOfferAvailability(offer);
} }
void takeOffer(TradeResultHandler handler) { void takeOffer(TakeOfferResultHandler handler) {
tradeManager.requestTakeOffer(amountAsCoin.get(), offer, (trade) -> handler.handleTradeResult(trade)); tradeManager.requestTakeOffer(amountAsCoin.get(), offer, (trade) -> handler.handleResult(trade));
} }
void calculateVolume() { void calculateVolume() {

View file

@ -207,27 +207,25 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
isTakeOfferSpinnerVisible.set(true); isTakeOfferSpinnerVisible.set(true);
dataModel.takeOffer((trade) -> { dataModel.takeOffer((takerTrade) -> {
trade.processStateProperty().addListener((ov, oldValue, newValue) -> { takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("trade state = " + newValue); log.debug("takerTrade state = " + newValue);
String msg = ""; String msg = "";
if (newValue.getErrorMessage() != null) if (newValue.getErrorMessage() != null)
msg = "\nError message: " + newValue.getErrorMessage(); msg = "\nError message: " + newValue.getErrorMessage();
switch (newValue) { switch (newValue) {
case INIT:
break;
case TAKE_OFFER_FEE_TX_CREATED: case TAKE_OFFER_FEE_TX_CREATED:
break; break;
case DEPOSIT_PUBLISHED: case DEPOSIT_PUBLISHED:
case DEPOSIT_CONFIRMED: case DEPOSIT_CONFIRMED:
transactionId.set(trade.getDepositTx().getHashAsString()); transactionId.set(takerTrade.getDepositTx().getHashAsString());
applyTakeOfferRequestResult(true); applyTakeOfferRequestResult(true);
break; break;
case FIAT_PAYMENT_STARTED: case FIAT_PAYMENT_STARTED:
break; break;
case TAKE_OFFER_FEE_PUBLISH_FAILED: case TAKE_OFFER_FEE_PUBLISH_FAILED:
errorMessage.set("An error occurred when paying the trade fee." + msg); errorMessage.set("An error occurred when paying the takerTrade fee." + msg);
takeOfferRequested = false; takeOfferRequested = false;
break; break;
case MESSAGE_SENDING_FAILED: case MESSAGE_SENDING_FAILED:
@ -237,12 +235,12 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
break; break;
case PAYOUT_PUBLISHED: case PAYOUT_PUBLISHED:
break; break;
case FAULT: case UNSPECIFIC_FAULT:
errorMessage.set(msg); errorMessage.set(msg);
takeOfferRequested = false; takeOfferRequested = false;
break; break;
default: default:
log.warn("Unhandled trade state: " + newValue); log.warn("Unhandled takerTrade state: " + newValue);
break; break;
} }

View file

@ -79,12 +79,12 @@ public class BSFormatter {
@Inject @Inject
public BSFormatter(User user, ArbitrationRepository arbitrationRepository) { public BSFormatter(User user, ArbitrationRepository arbitrationRepository) {
this.arbitrationRepository = arbitrationRepository; this.arbitrationRepository = arbitrationRepository;
if (user.currentFiatAccountPropertyProperty().get() == null) if (user.currentFiatAccountProperty().get() == null)
setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode()); setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode());
else if (user.currentFiatAccountPropertyProperty().get() != null) else if (user.currentFiatAccountProperty().get() != null)
setFiatCurrencyCode(user.currentFiatAccountPropertyProperty().get().currencyCode); setFiatCurrencyCode(user.currentFiatAccountProperty().get().currencyCode);
user.currentFiatAccountPropertyProperty().addListener((ov, oldValue, newValue) -> { user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> {
if (newValue != null) if (newValue != null)
setFiatCurrencyCode(newValue.currencyCode); setFiatCurrencyCode(newValue.currencyCode);
}); });
@ -313,7 +313,7 @@ public class BSFormatter {
} }
public String countryLocalesToString(List<Country> countries) { public String countryLocalesToString(List<Country> countries) {
return countries.stream().map(e-> e.name).collect(Collectors.joining(", ")); return countries.stream().map(e -> e.name).collect(Collectors.joining(", "));
} }
public String arbitratorsToNames(List<Arbitrator> arbitrators) { public String arbitratorsToNames(List<Arbitrator> arbitrators) {

View file

@ -39,12 +39,12 @@ public final class FiatValidator extends NumberValidator {
@Inject @Inject
public FiatValidator(User user) { public FiatValidator(User user) {
if (user != null) { if (user != null) {
if (user.currentFiatAccountPropertyProperty().get() == null) if (user.currentFiatAccountProperty().get() == null)
setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode()); setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode());
else if (user.currentFiatAccountPropertyProperty().get() != null) else if (user.currentFiatAccountProperty().get() != null)
setFiatCurrencyCode(user.currentFiatAccountPropertyProperty().get().currencyCode); setFiatCurrencyCode(user.currentFiatAccountProperty().get().currencyCode);
user.currentFiatAccountPropertyProperty().addListener((ov, oldValue, newValue) -> { user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> {
if (newValue != null) if (newValue != null)
setFiatCurrencyCode(newValue.currencyCode); setFiatCurrencyCode(newValue.currencyCode);
}); });

View file

@ -39,12 +39,12 @@ public final class OptionalFiatValidator extends NumberValidator {
@Inject @Inject
public OptionalFiatValidator(User user) { public OptionalFiatValidator(User user) {
if (user != null) { if (user != null) {
if (user.currentFiatAccountPropertyProperty().get() == null) if (user.currentFiatAccountProperty().get() == null)
setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode()); setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode());
else if (user.currentFiatAccountPropertyProperty().get() != null) else if (user.currentFiatAccountProperty().get() != null)
setFiatCurrencyCode(user.currentFiatAccountPropertyProperty().get().currencyCode); setFiatCurrencyCode(user.currentFiatAccountProperty().get().currencyCode);
user.currentFiatAccountPropertyProperty().addListener((ov, oldValue, newValue) -> { user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> {
if (newValue != null) if (newValue != null)
setFiatCurrencyCode(newValue.currencyCode); setFiatCurrencyCode(newValue.currencyCode);
}); });

View file

@ -150,14 +150,14 @@ public class OfferBook {
private void addListeners() { private void addListeners() {
log.debug("addListeners "); log.debug("addListeners ");
user.currentFiatAccountPropertyProperty().addListener(bankAccountChangeListener); user.currentFiatAccountProperty().addListener(bankAccountChangeListener);
offerBookService.addListener(offerBookServiceListener); offerBookService.addListener(offerBookServiceListener);
offerBookService.invalidationTimestampProperty().addListener(invalidationListener); offerBookService.invalidationTimestampProperty().addListener(invalidationListener);
} }
private void removeListeners() { private void removeListeners() {
log.debug("removeListeners "); log.debug("removeListeners ");
user.currentFiatAccountPropertyProperty().removeListener(bankAccountChangeListener); user.currentFiatAccountProperty().removeListener(bankAccountChangeListener);
offerBookService.removeListener(offerBookServiceListener); offerBookService.removeListener(offerBookServiceListener);
offerBookService.invalidationTimestampProperty().removeListener(invalidationListener); offerBookService.invalidationTimestampProperty().removeListener(invalidationListener);
} }
@ -180,7 +180,7 @@ public class OfferBook {
// TODO Just temporary, will be removed later when we have a push solution // TODO Just temporary, will be removed later when we have a push solution
private void startPolling() { private void startPolling() {
addListeners(); addListeners();
setBankAccount(user.currentFiatAccountPropertyProperty().get()); setBankAccount(user.currentFiatAccountProperty().get());
pollingTimer = Utilities.setInterval(POLLING_INTERVAL, (animationTimer) -> { pollingTimer = Utilities.setInterval(POLLING_INTERVAL, (animationTimer) -> {
offerBookService.requestInvalidationTimeStampFromDHT(fiatCode); offerBookService.requestInvalidationTimeStampFromDHT(fiatCode);
return null; return null;

View file

@ -172,14 +172,6 @@ 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

@ -20,8 +20,21 @@ package io.bitsquare.trade;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.trade.protocol.trade.offerer.OffererAsBuyerProtocol; import io.bitsquare.trade.protocol.trade.offerer.OffererAsBuyerProtocol;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -30,13 +43,141 @@ public class OffererTrade extends Trade implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(OffererTrade.class); transient private static final Logger log = LoggerFactory.getLogger(OffererTrade.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Enum
///////////////////////////////////////////////////////////////////////////////////////////
public enum OffererLifeCycleState implements LifeCycleState {
OPEN_OFFER,
OFFER_CANCELED,
PENDING,
COMPLETED,
FAILED
}
public enum OffererProcessState implements ProcessState {
DEPOSIT_PUBLISHED,
DEPOSIT_CONFIRMED,
FIAT_PAYMENT_STARTED,
PAYOUT_PUBLISHED,
MESSAGE_SENDING_FAILED,
UNSPECIFIC_FAULT;
protected String errorMessage;
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getErrorMessage() {
return errorMessage;
}
}
protected OffererProcessState processState;
protected OffererLifeCycleState lifeCycleState;
transient protected ObjectProperty<OffererProcessState> processStateProperty = new SimpleObjectProperty<>(processState);
transient protected ObjectProperty<OffererLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public OffererTrade(Offer offer) { public OffererTrade(Offer offer) {
super(offer); super(offer);
} }
// Serialized object does not create our transient objects
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
processStateProperty = new SimpleObjectProperty<>(processState);
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
}
public void onFiatPaymentStarted() { public void onFiatPaymentStarted() {
((OffererAsBuyerProtocol) protocol).onFiatPaymentStarted(); ((OffererAsBuyerProtocol) protocol).onFiatPaymentStarted();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setProcessState(OffererProcessState processState) {
this.processState = processState;
processStateProperty.set(processState);
switch (processState) {
case UNSPECIFIC_FAULT:
disposeProtocol();
setLifeCycleState(OffererLifeCycleState.FAILED);
break;
}
}
public void setLifeCycleState(OffererLifeCycleState lifeCycleState) {
switch (lifeCycleState) {
case FAILED:
disposeProtocol();
break;
case COMPLETED:
disposeProtocol();
break;
}
this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty.set(lifeCycleState);
}
public void setDepositTx(Transaction tx) {
this.depositTx = tx;
setConfidenceListener();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public OffererProcessState getProcessState() {
return processState;
}
public OffererLifeCycleState getLifeCycleState() {
return lifeCycleState;
}
public ReadOnlyObjectProperty<OffererProcessState> processStateProperty() {
return processStateProperty;
}
public ReadOnlyObjectProperty<OffererLifeCycleState> lifeCycleStateProperty() {
return lifeCycleStateProperty;
}
///////////////////////////////////////////////////////////////////////////////////////////
// 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) {
if (processState.ordinal() < OffererProcessState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(OffererProcessState.DEPOSIT_CONFIRMED);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
log.error(t.getMessage());
Throwables.propagate(t);
}
});
}
} }

View file

@ -20,8 +20,21 @@ package io.bitsquare.trade;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.trade.protocol.trade.taker.TakerAsSellerProtocol; import io.bitsquare.trade.protocol.trade.taker.TakerAsSellerProtocol;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -30,11 +43,128 @@ public class TakerTrade extends Trade implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class); transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Enum
///////////////////////////////////////////////////////////////////////////////////////////
public enum TakerLifeCycleState implements LifeCycleState {
PENDING,
COMPLETED,
FAILED
}
public enum TakerProcessState implements ProcessState {
TAKE_OFFER_FEE_TX_CREATED,
TAKE_OFFER_FEE_PUBLISHED,
TAKE_OFFER_FEE_PUBLISH_FAILED,
DEPOSIT_PUBLISHED,
DEPOSIT_CONFIRMED,
FIAT_PAYMENT_STARTED,
FIAT_PAYMENT_RECEIVED,
PAYOUT_PUBLISHED,
MESSAGE_SENDING_FAILED,
UNSPECIFIC_FAULT;
protected String errorMessage;
@Override
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
@Override
public String getErrorMessage() {
return errorMessage;
}
}
protected TakerProcessState processState;
protected TakerLifeCycleState lifeCycleState;
transient protected ObjectProperty<TakerProcessState> processStateProperty = new SimpleObjectProperty<>(processState);
transient protected ObjectProperty<TakerLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public TakerTrade(Offer offer) { public TakerTrade(Offer offer) {
super(offer); super(offer);
} }
// Serialized object does not create our transient objects
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
processStateProperty = new SimpleObjectProperty<>(processState);
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
}
public void onFiatPaymentReceived() { public void onFiatPaymentReceived() {
((TakerAsSellerProtocol) protocol).onFiatPaymentReceived(); ((TakerAsSellerProtocol) protocol).onFiatPaymentReceived();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setProcessState(TakerProcessState processState) {
this.processState = processState;
processStateProperty.set(processState);
if (processState == TakerProcessState.UNSPECIFIC_FAULT) {
setLifeCycleState(TakerLifeCycleState.FAILED);
disposeProtocol();
}
}
public void setLifeCycleState(TakerLifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty.set(lifeCycleState);
}
public void setDepositTx(Transaction tx) {
this.depositTx = tx;
setConfidenceListener();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public ReadOnlyObjectProperty<TakerProcessState> processStateProperty() {
return processStateProperty;
}
public ReadOnlyObjectProperty<TakerLifeCycleState> lifeCycleStateProperty() {
return lifeCycleStateProperty;
}
///////////////////////////////////////////////////////////////////////////////////////////
// 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) {
if (processState.ordinal() < TakerProcessState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(TakerProcessState.DEPOSIT_CONFIRMED);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
log.error(t.getMessage());
Throwables.propagate(t);
}
});
}
} }

View file

@ -24,76 +24,39 @@ 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;
import org.bitcoinj.core.TransactionConfidence;
import org.bitcoinj.utils.Fiat; import org.bitcoinj.utils.Fiat;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class Trade implements Serializable { abstract public class Trade implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization. // That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
transient protected static final Logger log = LoggerFactory.getLogger(Trade.class); transient protected static final Logger log = LoggerFactory.getLogger(Trade.class);
public interface ProcessState {
/////////////////////////////////////////////////////////////////////////////////////////// void setErrorMessage(String errorMessage);
// Enum String getErrorMessage();
///////////////////////////////////////////////////////////////////////////////////////////
public enum LifeCycleState {
OPEN_OFFER,
CANCELED,
PENDING,
COMPLETED,
FAILED
} }
public enum ProcessState { public interface LifeCycleState {
INIT,
TAKE_OFFER_FEE_PUBLISH_FAILED,
TAKE_OFFER_FEE_TX_CREATED,
DEPOSIT_PUBLISHED,
TAKE_OFFER_FEE_PUBLISHED,
DEPOSIT_CONFIRMED,
FIAT_PAYMENT_STARTED,
FIAT_PAYMENT_RECEIVED,
PAYOUT_PUBLISHED,
MESSAGE_SENDING_FAILED,
FAULT;
protected String errorMessage;
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getErrorMessage() {
return errorMessage;
}
} }
transient protected Protocol protocol; transient protected Protocol protocol;
protected MailboxMessage mailboxMessage; protected MailboxMessage mailboxMessage;
protected final Offer offer; protected final Offer offer;
protected final Date date; protected final Date date;
protected ProcessState processState;
protected LifeCycleState lifeCycleState;
protected Coin tradeAmount; protected Coin tradeAmount;
protected Contract contract; protected Contract contract;
@ -105,13 +68,8 @@ public class Trade implements Serializable {
protected Peer tradingPeer; protected Peer tradingPeer;
protected int depthInBlocks = 0; protected int depthInBlocks = 0;
// For changing values we use properties to get binding support in the UI (table) transient protected ObjectProperty<Coin> tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
// When serialized those transient properties are not instantiated, so we instantiate them in the getters at first transient protected ObjectProperty<Fiat> tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
// access. Only use the accessor not the protected field.
transient protected ObjectProperty<Coin> tradeAmountProperty;
transient protected ObjectProperty<Fiat> tradeVolumeProperty;
transient protected ObjectProperty<ProcessState> processStateProperty;
transient protected ObjectProperty<LifeCycleState> lifeCycleStateProperty;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -121,18 +79,14 @@ public class Trade implements Serializable {
public Trade(Offer offer) { public Trade(Offer offer) {
this.offer = offer; this.offer = offer;
date = new Date(); date = new Date();
setProcessState(ProcessState.INIT);
log.debug("Trade ");
} }
// Serialized object does not create our transient objects // Serialized object does not create our transient objects
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject(); in.defaultReadObject();
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount); tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume()); tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
processStateProperty = new SimpleObjectProperty<>(processState);
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
} }
@ -148,10 +102,11 @@ public class Trade implements Serializable {
} }
public void disposeProtocol() { public void disposeProtocol() {
if (protocol != null) if (protocol != null) {
protocol.cleanup(); protocol.cleanup();
protocol = null; protocol = null;
} }
}
public void setMailboxMessage(MailboxMessage mailboxMessage) { public void setMailboxMessage(MailboxMessage mailboxMessage) {
this.mailboxMessage = mailboxMessage; this.mailboxMessage = mailboxMessage;
@ -164,6 +119,14 @@ public class Trade implements Serializable {
// Setters // Setters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void setTradeAmount(Coin tradeAmount) {
this.tradeAmount = tradeAmount;
tradeAmountProperty.set(tradeAmount);
tradeVolumeProperty.set(getTradeVolume());
}
public void setTradingPeer(Peer tradingPeer) { public void setTradingPeer(Peer tradingPeer) {
this.tradingPeer = tradingPeer; this.tradingPeer = tradingPeer;
} }
@ -180,12 +143,6 @@ public class Trade implements Serializable {
return tradeAmount; return tradeAmount;
} }
public void setTradeAmount(Coin tradeAmount) {
this.tradeAmount = tradeAmount;
tradeAmountProperty().set(tradeAmount);
tradeVolumeProperty().set(getTradeVolume());
}
public Contract getContract() { public Contract getContract() {
return contract; return contract;
} }
@ -198,25 +155,10 @@ public class Trade implements Serializable {
this.contract = contract; this.contract = contract;
} }
public void setDepositTx(Transaction tx) {
this.depositTx = tx;
setConfidenceListener();
}
public void setPayoutTx(Transaction tx) { public void setPayoutTx(Transaction tx) {
this.payoutTx = tx; this.payoutTx = tx;
} }
public void setProcessState(ProcessState processState) {
this.processState = processState;
processStateProperty().set(processState);
}
public void setLifeCycleState(LifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty().set(lifeCycleState);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Getters // Getters
@ -242,14 +184,6 @@ public class Trade implements Serializable {
return payoutTx; return payoutTx;
} }
public ProcessState getProcessState() {
return processState;
}
public LifeCycleState getLifeCycleState() {
return lifeCycleState;
}
public Coin getSecurityDeposit() { public Coin getSecurityDeposit() {
return offer.getSecurityDeposit(); return offer.getSecurityDeposit();
} }
@ -274,45 +208,19 @@ public class Trade implements Serializable {
return tradingPeer; return tradingPeer;
} }
public ObjectProperty<Coin> tradeAmountProperty() { public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
return tradeAmountProperty; return tradeAmountProperty;
} }
public ObjectProperty<Fiat> tradeVolumeProperty() { public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
return tradeVolumeProperty; return tradeVolumeProperty;
} }
public ObjectProperty<ProcessState> processStateProperty() { abstract public ReadOnlyObjectProperty<? extends ProcessState> processStateProperty();
return processStateProperty;
}
public ObjectProperty<LifeCycleState> lifeCycleStateProperty() { abstract public ReadOnlyObjectProperty<? extends LifeCycleState> lifeCycleStateProperty();
return lifeCycleStateProperty;
}
///////////////////////////////////////////////////////////////////////////////////////////
// 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{" +
@ -320,8 +228,6 @@ public class Trade implements Serializable {
", mailboxMessage=" + mailboxMessage + ", mailboxMessage=" + mailboxMessage +
", offer=" + offer + ", offer=" + offer +
", date=" + date + ", date=" + date +
", processState=" + processState +
", lifeCycleState=" + lifeCycleState +
", tradeAmount=" + tradeAmount + ", tradeAmount=" + tradeAmount +
", contract=" + contract + ", contract=" + contract +
", contractAsJson='" + contractAsJson + '\'' + ", contractAsJson='" + contractAsJson + '\'' +

View file

@ -33,7 +33,7 @@ import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MailboxService;
import io.bitsquare.p2p.MessageService; import io.bitsquare.p2p.MessageService;
import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.handlers.TradeResultHandler; import io.bitsquare.trade.handlers.TakeOfferResultHandler;
import io.bitsquare.trade.handlers.TransactionResultHandler; import io.bitsquare.trade.handlers.TransactionResultHandler;
import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityModel; import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityModel;
import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityProtocol; import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityProtocol;
@ -51,7 +51,6 @@ 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;
@ -63,8 +62,6 @@ 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;
@ -74,15 +71,15 @@ public class TradeManager {
private final User user; private final User user;
private final AccountSettings accountSettings; private final AccountSettings accountSettings;
private final MessageService messageService; private final MessageService messageService;
private MailboxService mailboxService; private final MailboxService mailboxService;
private final AddressService addressService; private final AddressService addressService;
private final BlockChainService blockChainService; private final BlockChainService blockChainService;
private final WalletService walletService; private final WalletService walletService;
private final SignatureService signatureService; private final SignatureService signatureService;
private EncryptionService<MailboxMessage> encryptionService; private final EncryptionService<MailboxMessage> encryptionService;
private final OfferBookService offerBookService; private final OfferBookService offerBookService;
private ArbitrationRepository arbitrationRepository; private final ArbitrationRepository arbitrationRepository;
private File storageDir; private final File storageDir;
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>(); private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
@ -124,20 +121,25 @@ public class TradeManager {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// When all services are initialized we create the protocols for our open offers and persisted not completed pendingTrades // When all services are initialized we create the protocols for our open offers and persisted not completed pendingTrades
// BuyerAcceptsOfferProtocol listens for take offer requests, so we need to instantiate it early. // OffererAsBuyerProtocol listens for take offer requests, so we need to instantiate it early.
public void onAllServicesInitialized() { public void onAllServicesInitialized() {
for (OffererTrade offererTrade : openOfferTrades) { for (OffererTrade offererTrade : openOfferTrades) {
createOffererAsBuyerProtocol(offererTrade); OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade);
offererTrade.setProtocol(protocol);
} }
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 (trade instanceof OffererTrade) { if (trade instanceof OffererTrade) {
createOffererAsBuyerProtocol((OffererTrade) trade); OffererTrade offererTrade = (OffererTrade) trade;
OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade);
offererTrade.setProtocol(protocol);
} }
else if (trade instanceof TakerTrade) { else if (trade instanceof TakerTrade) {
createTakerAsSellerProtocol((TakerTrade) trade); TakerTrade takerTrade = (TakerTrade) trade;
TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(takerTrade);
takerTrade.setProtocol(sellerTakesOfferProtocol);
} }
} }
@ -148,10 +150,6 @@ public class TradeManager {
}); });
} }
public boolean isMyOffer(Offer offer) {
return offer.getP2PSigPubKey().equals(user.getP2PSigPubKey());
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Offer // Offer
@ -165,7 +163,7 @@ public class TradeManager {
TransactionResultHandler resultHandler, TransactionResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler) { ErrorMessageHandler errorMessageHandler) {
FiatAccount currentFiatAccount = user.currentFiatAccountPropertyProperty().get(); FiatAccount currentFiatAccount = user.currentFiatAccountProperty().get();
Offer offer = new Offer(id, Offer offer = new Offer(id,
user.getP2PSigPubKey(), user.getP2PSigPubKey(),
direction, direction,
@ -181,20 +179,13 @@ public class TradeManager {
accountSettings.getAcceptedCountries(), accountSettings.getAcceptedCountries(),
accountSettings.getAcceptedLanguageLocaleCodes()); accountSettings.getAcceptedLanguageLocaleCodes());
try {
Data offerData = new Data(offer);
log.trace("-------------------------- placeOffer hash" + offerData.hash().toString());
} catch (IOException e) {
e.printStackTrace();
}
PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService); PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService);
PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol( PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol(
model, model,
(transaction) -> { (transaction) -> {
OffererTrade offererTrade = new OffererTrade(offer); OffererTrade offererTrade = new OffererTrade(offer);
offererTrade.setLifeCycleState(Trade.LifeCycleState.OPEN_OFFER); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OPEN_OFFER);
openOfferTrades.add(offererTrade); openOfferTrades.add(offererTrade);
OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade); OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade);
@ -239,19 +230,20 @@ public class TradeManager {
disposeCheckOfferAvailabilityRequest(offer); disposeCheckOfferAvailabilityRequest(offer);
} }
public void requestTakeOffer(Coin amount, Offer offer, TradeResultHandler tradeResultHandler) { // First we check if offer is still available then we create the trade with the protocol
public void requestTakeOffer(Coin amount, Offer offer, TakeOfferResultHandler takeOfferResultHandler) {
CheckOfferAvailabilityModel model = new CheckOfferAvailabilityModel(offer, messageService, addressService); CheckOfferAvailabilityModel model = new CheckOfferAvailabilityModel(offer, messageService, addressService);
CheckOfferAvailabilityProtocol protocol = new CheckOfferAvailabilityProtocol(model, CheckOfferAvailabilityProtocol availabilityProtocol = new CheckOfferAvailabilityProtocol(model,
() -> { () -> {
disposeCheckOfferAvailabilityRequest(offer); disposeCheckOfferAvailabilityRequest(offer);
if (offer.getState() == Offer.State.AVAILABLE) { if (offer.getState() == Offer.State.AVAILABLE) {
Trade trade = takeAvailableOffer(amount, offer, model.getPeer()); TakerTrade trade = takeAvailableOffer(amount, offer, model.getPeer());
tradeResultHandler.handleTradeResult(trade); takeOfferResultHandler.handleResult(trade);
} }
}, },
(errorMessage) -> disposeCheckOfferAvailabilityRequest(offer)); (errorMessage) -> disposeCheckOfferAvailabilityRequest(offer));
checkOfferAvailabilityProtocolMap.put(offer.getId(), protocol); checkOfferAvailabilityProtocolMap.put(offer.getId(), availabilityProtocol);
protocol.checkOfferAvailability(); availabilityProtocol.checkOfferAvailability();
} }
@ -268,10 +260,13 @@ public class TradeManager {
} }
public void onWithdrawAtTradeCompleted(Trade trade) { public void onWithdrawAtTradeCompleted(Trade trade) {
trade.setLifeCycleState(Trade.LifeCycleState.COMPLETED); if (trade instanceof OffererTrade)
((OffererTrade) trade).setLifeCycleState(OffererTrade.OffererLifeCycleState.COMPLETED);
else
((TakerTrade) trade).setLifeCycleState(TakerTrade.TakerLifeCycleState.COMPLETED);
pendingTrades.remove(trade); pendingTrades.remove(trade);
closedTrades.add(trade); closedTrades.add(trade);
trade.disposeProtocol();
} }
@ -305,10 +300,6 @@ public class TradeManager {
// Private methods // Private methods
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Offer
///////////////////////////////////////////////////////////////////////////////////////////
private void removeOpenOffer(Offer offer, private void removeOpenOffer(Offer offer,
ResultHandler resultHandler, ResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler, ErrorMessageHandler errorMessageHandler,
@ -322,7 +313,7 @@ public class TradeManager {
openOfferTrades.remove(offererTrade); openOfferTrades.remove(offererTrade);
if (isCancelRequest) { if (isCancelRequest) {
offererTrade.setLifeCycleState(Trade.LifeCycleState.CANCELED); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_CANCELED);
closedTrades.add(offererTrade); closedTrades.add(offererTrade);
offererTrade.disposeProtocol(); offererTrade.disposeProtocol();
} }
@ -335,16 +326,10 @@ public class TradeManager {
(message, throwable) -> errorMessageHandler.handleErrorMessage(message)); (message, throwable) -> errorMessageHandler.handleErrorMessage(message));
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Take offer
///////////////////////////////////////////////////////////////////////////////////////////
private void disposeCheckOfferAvailabilityRequest(Offer offer) { private void disposeCheckOfferAvailabilityRequest(Offer offer) {
if (checkOfferAvailabilityProtocolMap.containsKey(offer.getId())) { if (checkOfferAvailabilityProtocolMap.containsKey(offer.getId())) {
CheckOfferAvailabilityProtocol protocol = checkOfferAvailabilityProtocolMap.get(offer.getId()); CheckOfferAvailabilityProtocol protocol = checkOfferAvailabilityProtocolMap.get(offer.getId());
protocol.cancel(); protocol.cancel();
protocol.cleanup();
checkOfferAvailabilityProtocolMap.remove(offer.getId()); checkOfferAvailabilityProtocolMap.remove(offer.getId());
} }
} }
@ -354,11 +339,11 @@ public class TradeManager {
// Trade // Trade
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
private Trade takeAvailableOffer(Coin amount, Offer offer, Peer peer) { private TakerTrade takeAvailableOffer(Coin amount, Offer offer, Peer peer) {
TakerTrade takerTrade = new TakerTrade(offer); TakerTrade takerTrade = new TakerTrade(offer);
takerTrade.setTradeAmount(amount); takerTrade.setTradeAmount(amount);
takerTrade.setTradingPeer(peer); takerTrade.setTradingPeer(peer);
takerTrade.setLifeCycleState(Trade.LifeCycleState.PENDING); takerTrade.setLifeCycleState(TakerTrade.TakerLifeCycleState.PENDING);
pendingTrades.add(takerTrade); pendingTrades.add(takerTrade);
TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(takerTrade); TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(takerTrade);
@ -370,30 +355,6 @@ public class TradeManager {
private TakerAsSellerProtocol createTakerAsSellerProtocol(TakerTrade takerTrade) { private TakerAsSellerProtocol createTakerAsSellerProtocol(TakerTrade takerTrade) {
takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("takerTrade state = " + newValue);
switch (newValue) {
case INIT:
break;
case TAKE_OFFER_FEE_TX_CREATED:
case DEPOSIT_PUBLISHED:
case DEPOSIT_CONFIRMED:
case FIAT_PAYMENT_STARTED:
case FIAT_PAYMENT_RECEIVED:
case PAYOUT_PUBLISHED:
// persistPendingTrades();
break;
case MESSAGE_SENDING_FAILED:
case FAULT:
takerTrade.setLifeCycleState(Trade.LifeCycleState.FAILED);
takerTrade.disposeProtocol();
break;
default:
log.warn("Unhandled takerTrade state: " + newValue);
break;
}
});
TakerAsSellerModel model = new TakerAsSellerModel( TakerAsSellerModel model = new TakerAsSellerModel(
takerTrade, takerTrade,
messageService, messageService,
@ -426,33 +387,15 @@ public class TradeManager {
offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("offererTrade state = " + newValue); log.debug("offererTrade state = " + newValue);
switch (newValue) { switch (newValue) {
case INIT:
break;
case TAKE_OFFER_FEE_TX_CREATED:
// persistPendingTrades();
break;
case DEPOSIT_PUBLISHED: case DEPOSIT_PUBLISHED:
removeOpenOffer(offererTrade.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); ((OffererTrade) model.trade).setLifeCycleState(OffererTrade.OffererLifeCycleState.PENDING);
pendingTrades.add(offererTrade); pendingTrades.add(offererTrade);
break; break;
case DEPOSIT_CONFIRMED:
case FIAT_PAYMENT_STARTED:
case FIAT_PAYMENT_RECEIVED:
case PAYOUT_PUBLISHED:
// persistPendingTrades();
break;
case TAKE_OFFER_FEE_PUBLISH_FAILED:
case MESSAGE_SENDING_FAILED:
case FAULT:
offererTrade.setLifeCycleState(Trade.LifeCycleState.FAILED);
offererTrade.disposeProtocol();
break;
default: default:
log.warn("Unhandled offererTrade state: " + newValue);
break; break;
} }
}); });

View file

@ -17,9 +17,9 @@
package io.bitsquare.trade.handlers; package io.bitsquare.trade.handlers;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
public interface TradeResultHandler { public interface TakeOfferResultHandler {
void handleTradeResult(Trade trade); void handleResult(TakerTrade trade);
} }

View file

@ -88,6 +88,7 @@ public class CheckOfferAvailabilityProtocol {
public void cancel() { public void cancel() {
isCanceled = true; isCanceled = true;
taskRunner.cancel(); taskRunner.cancel();
cleanup();
} }

View file

@ -23,7 +23,7 @@ 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.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.protocol.Protocol; import io.bitsquare.trade.protocol.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;
@ -107,7 +107,7 @@ public class OffererAsBuyerProtocol implements Protocol {
// We don't store anything in the model as we might be in a trade process and receive that request from another peer who wants to take the offer // We don't store anything in the model as we might be in a trade process and receive that request from another peer who wants to take the offer
// at the same time // at the same time
boolean isOfferOpen = model.trade.getLifeCycleState() == Trade.LifeCycleState.OPEN_OFFER; boolean isOfferOpen = model.trade.getLifeCycleState() == OffererTrade.OffererLifeCycleState.OPEN_OFFER;
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = new ReportOfferAvailabilityMessage(model.id, isOfferOpen); ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = new ReportOfferAvailabilityMessage(model.id, isOfferOpen);
model.messageService.sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() { model.messageService.sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() {
@Override @Override

View file

@ -24,7 +24,7 @@ import io.bitsquare.crypto.SignatureService;
import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MailboxService;
import io.bitsquare.p2p.MessageService; import io.bitsquare.p2p.MessageService;
import io.bitsquare.storage.Storage; import io.bitsquare.storage.Storage;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.protocol.trade.SharedTradeModel; import io.bitsquare.trade.protocol.trade.SharedTradeModel;
import io.bitsquare.user.User; import io.bitsquare.user.User;
@ -41,7 +41,7 @@ public class OffererAsBuyerModel extends SharedTradeModel implements Serializabl
transient private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerModel.class); transient private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerModel.class);
transient private Storage<OffererAsBuyerModel> storage; transient private Storage<OffererAsBuyerModel> storage;
transient public final Trade trade; transient public final OffererTrade trade;
public final Taker taker; public final Taker taker;
public final Offerer offerer; public final Offerer offerer;
@ -49,7 +49,7 @@ public class OffererAsBuyerModel extends SharedTradeModel implements Serializabl
// written by tasks // written by tasks
private String takeOfferFeeTxId; private String takeOfferFeeTxId;
public OffererAsBuyerModel(Trade trade, public OffererAsBuyerModel(OffererTrade trade,
MessageService messageService, MessageService messageService,
MailboxService mailboxService, MailboxService mailboxService,
WalletService walletService, WalletService walletService,

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel;
@ -43,7 +43,7 @@ public class ProcessPayoutTxPublishedMessage extends Task<OffererAsBuyerModel> {
model.trade.setPayoutTx(checkNotNull(((PayoutTxPublishedMessage) model.getTradeMessage()).payoutTx)); model.trade.setPayoutTx(checkNotNull(((PayoutTxPublishedMessage) model.getTradeMessage()).payoutTx));
model.trade.setProcessState(Trade.ProcessState.PAYOUT_PUBLISHED); model.trade.setProcessState(OffererTrade.OffererProcessState.PAYOUT_PUBLISHED);
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {

View file

@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel;
@ -50,19 +50,19 @@ public class SendBankTransferStartedMessage extends Task<OffererAsBuyerModel> {
@Override @Override
public void handleResult() { public void handleResult() {
log.trace("Sending BankTransferInitedMessage succeeded."); log.trace("Sending BankTransferInitedMessage succeeded.");
model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_STARTED); model.trade.setProcessState(OffererTrade.OffererProcessState.FIAT_PAYMENT_STARTED);
complete(); complete();
} }
@Override @Override
public void handleFault() { public void handleFault() {
failed("Sending BankTransferInitedMessage failed."); failed("Sending BankTransferInitedMessage failed.");
model.trade.setProcessState(Trade.ProcessState.FAULT); model.trade.setProcessState(OffererTrade.OffererProcessState.UNSPECIFIC_FAULT);
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
failed("Sending BankTransferInitedMessage failed."); failed("Sending BankTransferInitedMessage failed.");
model.trade.setProcessState(Trade.ProcessState.FAULT); model.trade.setProcessState(OffererTrade.OffererProcessState.UNSPECIFIC_FAULT);
} }
} }
} }

View file

@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.btc.FeePolicy; import io.bitsquare.btc.FeePolicy;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.OffererTrade;
import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel; import io.bitsquare.trade.protocol.trade.offerer.models.OffererAsBuyerModel;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -59,7 +59,7 @@ public class SignAndPublishDepositTx extends Task<OffererAsBuyerModel> {
log.trace("offererSignAndPublishTx succeeded " + transaction); log.trace("offererSignAndPublishTx succeeded " + transaction);
model.trade.setDepositTx(transaction); model.trade.setDepositTx(transaction);
model.trade.setProcessState(Trade.ProcessState.DEPOSIT_PUBLISHED); model.trade.setProcessState(OffererTrade.OffererProcessState.DEPOSIT_PUBLISHED);
complete(); complete();
} }

View file

@ -22,7 +22,7 @@ import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.Message; 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.TakerTrade;
import io.bitsquare.trade.protocol.Protocol; 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;
@ -166,7 +166,7 @@ public class TakerAsSellerProtocol implements Protocol {
// User clicked the "bank transfer received" button, so we release the funds for pay out // User clicked the "bank transfer received" button, so we release the funds for pay out
public void onFiatPaymentReceived() { public void onFiatPaymentReceived() {
model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_RECEIVED); model.trade.setProcessState(TakerTrade.TakerProcessState.FIAT_PAYMENT_RECEIVED);
TaskRunner<TakerAsSellerModel> taskRunner = new TaskRunner<>(model, TaskRunner<TakerAsSellerModel> taskRunner = new TaskRunner<>(model,
() -> { () -> {

View file

@ -24,7 +24,7 @@ import io.bitsquare.crypto.SignatureService;
import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MailboxService;
import io.bitsquare.p2p.MessageService; import io.bitsquare.p2p.MessageService;
import io.bitsquare.storage.Storage; import io.bitsquare.storage.Storage;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.SharedTradeModel; import io.bitsquare.trade.protocol.trade.SharedTradeModel;
import io.bitsquare.user.User; import io.bitsquare.user.User;
@ -43,7 +43,7 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable
transient private static final Logger log = LoggerFactory.getLogger(TakerAsSellerModel.class); transient private static final Logger log = LoggerFactory.getLogger(TakerAsSellerModel.class);
transient private Storage<TakerAsSellerModel> storage; transient private Storage<TakerAsSellerModel> storage;
transient public final Trade trade; transient public final TakerTrade trade;
public final Taker taker; public final Taker taker;
public final Offerer offerer; public final Offerer offerer;
@ -52,7 +52,7 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable
private Transaction takeOfferFeeTx; private Transaction takeOfferFeeTx;
private Transaction payoutTx; private Transaction payoutTx;
public TakerAsSellerModel(Trade trade, public TakerAsSellerModel(TakerTrade trade,
MessageService messageService, MessageService messageService,
MailboxService mailboxService, MailboxService mailboxService,
WalletService walletService, WalletService walletService,

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
@ -47,14 +47,14 @@ public class BroadcastTakeOfferFeeTx extends Task<TakerAsSellerModel> {
public void onSuccess(Transaction transaction) { public void onSuccess(Transaction transaction) {
log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString()); log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString());
model.trade.setProcessState(Trade.ProcessState.TAKE_OFFER_FEE_PUBLISHED); model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISHED);
complete(); complete();
} }
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
model.trade.setProcessState(Trade.ProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED); model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED);
failed(t); failed(t);
} }
@ -63,7 +63,7 @@ public class BroadcastTakeOfferFeeTx extends Task<TakerAsSellerModel> {
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again."); appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again.");
appendToErrorMessage(e.getMessage()); appendToErrorMessage(e.getMessage());
model.trade.setProcessState(Trade.ProcessState.FAULT); model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT);
failed(e); failed(e);
} }

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
@ -40,13 +40,13 @@ public class CreateTakeOfferFeeTx extends Task<TakerAsSellerModel> {
Transaction createTakeOfferFeeTx = model.tradeWalletService.createTakeOfferFeeTx(model.taker.addressEntry); Transaction createTakeOfferFeeTx = model.tradeWalletService.createTakeOfferFeeTx(model.taker.addressEntry);
model.setTakeOfferFeeTx(createTakeOfferFeeTx); model.setTakeOfferFeeTx(createTakeOfferFeeTx);
model.trade.setProcessState(Trade.ProcessState.TAKE_OFFER_FEE_TX_CREATED); model.trade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_TX_CREATED);
complete(); complete();
} catch (Exception e) { } catch (Exception e) {
appendToErrorMessage(e.getMessage()); appendToErrorMessage(e.getMessage());
model.trade.setProcessState(Trade.ProcessState.FAULT); model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT);
failed(e); failed(e);
} }

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
@ -43,7 +43,7 @@ public class ProcessDepositTxPublishedMessage extends Task<TakerAsSellerModel> {
DepositTxPublishedMessage message = (DepositTxPublishedMessage) model.getTradeMessage(); DepositTxPublishedMessage message = (DepositTxPublishedMessage) model.getTradeMessage();
model.trade.setDepositTx(checkNotNull(message.depositTx)); model.trade.setDepositTx(checkNotNull(message.depositTx));
model.trade.setProcessState(Trade.ProcessState.DEPOSIT_PUBLISHED); model.trade.setProcessState(TakerTrade.TakerProcessState.DEPOSIT_PUBLISHED);
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
@ -46,11 +46,11 @@ public class ProcessFiatTransferStartedMessage extends Task<TakerAsSellerModel>
model.offerer.payoutAmount = positiveCoinOf(nonZeroCoinOf(message.offererPayoutAmount)); model.offerer.payoutAmount = positiveCoinOf(nonZeroCoinOf(message.offererPayoutAmount));
model.taker.payoutAmount = positiveCoinOf(nonZeroCoinOf(message.takerPayoutAmount)); model.taker.payoutAmount = positiveCoinOf(nonZeroCoinOf(message.takerPayoutAmount));
model.offerer.payoutAddressString = nonEmptyStringOf(message.offererPayoutAddress); model.offerer.payoutAddressString = nonEmptyStringOf(message.offererPayoutAddress);
model.trade.setProcessState(Trade.ProcessState.FIAT_PAYMENT_STARTED); model.trade.setProcessState(TakerTrade.TakerProcessState.FIAT_PAYMENT_STARTED);
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
model.trade.setProcessState(Trade.ProcessState.FAULT); model.trade.setProcessState(TakerTrade.TakerProcessState.UNSPECIFIC_FAULT);
failed(t); failed(t);
} }
} }

View file

@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage; import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
@ -67,7 +67,7 @@ public class SendRequestDepositTxInputsMessage extends Task<TakerAsSellerModel>
"connection. " + "connection. " +
"We persisted the state of the trade, please try again later or cancel that trade."); "We persisted the state of the trade, please try again later or cancel that trade.");
model.trade.setProcessState(Trade.ProcessState.MESSAGE_SENDING_FAILED); model.trade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED);
failed(); failed();
} }

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
@ -55,7 +55,7 @@ public class SignAndPublishPayoutTx extends Task<TakerAsSellerModel> {
@Override @Override
public void onSuccess(Transaction transaction) { public void onSuccess(Transaction transaction) {
model.setPayoutTx(transaction); model.setPayoutTx(transaction);
model.trade.setProcessState(Trade.ProcessState.PAYOUT_PUBLISHED); model.trade.setProcessState(TakerTrade.TakerProcessState.PAYOUT_PUBLISHED);
complete(); complete();
} }

View file

@ -21,7 +21,7 @@ import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.TradeWalletService; import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerAsSellerModel;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -59,7 +59,7 @@ public class TakerCreatesAndSignsDepositTx extends Task<TakerAsSellerModel> {
complete(); complete();
} catch (Exception e) { } catch (Exception e) {
Trade.ProcessState processState = Trade.ProcessState.FAULT; TakerTrade.TakerProcessState processState = TakerTrade.TakerProcessState.UNSPECIFIC_FAULT;
processState.setErrorMessage(errorMessage); processState.setErrorMessage(errorMessage);
model.trade.setProcessState(processState); model.trade.setProcessState(processState);

View file

@ -224,7 +224,7 @@ public class User implements Serializable {
return currentFiatAccount; return currentFiatAccount;
} }
public ObjectProperty<FiatAccount> currentFiatAccountPropertyProperty() { public ObjectProperty<FiatAccount> currentFiatAccountProperty() {
return currentFiatAccountProperty; return currentFiatAccountProperty;
} }