Change state handling

This commit is contained in:
Manfred Karrer 2015-04-23 13:10:32 +02:00
parent ca3d1c96f2
commit 398a729a83
62 changed files with 976 additions and 501 deletions

View file

@ -22,8 +22,6 @@ import io.bitsquare.p2p.Peer;
import io.bitsquare.storage.Storage; import io.bitsquare.storage.Storage;
import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.offer.Offer;
import io.bitsquare.trade.protocol.trade.BuyerProtocol; import io.bitsquare.trade.protocol.trade.BuyerProtocol;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -52,10 +50,8 @@ public abstract class BuyerTrade extends Trade implements Serializable {
@Override @Override
protected void initStates() { protected void initStates() {
if (processState == null) if (tradeState == null)
processState = BuyerTradeState.ProcessState.UNDEFINED; tradeState = TradeState.BuyerState.PREPARATION;
if (lifeCycleState == null)
lifeCycleState = Trade.LifeCycleState.PREPARATION;
initStateProperties(); initStateProperties();
} }
@ -65,59 +61,73 @@ public abstract class BuyerTrade extends Trade implements Serializable {
} }
@Override
public boolean isFailedState() {
return tradeState == TradeState.BuyerState.FAILED;
}
@Override
public void setFailedState() {
TradeState tradeState = TradeState.BuyerState.FAILED;
// We store the phase of the last state into the failed state
tradeState.setPhase(tradeState.getPhase());
setTradeState(tradeState);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects // Setter for Mutable objects
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void setProcessState(TradeState.ProcessState processState) { public void setTradeState(TradeState tradeState) {
super.setProcessState(processState); super.setTradeState(tradeState);
switch ((TradeState.BuyerState) tradeState) {
case PREPARATION:
break;
switch ((BuyerTradeState.ProcessState) processState) {
case DEPOSIT_PUBLISHED: case DEPOSIT_PUBLISHED:
takeOfferDate = new Date(); takeOfferDate = new Date();
if (this instanceof OffererTrade) if (this instanceof OffererTrade)
openOfferManager.closeOpenOffer(getOffer()); openOfferManager.closeOpenOffer(getOffer());
break; break;
case DEPOSIT_PUBLISHED_MSG_SENT:
case TIMEOUT: break;
disposeProtocol(); case DEPOSIT_CONFIRMED:
setLifeCycleState(Trade.LifeCycleState.FAILED);
tradeManager.removeFailedTrade(this);
break; break;
case FAULT: case FIAT_PAYMENT_STARTED:
disposeProtocol(); break;
setLifeCycleState(Trade.LifeCycleState.FAILED); case FIAT_PAYMENT_STARTED_MSG_SENT:
tradeManager.removeFailedTrade(this);
break; break;
}
}
@Override case FIAT_PAYMENT_RECEIPT_MSG_RECEIVED:
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) { break;
super.setLifeCycleState(lifeCycleState);
case PAYOUT_TX_COMMITTED:
break;
case PAYOUT_TX_SENT:
break;
case PAYOUT_BROAD_CASTED:
break;
case WITHDRAW_COMPLETED:
disposeProtocol();
break;
switch (lifeCycleState) {
case FAILED: case FAILED:
disposeProtocol(); disposeProtocol();
break; break;
case COMPLETED:
disposeProtocol(); default:
log.error("Unhandled state " + tradeState);
break; break;
} }
} }
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
// setProcessState(BuyerTradeState.ProcessState.EXCEPTION);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Protected // Protected
@ -125,7 +135,7 @@ public abstract class BuyerTrade extends Trade implements Serializable {
@Override @Override
protected void handleConfidenceResult() { protected void handleConfidenceResult() {
if (((BuyerTradeState.ProcessState) processState).ordinal() < BuyerTradeState.ProcessState.DEPOSIT_CONFIRMED.ordinal()) if (((TradeState.BuyerState) tradeState).ordinal() < TradeState.BuyerState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(BuyerTradeState.ProcessState.DEPOSIT_CONFIRMED); setTradeState(TradeState.BuyerState.DEPOSIT_CONFIRMED);
} }
} }

View file

@ -22,8 +22,6 @@ import io.bitsquare.p2p.Peer;
import io.bitsquare.storage.Storage; import io.bitsquare.storage.Storage;
import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.offer.Offer;
import io.bitsquare.trade.protocol.trade.SellerProtocol; import io.bitsquare.trade.protocol.trade.SellerProtocol;
import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -52,10 +50,8 @@ public abstract class SellerTrade extends Trade implements Serializable {
@Override @Override
protected void initStates() { protected void initStates() {
if (processState == null) if (tradeState == null)
processState = SellerTradeState.ProcessState.UNDEFINED; tradeState = TradeState.SellerState.PREPARATION;
if (lifeCycleState == null)
lifeCycleState = Trade.LifeCycleState.PENDING;
initStateProperties(); initStateProperties();
} }
@ -64,59 +60,70 @@ public abstract class SellerTrade extends Trade implements Serializable {
((SellerProtocol) tradeProtocol).onFiatPaymentReceived(); ((SellerProtocol) tradeProtocol).onFiatPaymentReceived();
} }
public boolean isFailedState() {
return tradeState == TradeState.SellerState.FAILED;
}
public void setFailedState() {
TradeState tradeState = TradeState.SellerState.FAILED;
// We store the phase of the last state into the failed state
tradeState.setPhase(tradeState.getPhase());
setTradeState(tradeState);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects // Setter for Mutable objects
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void setProcessState(TradeState.ProcessState processState) { public void setTradeState(TradeState tradeState) {
super.setProcessState(processState); super.setTradeState(tradeState);
switch ((TradeState.SellerState) tradeState) {
case PREPARATION:
break;
switch ((SellerTradeState.ProcessState) processState) {
case DEPOSIT_PUBLISHED_MSG_RECEIVED: case DEPOSIT_PUBLISHED_MSG_RECEIVED:
takeOfferDate = new Date(); takeOfferDate = new Date();
if (this instanceof OffererTrade) if (this instanceof OffererTrade)
openOfferManager.closeOpenOffer(getOffer()); openOfferManager.closeOpenOffer(getOffer());
break; break;
case DEPOSIT_CONFIRMED:
case TIMEOUT:
disposeProtocol();
setLifeCycleState(Trade.LifeCycleState.FAILED);
tradeManager.removeFailedTrade(this);
break; break;
case FAULT: case FIAT_PAYMENT_STARTED_MSG_RECEIVED:
disposeProtocol();
setLifeCycleState(Trade.LifeCycleState.FAILED);
tradeManager.removeFailedTrade(this);
break; break;
}
}
@Override case FIAT_PAYMENT_RECEIPT:
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) { break;
super.setLifeCycleState(lifeCycleState); case FIAT_PAYMENT_RECEIPT_MSG_SENT:
break;
case PAYOUT_TX_RECEIVED:
break;
case PAYOUT_TX_COMMITTED:
break;
case PAYOUT_BROAD_CASTED:
break;
case WITHDRAW_COMPLETED:
disposeProtocol();
break;
switch (lifeCycleState) {
case FAILED: case FAILED:
disposeProtocol(); disposeProtocol();
break; break;
case COMPLETED:
disposeProtocol(); default:
log.error("Unhandled state " + tradeState);
break; break;
} }
} }
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
// setProcessState(SellerTradeState.ProcessState.EXCEPTION);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Protected // Protected
@ -124,7 +131,7 @@ public abstract class SellerTrade extends Trade implements Serializable {
@Override @Override
protected void handleConfidenceResult() { protected void handleConfidenceResult() {
if (((SellerTradeState.ProcessState) processState).ordinal() < SellerTradeState.ProcessState.DEPOSIT_CONFIRMED.ordinal()) if (((TradeState.SellerState) tradeState).ordinal() < TradeState.SellerState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(SellerTradeState.ProcessState.DEPOSIT_CONFIRMED); setTradeState(TradeState.SellerState.DEPOSIT_CONFIRMED);
} }
} }

View file

