Trade process error handling

This commit is contained in:
Manfred Karrer 2015-04-23 00:35:37 +02:00
parent 3f6f8dd160
commit ca3d1c96f2
56 changed files with 306 additions and 243 deletions

View file

@ -38,7 +38,7 @@ public class FiatAccount implements Serializable {
public static final long WEEK_IN_BLOCKS = DAY_IN_BLOCKS * 7; public static final long WEEK_IN_BLOCKS = DAY_IN_BLOCKS * 7;
public enum Type { public enum Type {
IRC("", "", 1), IRC("", "", 0),
SEPA("IBAN", "BIC", WEEK_IN_BLOCKS), SEPA("IBAN", "BIC", WEEK_IN_BLOCKS),
WIRE("primary ID", "secondary ID", WEEK_IN_BLOCKS), WIRE("primary ID", "secondary ID", WEEK_IN_BLOCKS),
INTERNATIONAL("primary ID", "secondary ID", 2 * WEEK_IN_BLOCKS), INTERNATIONAL("primary ID", "secondary ID", 2 * WEEK_IN_BLOCKS),

View file

@ -169,8 +169,8 @@ public class TomP2PMessageService extends TomP2PService implements MessageServic
private void setupReplyHandler() { private void setupReplyHandler() {
peerDHT.peer().objectDataReply((sender, message) -> { peerDHT.peer().objectDataReply((sender, message) -> {
log.debug("Incoming message with peerAddress " + sender); //log.debug("Incoming message with peerAddress " + sender);
log.debug("Incoming message with type " + message); //log.debug("Incoming message with type " + message);
int messageSize = 0; int messageSize = 0;
if (message != null) if (message != null)
@ -189,7 +189,7 @@ public class TomP2PMessageService extends TomP2PService implements MessageServic
MessageWithPubKey messageWithPubKey = null; MessageWithPubKey messageWithPubKey = null;
try { try {
messageWithPubKey = getDecryptedMessageWithPubKey((SealedAndSignedMessage) message); messageWithPubKey = getDecryptedMessageWithPubKey((SealedAndSignedMessage) message);
log.debug("decrypted message " + messageWithPubKey.getMessage()); //log.debug("decrypted message " + messageWithPubKey.getMessage());
e.handleMessage(messageWithPubKey, new TomP2PPeer(sender)); e.handleMessage(messageWithPubKey, new TomP2PPeer(sender));
} catch (CryptoException e1) { } catch (CryptoException e1) {
e1.printStackTrace(); e1.printStackTrace();

View file

@ -29,6 +29,8 @@ import org.bitcoinj.core.Coin;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -50,8 +52,10 @@ public abstract class BuyerTrade extends Trade implements Serializable {
@Override @Override
protected void initStates() { protected void initStates() {
processState = BuyerTradeState.ProcessState.UNDEFINED; if (processState == null)
lifeCycleState = Trade.LifeCycleState.PREPARATION; processState = BuyerTradeState.ProcessState.UNDEFINED;
if (lifeCycleState == null)
lifeCycleState = Trade.LifeCycleState.PREPARATION;
initStateProperties(); initStateProperties();
} }
@ -69,12 +73,28 @@ public abstract class BuyerTrade extends Trade implements Serializable {
public void setProcessState(TradeState.ProcessState processState) { public void setProcessState(TradeState.ProcessState processState) {
super.setProcessState(processState); super.setProcessState(processState);
/* switch ((BuyerTradeState.ProcessState) processState) { switch ((BuyerTradeState.ProcessState) processState) {
case EXCEPTION: case DEPOSIT_PUBLISHED:
takeOfferDate = new Date();
if (this instanceof OffererTrade)
openOfferManager.closeOpenOffer(getOffer());
break;
case TIMEOUT:
disposeProtocol(); disposeProtocol();
setLifeCycleState(Trade.LifeCycleState.FAILED); setLifeCycleState(Trade.LifeCycleState.FAILED);
tradeManager.removeFailedTrade(this);
break; break;
}*/
case FAULT:
disposeProtocol();
setLifeCycleState(Trade.LifeCycleState.FAILED);
tradeManager.removeFailedTrade(this);
break;
}
} }
@Override @Override

View file

@ -29,6 +29,8 @@ import org.bitcoinj.core.Coin;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -50,8 +52,10 @@ public abstract class SellerTrade extends Trade implements Serializable {
@Override @Override
protected void initStates() { protected void initStates() {
processState = SellerTradeState.ProcessState.UNDEFINED; if (processState == null)
lifeCycleState = Trade.LifeCycleState.PENDING; processState = SellerTradeState.ProcessState.UNDEFINED;
if (lifeCycleState == null)
lifeCycleState = Trade.LifeCycleState.PENDING;
initStateProperties(); initStateProperties();
} }
@ -68,12 +72,28 @@ public abstract class SellerTrade extends Trade implements Serializable {
public void setProcessState(TradeState.ProcessState processState) { public void setProcessState(TradeState.ProcessState processState) {
super.setProcessState(processState); super.setProcessState(processState);
/* switch ((SellerTradeState.ProcessState) processState) { switch ((SellerTradeState.ProcessState) processState) {
case EXCEPTION: case DEPOSIT_PUBLISHED_MSG_RECEIVED:
takeOfferDate = new Date();
if (this instanceof OffererTrade)
openOfferManager.closeOpenOffer(getOffer());
break;
case TIMEOUT:
disposeProtocol(); disposeProtocol();
setLifeCycleState(Trade.LifeCycleState.FAILED); setLifeCycleState(Trade.LifeCycleState.FAILED);
tradeManager.removeFailedTrade(this);
break; break;
}*/
case FAULT:
disposeProtocol();
setLifeCycleState(Trade.LifeCycleState.FAILED);
tradeManager.removeFailedTrade(this);
break;
}
} }
@Override @Override

View file

@ -31,6 +31,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.offer.Offer; import io.bitsquare.trade.offer.Offer;
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.BuyerTradeState;
@ -75,6 +76,7 @@ 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 LifeCycleState { public enum LifeCycleState {
PREPARATION, PREPARATION,
PENDING, PENDING,
@ -100,6 +102,9 @@ abstract public class Trade implements Tradable, Model, Serializable {
transient private Storage<? extends TradableList> storage; transient private Storage<? extends TradableList> storage;
transient protected TradeProtocol tradeProtocol; transient protected TradeProtocol tradeProtocol;
transient protected TradeManager tradeManager;
transient protected OpenOfferManager openOfferManager;
// Immutable // Immutable
private final Offer offer; private final Offer offer;
private final ProcessModel processModel; private final ProcessModel processModel;
@ -107,7 +112,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
// Mutable // Mutable
private MessageWithPubKey messageWithPubKey; private MessageWithPubKey messageWithPubKey;
private Date takeOfferDate; protected Date takeOfferDate;
protected TradeState.ProcessState processState; protected TradeState.ProcessState processState;
protected Trade.LifeCycleState lifeCycleState; protected Trade.LifeCycleState lifeCycleState;
private Transaction depositTx; private Transaction depositTx;
@ -169,9 +174,14 @@ abstract public class Trade implements Tradable, Model, Serializable {
BlockChainService blockChainService, BlockChainService blockChainService,
CryptoService cryptoService, CryptoService cryptoService,
ArbitrationRepository arbitrationRepository, ArbitrationRepository arbitrationRepository,
TradeManager tradeManager,
OpenOfferManager openOfferManager,
User user, User user,
KeyRing keyRing) { KeyRing keyRing) {
this.tradeManager = tradeManager;
this.openOfferManager = openOfferManager;
processModel.onAllServicesInitialized(offer, processModel.onAllServicesInitialized(offer,
messageService, messageService,
addressService, addressService,
@ -254,6 +264,21 @@ abstract public class Trade implements Tradable, Model, Serializable {
setProcessState(BuyerTradeState.ProcessState.FAULT); setProcessState(BuyerTradeState.ProcessState.FAULT);
} }
public boolean isFaultState() {
return processState == BuyerTradeState.ProcessState.FAULT || processState == SellerTradeState.ProcessState.FAULT;
}
/* 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) { public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState; this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty.set(lifeCycleState); lifeCycleStateProperty.set(lifeCycleState);

View file

@ -45,8 +45,6 @@ import io.bitsquare.trade.protocol.availability.OfferAvailabilityModel;
import io.bitsquare.trade.protocol.trade.messages.DepositTxInputsRequest; import io.bitsquare.trade.protocol.trade.messages.DepositTxInputsRequest;
import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest; import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import org.bitcoinj.core.AddressFormatException; import org.bitcoinj.core.AddressFormatException;
@ -187,10 +185,9 @@ public class TradeManager {
trade = new SellerAsOffererTrade(offer, pendingTradesStorage); trade = new SellerAsOffererTrade(offer, pendingTradesStorage);
trade.setStorage(pendingTradesStorage); trade.setStorage(pendingTradesStorage);
pendingTrades.add(trade);
initTrade(trade); initTrade(trade);
pendingTrades.add(trade);
((OffererTrade) trade).handleTakeOfferRequest(message, sender); ((OffererTrade) trade).handleTakeOfferRequest(message, sender);
setupDepositPublishedListener(trade);
} }
else { else {
// TODO respond // TODO respond
@ -208,22 +205,12 @@ public class TradeManager {
blockChainService, blockChainService,
cryptoService, cryptoService,
arbitrationRepository, arbitrationRepository,
this,
openOfferManager,
user, user,
keyRing); keyRing);
} }
// Only after published we consider the openOffer as closed and the trade as completely initialized
private void setupDepositPublishedListener(Trade trade) {
trade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("setupDepositPublishedListener state = " + newValue);
if (newValue == BuyerTradeState.ProcessState.DEPOSIT_PUBLISHED ||
newValue == SellerTradeState.ProcessState.DEPOSIT_PUBLISHED_MSG_RECEIVED) {
openOfferManager.closeOpenOffer(trade.getOffer());
trade.setTakeOfferDate(new Date());
}
});
}
private void setMailboxMessagesToTrades(List<SealedAndSignedMessage> encryptedMessages) { private void setMailboxMessagesToTrades(List<SealedAndSignedMessage> encryptedMessages) {
log.trace("applyMailboxMessage encryptedMailboxMessage.size=" + encryptedMessages.size()); log.trace("applyMailboxMessage encryptedMailboxMessage.size=" + encryptedMessages.size());
for (SealedAndSignedMessage encrypted : encryptedMessages) { for (SealedAndSignedMessage encrypted : encryptedMessages) {
@ -268,9 +255,9 @@ public class TradeManager {
initTrade(trade); initTrade(trade);
} }
} }
for (Trade trade : failedTrades) { for (Trade trade : failedTrades) {
pendingTrades.remove(trade); removeFailedTrade(trade);
closedTradableManager.add(trade);
} }
} }
@ -367,6 +354,12 @@ public class TradeManager {
} }
} }
// In a fault case we remove it and add it to the closed trades
public void removeFailedTrade(Trade trade) {
pendingTrades.remove(trade);
closedTradableManager.add(trade);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Getters // Getters
@ -380,5 +373,8 @@ public class TradeManager {
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

@ -167,6 +167,10 @@ public class Offer implements Serializable {
// TODO check upper and lower bounds for fiat // TODO check upper and lower bounds for fiat
} }
public void resetState() {
setState(State.UNDEFINED);
}
public boolean isMyOffer(KeyRing keyRing) { public boolean isMyOffer(KeyRing keyRing) {
return getPubKeyRing().getHashString().equals(keyRing.getPubKeyRing().getHashString()); return getPubKeyRing().getHashString().equals(keyRing.getPubKeyRing().getHashString());
} }

View file

@ -84,7 +84,6 @@ public class OpenOffer implements Tradable, Serializable {
startTimeout(); startTimeout();
else else
stopTimeout(); stopTimeout();
} }
public State getState() { public State getState() {

View file

@ -231,7 +231,7 @@ public class OpenOfferManager {
} }
public Optional<OpenOffer> findOpenOffer(String offerId) { public Optional<OpenOffer> findOpenOffer(String offerId) {
return openOffers.stream().filter(openOffer -> openOffer.getOffer().getId().equals(offerId)).findAny(); return openOffers.stream().filter(openOffer -> openOffer.getId().equals(offerId)).findAny();
} }
// Close openOffer after deposit published // Close openOffer after deposit published

View file

@ -60,7 +60,6 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
public BuyerAsOffererProtocol(BuyerAsOffererTrade trade) { public BuyerAsOffererProtocol(BuyerAsOffererTrade trade) {
super(trade.getProcessModel()); super(trade.getProcessModel());
log.debug("New OffererProtocol " + this);
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
@ -68,10 +67,10 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
if (state == BuyerTradeState.ProcessState.PAYOUT_TX_COMMITTED || if (state == BuyerTradeState.ProcessState.PAYOUT_TX_COMMITTED ||
state == BuyerTradeState.ProcessState.PAYOUT_TX_SENT || state == BuyerTradeState.ProcessState.PAYOUT_TX_SENT ||
state == BuyerTradeState.ProcessState.PAYOUT_BROAD_CASTED) { state == BuyerTradeState.ProcessState.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> { () -> {
log.debug("taskRunner completed"); handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
// we are done!
processModel.onComplete(); processModel.onComplete();
}, },
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
@ -83,29 +82,9 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Public methods // Mailbox
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void handleTakeOfferRequest(TradeMessage message, Peer taker) {
checkTradeId(processModel.getId(), message);
processModel.setTradeMessage(message);
buyerAsOffererTrade.setTradingPeer(taker);
//buyerAsOffererTrade.setLifeCycleState(OffererTradeState.LifeCycleState.OFFER_RESERVED);
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> log.debug("taskRunner at handleRequestDepositTxInputsMessage completed"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
ProcessDepositTxInputsRequest.class,
CreateDepositTxInputs.class,
SendPayDepositRequest.class
);
startTimeout();
taskRunner.run();
}
@Override @Override
public void doApplyMailboxMessage(Message message, Trade trade) { public void doApplyMailboxMessage(Message message, Trade trade) {
this.trade = trade; this.trade = trade;
@ -123,6 +102,29 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Start trade
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void handleTakeOfferRequest(TradeMessage message, Peer taker) {
checkTradeId(processModel.getId(), message);
processModel.setTradeMessage(message);
buyerAsOffererTrade.setTradingPeer(taker);
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> handleTaskRunnerSuccess("handleTakeOfferRequest"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
ProcessDepositTxInputsRequest.class,
CreateDepositTxInputs.class,
SendPayDepositRequest.class
);
startTimeout();
taskRunner.run();
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Incoming message handling // Incoming message handling
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -132,7 +134,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> log.debug("taskRunner at handleRequestPublishDepositTxMessage completed"), () -> handleTaskRunnerSuccess("PublishDepositTxRequest"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
ProcessPublishDepositTxRequest.class, ProcessPublishDepositTxRequest.class,
@ -155,7 +157,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
buyerAsOffererTrade.setProcessState(BuyerTradeState.ProcessState.FIAT_PAYMENT_STARTED); buyerAsOffererTrade.setProcessState(BuyerTradeState.ProcessState.FIAT_PAYMENT_STARTED);
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> log.debug("taskRunner at handleBankTransferStartedUIEvent completed"), () -> handleTaskRunnerSuccess("onFiatPaymentStarted"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
VerifyTakeOfferFeePayment.class, VerifyTakeOfferFeePayment.class,
@ -175,8 +177,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> { () -> {
log.debug("taskRunner at handlePayoutTxPublishedMessage completed"); handleTaskRunnerSuccess("FinalizePayoutTxRequest");
// we are done!
processModel.onComplete(); processModel.onComplete();
}, },
this::handleTaskRunnerFault); this::handleTaskRunnerFault);

View file

@ -60,7 +60,6 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
public BuyerAsTakerProtocol(BuyerAsTakerTrade trade) { public BuyerAsTakerProtocol(BuyerAsTakerTrade trade) {
super(trade.getProcessModel()); super(trade.getProcessModel());
log.debug("New SellerAsTakerProtocol " + this);
this.buyerAsTakerTrade = trade; this.buyerAsTakerTrade = trade;
processModel.tradingPeer.setPubKeyRing(trade.getOffer().getPubKeyRing()); processModel.tradingPeer.setPubKeyRing(trade.getOffer().getPubKeyRing());
@ -72,8 +71,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
state == BuyerTradeState.ProcessState.PAYOUT_BROAD_CASTED) { state == BuyerTradeState.ProcessState.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> { () -> {
log.debug("taskRunner completed"); handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
// we are done!
processModel.onComplete(); processModel.onComplete();
}, },
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
@ -85,7 +83,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Public methods // Mailbox
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
@ -104,10 +102,15 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
})); }));
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Start trade
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void takeAvailableOffer() { public void takeAvailableOffer() {
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> log.debug("taskRunner at takeAvailableOffer completed"), () -> handleTaskRunnerSuccess("takeAvailableOffer"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
@ -130,7 +133,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> log.debug("taskRunner at handleRequestPublishDepositTxMessage completed"), () -> handleTaskRunnerSuccess("PublishDepositTxRequest"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
ProcessPublishDepositTxRequest.class, ProcessPublishDepositTxRequest.class,
@ -152,9 +155,8 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
public void onFiatPaymentStarted() { public void onFiatPaymentStarted() {
buyerAsTakerTrade.setProcessState(BuyerTradeState.ProcessState.FIAT_PAYMENT_STARTED); buyerAsTakerTrade.setProcessState(BuyerTradeState.ProcessState.FIAT_PAYMENT_STARTED);
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> log.debug("taskRunner at onFiatPaymentStarted completed"), () -> handleTaskRunnerSuccess("onFiatPaymentStarted"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
VerifyOfferFeePayment.class, VerifyOfferFeePayment.class,
@ -174,8 +176,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> { () -> {
log.debug("taskRunner at handlePayoutTxPublishedMessage completed"); handleTaskRunnerSuccess("FinalizePayoutTxRequest");
// we are done!
processModel.onComplete(); processModel.onComplete();
}, },
this::handleTaskRunnerFault); this::handleTaskRunnerFault);

View file

@ -58,7 +58,6 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
public SellerAsOffererProtocol(SellerAsOffererTrade trade) { public SellerAsOffererProtocol(SellerAsOffererTrade trade) {
super(trade.getProcessModel()); super(trade.getProcessModel());
log.debug("New OffererProtocol " + this);
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
@ -68,8 +67,7 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
state == SellerTradeState.ProcessState.PAYOUT_BROAD_CASTED) { state == SellerTradeState.ProcessState.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> { () -> {
log.debug("taskRunner completed"); handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
// we are done!
processModel.onComplete(); processModel.onComplete();
}, },
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
@ -81,29 +79,9 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Public methods // Mailbox
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void handleTakeOfferRequest(TradeMessage message, Peer taker) {
processModel.setTradeMessage(message);
sellerAsOffererTrade.setTradingPeer(taker);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
ProcessPayDepositRequest.class,
VerifyTakerAccount.class,
CreateAndSignContract.class,
CreateAndSignDepositTx.class,
SendPublishDepositTxRequest.class
);
startTimeout();
taskRunner.run();
}
@Override @Override
public void doApplyMailboxMessage(Message message, Trade trade) { public void doApplyMailboxMessage(Message message, Trade trade) {
this.trade = trade; this.trade = trade;
@ -129,6 +107,31 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Start trade
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void handleTakeOfferRequest(TradeMessage message, Peer taker) {
processModel.setTradeMessage(message);
sellerAsOffererTrade.setTradingPeer(taker);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> handleTaskRunnerSuccess("handleTakeOfferRequest"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
ProcessPayDepositRequest.class,
VerifyTakerAccount.class,
CreateAndSignContract.class,
CreateAndSignDepositTx.class,
SendPublishDepositTxRequest.class
);
startTimeout();
taskRunner.run();
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Incoming message handling // Incoming message handling
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -138,7 +141,7 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> log.debug("taskRunner at handleDepositTxPublishedMessage completed"), () -> handleTaskRunnerSuccess("DepositTxPublishedMessage"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
@ -157,7 +160,7 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"), () -> handleTaskRunnerSuccess("FiatTransferStartedMessage"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks(ProcessFiatTransferStartedMessage.class); taskRunner.addTasks(ProcessFiatTransferStartedMessage.class);
@ -175,12 +178,7 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
sellerAsOffererTrade.setProcessState(SellerTradeState.ProcessState.FIAT_PAYMENT_RECEIPT); sellerAsOffererTrade.setProcessState(SellerTradeState.ProcessState.FIAT_PAYMENT_RECEIPT);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> { () -> handleTaskRunnerSuccess("onFiatPaymentReceived"),
log.debug("taskRunner at handleFiatReceivedUIEvent completed");
// we are done!
processModel.onComplete();
},
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
@ -188,14 +186,19 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
SignPayoutTx.class, SignPayoutTx.class,
SendFinalizePayoutTxRequest.class SendFinalizePayoutTxRequest.class
); );
startTimeout();
taskRunner.run(); taskRunner.run();
} }
private void handle(PayoutTxFinalizedMessage tradeMessage) { private void handle(PayoutTxFinalizedMessage tradeMessage) {
stopTimeout();
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"), () -> {
handleTaskRunnerSuccess("PayoutTxFinalizedMessage");
processModel.onComplete();
},
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(

View file

@ -63,7 +63,6 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
public SellerAsTakerProtocol(SellerAsTakerTrade trade) { public SellerAsTakerProtocol(SellerAsTakerTrade trade) {
super(trade.getProcessModel()); super(trade.getProcessModel());
log.debug("New SellerAsTakerProtocol " + this);
this.sellerAsTakerTrade = trade; this.sellerAsTakerTrade = trade;
processModel.tradingPeer.setPubKeyRing(trade.getOffer().getPubKeyRing()); processModel.tradingPeer.setPubKeyRing(trade.getOffer().getPubKeyRing());
@ -76,8 +75,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
state == SellerTradeState.ProcessState.PAYOUT_BROAD_CASTED) { state == SellerTradeState.ProcessState.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade, TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> { () -> {
log.debug("taskRunner completed"); handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
// we are done!
processModel.onComplete(); processModel.onComplete();
}, },
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
@ -90,7 +88,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Public methods // Mailbox
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
@ -117,10 +115,15 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
} }
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Start trade
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void takeAvailableOffer() { public void takeAvailableOffer() {
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at takeAvailableOffer completed"), () -> handleTaskRunnerSuccess("takeAvailableOffer"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
@ -143,7 +146,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at RequestPayDepositMessage completed"), () -> handleTaskRunnerSuccess("PayDepositRequest"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
@ -162,7 +165,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at DepositTxPublishedMessage completed"), () -> handleTaskRunnerSuccess("DepositTxPublishedMessage"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
@ -181,7 +184,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at FiatTransferStartedMessage completed"), () -> handleTaskRunnerSuccess("FiatTransferStartedMessage"),
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks(ProcessFiatTransferStartedMessage.class); taskRunner.addTasks(ProcessFiatTransferStartedMessage.class);
@ -199,12 +202,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
sellerAsTakerTrade.setProcessState(SellerTradeState.ProcessState.FIAT_PAYMENT_RECEIPT); sellerAsTakerTrade.setProcessState(SellerTradeState.ProcessState.FIAT_PAYMENT_RECEIPT);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> { () -> handleTaskRunnerSuccess("onFiatPaymentReceived"),
log.debug("taskRunner at onFiatPaymentReceived completed");
// we are done!
processModel.onComplete();
},
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(
@ -212,15 +210,19 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
SignPayoutTx.class, SignPayoutTx.class,
SendFinalizePayoutTxRequest.class SendFinalizePayoutTxRequest.class
); );
startTimeout();
taskRunner.run(); taskRunner.run();
} }
private void handle(PayoutTxFinalizedMessage tradeMessage) { private void handle(PayoutTxFinalizedMessage tradeMessage) {
log.debug("handle PayoutTxFinalizedMessage"); stopTimeout();
processModel.setTradeMessage(tradeMessage); processModel.setTradeMessage(tradeMessage);
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at PayoutTxFinalizedMessage completed"), () -> {
handleTaskRunnerSuccess("PayoutTxFinalizedMessage");
processModel.onComplete();
},
this::handleTaskRunnerFault); this::handleTaskRunnerFault);
taskRunner.addTasks( taskRunner.addTasks(

View file

@ -157,6 +157,10 @@ public abstract class TradeProtocol {
} }
} }
protected void handleTaskRunnerSuccess(String info) {
log.debug("handleTaskRunnerSuccess " + info);
}
protected void handleTaskRunnerFault(String errorMessage) { protected void handleTaskRunnerFault(String errorMessage) {
log.error(errorMessage); log.error(errorMessage);
cleanup(); cleanup();

View file

@ -32,4 +32,5 @@ public class TradeTaskRunner extends TaskRunner<Trade> {
public TradeTaskRunner(Trade sharedModel, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { public TradeTaskRunner(Trade sharedModel, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
super(sharedModel, (Class<? extends Model>) sharedModel.getClass().getSuperclass().getSuperclass(), resultHandler, errorMessageHandler); super(sharedModel, (Class<? extends Model>) sharedModel.getClass().getSuperclass().getSuperclass(), resultHandler, errorMessageHandler);
} }
} }

View file

@ -35,6 +35,7 @@ public class PayDepositRequest extends TradeMessage implements Serializable {
// That object is sent over the wire, so we need to take care of version compatibility. // That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION; private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
public final Coin tradeAmount;
public final List<TransactionOutput> buyerConnectedOutputsForAllInputs; public final List<TransactionOutput> buyerConnectedOutputsForAllInputs;
public final List<TransactionOutput> buyerOutputs; public final List<TransactionOutput> buyerOutputs;
public final byte[] buyerTradeWalletPubKey; public final byte[] buyerTradeWalletPubKey;
@ -42,7 +43,7 @@ public class PayDepositRequest extends TradeMessage implements Serializable {
public final PubKeyRing buyerPubKeyRing; public final PubKeyRing buyerPubKeyRing;
public final FiatAccount buyerFiatAccount; public final FiatAccount buyerFiatAccount;
public final String buyerAccountId; public final String buyerAccountId;
public final Coin tradeAmount; public final String takeOfferFeeTxId;
public PayDepositRequest(String tradeId, public PayDepositRequest(String tradeId,
Coin tradeAmount, Coin tradeAmount,
@ -52,7 +53,8 @@ public class PayDepositRequest extends TradeMessage implements Serializable {
byte[] buyerTradeWalletPubKey, byte[] buyerTradeWalletPubKey,
PubKeyRing buyerPubKeyRing, PubKeyRing buyerPubKeyRing,
FiatAccount buyerFiatAccount, FiatAccount buyerFiatAccount,
String buyerAccountId) { String buyerAccountId,
String takeOfferFeeTxId) {
super(tradeId); super(tradeId);
this.tradeAmount = tradeAmount; this.tradeAmount = tradeAmount;
this.isInitialRequest = isInitialRequest; this.isInitialRequest = isInitialRequest;
@ -62,5 +64,6 @@ public class PayDepositRequest extends TradeMessage implements Serializable {
this.buyerTradeWalletPubKey = buyerTradeWalletPubKey; this.buyerTradeWalletPubKey = buyerTradeWalletPubKey;
this.buyerFiatAccount = buyerFiatAccount; this.buyerFiatAccount = buyerFiatAccount;
this.buyerAccountId = buyerAccountId; this.buyerAccountId = buyerAccountId;
this.takeOfferFeeTxId = takeOfferFeeTxId;
} }
} }

View file

@ -15,11 +15,12 @@
* 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.protocol.trade; package io.bitsquare.trade.protocol.trade.tasks;
import io.bitsquare.common.taskrunner.Task; import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.ProcessModel;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -21,7 +21,7 @@ import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.TradeWalletService; import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;

View file

@ -19,8 +19,8 @@ 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.protocol.trade.TradeTask;
import io.bitsquare.trade.protocol.trade.messages.DepositTxInputsRequest; import io.bitsquare.trade.protocol.trade.messages.DepositTxInputsRequest;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;

View file

@ -19,8 +19,8 @@ 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.protocol.trade.TradeTask;
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.states.BuyerTradeState; import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;

View file

@ -19,8 +19,8 @@ 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.protocol.trade.TradeTask;
import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest; import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;

View file

@ -20,8 +20,8 @@ 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.protocol.trade.TradeTask;
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.states.BuyerTradeState; import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;

View file

@ -20,8 +20,8 @@ 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.protocol.trade.TradeTask;
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.states.BuyerTradeState; import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;

View file

@ -21,8 +21,8 @@ import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener; import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.BuyerAsTakerTrade; import io.bitsquare.trade.BuyerAsTakerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.TradeTask;
import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest; import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -49,7 +49,8 @@ public class SendPayDepositRequest extends TradeTask {
processModel.getTradeWalletPubKey(), processModel.getTradeWalletPubKey(),
processModel.getPubKeyRing(), processModel.getPubKeyRing(),
processModel.getFiatAccount(), processModel.getFiatAccount(),
processModel.getAccountId()); processModel.getAccountId(),
processModel.getTakeOfferFeeTxId());
processModel.getMessageService().sendEncryptedMessage( processModel.getMessageService().sendEncryptedMessage(
trade.getTradingPeer(), trade.getTradingPeer(),

View file

@ -20,8 +20,8 @@ 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.protocol.trade.TradeTask;
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.states.BuyerTradeState; import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;

View file

@ -19,7 +19,7 @@ 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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;

View file

@ -21,7 +21,7 @@ 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.BuyerTrade;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState; import io.bitsquare.trade.states.BuyerTradeState;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;

View file

@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Contract; import io.bitsquare.trade.Contract;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.tasks.offerer;
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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.tasks.offerer;
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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;

View file

@ -19,7 +19,7 @@ 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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;

View file

@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.trade.tasks.seller;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Contract; import io.bitsquare.trade.Contract;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;
import org.slf4j.Logger; import org.slf4j.Logger;

View file

@ -21,7 +21,7 @@ import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.TradeWalletService; import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;

View file

@ -19,8 +19,8 @@ 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.protocol.trade.TradeTask;
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.states.SellerTradeState; import io.bitsquare.trade.states.SellerTradeState;
import org.slf4j.Logger; import org.slf4j.Logger;

View file

@ -19,8 +19,8 @@ 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.protocol.trade.TradeTask;
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.states.SellerTradeState; import io.bitsquare.trade.states.SellerTradeState;
import org.slf4j.Logger; import org.slf4j.Logger;

View file

@ -19,8 +19,8 @@ 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.protocol.trade.TradeTask;
import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest; import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -50,6 +50,7 @@ public class ProcessPayDepositRequest extends TradeTask {
processModel.tradingPeer.setPubKeyRing(checkNotNull(message.buyerPubKeyRing)); processModel.tradingPeer.setPubKeyRing(checkNotNull(message.buyerPubKeyRing));
processModel.tradingPeer.setFiatAccount(checkNotNull(message.buyerFiatAccount)); processModel.tradingPeer.setFiatAccount(checkNotNull(message.buyerFiatAccount));
processModel.tradingPeer.setAccountId(nonEmptyStringOf(message.buyerAccountId)); processModel.tradingPeer.setAccountId(nonEmptyStringOf(message.buyerAccountId));
processModel.setTakeOfferFeeTxId(nonEmptyStringOf(message.takeOfferFeeTxId));
trade.setTradeAmount(positiveCoinOf(nonZeroCoinOf(message.tradeAmount))); trade.setTradeAmount(positiveCoinOf(nonZeroCoinOf(message.tradeAmount)));
complete(); complete();

View file

@ -19,8 +19,8 @@ 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.protocol.trade.TradeTask;
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.states.SellerTradeState; import io.bitsquare.trade.states.SellerTradeState;
import org.slf4j.Logger; import org.slf4j.Logger;

View file

@ -20,8 +20,8 @@ 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.protocol.trade.TradeTask;
import io.bitsquare.trade.protocol.trade.messages.DepositTxInputsRequest; import io.bitsquare.trade.protocol.trade.messages.DepositTxInputsRequest;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.bitcoinj.utils.Threading; import org.bitcoinj.utils.Threading;

View file

@ -20,8 +20,8 @@ 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.protocol.trade.TradeTask;
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.states.SellerTradeState; import io.bitsquare.trade.states.SellerTradeState;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;

View file

@ -20,8 +20,8 @@ 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.protocol.trade.TradeTask;
import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest; import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.StateUtil; import io.bitsquare.trade.states.StateUtil;
import org.slf4j.Logger; import org.slf4j.Logger;

View file

@ -19,7 +19,7 @@ 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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;

View file

@ -21,7 +21,7 @@ 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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState; import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.SellerTradeState; import io.bitsquare.trade.states.SellerTradeState;

View file

@ -21,7 +21,7 @@ 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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import io.bitsquare.trade.states.BuyerTradeState; import io.bitsquare.trade.states.BuyerTradeState;
import io.bitsquare.trade.states.SellerTradeState; import io.bitsquare.trade.states.SellerTradeState;

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.tasks.taker;
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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.tasks.taker;
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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.tasks.taker;
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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.tasks.taker;
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.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -1,26 +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;
public enum TradePhase {
PREPARATION, // No damage
TAKE_OFFER__FEE_PAID, // Offer fee can be lost
DEPOSIT_BROAD_CASTED, // Need arbitrator
PAYOUT_BROAD_CASTED // Only charge back risk open
}

View file

@ -158,7 +158,7 @@ public class BitsquareApp extends Application {
primaryStage.show(); primaryStage.show();
//TODO just temp. //TODO just temp.
// showDebugWindow(); showDebugWindow();
} catch (Throwable throwable) { } catch (Throwable throwable) {
showErrorPopup(throwable, true); showErrorPopup(throwable, true);
} }

View file

@ -34,6 +34,7 @@ import org.bitcoinj.utils.Fiat;
import com.google.inject.Inject; import com.google.inject.Inject;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@ -145,7 +146,9 @@ class TakeOfferDataModel implements Activatable, DataModel {
}; };
updateBalance(walletService.getBalanceForAddress(addressEntry.getAddress())); updateBalance(walletService.getBalanceForAddress(addressEntry.getAddress()));
tradeManager.onCheckOfferAvailability(offer); // delay a bit to get the listeners called
offer.resetState();
Platform.runLater(() -> tradeManager.onCheckOfferAvailability(offer));
} }

View file

@ -24,7 +24,7 @@
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" tabClosingPolicy="UNAVAILABLE"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">
<Tab fx:id="offersTab" text="Open offers"/> <Tab fx:id="openOffersTab" text="Open offers"/>
<Tab fx:id="openTradesTab" text="Open trades"/> <Tab fx:id="openTradesTab" text="Open trades"/>
<Tab fx:id="closedTradesTab" text="History"/> <Tab fx:id="closedTradesTab" text="History"/>

View file

@ -28,7 +28,6 @@ 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.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;
import io.bitsquare.trade.TradeManager;
import javax.inject.Inject; import javax.inject.Inject;
@ -39,7 +38,7 @@ import javafx.scene.control.*;
@FxmlView @FxmlView
public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> { public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab offersTab, openTradesTab, closedTradesTab; @FXML Tab openOffersTab, openTradesTab, closedTradesTab;
private Tab currentTab; private Tab currentTab;
private Navigation.Listener navigationListener; private Navigation.Listener navigationListener;
@ -49,7 +48,7 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
private final Navigation navigation; private final Navigation navigation;
@Inject @Inject
public PortfolioView(CachingViewLoader viewLoader, Navigation navigation, TradeManager tradeManager) { public PortfolioView(CachingViewLoader viewLoader, Navigation navigation) {
this.viewLoader = viewLoader; this.viewLoader = viewLoader;
this.navigation = navigation; this.navigation = navigation;
} }
@ -57,12 +56,14 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
@Override @Override
public void initialize() { public void initialize() {
navigationListener = viewPath -> { navigationListener = viewPath -> {
log.debug("navigationListener");
if (viewPath.size() == 3 && viewPath.indexOf(PortfolioView.class) == 1) if (viewPath.size() == 3 && viewPath.indexOf(PortfolioView.class) == 1)
loadView(viewPath.tip()); loadView(viewPath.tip());
}; };
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == offersTab) log.debug("tabChangeListener");
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 == openTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class); navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
@ -76,10 +77,12 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener); root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
/* if (tradeManager.getPendingTrades().size() == 0) if (root.getSelectionModel().getSelectedItem() == openOffersTab)
navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class); navigation.navigateTo(MainView.class, PortfolioView.class, OpenOffersView.class);
else else if (root.getSelectionModel().getSelectedItem() == openTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);*/ navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
else if (root.getSelectionModel().getSelectedItem() == closedTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class);
} }
@Override @Override
@ -96,7 +99,7 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
View view = viewLoader.load(viewClass); View view = viewLoader.load(viewClass);
if (view instanceof OpenOffersView) currentTab = offersTab; if (view instanceof OpenOffersView) currentTab = openOffersTab;
else if (view instanceof PendingTradesView) currentTab = openTradesTab; else if (view instanceof PendingTradesView) currentTab = openTradesTab;
else if (view instanceof ClosedTradesView) currentTab = closedTradesTab; else if (view instanceof ClosedTradesView) currentTab = closedTradesTab;

View file

@ -92,6 +92,10 @@ public class BuyerSubView extends TradeSubView {
tradeStepDetailsView.deactivate(); tradeStepDetailsView.deactivate();
switch (state) { switch (state) {
case UNDEFINED:
/* showItem(waitTxInBlockchain);
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Trade is in an incomplete state.");*/
break;
case WAIT_FOR_BLOCKCHAIN_CONFIRMATION: case WAIT_FOR_BLOCKCHAIN_CONFIRMATION:
showItem(waitTxInBlockchain); showItem(waitTxInBlockchain);
@ -144,6 +148,14 @@ 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: /*case MESSAGE_SENDING_FAILED:
Popups.openWarningPopup("Sending message to trading peer failed.", model.getErrorMessage()); Popups.openWarningPopup("Sending message to trading peer failed.", model.getErrorMessage());
break; break;

View file

@ -108,12 +108,12 @@ class PendingTradesDataModel implements Activatable, DataModel {
private void onListChanged() { private void onListChanged() {
list.clear(); list.clear();
list.addAll(tradeManager.getPendingTrades().stream().map(PendingTradesListItem::new).collect(Collectors.toList())); list.addAll(tradeManager.getPendingTrades().stream().filter(e -> !e.isFaultState())
.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()));
log.debug("onListChanged {}", list.size());
if (list.size() > 0) if (list.size() > 0)
onSelectTrade(list.get(0)); onSelectTrade(list.get(0));
else if (list.size() == 0) else if (list.size() == 0)
@ -131,7 +131,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
void onSelectTrade(PendingTradesListItem item) { void onSelectTrade(PendingTradesListItem item) {
log.debug("selectTrade {} {}", item != null, item != null ? item.getTrade().getId() : "null");
// clean up previous selectedItem // clean up previous selectedItem
unbindStates(); unbindStates();
@ -176,7 +175,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
toAddress, toAddress,
trade, trade,
() -> { () -> {
log.debug("requestWithdraw was successful");
Platform.runLater(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class)); Platform.runLater(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class));
}, },
(errorMessage, throwable) -> { (errorMessage, throwable) -> {

View file

@ -53,44 +53,30 @@ import org.slf4j.LoggerFactory;
public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataModel> implements ViewModel { public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataModel> implements ViewModel {
private static final Logger log = LoggerFactory.getLogger(PendingTradesViewModel.class); private static final Logger log = LoggerFactory.getLogger(PendingTradesViewModel.class);
/* enum ViewState {
UNDEFINED,
WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
WAIT_FOR_FIAT_PAYMENT_STARTED,
REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED,
SELLER_REQUEST_PAYOUT_FINALIZE_MSG_SENT,
SELLER_PAYOUT_FINALIZED,
SELLER_COMPLETED,
WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
BUYER_START_PAYMENT,
BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED,
BUYER_PAYOUT_FINALIZED,
BUYER_COMPLETED,
MESSAGE_SENDING_FAILED,
TIMEOUT,
EXCEPTION
}*/
interface State { interface State {
} }
enum BuyerState implements State { enum BuyerState implements State {
UNDEFINED,
WAIT_FOR_BLOCKCHAIN_CONFIRMATION, WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
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 {
UNDEFINED,
WAIT_FOR_BLOCKCHAIN_CONFIRMATION, WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
WAIT_FOR_FIAT_PAYMENT_STARTED, WAIT_FOR_FIAT_PAYMENT_STARTED,
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;
@ -98,8 +84,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.WAIT_FOR_BLOCKCHAIN_CONFIRMATION); private final ObjectProperty<BuyerState> buyerState = new SimpleObjectProperty<>(BuyerState.UNDEFINED);
private final ObjectProperty<SellerState> sellerState = new SimpleObjectProperty<>(SellerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION); private final ObjectProperty<SellerState> sellerState = new SimpleObjectProperty<>(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);
@ -191,6 +177,10 @@ 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) {
@ -338,6 +328,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
if (processState != null) { if (processState != null) {
switch (processState) { switch (processState) {
case UNDEFINED: case UNDEFINED:
sellerState.set(SellerState.UNDEFINED);
break;
case DEPOSIT_PUBLISHED_MSG_RECEIVED: case DEPOSIT_PUBLISHED_MSG_RECEIVED:
sellerState.set(SellerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION); sellerState.set(SellerState.WAIT_FOR_BLOCKCHAIN_CONFIRMATION);
@ -373,17 +365,10 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
break; break;
/* case PAYOUT_BROAD_CASTED_FAILED: case FAULT:
// sellerState.set(SellerState.EXCEPTION); sellerState.set(SellerState.FAULT);
break; break;
case MESSAGE_SENDING_FAILED:
//sellerState.set(SellerState.MESSAGE_SENDING_FAILED);
break;
case EXCEPTION:
// sellerState.set(SellerState.EXCEPTION);
break;*/
default: default:
log.warn("unhandled processState " + processState); log.warn("unhandled processState " + processState);
break; break;
@ -402,6 +387,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
if (processState != null) { if (processState != null) {
switch (processState) { switch (processState) {
case UNDEFINED: case UNDEFINED:
sellerState.set(SellerState.UNDEFINED);
break; break;
@ -436,18 +422,10 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
break; break;
/* case PAYOUT_BROAD_CASTED_FAILED: case FAULT:
// buyerState.set(BuyerState.EXCEPTION); sellerState.set(SellerState.FAULT);
break; break;
case MESSAGE_SENDING_FAILED:
// buyerState.set(BuyerState.MESSAGE_SENDING_FAILED);
break;
case EXCEPTION:
// buyerState.set(BuyerState.EXCEPTION);
break;
*/
default: default:
log.warn("unhandled viewState " + processState); log.warn("unhandled viewState " + processState);
break; break;

View file

@ -92,6 +92,10 @@ public class SellerSubView extends TradeSubView {
tradeStepDetailsView.deactivate(); tradeStepDetailsView.deactivate();
switch (viewState) { switch (viewState) {
case UNDEFINED:
/* showItem(waitTxInBlockchain);
((WaitTxInBlockchainView) tradeStepDetailsView).setInfoLabelText("Trade is in an incomplete state.");*/
break;
case WAIT_FOR_BLOCKCHAIN_CONFIRMATION: case WAIT_FOR_BLOCKCHAIN_CONFIRMATION:
showItem(waitTxInBlockchain); showItem(waitTxInBlockchain);
@ -173,6 +177,15 @@ 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: /* case MESSAGE_SENDING_FAILED:
Popups.openWarningPopup("Sending message to trading peer failed.", model.getErrorMessage()); Popups.openWarningPopup("Sending message to trading peer failed.", model.getErrorMessage());
break; break;