@ -34,9 +34,6 @@ import io.bitsquare.trade.offer.Offer;
import io.bitsquare.trade.offer.OpenOfferManager; import io.bitsquare.trade.offer.OpenOfferManager;
import io.bitsquare.trade.protocol.trade.ProcessModel; import io.bitsquare.trade.protocol.trade.ProcessModel;
import io.bitsquare.trade.protocol.trade.TradeProtocol; import io.bitsquare.trade.protocol.trade.TradeProtocol;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.trade.states.TradeState;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -76,13 +73,16 @@ abstract public class Trade implements Tradable, Model, Serializable {
private transient static final Logger log = LoggerFactory.getLogger(Trade.class); private transient static final Logger log = LoggerFactory.getLogger(Trade.class);
/* public enum CriticalPhase {
public enum LifeCycleState {
PREPARATION, PREPARATION,
PENDING, TAKER_FEE_PAID,
COMPLETED, DEPOSIT_PAID,
FIAT_SENT,
FIAT_RECEIVED,
PAYOUT_PAID,
WITHDRAWN,
FAILED FAILED
} }*/
// Mutable // Mutable
private Coin tradeAmount; private Coin tradeAmount;
@ -96,8 +96,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Transient/Immutable // Transient/Immutable
private transient ObjectProperty<TradeState.ProcessState> processStateProperty; private transient ObjectProperty<TradeState> processStateProperty;
private transient ObjectProperty<Trade.LifeCycleState> lifeCycleStateProperty;
// Trades are saved in the TradeList // Trades are saved in the TradeList
transient private Storage<? extends TradableList> storage; transient private Storage<? extends TradableList> storage;
transient protected TradeProtocol tradeProtocol; transient protected TradeProtocol tradeProtocol;
@ -113,8 +112,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
// Mutable // Mutable
private MessageWithPubKey messageWithPubKey; private MessageWithPubKey messageWithPubKey;
protected Date takeOfferDate; protected Date takeOfferDate;
protected TradeState.ProcessState processState; protected TradeState tradeState;
protected Trade.LifeCycleState lifeCycleState;
private Transaction depositTx; private Transaction depositTx;
private Contract contract; private Contract contract;
private String contractAsJson; private String contractAsJson;
@ -122,10 +120,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
private String buyerContractSignature; private String buyerContractSignature;
private Transaction payoutTx; private Transaction payoutTx;
private long lockTime; private long lockTime;
private String errorMessage;
// Transient/Mutable
transient private String errorMessage;
transient private Throwable throwable;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -205,8 +200,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
} }
protected void initStateProperties() { protected void initStateProperties() {
processStateProperty = new SimpleObjectProperty<>(processState); processStateProperty = new SimpleObjectProperty<>(tradeState);
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
} }
protected void initAmountProperty() { protected void initAmountProperty() {
@ -251,40 +245,20 @@ abstract public class Trade implements Tradable, Model, Serializable {
this.storage = storage; this.storage = storage;
} }
public void setProcessState(TradeState.ProcessState processState) { public void setTradeState(TradeState tradeState) {
this.processState = processState; this.tradeState = tradeState;
processStateProperty.set(processState); processStateProperty.set(tradeState);
storage.queueUpForSave(); storage.queueUpForSave();
} }
public void setFaultState() { abstract public boolean isFailedState();
if (this instanceof SellerTrade)
setProcessState(SellerTradeState.ProcessState.FAULT);
else if (this instanceof BuyerTrade)
setProcessState(BuyerTradeState.ProcessState.FAULT);
}
public boolean isFaultState() { abstract public void setFailedState();
return processState == BuyerTradeState.ProcessState.FAULT || processState == SellerTradeState.ProcessState.FAULT;
public boolean isCriticalFault() {
return tradeState.getPhase().ordinal() >= TradeState.Phase.DEPOSIT_PAID.ordinal();
} }
/* public void resetFault() {
if (this instanceof SellerTrade)
setProcessState(SellerTradeState.ProcessState.UNDEFINED);
else if (this instanceof BuyerTrade)
setProcessState(BuyerTradeState.ProcessState.UNDEFINED);
setLifeCycleState(LifeCycleState.PREPARATION);
errorMessage = null;
throwable = null;
}*/
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty.set(lifeCycleState);
storage.queueUpForSave();
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Storage // Storage
@ -340,14 +314,10 @@ abstract public class Trade implements Tradable, Model, Serializable {
return null; return null;
} }
public ReadOnlyObjectProperty<? extends TradeState.ProcessState> processStateProperty() { public ReadOnlyObjectProperty<? extends TradeState> tradeStateProperty() {
return processStateProperty; return processStateProperty;
} }
public ReadOnlyObjectProperty<Trade.LifeCycleState> lifeCycleStateProperty() {
return lifeCycleStateProperty;
}
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() { public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
return tradeAmountProperty; return tradeAmountProperty;
} }
@ -446,6 +416,15 @@ abstract public class Trade implements Tradable, Model, Serializable {
public void setErrorMessage(String errorMessage) { public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage; this.errorMessage = errorMessage;
if (errorMessage != null && errorMessage.length() > 0) {
setFailedState();
if (isCriticalFault())
tradeManager.addTradeToFailedTrades(this);
else if (isFailedState())
tradeManager.addTradeToClosedTrades(this);
}
} }
@Nullable @Nullable
@ -453,15 +432,6 @@ abstract public class Trade implements Tradable, Model, Serializable {
return errorMessage; return errorMessage;
} }
public void setThrowable(Throwable throwable) {
this.throwable = throwable;
}
@Nullable
public Throwable getThrowable() {
return throwable;
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Private // Private
@ -501,14 +471,12 @@ abstract public class Trade implements Tradable, Model, Serializable {
", tradeAmountProperty=" + tradeAmountProperty + ", tradeAmountProperty=" + tradeAmountProperty +
", tradeVolumeProperty=" + tradeVolumeProperty + ", tradeVolumeProperty=" + tradeVolumeProperty +
", processStateProperty=" + processStateProperty + ", processStateProperty=" + processStateProperty +
", lifeCycleStateProperty=" + lifeCycleStateProperty +
", storage=" + storage + ", storage=" + storage +
", tradeProtocol=" + tradeProtocol + ", tradeProtocol=" + tradeProtocol +
", offer=" + offer + ", offer=" + offer +
", date=" + takeOfferDate + ", date=" + takeOfferDate +
", processModel=" + processModel + ", processModel=" + processModel +
", processState=" + processState + ", processState=" + tradeState +
", lifeCycleState=" + lifeCycleState +
", messageWithPubKey=" + messageWithPubKey + ", messageWithPubKey=" + messageWithPubKey +
", depositTx=" + depositTx + ", depositTx=" + depositTx +
/* ", contract=" + contract + /* ", contract=" + contract +
@ -517,7 +485,6 @@ abstract public class Trade implements Tradable, Model, Serializable {
", buyerContractSignature='" + buyerContractSignature + '\'' +*/ ", buyerContractSignature='" + buyerContractSignature + '\'' +*/
", payoutTx=" + payoutTx + ", payoutTx=" + payoutTx +
", errorMessage='" + errorMessage + '\'' + ", errorMessage='" + errorMessage + '\'' +
", throwable=" + throwable +
'}'; '}';
} }

View file

@ -37,6 +37,7 @@ import io.bitsquare.p2p.MessageService;
import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.Peer;
import io.bitsquare.storage.Storage; import io.bitsquare.storage.Storage;
import io.bitsquare.trade.closed.ClosedTradableManager; import io.bitsquare.trade.closed.ClosedTradableManager;
import io.bitsquare.trade.failed.FailedTradesManager;
import io.bitsquare.trade.handlers.TakeOfferResultHandler; import io.bitsquare.trade.handlers.TakeOfferResultHandler;
import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.offer.Offer;
import io.bitsquare.trade.offer.OpenOffer; import io.bitsquare.trade.offer.OpenOffer;
@ -87,6 +88,7 @@ public class TradeManager {
private final CryptoService<MailboxMessage> cryptoService; private final CryptoService<MailboxMessage> cryptoService;
private final OpenOfferManager openOfferManager; private final OpenOfferManager openOfferManager;
private final ClosedTradableManager closedTradableManager; private final ClosedTradableManager closedTradableManager;
private FailedTradesManager failedTradesManager;
private final ArbitrationRepository arbitrationRepository; private final ArbitrationRepository arbitrationRepository;
private final Storage<TradableList<Trade>> pendingTradesStorage; private final Storage<TradableList<Trade>> pendingTradesStorage;
@ -109,6 +111,7 @@ public class TradeManager {
CryptoService<MailboxMessage> cryptoService, CryptoService<MailboxMessage> cryptoService,
OpenOfferManager openOfferManager, OpenOfferManager openOfferManager,
ClosedTradableManager closedTradableManager, ClosedTradableManager closedTradableManager,
FailedTradesManager failedTradesManager,
ArbitrationRepository arbitrationRepository, ArbitrationRepository arbitrationRepository,
@Named("storage.dir") File storageDir) { @Named("storage.dir") File storageDir) {
this.user = user; this.user = user;
@ -122,6 +125,7 @@ public class TradeManager {
this.cryptoService = cryptoService; this.cryptoService = cryptoService;
this.openOfferManager = openOfferManager; this.openOfferManager = openOfferManager;
this.closedTradableManager = closedTradableManager; this.closedTradableManager = closedTradableManager;
this.failedTradesManager = failedTradesManager;
this.arbitrationRepository = arbitrationRepository; this.arbitrationRepository = arbitrationRepository;
pendingTradesStorage = new Storage<>(storageDir); pendingTradesStorage = new Storage<>(storageDir);
@ -246,7 +250,7 @@ public class TradeManager {
// 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.lifeCycleState == Trade.LifeCycleState.FAILED) { if (trade.isFailedState()) {
failedTrades.add(trade); failedTrades.add(trade);
} }
else { else {
@ -257,7 +261,10 @@ public class TradeManager {
} }
for (Trade trade : failedTrades) { for (Trade trade : failedTrades) {
removeFailedTrade(trade); if (trade.isCriticalFault())
addTradeToFailedTrades(trade);
else
addTradeToClosedTrades(trade);
} }
} }
@ -329,7 +336,11 @@ public class TradeManager {
public void onSuccess(@javax.annotation.Nullable Transaction transaction) { public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
if (transaction != null) { if (transaction != null) {
log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString()); log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
trade.setLifeCycleState(Trade.LifeCycleState.COMPLETED);
if (trade instanceof BuyerTrade)
trade.setTradeState(TradeState.BuyerState.WITHDRAW_COMPLETED);
else if (trade instanceof SellerTrade)
trade.setTradeState(TradeState.SellerState.WITHDRAW_COMPLETED);
pendingTrades.remove(trade); pendingTrades.remove(trade);
closedTradableManager.add(trade); closedTradableManager.add(trade);
@ -355,12 +366,16 @@ public class TradeManager {
} }
// In a fault case we remove it and add it to the closed trades // In a fault case we remove it and add it to the closed trades
public void removeFailedTrade(Trade trade) { public void addTradeToClosedTrades(Trade trade) {
pendingTrades.remove(trade); pendingTrades.remove(trade);
closedTradableManager.add(trade); closedTradableManager.add(trade);
} }
public void addTradeToFailedTrades(Trade trade) {
pendingTrades.remove(trade);
failedTradesManager.add(trade);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Getters // Getters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -372,9 +387,4 @@ public class TradeManager {
public boolean isMyOffer(Offer offer) { public boolean isMyOffer(Offer offer) {
return offer.isMyOffer(keyRing); return offer.isMyOffer(keyRing);
} }
private Optional<Trade> findTrade(String id) {
return pendingTrades.stream().filter(trade -> trade.getId().equals(id)).findAny();
}
} }

View file

@ -19,6 +19,7 @@ package io.bitsquare.trade;
import io.bitsquare.BitsquareModule; import io.bitsquare.BitsquareModule;
import io.bitsquare.trade.closed.ClosedTradableManager; import io.bitsquare.trade.closed.ClosedTradableManager;
import io.bitsquare.trade.failed.FailedTradesManager;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@ -38,11 +39,6 @@ public class TradeModule extends BitsquareModule {
protected void configure() { protected void configure() {
bind(TradeManager.class).in(Singleton.class); bind(TradeManager.class).in(Singleton.class);
bind(ClosedTradableManager.class).in(Singleton.class); bind(ClosedTradableManager.class).in(Singleton.class);
bind(FailedTradesManager.class).in(Singleton.class);
} }
/* @Override
protected void doClose(Injector injector) {
log.trace("doClose " + getClass().getSimpleName());
injector.getInstance(TradeManager.class).shutDown();
}*/
} }

View file

@ -0,0 +1,112 @@
/*
* 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;
public interface TradeState {
Phase getPhase();
void setPhase(Phase phase);
enum SellerState implements TradeState {
PREPARATION(Phase.PREPARATION),
DEPOSIT_PUBLISHED_MSG_RECEIVED(Phase.DEPOSIT_PAID),
DEPOSIT_CONFIRMED(Phase.DEPOSIT_PAID),
FIAT_PAYMENT_STARTED_MSG_RECEIVED(Phase.FIAT_SENT),
FIAT_PAYMENT_RECEIPT(Phase.FIAT_RECEIVED),
FIAT_PAYMENT_RECEIPT_MSG_SENT(Phase.FIAT_RECEIVED),
PAYOUT_TX_RECEIVED(Phase.PAYOUT_PAID),
PAYOUT_TX_COMMITTED(Phase.PAYOUT_PAID),
PAYOUT_BROAD_CASTED(Phase.PAYOUT_PAID),
WITHDRAW_COMPLETED(Phase.WITHDRAWN),
FAILED();
public Phase getPhase() {
return phase;
}
public void setPhase(Phase phase) {
this.phase = phase;
}
private Phase phase;
SellerState() {
}
SellerState(Phase phase) {
this.phase = phase;
}
}
enum BuyerState implements TradeState {
PREPARATION(Phase.PREPARATION),
DEPOSIT_PUBLISHED(Phase.DEPOSIT_PAID),
DEPOSIT_PUBLISHED_MSG_SENT(Phase.DEPOSIT_PAID),
DEPOSIT_CONFIRMED(Phase.DEPOSIT_PAID),
FIAT_PAYMENT_STARTED(Phase.FIAT_SENT),
FIAT_PAYMENT_STARTED_MSG_SENT(Phase.FIAT_SENT),
FIAT_PAYMENT_RECEIPT_MSG_RECEIVED(Phase.FIAT_RECEIVED),
PAYOUT_TX_COMMITTED(Phase.PAYOUT_PAID),
PAYOUT_TX_SENT(Phase.PAYOUT_PAID),
PAYOUT_BROAD_CASTED(Phase.PAYOUT_PAID),
WITHDRAW_COMPLETED(Phase.WITHDRAWN),
FAILED();
public Phase getPhase() {
return phase;
}
public void setPhase(Phase phase) {
this.phase = phase;
}
private Phase phase;
BuyerState() {
}
BuyerState(Phase phase) {
this.phase = phase;
}
}
enum Phase {
PREPARATION,
TAKER_FEE_PAID,
DEPOSIT_PAID,
FIAT_SENT,
FIAT_RECEIVED,
PAYOUT_PAID,
WITHDRAWN
}
}

View file

@ -43,7 +43,6 @@ public class ClosedTradableManager {
public ClosedTradableManager(KeyRing keyRing, @Named("storage.dir") File storageDir) { public ClosedTradableManager(KeyRing keyRing, @Named("storage.dir") File storageDir) {
this.keyRing = keyRing; this.keyRing = keyRing;
this.closedTrades = new TradableList<>(new Storage<>(storageDir), "ClosedTrades"); this.closedTrades = new TradableList<>(new Storage<>(storageDir), "ClosedTrades");
} }
public void add(Tradable tradable) { public void add(Tradable tradable) {

View file

@ -0,0 +1,60 @@
/*
* 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.failed;
import io.bitsquare.crypto.KeyRing;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.TradableList;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.offer.Offer;
import com.google.inject.Inject;
import java.io.File;
import javax.inject.Named;
import javafx.collections.ObservableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FailedTradesManager {
private static final Logger log = LoggerFactory.getLogger(FailedTradesManager.class);
private final TradableList<Trade> failedTrades;
private KeyRing keyRing;
@Inject
public FailedTradesManager(KeyRing keyRing, @Named("storage.dir") File storageDir) {
this.keyRing = keyRing;
this.failedTrades = new TradableList<>(new Storage<>(storageDir), "FailedTrades");
}
public void add(Trade trade) {
failedTrades.add(trade);
}
public boolean wasMyOffer(Offer offer) {
return offer.isMyOffer(keyRing);
}
public ObservableList<Trade> getFailedTrades() {
return failedTrades.getObservableList();
}
}

View file

@ -21,6 +21,7 @@ import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.BuyerAsOffererTrade; import io.bitsquare.trade.BuyerAsOffererTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest; import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest;
import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest; import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
@ -39,8 +40,6 @@ import io.bitsquare.trade.protocol.trade.tasks.offerer.VerifyTakeOfferFeePayment
import io.bitsquare.trade.protocol.trade.tasks.offerer.VerifyTakerAccount; import io.bitsquare.trade.protocol.trade.tasks.offerer.VerifyTakerAccount;
import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx;
import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener; import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -63,10 +62,10 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
this.buyerAsOffererTrade = trade; this.buyerAsOffererTrade = trade;
// If we are after the timelock state we need to setup the listener again // If we are after the timelock state we need to setup the listener again
TradeState.ProcessState state = trade.processStateProperty().get(); TradeState tradeState = trade.tradeStateProperty().get();
if (state == BuyerTradeState.ProcessState.PAYOUT_TX_COMMITTED || if (tradeState == TradeState.BuyerState.PAYOUT_TX_COMMITTED ||
state == BuyerTradeState.ProcessState.PAYOUT_TX_SENT || tradeState == TradeState.BuyerState.PAYOUT_TX_SENT ||
state == BuyerTradeState.ProcessState.PAYOUT_BROAD_CASTED) { tradeState == TradeState.BuyerState.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> { () -> {
@ -100,7 +99,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
log.error(errorMessage); log.error(errorMessage);
})); }));
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Start trade // Start trade
@ -154,7 +153,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
// User clicked the "bank transfer started" button // User clicked the "bank transfer started" button
@Override @Override
public void onFiatPaymentStarted() { public void onFiatPaymentStarted() {
buyerAsOffererTrade.setProcessState(BuyerTradeState.ProcessState.FIAT_PAYMENT_STARTED); buyerAsOffererTrade.setTradeState(TradeState.BuyerState.FIAT_PAYMENT_STARTED);
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> handleTaskRunnerSuccess("onFiatPaymentStarted"), () -> handleTaskRunnerSuccess("onFiatPaymentStarted"),

View file

@ -21,6 +21,7 @@ import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.BuyerAsTakerTrade; import io.bitsquare.trade.BuyerAsTakerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest; import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest;
import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest; import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
@ -41,8 +42,6 @@ import io.bitsquare.trade.protocol.trade.tasks.taker.BroadcastTakeOfferFeeTx;
import io.bitsquare.trade.protocol.trade.tasks.taker.CreateTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.tasks.taker.CreateTakeOfferFeeTx;
import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOfferFeePayment; import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOfferFeePayment;
import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOffererAccount; import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOffererAccount;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -65,10 +64,10 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
processModel.tradingPeer.setPubKeyRing(trade.getOffer().getPubKeyRing()); processModel.tradingPeer.setPubKeyRing(trade.getOffer().getPubKeyRing());
// If we are after the timelock state we need to setup the listener again // If we are after the timelock state we need to setup the listener again
TradeState.ProcessState state = trade.processStateProperty().get(); TradeState tradeState = trade.tradeStateProperty().get();
if (state == BuyerTradeState.ProcessState.PAYOUT_TX_COMMITTED || if (tradeState == TradeState.BuyerState.PAYOUT_TX_COMMITTED ||
state == BuyerTradeState.ProcessState.PAYOUT_TX_SENT || tradeState == TradeState.BuyerState.PAYOUT_TX_SENT ||
state == BuyerTradeState.ProcessState.PAYOUT_BROAD_CASTED) { tradeState == TradeState.BuyerState.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> { () -> {
handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener"); handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
@ -153,7 +152,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
// User clicked the "bank transfer started" button // User clicked the "bank transfer started" button
@Override @Override
public void onFiatPaymentStarted() { public void onFiatPaymentStarted() {
buyerAsTakerTrade.setProcessState(BuyerTradeState.ProcessState.FIAT_PAYMENT_STARTED); buyerAsTakerTrade.setTradeState(TradeState.BuyerState.FIAT_PAYMENT_STARTED);
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> handleTaskRunnerSuccess("onFiatPaymentStarted"), () -> handleTaskRunnerSuccess("onFiatPaymentStarted"),

View file

@ -21,6 +21,7 @@ import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.Peer; import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.SellerAsOffererTrade; import io.bitsquare.trade.SellerAsOffererTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
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.PayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage;
@ -39,8 +40,6 @@ import io.bitsquare.trade.protocol.trade.tasks.seller.SendPublishDepositTxReques
import io.bitsquare.trade.protocol.trade.tasks.seller.SignPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.seller.SignPayoutTx;
import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx;
import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener; import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener;
import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -61,10 +60,10 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
this.sellerAsOffererTrade = trade; this.sellerAsOffererTrade = trade;
// If we are after the timelock state we need to setup the listener again // If we are after the timelock state we need to setup the listener again
TradeState.ProcessState state = trade.processStateProperty().get(); TradeState tradeState = trade.tradeStateProperty().get();
if (state == SellerTradeState.ProcessState.PAYOUT_TX_RECEIVED || if (tradeState == TradeState.SellerState.PAYOUT_TX_RECEIVED ||
state == SellerTradeState.ProcessState.PAYOUT_TX_COMMITTED || tradeState == TradeState.SellerState.PAYOUT_TX_COMMITTED ||
state == SellerTradeState.ProcessState.PAYOUT_BROAD_CASTED) { tradeState == TradeState.SellerState.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> { () -> {
handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener"); handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
@ -175,7 +174,7 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
// 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
@Override @Override
public void onFiatPaymentReceived() { public void onFiatPaymentReceived() {
sellerAsOffererTrade.setProcessState(SellerTradeState.ProcessState.FIAT_PAYMENT_RECEIPT); sellerAsOffererTrade.setTradeState(TradeState.SellerState.FIAT_PAYMENT_RECEIPT);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> handleTaskRunnerSuccess("onFiatPaymentReceived"), () -> handleTaskRunnerSuccess("onFiatPaymentReceived"),

View file

@ -22,6 +22,7 @@ import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.SellerAsTakerTrade; import io.bitsquare.trade.SellerAsTakerTrade;
import io.bitsquare.trade.SellerTrade; import io.bitsquare.trade.SellerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
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.PayDepositRequest; import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest;
@ -44,8 +45,6 @@ import io.bitsquare.trade.protocol.trade.tasks.taker.BroadcastTakeOfferFeeTx;
import io.bitsquare.trade.protocol.trade.tasks.taker.CreateTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.tasks.taker.CreateTakeOfferFeeTx;
import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOfferFeePayment; import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOfferFeePayment;
import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOffererAccount; import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOffererAccount;
import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -69,10 +68,10 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
// If we are after the timelock state we need to setup the listener again // If we are after the timelock state we need to setup the listener again
if (trade instanceof SellerTrade) { if (trade instanceof SellerTrade) {
TradeState.ProcessState state = trade.processStateProperty().get(); TradeState tradeState = trade.tradeStateProperty().get();
if (state == SellerTradeState.ProcessState.PAYOUT_TX_RECEIVED || if (tradeState == TradeState.SellerState.PAYOUT_TX_RECEIVED ||
state == SellerTradeState.ProcessState.PAYOUT_TX_COMMITTED || tradeState == TradeState.SellerState.PAYOUT_TX_COMMITTED ||
state == SellerTradeState.ProcessState.PAYOUT_BROAD_CASTED) { tradeState == TradeState.SellerState.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> { () -> {
handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener"); handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
@ -199,7 +198,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
// 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
@Override @Override
public void onFiatPaymentReceived() { public void onFiatPaymentReceived() {
sellerAsTakerTrade.setProcessState(SellerTradeState.ProcessState.FIAT_PAYMENT_RECEIPT); sellerAsTakerTrade.setTradeState(TradeState.SellerState.FIAT_PAYMENT_RECEIPT);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> handleTaskRunnerSuccess("onFiatPaymentReceived"), () -> handleTaskRunnerSuccess("onFiatPaymentReceived"),

View file

@ -28,10 +28,9 @@ import io.bitsquare.p2p.listener.GetPeerAddressListener;
import io.bitsquare.trade.BuyerTrade; import io.bitsquare.trade.BuyerTrade;
import io.bitsquare.trade.SellerTrade; import io.bitsquare.trade.SellerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener; import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;
import java.util.Timer; import java.util.Timer;
@ -121,9 +120,9 @@ public abstract class TradeProtocol {
boolean needPayoutTxBroadcast = false; boolean needPayoutTxBroadcast = false;
if (trade instanceof SellerTrade) if (trade instanceof SellerTrade)
needPayoutTxBroadcast = trade.processStateProperty().get() == SellerTradeState.ProcessState.PAYOUT_TX_COMMITTED; needPayoutTxBroadcast = trade.tradeStateProperty().get() == TradeState.SellerState.PAYOUT_TX_COMMITTED;
else if (trade instanceof BuyerTrade) else if (trade instanceof BuyerTrade)
needPayoutTxBroadcast = trade.processStateProperty().get() == BuyerTradeState.ProcessState.PAYOUT_TX_COMMITTED; needPayoutTxBroadcast = trade.tradeStateProperty().get() == TradeState.BuyerState.PAYOUT_TX_COMMITTED;
if (needPayoutTxBroadcast) { if (needPayoutTxBroadcast) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
@ -143,10 +142,7 @@ public abstract class TradeProtocol {
timeoutTimer = Utilities.setTimeout(TIMEOUT, () -> { timeoutTimer = Utilities.setTimeout(TIMEOUT, () -> {
log.debug("Timeout reached"); log.debug("Timeout reached");
if (trade instanceof SellerTrade) trade.setErrorMessage("A timeout occured.");
trade.setProcessState(SellerTradeState.ProcessState.TIMEOUT);
else if (trade instanceof BuyerTrade)
trade.setProcessState(BuyerTradeState.ProcessState.TIMEOUT);
}); });
} }

View file

@ -46,9 +46,7 @@ public class TradeTask extends Task<Trade> {
protected void failed(Throwable t) { protected void failed(Throwable t) {
t.printStackTrace(); t.printStackTrace();
appendExceptionToErrorMessage(t); appendExceptionToErrorMessage(t);
trade.setThrowable(t);
trade.setErrorMessage(errorMessage); trade.setErrorMessage(errorMessage);
trade.setFaultState();
failed(); failed();
} }
} }

View file

@ -51,7 +51,6 @@ public class CreateDepositTxInputs extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
StateUtil.setOfferOpenState(trade); StateUtil.setOfferOpenState(trade);

View file

@ -52,7 +52,6 @@ public class ProcessDepositTxInputsRequest extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
StateUtil.setOfferOpenState(trade); StateUtil.setOfferOpenState(trade);
failed(t); failed(t);
} }

View file

@ -19,9 +19,9 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest; import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -49,12 +49,12 @@ public class ProcessFinalizePayoutTxRequest extends TradeTask {
processModel.tradingPeer.setPayoutAddressString(nonEmptyStringOf(message.sellerPayoutAddress)); processModel.tradingPeer.setPayoutAddressString(nonEmptyStringOf(message.sellerPayoutAddress));
trade.setLockTime(nonNegativeLongOf(message.lockTime)); trade.setLockTime(nonNegativeLongOf(message.lockTime));
trade.setProcessState(BuyerTradeState.ProcessState.FIAT_PAYMENT_RECEIPT_MSG_RECEIVED); trade.setTradeState(TradeState.BuyerState.FIAT_PAYMENT_RECEIPT_MSG_RECEIVED);
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
StateUtil.setOfferOpenState(trade); StateUtil.setOfferOpenState(trade);
failed(t); failed(t);
} }

View file

@ -57,7 +57,7 @@ public class ProcessPublishDepositTxRequest extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
StateUtil.setOfferOpenState(trade); StateUtil.setOfferOpenState(trade);
failed(t); failed(t);
} }

View file

@ -20,9 +20,9 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer;
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.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -50,7 +50,7 @@ public class SendDepositTxPublishedMessage extends TradeTask {
public void handleResult() { public void handleResult() {
log.trace("DepositTxPublishedMessage successfully arrived at peer"); log.trace("DepositTxPublishedMessage successfully arrived at peer");
trade.setProcessState(BuyerTradeState.ProcessState.DEPOSIT_PUBLISHED_MSG_SENT); trade.setTradeState(TradeState.BuyerState.DEPOSIT_PUBLISHED_MSG_SENT);
complete(); complete();
} }
@ -67,7 +67,7 @@ public class SendDepositTxPublishedMessage extends TradeTask {
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -20,9 +20,9 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer;
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.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -52,7 +52,7 @@ public class SendFiatTransferStartedMessage extends TradeTask {
public void handleResult() { public void handleResult() {
log.trace("Sending FiatTransferStartedMessage succeeded."); log.trace("Sending FiatTransferStartedMessage succeeded.");
trade.setProcessState(BuyerTradeState.ProcessState.FIAT_PAYMENT_STARTED_MSG_SENT); trade.setTradeState(TradeState.BuyerState.FIAT_PAYMENT_STARTED_MSG_SENT);
complete(); complete();
} }
@ -70,7 +70,7 @@ public class SendFiatTransferStartedMessage extends TradeTask {
); );
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -74,7 +74,7 @@ public class SendPayDepositRequest extends TradeTask {
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
StateUtil.setOfferOpenState(trade); StateUtil.setOfferOpenState(trade);
StateUtil.setSendFailedState(trade); StateUtil.setSendFailedState(trade);
failed(t); failed(t);

View file

@ -20,9 +20,9 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer;
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.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -49,7 +49,7 @@ public class SendPayoutTxFinalizedMessage extends TradeTask {
public void handleResult() { public void handleResult() {
log.trace("PayoutTxFinalizedMessage successfully arrived at peer"); log.trace("PayoutTxFinalizedMessage successfully arrived at peer");
trade.setProcessState(BuyerTradeState.ProcessState.PAYOUT_TX_SENT); trade.setTradeState(TradeState.BuyerState.PAYOUT_TX_SENT);
complete(); complete();
} }
@ -64,7 +64,7 @@ public class SendPayoutTxFinalizedMessage extends TradeTask {
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -61,7 +61,7 @@ public class SignAndFinalizePayoutTx extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -19,10 +19,9 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer;
import io.bitsquare.btc.FeePolicy; import io.bitsquare.btc.FeePolicy;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.BuyerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
@ -65,8 +64,7 @@ public class SignAndPublishDepositTx extends TradeTask {
trade.setDepositTx(transaction); trade.setDepositTx(transaction);
trade.setLifeCycleState(Trade.LifeCycleState.PENDING); trade.setTradeState(TradeState.BuyerState.DEPOSIT_PUBLISHED);
trade.setProcessState(BuyerTradeState.ProcessState.DEPOSIT_PUBLISHED);
trade.setTakeOfferDate(new Date()); trade.setTakeOfferDate(new Date());
complete(); complete();
@ -84,10 +82,6 @@ public class SignAndPublishDepositTx extends TradeTask {
private void handleFault(Throwable t) { private void handleFault(Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
if (trade instanceof BuyerTrade)
trade.setLifeCycleState(Trade.LifeCycleState.PREPARATION);
failed(t); failed(t);
} }

View file

@ -58,7 +58,7 @@ public class VerifyAndSignContract extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
StateUtil.setOfferOpenState(trade); StateUtil.setOfferOpenState(trade);

View file

@ -44,7 +44,7 @@ public class VerifyTakeOfferFeePayment extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -56,7 +56,7 @@ public class VerifyTakerAccount extends TradeTask {
} }
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
StateUtil.setOfferOpenState(trade); StateUtil.setOfferOpenState(trade);

View file

@ -45,7 +45,7 @@ public class CommitDepositTx extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -58,7 +58,7 @@ public class CreateAndSignContract extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -60,7 +60,7 @@ public class CreateAndSignDepositTx extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -19,9 +19,9 @@ package io.bitsquare.trade.protocol.trade.tasks.seller;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.SellerTradeState;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -46,12 +46,12 @@ public class ProcessDepositTxPublishedMessage extends TradeTask {
trade.setDepositTx(checkNotNull(message.depositTx)); trade.setDepositTx(checkNotNull(message.depositTx));
trade.setProcessState(SellerTradeState.ProcessState.DEPOSIT_PUBLISHED_MSG_RECEIVED); trade.setTradeState(TradeState.SellerState.DEPOSIT_PUBLISHED_MSG_RECEIVED);
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -19,9 +19,9 @@ package io.bitsquare.trade.protocol.trade.tasks.seller;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.SellerTradeState;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -46,12 +46,12 @@ public class ProcessFiatTransferStartedMessage extends TradeTask {
processModel.tradingPeer.setPayoutAddressString(nonEmptyStringOf(message.buyerPayoutAddress)); processModel.tradingPeer.setPayoutAddressString(nonEmptyStringOf(message.buyerPayoutAddress));
trade.setProcessState(SellerTradeState.ProcessState.FIAT_PAYMENT_STARTED_MSG_RECEIVED); trade.setTradeState(TradeState.SellerState.FIAT_PAYMENT_STARTED_MSG_RECEIVED);
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -56,7 +56,7 @@ public class ProcessPayDepositRequest extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -19,9 +19,9 @@ package io.bitsquare.trade.protocol.trade.tasks.seller;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.SellerTradeState;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -46,12 +46,12 @@ public class ProcessPayoutTxFinalizedMessage extends TradeTask {
trade.setPayoutTx(checkNotNull(message.payoutTx)); trade.setPayoutTx(checkNotNull(message.payoutTx));
trade.setProcessState(SellerTradeState.ProcessState.PAYOUT_TX_RECEIVED); trade.setTradeState(TradeState.SellerState.PAYOUT_TX_RECEIVED);
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -83,7 +83,7 @@ public class SendDepositTxInputsRequest extends TradeTask {
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -20,9 +20,9 @@ package io.bitsquare.trade.protocol.trade.tasks.seller;
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.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest; import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -55,7 +55,7 @@ public class SendFinalizePayoutTxRequest extends TradeTask {
public void handleResult() { public void handleResult() {
log.trace("PayoutTxPublishedMessage successfully arrived at peer"); log.trace("PayoutTxPublishedMessage successfully arrived at peer");
trade.setProcessState(SellerTradeState.ProcessState.FIAT_PAYMENT_RECEIPT_MSG_SENT); trade.setTradeState(TradeState.SellerState.FIAT_PAYMENT_RECEIPT_MSG_SENT);
complete(); complete();
} }
@ -70,7 +70,7 @@ public class SendFinalizePayoutTxRequest extends TradeTask {
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -72,7 +72,7 @@ public class SendPublishDepositTxRequest extends TradeTask {
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -62,7 +62,7 @@ public class SignPayoutTx extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -21,9 +21,8 @@ import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.BuyerTrade; import io.bitsquare.trade.BuyerTrade;
import io.bitsquare.trade.SellerTrade; import io.bitsquare.trade.SellerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.SellerTradeState;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
@ -46,14 +45,14 @@ public class CommitPayoutTx extends TradeTask {
trade.setPayoutTx(transaction); trade.setPayoutTx(transaction);
if (trade instanceof BuyerTrade) if (trade instanceof BuyerTrade)
trade.setProcessState(BuyerTradeState.ProcessState.PAYOUT_TX_COMMITTED); trade.setTradeState(TradeState.BuyerState.PAYOUT_TX_COMMITTED);
else if (trade instanceof SellerTrade) else if (trade instanceof SellerTrade)
trade.setProcessState(SellerTradeState.ProcessState.PAYOUT_TX_COMMITTED); trade.setTradeState(TradeState.SellerState.PAYOUT_TX_COMMITTED);
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -21,9 +21,8 @@ import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.BuyerTrade; import io.bitsquare.trade.BuyerTrade;
import io.bitsquare.trade.SellerTrade; import io.bitsquare.trade.SellerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.SellerTradeState;
import org.bitcoinj.core.StoredBlock; import org.bitcoinj.core.StoredBlock;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
@ -69,7 +68,7 @@ public class SetupPayoutTxLockTimeReachedListener extends TradeTask {
} }
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }
@ -81,9 +80,9 @@ public class SetupPayoutTxLockTimeReachedListener extends TradeTask {
log.debug("BroadcastTx succeeded. Transaction:" + transaction); log.debug("BroadcastTx succeeded. Transaction:" + transaction);
if (trade instanceof BuyerTrade) if (trade instanceof BuyerTrade)
trade.setProcessState(BuyerTradeState.ProcessState.PAYOUT_BROAD_CASTED); trade.setTradeState(TradeState.BuyerState.PAYOUT_BROAD_CASTED);
else if (trade instanceof SellerTrade) else if (trade instanceof SellerTrade)
trade.setProcessState(SellerTradeState.ProcessState.PAYOUT_BROAD_CASTED); trade.setTradeState(TradeState.SellerState.PAYOUT_BROAD_CASTED);
complete(); complete();
@ -92,7 +91,7 @@ public class SetupPayoutTxLockTimeReachedListener extends TradeTask {
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
/* /*
if (trade instanceof TakerTrade) if (trade instanceof TakerTrade)
trade.setProcessState(TakerTradeState.ProcessState.PAYOUT_BROAD_CASTED_FAILED); trade.setProcessState(TakerTradeState.ProcessState.PAYOUT_BROAD_CASTED_FAILED);

View file

@ -43,7 +43,7 @@ public class VerifyOfferFeePayment extends TradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -49,7 +49,7 @@ public class VerifyOffererAccount extends TradeTask {
} }
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
trade.setThrowable(t);
failed(t); failed(t);
} }
} }

View file

@ -1,46 +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.states;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BuyerTradeState {
private static final Logger log = LoggerFactory.getLogger(BuyerTradeState.class);
public enum ProcessState implements TradeState.ProcessState {
UNDEFINED,
DEPOSIT_PUBLISHED,
DEPOSIT_PUBLISHED_MSG_SENT,
DEPOSIT_CONFIRMED,
FIAT_PAYMENT_STARTED,
FIAT_PAYMENT_STARTED_MSG_SENT,
FIAT_PAYMENT_RECEIPT_MSG_RECEIVED,
PAYOUT_TX_COMMITTED,
PAYOUT_TX_SENT,
PAYOUT_BROAD_CASTED,
TIMEOUT,
FAULT
}
}

View file

@ -1,45 +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.states;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SellerTradeState {
private static final Logger log = LoggerFactory.getLogger(SellerTradeState.class);
public enum ProcessState implements TradeState.ProcessState {
UNDEFINED,
DEPOSIT_PUBLISHED_MSG_RECEIVED,
DEPOSIT_CONFIRMED,
FIAT_PAYMENT_STARTED_MSG_RECEIVED,
FIAT_PAYMENT_RECEIPT,
FIAT_PAYMENT_RECEIPT_MSG_SENT,
PAYOUT_TX_RECEIVED,
PAYOUT_TX_COMMITTED,
PAYOUT_BROAD_CASTED,
TIMEOUT,
FAULT
}
}

View file

@ -17,7 +17,6 @@
package io.bitsquare.trade.states; package io.bitsquare.trade.states;
import io.bitsquare.trade.BuyerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -26,15 +25,17 @@ import org.slf4j.LoggerFactory;
public class StateUtil { public class StateUtil {
private static final Logger log = LoggerFactory.getLogger(StateUtil.class); private static final Logger log = LoggerFactory.getLogger(StateUtil.class);
// TODO remove?
public static void setSendFailedState(Trade trade) { public static void setSendFailedState(Trade trade) {
/* if (trade instanceof BuyerTrade) /* if (trade instanceof BuyerTrade)
trade.setProcessState(BuyerTradeState.ProcessState.MESSAGE_SENDING_FAILED); trade.setProcessState(BuyerProcessState.MESSAGE_SENDING_FAILED);
else if (trade instanceof SellerTrade) else if (trade instanceof SellerTrade)
trade.setProcessState(SellerTradeState.ProcessState.MESSAGE_SENDING_FAILED);*/ trade.setProcessState(SellerProcessState.MESSAGE_SENDING_FAILED);*/
} }
// TODO remove?
public static void setOfferOpenState(Trade trade) { public static void setOfferOpenState(Trade trade) {
if (trade instanceof BuyerTrade) /*if (trade instanceof BuyerTrade)
trade.setLifeCycleState(Trade.LifeCycleState.PREPARATION); trade.setLifeCycleState(Trade.LifeCycleState.PREPARATION);*/
} }
} }

View file

@ -135,7 +135,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
@Override @Override
public void doActivate() { public void doActivate() {
addBindings(); addBindings();
// setOfferBookInfo has been called before // setOfferBookInfo has been called before
table.setItems(model.getOfferList()); table.setItems(model.getOfferList());
priceColumn.setSortType((model.getDirection() == Offer.Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING); priceColumn.setSortType((model.getDirection() == Offer.Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING);

View file

@ -74,7 +74,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private final Navigation navigation; private final Navigation navigation;
private final OverlayManager overlayManager; private final OverlayManager overlayManager;
@FXML ScrollPane scrollPane; @FXML ScrollPane scrollPane;
@FXML ImageView imageView; @FXML ImageView imageView;
@FXML InputTextField amountTextField; @FXML InputTextField amountTextField;

View file

@ -28,10 +28,8 @@ import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.trade.BuyerAsTakerTrade; import io.bitsquare.trade.BuyerAsTakerTrade;
import io.bitsquare.trade.SellerAsTakerTrade; import io.bitsquare.trade.SellerAsTakerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.offer.Offer;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.bitcoinj.core.Address; import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -104,7 +102,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
final ObjectProperty<Address> address = new SimpleObjectProperty<>(); final ObjectProperty<Address> address = new SimpleObjectProperty<>();
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>(); final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<State> state = new SimpleObjectProperty<>(State.CHECK_AVAILABILITY); final ObjectProperty<State> state = new SimpleObjectProperty<>(TakeOfferViewModel.State.CHECK_AVAILABILITY);
final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>(); final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>();
private boolean takeOfferRequested; private boolean takeOfferRequested;
@ -114,7 +112,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private ChangeListener<Boolean> isWalletFundedChangeListener; private ChangeListener<Boolean> isWalletFundedChangeListener;
private ChangeListener<Coin> amountAsCoinChangeListener; private ChangeListener<Coin> amountAsCoinChangeListener;
private ChangeListener<Offer.State> offerStateChangeListener; private ChangeListener<Offer.State> offerStateChangeListener;
private ChangeListener<TradeState.ProcessState> tradeStateChangeListener; private ChangeListener<TradeState> tradeStateChangeListener;
// Offer and trade are stored only for remove listener at deactivate // Offer and trade are stored only for remove listener at deactivate
private Offer offer; private Offer offer;
private Trade trade; private Trade trade;
@ -204,7 +202,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
offer.stateProperty().removeListener(offerStateChangeListener); offer.stateProperty().removeListener(offerStateChangeListener);
if (trade != null) if (trade != null)
trade.processStateProperty().removeListener(tradeStateChangeListener); trade.tradeStateProperty().removeListener(tradeStateChangeListener);
} }
@ -267,14 +265,14 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
isTakeOfferSpinnerVisible.set(true); isTakeOfferSpinnerVisible.set(true);
dataModel.onTakeOffer((trade) -> { dataModel.onTakeOffer((trade) -> {
this.trade = trade; this.trade = trade;
trade.processStateProperty().addListener(tradeStateChangeListener); trade.tradeStateProperty().addListener(tradeStateChangeListener);
applyTradeState(trade.processStateProperty().get()); applyTradeState(trade.tradeStateProperty().get());
evaluateViewState(); evaluateViewState();
}); });
} }
void onShowPaymentScreen() { void onShowPaymentScreen() {
state.set(State.PAYMENT_SCREEN); state.set(TakeOfferViewModel.State.PAYMENT_SCREEN);
} }
void onToggleShowAdvancedSettings() { void onToggleShowAdvancedSettings() {
@ -294,7 +292,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
// TODO set spinner? // TODO set spinner?
break; break;
case AVAILABLE: case AVAILABLE:
this.state.set(State.AMOUNT_SCREEN); this.state.set(TakeOfferViewModel.State.AMOUNT_SCREEN);
break; break;
case NOT_AVAILABLE: case NOT_AVAILABLE:
if (takeOfferRequested) if (takeOfferRequested)
@ -343,16 +341,16 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
evaluateViewState(); evaluateViewState();
} }
private void applyTradeState(TradeState.ProcessState state) { private void applyTradeState(TradeState tradeState) {
log.debug("applyTradeState state = " + state); log.debug("applyTradeState state = " + tradeState);
String msg = "An error occurred."; String msg = "An error occurred.";
if (trade.getErrorMessage() != null) if (trade.getErrorMessage() != null)
msg = "Error message: " + trade.getErrorMessage(); msg = "Error message: " + trade.getErrorMessage();
if (trade instanceof SellerAsTakerTrade) { if (trade instanceof SellerAsTakerTrade) {
switch ((SellerTradeState.ProcessState) state) { switch ((TradeState.SellerState) tradeState) {
case UNDEFINED: case PREPARATION:
break; break;
case DEPOSIT_PUBLISHED_MSG_RECEIVED: case DEPOSIT_PUBLISHED_MSG_RECEIVED:
assert trade.getDepositTx() != null; assert trade.getDepositTx() != null;
@ -367,7 +365,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
case PAYOUT_TX_COMMITTED: case PAYOUT_TX_COMMITTED:
case PAYOUT_BROAD_CASTED: case PAYOUT_BROAD_CASTED:
break; break;
case TIMEOUT: /* case TIMEOUT:
errorMessage.set("A timeout occurred. Maybe there are connection problems. " + errorMessage.set("A timeout occurred. Maybe there are connection problems. " +
"Please try later again.\n" + msg); "Please try later again.\n" + msg);
takeOfferRequested = false; takeOfferRequested = false;
@ -375,15 +373,15 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
case FAULT: case FAULT:
errorMessage.set(msg); errorMessage.set(msg);
takeOfferRequested = false; takeOfferRequested = false;
break; break;*/
default: default:
log.warn("Unhandled trade state: " + state); log.warn("Unhandled trade state: " + tradeState);
break; break;
} }
} }
else if (trade instanceof BuyerAsTakerTrade) { else if (trade instanceof BuyerAsTakerTrade) {
switch ((BuyerTradeState.ProcessState) state) { switch ((TradeState.BuyerState) tradeState) {
case UNDEFINED: case PREPARATION:
break; break;
case DEPOSIT_PUBLISHED: case DEPOSIT_PUBLISHED:
assert trade.getDepositTx() != null; assert trade.getDepositTx() != null;
@ -399,7 +397,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
case PAYOUT_TX_SENT: case PAYOUT_TX_SENT:
case PAYOUT_BROAD_CASTED: case PAYOUT_BROAD_CASTED:
break; break;
case TIMEOUT: /* case TIMEOUT:
errorMessage.set("A timeout occurred. Maybe there are connection problems. " + errorMessage.set("A timeout occurred. Maybe there are connection problems. " +
"Please try later again.\n" + msg); "Please try later again.\n" + msg);
takeOfferRequested = false; takeOfferRequested = false;
@ -407,9 +405,9 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
case FAULT: case FAULT:
errorMessage.set(msg); errorMessage.set(msg);
takeOfferRequested = false; takeOfferRequested = false;
break; break;*/
default: default:
log.warn("Unhandled trade state: " + state); log.warn("Unhandled trade state: " + tradeState);
break; break;
} }
} }
@ -562,8 +560,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
!dataModel.isAmountLargerThanOfferAmount() && !dataModel.isAmountLargerThanOfferAmount() &&
dataModel.isWalletFunded.get(); dataModel.isWalletFunded.get();
if (isAmountAndPriceValidAndWalletFunded && state.get() != State.CHECK_AVAILABILITY) if (isAmountAndPriceValidAndWalletFunded && state.get() != TakeOfferViewModel.State.CHECK_AVAILABILITY)
state.set(State.PAYMENT_SCREEN); state.set(TakeOfferViewModel.State.PAYMENT_SCREEN);
takeOfferButtonDisabled.set(!isAmountAndPriceValidAndWalletFunded || takeOfferRequested); takeOfferButtonDisabled.set(!isAmountAndPriceValidAndWalletFunded || takeOfferRequested);
} }

View file

@ -25,7 +25,8 @@
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">
<Tab fx:id="openOffersTab" text="Open offers"/> <Tab fx:id="openOffersTab" text="Open offers"/>
<Tab fx:id="openTradesTab" text="Open trades"/> <Tab fx:id="pendingTradesTab" text="Open trades"/>
<Tab fx:id="closedTradesTab" text="History"/> <Tab fx:id="closedTradesTab" text="History"/>
<Tab fx:id="failedTradesTab" text="Failed"/>
</TabPane> </TabPane>

View file

@ -26,6 +26,7 @@ import io.bitsquare.gui.common.view.View;
import io.bitsquare.gui.common.view.ViewLoader; import io.bitsquare.gui.common.view.ViewLoader;
import io.bitsquare.gui.main.MainView; import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.portfolio.closedtrades.ClosedTradesView; import io.bitsquare.gui.main.portfolio.closedtrades.ClosedTradesView;
import io.bitsquare.gui.main.portfolio.failedtrades.FailedTradesView;
import io.bitsquare.gui.main.portfolio.openoffer.OpenOffersView; import io.bitsquare.gui.main.portfolio.openoffer.OpenOffersView;
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesView; import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesView;
@ -38,7 +39,7 @@ import javafx.scene.control.*;
@FxmlView @FxmlView
public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> { public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab openOffersTab, openTradesTab, closedTradesTab; @FXML Tab openOffersTab, pendingTradesTab, closedTradesTab, failedTradesTab;
private Tab currentTab; private Tab currentTab;
private Navigation.Listener navigationListener; private Navigation.Listener navigationListener;
@ -65,10 +66,12 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
log.debug("tabChangeListener"); log.debug("tabChangeListener");
if (newValue == openOffersTab) if (newValue == openOffersTab)
navigation.navigateTo(MainView.class, PortfolioView.class, OpenOffersView.class); navigation.navigateTo(MainView.class, PortfolioView.class, OpenOffersView.class);
else if (newValue == openTradesTab) else if (newValue == pendingTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class); navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
else if (newValue == closedTradesTab) else if (newValue == closedTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class); navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class);
else if (newValue == failedTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, FailedTradesView.class);
}; };
} }
@ -79,10 +82,12 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
if (root.getSelectionModel().getSelectedItem() == openOffersTab) if (root.getSelectionModel().getSelectedItem() == openOffersTab)
navigation.navigateTo(MainView.class, PortfolioView.class, OpenOffersView.class); navigation.navigateTo(MainView.class, PortfolioView.class, OpenOffersView.class);
else if (root.getSelectionModel().getSelectedItem() == openTradesTab) else if (root.getSelectionModel().getSelectedItem() == pendingTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class); navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
else if (root.getSelectionModel().getSelectedItem() == closedTradesTab) else if (root.getSelectionModel().getSelectedItem() == closedTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class); navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class);
else if (root.getSelectionModel().getSelectedItem() == failedTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, FailedTradesView.class);
} }
@Override @Override
@ -100,8 +105,9 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
View view = viewLoader.load(viewClass); View view = viewLoader.load(viewClass);
if (view instanceof OpenOffersView) currentTab = openOffersTab; if (view instanceof OpenOffersView) currentTab = openOffersTab;
else if (view instanceof PendingTradesView) currentTab = openTradesTab; else if (view instanceof PendingTradesView) currentTab = pendingTradesTab;
else if (view instanceof ClosedTradesView) currentTab = closedTradesTab; else if (view instanceof ClosedTradesView) currentTab = closedTradesTab;
else if (view instanceof FailedTradesView) currentTab = failedTradesTab;
currentTab.setContent(view.getRoot()); currentTab.setContent(view.getRoot());
root.getSelectionModel().select(currentTab); root.getSelectionModel().select(currentTab);

View file

@ -26,20 +26,10 @@ class ClosedTradesListItem {
private final Tradable tradable; private final Tradable tradable;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
ClosedTradesListItem(Tradable tradable) { ClosedTradesListItem(Tradable tradable) {
this.tradable = tradable; this.tradable = tradable;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
Tradable getTradable() { Tradable getTradable() {
return tradable; return tradable;
} }

View file

@ -20,7 +20,10 @@ package io.bitsquare.gui.main.portfolio.closedtrades;
import io.bitsquare.gui.common.model.ActivatableWithDataModel; import io.bitsquare.gui.common.model.ActivatableWithDataModel;
import io.bitsquare.gui.common.model.ViewModel; import io.bitsquare.gui.common.model.ViewModel;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.trade.BuyerTrade;
import io.bitsquare.trade.SellerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.offer.OpenOffer; import io.bitsquare.trade.offer.OpenOffer;
import com.google.inject.Inject; import com.google.inject.Inject;
@ -80,13 +83,29 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
String getState(ClosedTradesListItem item) { String getState(ClosedTradesListItem item) {
if (item != null) { if (item != null) {
if (item.getTradable() instanceof Trade) { if (item.getTradable() instanceof Trade) {
switch (((Trade) item.getTradable()).lifeCycleStateProperty().get()) { Trade trade = (Trade) item.getTradable();
case COMPLETED: TradeState tradeState = trade.tradeStateProperty().get();
return "Completed"; if (trade instanceof BuyerTrade) {
case FAILED: if (tradeState == TradeState.BuyerState.FAILED) {
return "Failed"; return "Failed";
case PENDING: }
throw new RuntimeException("That must not happen. We got a pending state but we are in the closed trades list."); else if (tradeState == TradeState.BuyerState.WITHDRAW_COMPLETED) {
return "Completed";
}
else {
log.error("That must not happen. We got a pending state but we are in the closed trades list.");
}
}
else if (trade instanceof SellerTrade) {
if (tradeState == TradeState.SellerState.FAILED) {
return "Failed";
}
else if (tradeState == TradeState.SellerState.WITHDRAW_COMPLETED) {
return "Completed";
}
else {
log.error("That must not happen. We got a pending state but we are in the closed trades list.");
}
} }
} }
else if (item.getTradable() instanceof OpenOffer) { else if (item.getTradable() instanceof OpenOffer) {

View file

@ -0,0 +1,76 @@
/*
* 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.gui.main.portfolio.failedtrades;
import io.bitsquare.gui.common.model.Activatable;
import io.bitsquare.gui.common.model.DataModel;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.failed.FailedTradesManager;
import io.bitsquare.trade.offer.Offer;
import com.google.inject.Inject;
import java.util.stream.Collectors;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
class FailedTradesDataModel implements Activatable, DataModel {
private final FailedTradesManager failedTradesManager;
private final ObservableList<FailedTradesListItem> list = FXCollections.observableArrayList();
private final ListChangeListener<Trade> tradesListChangeListener;
@Inject
public FailedTradesDataModel(FailedTradesManager failedTradesManager) {
this.failedTradesManager = failedTradesManager;
tradesListChangeListener = change -> applyList();
}
@Override
public void activate() {
applyList();
failedTradesManager.getFailedTrades().addListener(tradesListChangeListener);
}
@Override
public void deactivate() {
failedTradesManager.getFailedTrades().removeListener(tradesListChangeListener);
}
public ObservableList<FailedTradesListItem> getList() {
return list;
}
public Offer.Direction getDirection(Offer offer) {
return failedTradesManager.wasMyOffer(offer) ? offer.getDirection() : offer.getMirroredDirection();
}
private void applyList() {
list.clear();
list.addAll(failedTradesManager.getFailedTrades().stream().map(FailedTradesListItem::new).collect(Collectors.toList()));
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
}
}

View file

@ -15,14 +15,22 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>. * along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/ */
package io.bitsquare.trade.states; package io.bitsquare.gui.main.portfolio.failedtrades;
import org.slf4j.Logger; import io.bitsquare.trade.Trade;
import org.slf4j.LoggerFactory;
public class TradeState { /**
private static final Logger log = LoggerFactory.getLogger(TradeState.class); * We could remove that wrapper if it is not needed for additional UI only fields.
*/
class FailedTradesListItem {
public interface ProcessState { private final Trade trade;
FailedTradesListItem(Trade trade) {
this.trade = trade;
}
Trade getTrade() {
return trade;
} }
} }

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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/>.
-->
<?import io.bitsquare.gui.components.TitledSeparator?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.failedtrades.FailedTradesView"
hgap="5.0" vgap="5"
xmlns:fx="http://javafx.com/fxml">
<padding>
<Insets bottom="20.0" left="25.0" top="30.0" right="25"/>
</padding>
<TitledSeparator text="Closed trades" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2"/>
<TableView fx:id="table" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2">
<GridPane.margin>
<Insets top="10.0" left="-10" right="-10" bottom="-15"/>
</GridPane.margin>
<columns>
<TableColumn text="Trade ID" fx:id="tradeIdColumn" minWidth="100" sortable="false"/>
<TableColumn text="Date" fx:id="dateColumn" minWidth="130"/>
<TableColumn text="Trade amount in BTC" fx:id="amountColumn" minWidth="130" sortable="false"/>
<TableColumn text="Price" fx:id="priceColumn" minWidth="100" sortable="false"/>
<TableColumn text="Trade amount in EUR" fx:id="volumeColumn" minWidth="130" sortable="false"/>
<TableColumn text="Trade type" fx:id="directionColumn" minWidth="80" sortable="false"/>
<TableColumn text="State" fx:id="stateColumn" minWidth="80" sortable="false"/>
</columns>
</TableView>
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" minWidth="200"/>
<ColumnConstraints hgrow="ALWAYS"/>
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="ALWAYS"/>
</rowConstraints>
</GridPane>

View file

@ -0,0 +1,227 @@
/*
* 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.gui.main.portfolio.failedtrades;
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.components.Popups;
import javax.inject.Inject;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.util.Callback;
@FxmlView
public class FailedTradesView extends ActivatableViewAndModel<GridPane, FailedTradesViewModel> {
@FXML TableView<FailedTradesListItem> table;
@FXML TableColumn<FailedTradesListItem, FailedTradesListItem> priceColumn, amountColumn, volumeColumn,
directionColumn, dateColumn, tradeIdColumn, stateColumn;
@Inject
public FailedTradesView(FailedTradesViewModel model) {
super(model);
}
@Override
public void initialize() {
setTradeIdColumnCellFactory();
setDirectionColumnCellFactory();
setAmountColumnCellFactory();
setPriceColumnCellFactory();
setVolumeColumnCellFactory();
setDateColumnCellFactory();
setStateColumnCellFactory();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setPlaceholder(new Label("No closed trades available"));
}
@Override
public void doActivate() {
table.setItems(model.getList());
}
private void openOfferDetails(FailedTradesListItem item) {
// TODO Open popup with details view
log.debug("Trade details " + item);
Popups.openWarningPopup("Under construction", "This will open a details " +
"popup but that is not implemented yet.");
}
private void setTradeIdColumnCellFactory() {
tradeIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue()));
tradeIdColumn.setCellFactory(
new Callback<TableColumn<FailedTradesListItem, FailedTradesListItem>, TableCell<FailedTradesListItem,
FailedTradesListItem>>() {
@Override
public TableCell<FailedTradesListItem, FailedTradesListItem> call(TableColumn<FailedTradesListItem,
FailedTradesListItem> column) {
return new TableCell<FailedTradesListItem, FailedTradesListItem>() {
private Hyperlink hyperlink;
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
hyperlink = new Hyperlink(model.getTradeId(item));
hyperlink.setId("id-link");
Tooltip.install(hyperlink, new Tooltip(model.getTradeId(item)));
hyperlink.setOnAction(event -> openOfferDetails(item));
setGraphic(hyperlink);
}
else {
setGraphic(null);
setId(null);
}
}
};
}
});
}
private void setDateColumnCellFactory() {
dateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
dateColumn.setCellFactory(
new Callback<TableColumn<FailedTradesListItem, FailedTradesListItem>, TableCell<FailedTradesListItem,
FailedTradesListItem>>() {
@Override
public TableCell<FailedTradesListItem, FailedTradesListItem> call(
TableColumn<FailedTradesListItem, FailedTradesListItem> column) {
return new TableCell<FailedTradesListItem, FailedTradesListItem>() {
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
setText(model.getDate(item));
else
setText("");
}
};
}
});
}
private void setStateColumnCellFactory() {
stateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
stateColumn.setCellFactory(
new Callback<TableColumn<FailedTradesListItem, FailedTradesListItem>, TableCell<FailedTradesListItem,
FailedTradesListItem>>() {
@Override
public TableCell<FailedTradesListItem, FailedTradesListItem> call(
TableColumn<FailedTradesListItem, FailedTradesListItem> column) {
return new TableCell<FailedTradesListItem, FailedTradesListItem>() {
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
setText(model.getState(item));
else
setText("");
}
};
}
});
}
private void setAmountColumnCellFactory() {
amountColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
amountColumn.setCellFactory(
new Callback<TableColumn<FailedTradesListItem, FailedTradesListItem>, TableCell<FailedTradesListItem,
FailedTradesListItem>>() {
@Override
public TableCell<FailedTradesListItem, FailedTradesListItem> call(
TableColumn<FailedTradesListItem, FailedTradesListItem> column) {
return new TableCell<FailedTradesListItem, FailedTradesListItem>() {
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
setText(model.getAmount(item));
}
};
}
});
}
private void setPriceColumnCellFactory() {
priceColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
priceColumn.setCellFactory(
new Callback<TableColumn<FailedTradesListItem, FailedTradesListItem>, TableCell<FailedTradesListItem,
FailedTradesListItem>>() {
@Override
public TableCell<FailedTradesListItem, FailedTradesListItem> call(
TableColumn<FailedTradesListItem, FailedTradesListItem> column) {
return new TableCell<FailedTradesListItem, FailedTradesListItem>() {
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
setText(model.getPrice(item));
}
};
}
});
}
private void setVolumeColumnCellFactory() {
volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
volumeColumn.setCellFactory(
new Callback<TableColumn<FailedTradesListItem, FailedTradesListItem>, TableCell<FailedTradesListItem,
FailedTradesListItem>>() {
@Override
public TableCell<FailedTradesListItem, FailedTradesListItem> call(
TableColumn<FailedTradesListItem, FailedTradesListItem> column) {
return new TableCell<FailedTradesListItem, FailedTradesListItem>() {
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
setText(model.getVolume(item));
else
setText("");
}
};
}
});
}
private void setDirectionColumnCellFactory() {
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
directionColumn.setCellFactory(
new Callback<TableColumn<FailedTradesListItem, FailedTradesListItem>, TableCell<FailedTradesListItem,
FailedTradesListItem>>() {
@Override
public TableCell<FailedTradesListItem, FailedTradesListItem> call(
TableColumn<FailedTradesListItem, FailedTradesListItem> column) {
return new TableCell<FailedTradesListItem, FailedTradesListItem>() {
@Override
public void updateItem(final FailedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
setText(model.getDirectionLabel(item));
}
};
}
});
}
}

View file

@ -0,0 +1,105 @@
/*
* 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.gui.main.portfolio.failedtrades;
import io.bitsquare.gui.common.model.ActivatableWithDataModel;
import io.bitsquare.gui.common.model.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.trade.BuyerTrade;
import io.bitsquare.trade.SellerTrade;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeState;
import com.google.inject.Inject;
import javafx.collections.ObservableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class FailedTradesViewModel extends ActivatableWithDataModel<FailedTradesDataModel> implements ViewModel {
private static final Logger log = LoggerFactory.getLogger(FailedTradesViewModel.class);
private final BSFormatter formatter;
@Inject
public FailedTradesViewModel(FailedTradesDataModel dataModel, BSFormatter formatter) {
super(dataModel);
this.formatter = formatter;
}
public ObservableList<FailedTradesListItem> getList() {
return dataModel.getList();
}
String getTradeId(FailedTradesListItem item) {
return item.getTrade().getId();
}
String getAmount(FailedTradesListItem item) {
if (item != null && item.getTrade() instanceof Trade)
return formatter.formatCoinWithCode(((Trade) item.getTrade()).getTradeAmount());
else
return "";
}
String getPrice(FailedTradesListItem item) {
return (item != null) ? formatter.formatFiat(item.getTrade().getOffer().getPrice()) : "";
}
String getVolume(FailedTradesListItem item) {
if (item != null && item.getTrade() instanceof Trade)
return formatter.formatFiatWithCode(((Trade) item.getTrade()).getTradeVolume());
else
return "";
}
String getDirectionLabel(FailedTradesListItem item) {
return (item != null) ? formatter.formatDirection(dataModel.getDirection(item.getTrade().getOffer())) : "";
}
String getDate(FailedTradesListItem item) {
return formatter.formatDateTime(item.getTrade().getDate());
}
String getState(FailedTradesListItem item) {
if (item != null) {
Trade trade = item.getTrade();
TradeState tradeState = trade.tradeStateProperty().get();
if (trade instanceof BuyerTrade) {
if (tradeState == TradeState.BuyerState.FAILED) {
return "Failed";
}
else {
log.error("Wrong state " + item.getTrade().tradeStateProperty().get());
}
}
else if (trade instanceof SellerTrade) {
if (tradeState == TradeState.SellerState.FAILED) {
return "Failed";
}
else {
log.error("Wrong state " + item.getTrade().tradeStateProperty().get());
}
}
}
return "";
}
}

View file

@ -148,23 +148,6 @@ public class BuyerSubView extends TradeSubView {
"You can review the details to that trade any time in the closed trades screen."); "You can review the details to that trade any time in the closed trades screen.");
completedView.setWithdrawAmountTextFieldText(model.getPayoutAmount()); completedView.setWithdrawAmountTextFieldText(model.getPayoutAmount());
break; break;
case CLOSED:
showItem(waitTxInBlockchain);
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Trade is closed");
break;
case FAULT:
showItem(waitTxInBlockchain);
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Error occured");
break;
/*case MESSAGE_SENDING_FAILED:
Popups.openWarningPopup("Sending message to trading peer failed.", model.getErrorMessage());
break;
case EXCEPTION:
if (model.getTradeException() != null)
Popups.openExceptionPopup(model.getTradeException());
else
Popups.openErrorPopup("An error occurred", model.getErrorMessage());
break;*/
default: default:
log.warn("unhandled buyerState " + state); log.warn("unhandled buyerState " + state);
break; break;

View file

@ -32,8 +32,8 @@ import io.bitsquare.trade.Contract;
import io.bitsquare.trade.SellerTrade; import io.bitsquare.trade.SellerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeManager; import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.offer.Offer;
import io.bitsquare.trade.states.TradeState;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import org.bitcoinj.core.BlockChainListener; import org.bitcoinj.core.BlockChainListener;
@ -71,8 +71,8 @@ class PendingTradesDataModel implements Activatable, DataModel {
private final ListChangeListener<Trade> tradesListChangeListener; private final ListChangeListener<Trade> tradesListChangeListener;
private boolean isOffererRole; private boolean isOffererRole;
private final ObjectProperty<TradeState.ProcessState> sellerProcessState = new SimpleObjectProperty<>(); private final ObjectProperty<TradeState> sellerProcessState = new SimpleObjectProperty<>();
private final ObjectProperty<TradeState.ProcessState> buyerProcessState = new SimpleObjectProperty<>(); private final ObjectProperty<TradeState> buyerProcessState = new SimpleObjectProperty<>();
private final ObjectProperty<Trade> tradeProperty = new SimpleObjectProperty<>(); private final ObjectProperty<Trade> tradeProperty = new SimpleObjectProperty<>();
private final StringProperty txId = new SimpleStringProperty(); private final StringProperty txId = new SimpleStringProperty();
private Trade trade; private Trade trade;
@ -108,8 +108,7 @@ class PendingTradesDataModel implements Activatable, DataModel {
private void onListChanged() { private void onListChanged() {
list.clear(); list.clear();
list.addAll(tradeManager.getPendingTrades().stream().filter(e -> !e.isFaultState()) list.addAll(tradeManager.getPendingTrades().stream().map(PendingTradesListItem::new).collect(Collectors.toList()));
.map(PendingTradesListItem::new).collect(Collectors.toList()));
// we sort by date, earliest first // we sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate())); list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
@ -147,9 +146,9 @@ class PendingTradesDataModel implements Activatable, DataModel {
isOffererRole = tradeManager.isMyOffer(trade.getOffer()); isOffererRole = tradeManager.isMyOffer(trade.getOffer());
if (trade instanceof SellerTrade) if (trade instanceof SellerTrade)
sellerProcessState.bind(trade.processStateProperty()); sellerProcessState.bind(trade.tradeStateProperty());
else if (trade instanceof BuyerTrade) else if (trade instanceof BuyerTrade)
buyerProcessState.bind(trade.processStateProperty()); buyerProcessState.bind(trade.tradeStateProperty());
if (trade.getDepositTx() != null) if (trade.getDepositTx() != null)
txId.set(trade.getDepositTx().getHashAsString()); txId.set(trade.getDepositTx().getHashAsString());
@ -244,10 +243,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
return trade.getOffer().getCurrencyCode(); return trade.getOffer().getCurrencyCode();
} }
Throwable getTradeException() {
return trade.getThrowable();
}
String getErrorMessage() { String getErrorMessage() {
return trade.getErrorMessage(); return trade.getErrorMessage();
} }
@ -268,11 +263,11 @@ class PendingTradesDataModel implements Activatable, DataModel {
return trade; return trade;
} }
ReadOnlyObjectProperty<TradeState.ProcessState> getSellerProcessState() { ReadOnlyObjectProperty<TradeState> getSellerProcessState() {
return sellerProcessState; return sellerProcessState;
} }
ReadOnlyObjectProperty<TradeState.ProcessState> getBuyerProcessState() { ReadOnlyObjectProperty<TradeState> getBuyerProcessState() {
return buyerProcessState; return buyerProcessState;
} }

View file

@ -24,8 +24,7 @@ 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.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.states.BuyerTradeState; import io.bitsquare.trade.TradeState;
import io.bitsquare.trade.states.SellerTradeState;
import org.bitcoinj.core.BlockChainListener; import org.bitcoinj.core.BlockChainListener;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
@ -62,9 +61,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
REQUEST_START_FIAT_PAYMENT, REQUEST_START_FIAT_PAYMENT,
WAIT_FOR_FIAT_PAYMENT_RECEIPT, WAIT_FOR_FIAT_PAYMENT_RECEIPT,
WAIT_FOR_UNLOCK_PAYOUT, WAIT_FOR_UNLOCK_PAYOUT,
REQUEST_WITHDRAWAL, REQUEST_WITHDRAWAL
CLOSED,
FAULT
} }
enum SellerState implements State { enum SellerState implements State {
@ -74,9 +71,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED, REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED,
WAIT_FOR_PAYOUT_TX, WAIT_FOR_PAYOUT_TX,
WAIT_FOR_UNLOCK_PAYOUT, WAIT_FOR_UNLOCK_PAYOUT,
REQUEST_WITHDRAWAL, REQUEST_WITHDRAWAL
CLOSED,
FAULT
} }
private final BSFormatter formatter; private final BSFormatter formatter;
@ -84,8 +79,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
private final InvalidationListener buyerStateListener; private final InvalidationListener buyerStateListener;
private final BtcAddressValidator btcAddressValidator; private final BtcAddressValidator btcAddressValidator;
private final ObjectProperty<BuyerState> buyerState = new SimpleObjectProperty<>(BuyerState.UNDEFINED); private final ObjectProperty<BuyerState> buyerState = new SimpleObjectProperty<>(PendingTradesViewModel.BuyerState.UNDEFINED);
private final ObjectProperty<SellerState> sellerState = new SimpleObjectProperty<>(SellerState.UNDEFINED); private final ObjectProperty<SellerState> sellerState = new SimpleObjectProperty<>(PendingTradesViewModel.SellerState.UNDEFINED);
private final StringProperty txId = new SimpleStringProperty(); private final StringProperty txId = new SimpleStringProperty();
private final BooleanProperty withdrawalButtonDisable = new SimpleBooleanProperty(true); private final BooleanProperty withdrawalButtonDisable = new SimpleBooleanProperty(true);
@ -177,10 +172,6 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
public void onWithdrawRequest(String withdrawToAddress) { public void onWithdrawRequest(String withdrawToAddress) {
dataModel.onWithdrawRequest(withdrawToAddress); dataModel.onWithdrawRequest(withdrawToAddress);
if (dataModel.getSellerProcessState().get() instanceof SellerTradeState.ProcessState)
sellerState.setValue(SellerState.CLOSED);
else
buyerState.setValue(BuyerState.CLOSED);
} }
public void withdrawAddressFocusOut(String text) { public void withdrawAddressFocusOut(String text) {
@ -215,10 +206,6 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
return btcAddressValidator; return btcAddressValidator;
} }
Throwable getTradeException() {
return dataModel.getTradeException();
}
String getErrorMessage() { String getErrorMessage() {
return dataModel.getErrorMessage(); return dataModel.getErrorMessage();
} }
@ -322,51 +309,46 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
private void applySellerState() { private void applySellerState() {
if (dataModel.getSellerProcessState().get() instanceof SellerTradeState.ProcessState) { if (dataModel.getSellerProcessState().get() instanceof TradeState.SellerState) {
SellerTradeState.ProcessState processState = (SellerTradeState.ProcessState) dataModel.getSellerProcessState().get(); TradeState.SellerState processState = (TradeState.SellerState) dataModel.getSellerProcessState().get();
log.debug("updateSellerState (SellerTradeState) " + processState); log.debug("updateSellerState (SellerTradeState) " + processState);
if (processState != null) { if (processState != null) {
switch (processState) { switch (processState) {
case UNDEFINED: case PREPARATION:
sellerState.set(SellerState.UNDEFINED); sellerState.set(PendingTradesViewModel.SellerState.UNDEFINED);
break; break;
case DEPOSIT_PUBLISHED_MSG_RECEIVED: case DEPOSIT_PUBLISHED_MSG_RECEIVED:
sellerState.set(SellerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION); sellerState.set(PendingTradesViewModel.SellerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION);
break; break;
case DEPOSIT_CONFIRMED: case DEPOSIT_CONFIRMED:
sellerState.set(SellerState.WAIT_FOR_FIAT_PAYMENT_STARTED); sellerState.set(PendingTradesViewModel.SellerState.WAIT_FOR_FIAT_PAYMENT_STARTED);
break; break;
case FIAT_PAYMENT_STARTED_MSG_RECEIVED: case FIAT_PAYMENT_STARTED_MSG_RECEIVED:
sellerState.set(SellerState.REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED); sellerState.set(PendingTradesViewModel.SellerState.REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED);
break; break;
case FIAT_PAYMENT_RECEIPT: case FIAT_PAYMENT_RECEIPT:
break; break;
case FIAT_PAYMENT_RECEIPT_MSG_SENT: case FIAT_PAYMENT_RECEIPT_MSG_SENT:
sellerState.set(SellerState.WAIT_FOR_PAYOUT_TX); sellerState.set(PendingTradesViewModel.SellerState.WAIT_FOR_PAYOUT_TX);
break; break;
case PAYOUT_TX_RECEIVED: case PAYOUT_TX_RECEIVED:
break; break;
case PAYOUT_TX_COMMITTED: case PAYOUT_TX_COMMITTED:
sellerState.set(SellerState.WAIT_FOR_UNLOCK_PAYOUT); sellerState.set(PendingTradesViewModel.SellerState.WAIT_FOR_UNLOCK_PAYOUT);
break; break;
case PAYOUT_BROAD_CASTED: case PAYOUT_BROAD_CASTED:
sellerState.set(SellerState.REQUEST_WITHDRAWAL); sellerState.set(PendingTradesViewModel.SellerState.REQUEST_WITHDRAWAL);
break;
case FAULT:
sellerState.set(SellerState.FAULT);
break; break;
default: default:
@ -381,31 +363,31 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
} }
private void applyBuyerState() { private void applyBuyerState() {
if (dataModel.getBuyerProcessState().get() instanceof BuyerTradeState.ProcessState) { if (dataModel.getBuyerProcessState().get() instanceof TradeState.BuyerState) {
BuyerTradeState.ProcessState processState = (BuyerTradeState.ProcessState) dataModel.getBuyerProcessState().get(); TradeState.BuyerState processState = (TradeState.BuyerState) dataModel.getBuyerProcessState().get();
log.debug("updateBuyerState (BuyerTradeState) " + processState); log.debug("updateBuyerState (BuyerTradeState) " + processState);
if (processState != null) { if (processState != null) {
switch (processState) { switch (processState) {
case UNDEFINED: case PREPARATION:
sellerState.set(SellerState.UNDEFINED); sellerState.set(PendingTradesViewModel.SellerState.UNDEFINED);
break; break;
case DEPOSIT_PUBLISHED: case DEPOSIT_PUBLISHED:
case DEPOSIT_PUBLISHED_MSG_SENT: case DEPOSIT_PUBLISHED_MSG_SENT:
buyerState.set(BuyerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION); buyerState.set(PendingTradesViewModel.BuyerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION);
break; break;
case DEPOSIT_CONFIRMED: case DEPOSIT_CONFIRMED:
buyerState.set(BuyerState.REQUEST_START_FIAT_PAYMENT); buyerState.set(PendingTradesViewModel.BuyerState.REQUEST_START_FIAT_PAYMENT);
break; break;
case FIAT_PAYMENT_STARTED: case FIAT_PAYMENT_STARTED:
break; break;
case FIAT_PAYMENT_STARTED_MSG_SENT: case FIAT_PAYMENT_STARTED_MSG_SENT:
buyerState.set(BuyerState.WAIT_FOR_FIAT_PAYMENT_RECEIPT); buyerState.set(PendingTradesViewModel.BuyerState.WAIT_FOR_FIAT_PAYMENT_RECEIPT);
break; break;
@ -413,17 +395,12 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
case PAYOUT_TX_COMMITTED: case PAYOUT_TX_COMMITTED:
break; break;
case PAYOUT_TX_SENT: case PAYOUT_TX_SENT:
buyerState.set(BuyerState.WAIT_FOR_UNLOCK_PAYOUT); buyerState.set(PendingTradesViewModel.BuyerState.WAIT_FOR_UNLOCK_PAYOUT);
break; break;
case PAYOUT_BROAD_CASTED: case PAYOUT_BROAD_CASTED:
buyerState.set(BuyerState.REQUEST_WITHDRAWAL); buyerState.set(PendingTradesViewModel.BuyerState.REQUEST_WITHDRAWAL);
break;
case FAULT:
sellerState.set(SellerState.FAULT);
break; break;
default: default:

View file

@ -177,24 +177,6 @@ public class SellerSubView extends TradeSubView {
completedView.setWithdrawAmountTextFieldText(model.getPayoutAmount()); completedView.setWithdrawAmountTextFieldText(model.getPayoutAmount());
break; break;
case CLOSED:
showItem(waitTxInBlockchain);
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Trade is closed");
break;
case FAULT:
showItem(waitTxInBlockchain);
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Error occured");
break;
/* case MESSAGE_SENDING_FAILED:
Popups.openWarningPopup("Sending message to trading peer failed.", model.getErrorMessage());
break;
case EXCEPTION:
if (model.getTradeException() != null)
Popups.openExceptionPopup(model.getTradeException());
else
Popups.openErrorPopup("An error occurred", model.getErrorMessage());
break;*/
default: default:
log.warn("unhandled viewState " + viewState); log.warn("unhandled viewState " + viewState);
break; break;

View file

@ -21,7 +21,7 @@ package io.bitsquare.gui.util.validation;
* That validator accepts empty inputs * That validator accepts empty inputs
*/ */
public class OptionalBtcValidator extends BtcValidator { public class OptionalBtcValidator extends BtcValidator {
@Override @Override
public ValidationResult validate(String input) { public ValidationResult validate(String input) {
ValidationResult result = validateIfNotEmpty(input); ValidationResult result = validateIfNotEmpty(input);