Move process models to trade

This commit is contained in:
Manfred Karrer 2015-03-27 15:57:59 +01:00
parent fcf9523aba
commit 846cb1869a
20 changed files with 411 additions and 304 deletions

View file

@ -38,6 +38,8 @@ import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener; import javafx.collections.MapChangeListener;
import javafx.collections.ObservableMap; import javafx.collections.ObservableMap;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -46,16 +48,15 @@ public class ArbitrationRepository implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(ArbitrationRepository.class); transient private static final Logger log = LoggerFactory.getLogger(ArbitrationRepository.class);
transient private Storage<ArbitrationRepository> storage; transient private final Storage<ArbitrationRepository> storage;
transient private ArbitratorService arbitratorService; transient private final ArbitratorService arbitratorService;
transient private Arbitrator defaultArbitrator; transient private final Arbitrator defaultArbitrator;
transient private final ObservableMap<String, Arbitrator> arbitratorsObservableMap = FXCollections.observableHashMap();
transient private boolean allArbitratorsSynced;
// Persisted fields // Persisted fields
private final Map<String, Arbitrator> arbitratorsMap = new HashMap<>(); private final Map<String, Arbitrator> arbitratorsMap = new HashMap<>();
transient private final ObservableMap<String, Arbitrator> arbitratorsObservableMap = FXCollections.observableHashMap();
transient private boolean allArbitratorsSynced;
@Inject @Inject
public ArbitrationRepository(Storage<ArbitrationRepository> storage, public ArbitrationRepository(Storage<ArbitrationRepository> storage,
@ -82,11 +83,12 @@ public class ArbitrationRepository implements Serializable {
"https://bitsquare.io", "https://bitsquare.io",
"Bla bla..."); "Bla bla...");
arbitratorsMap.put(defaultArbitrator.getId(), defaultArbitrator);
ArbitrationRepository persisted = storage.initAndGetPersisted(this); ArbitrationRepository persisted = storage.initAndGetPersisted(this);
if (persisted != null) { if (persisted != null) {
arbitratorsMap.putAll(persisted.getArbitratorsMap()); arbitratorsMap.putAll(persisted.getArbitratorsMap());
} }
arbitratorsMap.put(defaultArbitrator.getId(), defaultArbitrator);
arbitratorsObservableMap.putAll(arbitratorsMap); arbitratorsObservableMap.putAll(arbitratorsMap);
arbitratorsObservableMap.addListener((MapChangeListener<String, Arbitrator>) change -> storage.queueUpForSave()); arbitratorsObservableMap.addListener((MapChangeListener<String, Arbitrator>) change -> storage.queueUpForSave());
allArbitratorsSynced = false; allArbitratorsSynced = false;
@ -120,6 +122,7 @@ public class ArbitrationRepository implements Serializable {
return allArbitratorsSynced; return allArbitratorsSynced;
} }
@NotNull
public Arbitrator getDefaultArbitrator() { public Arbitrator getDefaultArbitrator() {
return defaultArbitrator; return defaultArbitrator;
} }

View file

@ -28,6 +28,8 @@ import java.security.PublicKey;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.jetbrains.annotations.NotNull;
public class Arbitrator implements Serializable { public class Arbitrator 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 = 1L; private static final long serialVersionUID = 1L;
@ -83,19 +85,19 @@ public class Arbitrator implements Serializable {
private String webUrl; private String webUrl;
private String description; private String description;
public Arbitrator(Storage<Arbitrator> storage, public Arbitrator(@NotNull Storage<Arbitrator> storage,
String id, @NotNull String id,
byte[] pubKey, @NotNull byte[] pubKey,
PublicKey p2pSigPubKey, @NotNull PublicKey p2pSigPubKey,
String name, @NotNull String name,
Reputation reputation, @NotNull Reputation reputation,
ID_TYPE idType, @NotNull ID_TYPE idType,
List<String> languageCodes, @NotNull List<String> languageCodes,
Coin fee, @NotNull Coin fee,
List<METHOD> arbitrationMethods, @NotNull List<METHOD> arbitrationMethods,
List<ID_VERIFICATION> idVerifications, @NotNull List<ID_VERIFICATION> idVerifications,
String webUrl, @NotNull String webUrl,
String description) { @NotNull String description) {
this.storage = storage; this.storage = storage;
this.id = id; this.id = id;
this.pubKey = pubKey; this.pubKey = pubKey;
@ -139,8 +141,6 @@ public class Arbitrator implements Serializable {
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Setters // Setters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -25,6 +25,8 @@ import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import org.jetbrains.annotations.NotNull;
/** /**
* Is a minimalistic wallet abstraction used to separate transactions between different activities like: * Is a minimalistic wallet abstraction used to separate transactions between different activities like:
* Registration, trade and arbiter deposit. * Registration, trade and arbiter deposit.
@ -68,6 +70,7 @@ public class AddressEntry implements Serializable {
return getAddress().toString(); return getAddress().toString();
} }
@NotNull
public DeterministicKey getKeyPair() { public DeterministicKey getKeyPair() {
return keyPair; return keyPair;
} }

View file

@ -262,6 +262,7 @@ public class WalletService {
return ImmutableList.copyOf(addressEntryList); return ImmutableList.copyOf(addressEntryList);
} }
@NotNull
public AddressEntry getRegistrationAddressEntry() { public AddressEntry getRegistrationAddressEntry() {
return registrationAddressEntry; return registrationAddressEntry;
} }
@ -440,10 +441,6 @@ public class WalletService {
// Transactions // Transactions
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public TradeWalletService getTradeWalletService() {
return tradeWalletService;
}
public void payRegistrationFee(String stringifiedFiatAccounts, FutureCallback<Transaction> callback) throws public void payRegistrationFee(String stringifiedFiatAccounts, FutureCallback<Transaction> callback) throws
InsufficientMoneyException { InsufficientMoneyException {
log.debug("payRegistrationFee"); log.debug("payRegistrationFee");

View file

@ -36,6 +36,8 @@ import java.util.List;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -193,6 +195,7 @@ public class Offer implements Serializable {
// Getters // Getters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public String getId() { public String getId() {
return id; return id;
} }

View file

@ -26,6 +26,8 @@ import java.io.Serializable;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@ -69,10 +71,12 @@ public class Storage<T extends Serializable> {
this.dir = dir; this.dir = dir;
} }
@Nullable
public T initAndGetPersisted(T serializable) { public T initAndGetPersisted(T serializable) {
return initAndGetPersisted(serializable, serializable.getClass().getSimpleName()); return initAndGetPersisted(serializable, serializable.getClass().getSimpleName());
} }
@Nullable
public T initAndGetPersisted(T serializable, String fileName) { public T initAndGetPersisted(T serializable, String fileName) {
this.serializable = serializable; this.serializable = serializable;
this.fileName = fileName; this.fileName = fileName;
@ -102,6 +106,7 @@ public class Storage<T extends Serializable> {
// We do the file read on the UI thread to avoid problems from multi threading. // We do the file read on the UI thread to avoid problems from multi threading.
// Data are small and read is done only at startup, so it is no performance issue. // Data are small and read is done only at startup, so it is no performance issue.
@Nullable
private T getPersisted(T serializable) { private T getPersisted(T serializable) {
if (storageFile.exists()) { if (storageFile.exists()) {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@ -130,7 +135,6 @@ public class Storage<T extends Serializable> {
e.printStackTrace(); e.printStackTrace();
log.error(e.getMessage()); log.error(e.getMessage());
Throwables.propagate(e); Throwables.propagate(e);
} }
} }
return null; return null;

View file

@ -17,15 +17,10 @@
package io.bitsquare.trade; package io.bitsquare.trade;
import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.MailboxService;
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.protocol.trade.TradeProcessModel;
import io.bitsquare.trade.protocol.trade.offerer.OffererProtocol; import io.bitsquare.trade.protocol.trade.offerer.OffererProtocol;
import io.bitsquare.trade.protocol.trade.offerer.models.OffererTradeProcessModel; import io.bitsquare.trade.protocol.trade.offerer.models.OffererTradeProcessModel;
@ -41,10 +36,14 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import javax.annotation.Nullable;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -68,6 +67,7 @@ public class OffererTrade extends Trade implements Serializable {
} }
public enum OffererProcessState implements ProcessState { public enum OffererProcessState implements ProcessState {
UNDEFINED,
DEPOSIT_PUBLISHED, DEPOSIT_PUBLISHED,
DEPOSIT_CONFIRMED, DEPOSIT_CONFIRMED,
@ -80,34 +80,44 @@ public class OffererTrade extends Trade implements Serializable {
} }
private Coin tradeAmount; ///////////////////////////////////////////////////////////////////////////////////////////
private Peer tradingPeer; // Fields
private OffererProcessState processState; ///////////////////////////////////////////////////////////////////////////////////////////
private OffererLifeCycleState lifeCycleState;
private OffererTradeProcessModel processModel;
transient private ObjectProperty<OffererProcessState> processStateProperty = new SimpleObjectProperty<>(); @Nullable private Coin tradeAmount;
transient private ObjectProperty<OffererLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>(); @Nullable private Peer tradingPeer;
@NotNull private OffererProcessState processState = OffererProcessState.UNDEFINED;
@NotNull private OffererLifeCycleState lifeCycleState = OffererLifeCycleState.OFFER_OPEN;
@NotNull transient private ObjectProperty<OffererProcessState> processStateProperty = new SimpleObjectProperty<>(processState);
@NotNull transient private ObjectProperty<OffererLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor // Constructor
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public OffererTrade(Offer offer, OffererTradeProcessModel processModel, Storage storage) { public OffererTrade(@NotNull Offer offer, @NotNull Storage<? extends TradeProcessModel> storage) {
super(offer, storage); super(offer, storage);
this.processModel = processModel;
protocol = new OffererProtocol(this);
setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
} }
@Override
protected TradeProcessModel createProcessModel() {
return new OffererTradeProcessModel();
}
@Override
public void createProtocol() {
protocol = new OffererProtocol(this);
}
// Serialized object does not create our transient objects // Serialized object does not create our transient objects
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { private void readObject(@NotNull java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject(); in.defaultReadObject();
processStateProperty = new SimpleObjectProperty<>(processState); processStateProperty = new SimpleObjectProperty<>(processState);
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState); lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
tradeAmountProperty = new SimpleObjectProperty<>(); tradeAmountProperty = new SimpleObjectProperty<>();
tradeVolumeProperty = new SimpleObjectProperty<>(); tradeVolumeProperty = new SimpleObjectProperty<>();
if (tradeAmount != null) { if (tradeAmount != null) {
@ -117,41 +127,16 @@ public class OffererTrade extends Trade implements Serializable {
} }
public void onFiatPaymentStarted() { public void onFiatPaymentStarted() {
assert protocol != null;
((OffererProtocol) protocol).onFiatPaymentStarted(); ((OffererProtocol) protocol).onFiatPaymentStarted();
} }
public OffererTradeProcessModel getProcessModel() {
return processModel;
}
public void reActivate(MessageService messageService,
MailboxService mailboxService,
WalletService walletService,
TradeWalletService tradeWalletService,
BlockChainService blockChainService,
SignatureService signatureService) {
processModel.messageService = messageService;
processModel.mailboxService = mailboxService;
processModel.walletService = walletService;
processModel.tradeWalletService = tradeWalletService;
processModel.blockChainService = blockChainService;
processModel.signatureService = signatureService;
processModel.offerer.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();
processModel.offerer.addressEntry = walletService.getAddressEntry(getId());
protocol = new OffererProtocol(this);
if (mailboxMessage != null)
protocol.setMailboxMessage(mailboxMessage);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Setters // Setters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void setProcessState(OffererProcessState processState) { public void setProcessState(@NotNull OffererProcessState processState) {
this.processState = processState; this.processState = processState;
processStateProperty.set(processState); processStateProperty.set(processState);
@ -163,7 +148,7 @@ public class OffererTrade extends Trade implements Serializable {
} }
} }
public void setLifeCycleState(OffererLifeCycleState lifeCycleState) { public void setLifeCycleState(@NotNull OffererLifeCycleState lifeCycleState) {
switch (lifeCycleState) { switch (lifeCycleState) {
case FAILED: case FAILED:
disposeProtocol(); disposeProtocol();
@ -176,13 +161,13 @@ public class OffererTrade extends Trade implements Serializable {
lifeCycleStateProperty.set(lifeCycleState); lifeCycleStateProperty.set(lifeCycleState);
} }
public void setTradeAmount(Coin tradeAmount) { public void setTradeAmount(@NotNull Coin tradeAmount) {
this.tradeAmount = tradeAmount; this.tradeAmount = tradeAmount;
tradeAmountProperty.set(tradeAmount); tradeAmountProperty.set(tradeAmount);
tradeVolumeProperty.set(getTradeVolume()); tradeVolumeProperty.set(getTradeVolume());
} }
public void setTradingPeer(Peer tradingPeer) { public void setTradingPeer(@NotNull Peer tradingPeer) {
this.tradingPeer = tradingPeer; this.tradingPeer = tradingPeer;
} }
@ -191,26 +176,36 @@ public class OffererTrade extends Trade implements Serializable {
// Getters // Getters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public OffererTradeProcessModel getProcessModel() {
return (OffererTradeProcessModel) processModel;
}
@NotNull
@Override @Override
public ReadOnlyObjectProperty<OffererProcessState> processStateProperty() { public ReadOnlyObjectProperty<OffererProcessState> processStateProperty() {
return processStateProperty; return processStateProperty;
} }
@NotNull
@Override @Override
public ReadOnlyObjectProperty<OffererLifeCycleState> lifeCycleStateProperty() { public ReadOnlyObjectProperty<OffererLifeCycleState> lifeCycleStateProperty() {
return lifeCycleStateProperty; return lifeCycleStateProperty;
} }
@Nullable
@Override @Override
public Coin getTradeAmount() { public Coin getTradeAmount() {
return tradeAmount; return tradeAmount;
} }
@Nullable
@Override @Override
public Fiat getTradeVolume() { public Fiat getTradeVolume() {
return offer.getVolumeByAmount(tradeAmount); return offer.getVolumeByAmount(tradeAmount);
} }
@Nullable
@Override @Override
public Peer getTradingPeer() { public Peer getTradingPeer() {
return tradingPeer; return tradingPeer;
@ -223,6 +218,7 @@ public class OffererTrade extends Trade implements Serializable {
@Override @Override
protected void setConfidenceListener() { protected void setConfidenceListener() {
assert depositTx != null;
TransactionConfidence transactionConfidence = depositTx.getConfidence(); TransactionConfidence transactionConfidence = depositTx.getConfidence();
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1); ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() { Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@ -233,7 +229,7 @@ public class OffererTrade extends Trade implements Serializable {
} }
@Override @Override
public void onFailure(Throwable t) { public void onFailure(@NotNull Throwable t) {
t.printStackTrace(); t.printStackTrace();
log.error(t.getMessage()); log.error(t.getMessage());
Throwables.propagate(t); Throwables.propagate(t);

View file

@ -17,15 +17,10 @@
package io.bitsquare.trade; package io.bitsquare.trade;
import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.MailboxService;
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.protocol.trade.TradeProcessModel;
import io.bitsquare.trade.protocol.trade.taker.TakerProtocol; import io.bitsquare.trade.protocol.trade.taker.TakerProtocol;
import io.bitsquare.trade.protocol.trade.taker.models.TakerTradeProcessModel; import io.bitsquare.trade.protocol.trade.taker.models.TakerTradeProcessModel;
@ -45,6 +40,8 @@ import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -53,10 +50,6 @@ public class TakerTrade extends Trade implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class); transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class);
public TakerTradeProcessModel getProcessModel() {
return processModel;
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Enum // Enum
@ -69,6 +62,7 @@ public class TakerTrade extends Trade implements Serializable {
} }
public enum TakerProcessState implements ProcessState { public enum TakerProcessState implements ProcessState {
UNDEFINED,
TAKE_OFFER_FEE_TX_CREATED, TAKE_OFFER_FEE_TX_CREATED,
TAKE_OFFER_FEE_PUBLISHED, TAKE_OFFER_FEE_PUBLISHED,
TAKE_OFFER_FEE_PUBLISH_FAILED, TAKE_OFFER_FEE_PUBLISH_FAILED,
@ -85,38 +79,52 @@ public class TakerTrade extends Trade implements Serializable {
EXCEPTION EXCEPTION
} }
private final Coin tradeAmount;
private final Peer tradingPeer;
private TakerTradeProcessModel processModel;
private TakerProcessState processState; ///////////////////////////////////////////////////////////////////////////////////////////
private TakerLifeCycleState lifeCycleState; // Fields
///////////////////////////////////////////////////////////////////////////////////////////
transient private ObjectProperty<TakerProcessState> processStateProperty = new SimpleObjectProperty<>(); @NotNull private final Coin tradeAmount;
transient private ObjectProperty<TakerLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>(); @NotNull private final Peer tradingPeer;
@NotNull private TakerProcessState processState = TakerProcessState.UNDEFINED;
@NotNull private TakerLifeCycleState lifeCycleState = TakerLifeCycleState.PENDING;
@NotNull transient private ObjectProperty<TakerProcessState> processStateProperty = new SimpleObjectProperty<>(processState);
@NotNull transient private ObjectProperty<TakerLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor // Constructor
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public TakerTrade(Offer offer, Coin tradeAmount, Peer peer, TakerTradeProcessModel processModel, Storage storage) { public TakerTrade(@NotNull Offer offer, @NotNull Coin tradeAmount, @NotNull Peer peer,
@NotNull Storage<? extends TradeProcessModel> storage) {
super(offer, storage); super(offer, storage);
this.tradeAmount = tradeAmount; this.tradeAmount = tradeAmount;
this.tradingPeer = peer; this.tradingPeer = peer;
this.processModel = processModel;
protocol = new TakerProtocol(this);
setLifeCycleState(TakerTrade.TakerLifeCycleState.PENDING);
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount); tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume()); // cannot be set before offer is set tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume()); // cannot be set before offer is set
}
@Override
protected TradeProcessModel createProcessModel() {
return new TakerTradeProcessModel();
}
@Override
public void createProtocol() {
protocol = new TakerProtocol(this);
}
public void takeAvailableOffer() {
assert processModel != null;
((TakerProtocol) protocol).takeAvailableOffer(); ((TakerProtocol) protocol).takeAvailableOffer();
} }
// Serialized object does not create our transient objects // Serialized object does not create our transient objects
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { private void readObject(@NotNull java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject(); in.defaultReadObject();
processStateProperty = new SimpleObjectProperty<>(processState); processStateProperty = new SimpleObjectProperty<>(processState);
@ -125,29 +133,8 @@ public class TakerTrade extends Trade implements Serializable {
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume()); tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
} }
public void reActivate(MessageService messageService,
MailboxService mailboxService,
WalletService walletService,
TradeWalletService tradeWalletService,
BlockChainService blockChainService,
SignatureService signatureService) {
processModel.messageService = messageService;
processModel.mailboxService = mailboxService;
processModel.walletService = walletService;
processModel.tradeWalletService = tradeWalletService;
processModel.blockChainService = blockChainService;
processModel.signatureService = signatureService;
processModel.taker.registrationKeyPair =walletService.getRegistrationAddressEntry().getKeyPair();
processModel.taker.addressEntry = walletService.getAddressEntry(getId());
protocol = new TakerProtocol(this);
if (mailboxMessage != null)
protocol.setMailboxMessage(mailboxMessage);
}
public void onFiatPaymentReceived() { public void onFiatPaymentReceived() {
assert protocol != null;
((TakerProtocol) protocol).onFiatPaymentReceived(); ((TakerProtocol) protocol).onFiatPaymentReceived();
} }
@ -156,12 +143,12 @@ public class TakerTrade extends Trade implements Serializable {
// Setters // Setters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void setLifeCycleState(TakerLifeCycleState lifeCycleState) { public void setLifeCycleState(@NotNull TakerLifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState; this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty.set(lifeCycleState); lifeCycleStateProperty.set(lifeCycleState);
} }
public void setProcessState(TakerProcessState processState) { public void setProcessState(@NotNull TakerProcessState processState) {
this.processState = processState; this.processState = processState;
processStateProperty.set(processState); processStateProperty.set(processState);
@ -172,7 +159,7 @@ public class TakerTrade extends Trade implements Serializable {
} }
@Override @Override
public void setThrowable(Throwable throwable) { public void setThrowable(@NotNull Throwable throwable) {
super.setThrowable(throwable); super.setThrowable(throwable);
setProcessState(TakerTrade.TakerProcessState.EXCEPTION); setProcessState(TakerTrade.TakerProcessState.EXCEPTION);
} }
@ -182,16 +169,24 @@ public class TakerTrade extends Trade implements Serializable {
// Getters // Getters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public TakerTradeProcessModel getProcessModel() {
return (TakerTradeProcessModel) processModel;
}
@NotNull
@Override @Override
public ReadOnlyObjectProperty<TakerProcessState> processStateProperty() { public ReadOnlyObjectProperty<TakerProcessState> processStateProperty() {
return processStateProperty; return processStateProperty;
} }
@NotNull
@Override @Override
public ReadOnlyObjectProperty<TakerLifeCycleState> lifeCycleStateProperty() { public ReadOnlyObjectProperty<TakerLifeCycleState> lifeCycleStateProperty() {
return lifeCycleStateProperty; return lifeCycleStateProperty;
} }
@NotNull
@Override @Override
public Coin getTradeAmount() { public Coin getTradeAmount() {
return tradeAmount; return tradeAmount;
@ -202,6 +197,7 @@ public class TakerTrade extends Trade implements Serializable {
return offer.getVolumeByAmount(tradeAmount); return offer.getVolumeByAmount(tradeAmount);
} }
@NotNull
@Override @Override
public Peer getTradingPeer() { public Peer getTradingPeer() {
return tradingPeer; return tradingPeer;
@ -212,8 +208,11 @@ public class TakerTrade extends Trade implements Serializable {
// Private // Private
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
protected void setConfidenceListener() { protected void setConfidenceListener() {
assert depositTx != null;
TransactionConfidence transactionConfidence = depositTx.getConfidence(); TransactionConfidence transactionConfidence = depositTx.getConfidence();
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1); ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() { Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@ -224,7 +223,7 @@ public class TakerTrade extends Trade implements Serializable {
} }
@Override @Override
public void onFailure(Throwable t) { public void onFailure(@NotNull Throwable t) {
t.printStackTrace(); t.printStackTrace();
log.error(t.getMessage()); log.error(t.getMessage());
Throwables.propagate(t); Throwables.propagate(t);

View file

@ -17,14 +17,21 @@
package io.bitsquare.trade; package io.bitsquare.trade;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService; import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
import io.bitsquare.common.taskrunner.Model; import io.bitsquare.common.taskrunner.Model;
import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.MailboxMessage; import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.MailboxService;
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.protocol.Protocol; import io.bitsquare.trade.protocol.Protocol;
import io.bitsquare.trade.protocol.trade.taker.models.TakerTradeProcessModel; import io.bitsquare.trade.protocol.trade.TradeProcessModel;
import io.bitsquare.user.User;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
@ -34,10 +41,14 @@ import java.io.Serializable;
import java.util.Date; import java.util.Date;
import javax.annotation.Nullable;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -52,60 +63,118 @@ abstract public class Trade extends Model implements Serializable {
transient protected static final Logger log = LoggerFactory.getLogger(Trade.class); transient protected static final Logger log = LoggerFactory.getLogger(Trade.class);
public interface ProcessState { ///////////////////////////////////////////////////////////////////////////////////////////
// Interfaces
///////////////////////////////////////////////////////////////////////////////////////////
interface ProcessState {
} }
public interface LifeCycleState { public interface LifeCycleState {
} }
protected MailboxMessage mailboxMessage;
///////////////////////////////////////////////////////////////////////////////////////////
// Fields
///////////////////////////////////////////////////////////////////////////////////////////
protected final Offer offer; protected final Offer offer;
protected final Date date; @NotNull private final Date date;
@NotNull protected TradeProcessModel processModel = createProcessModel();
protected Contract contract; protected abstract TradeProcessModel createProcessModel();
protected String contractAsJson;
protected String takerContractSignature;
protected String offererContractSignature;
protected Transaction depositTx;
protected Transaction payoutTx;
protected int depthInBlocks = 0;
transient protected String errorMessage; @NotNull transient protected Protocol protocol;
transient protected Throwable throwable;
transient protected ObjectProperty<Coin> tradeAmountProperty = new SimpleObjectProperty<>(); @Nullable MailboxMessage mailboxMessage;
transient protected ObjectProperty<Fiat> tradeVolumeProperty = new SimpleObjectProperty<>(); @Nullable Transaction depositTx;
@Nullable private Transaction payoutTx;
@Nullable private Contract contract;
@Nullable private String contractAsJson;
@Nullable private String takerContractSignature;
@Nullable private String offererContractSignature;
@NotNull transient private Storage<? extends TradeProcessModel> storage;
@Nullable private transient String errorMessage;
@Nullable private transient Throwable throwable;
@NotNull transient ObjectProperty<Coin> tradeAmountProperty = new SimpleObjectProperty<>();
@NotNull transient ObjectProperty<Fiat> tradeVolumeProperty = new SimpleObjectProperty<>();
transient private Storage<TakerTradeProcessModel> storage;
transient protected Protocol protocol;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor // Constructor
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public Trade(Offer offer, Storage storage) { Trade(Offer offer, @NotNull Storage<? extends TradeProcessModel> storage) {
this.offer = offer; this.offer = offer;
this.storage = storage; this.storage = storage;
date = new Date(); date = new Date();
} }
public void initProcessModel(@NotNull MessageService messageService,
@NotNull MailboxService mailboxService,
@NotNull WalletService walletService,
@NotNull TradeWalletService tradeWalletService,
@NotNull BlockChainService blockChainService,
@NotNull SignatureService signatureService,
@NotNull ArbitrationRepository arbitrationRepository,
@NotNull User user) {
processModel.init(offer,
messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
createProtocol();
if (mailboxMessage != null)
protocol.setMailboxMessage(mailboxMessage);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// API // API
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// The deserialized tx has not actual confidence data, so we need to get the fresh one from the wallet. // The deserialized tx has not actual confidence data, so we need to get the fresh one from the wallet.
public void syncDepositTxWithWallet(TradeWalletService tradeWalletService) { public void syncDepositTxWithWallet(@NotNull TradeWalletService tradeWalletService) {
if (depositTx != null) if (depositTx != null)
setDepositTx(tradeWalletService.commitsDepositTx(depositTx)); setDepositTx(tradeWalletService.commitsDepositTx(depositTx));
} }
public void setDepositTx(Transaction tx) { public void setDepositTx(@NotNull Transaction tx) {
this.depositTx = tx; this.depositTx = tx;
setConfidenceListener(); setConfidenceListener();
} }
public void disposeProtocol() {
if (protocol != null) {
protocol.cleanup();
protocol = null;
}
}
public void setMailboxMessage(@NotNull MailboxMessage mailboxMessage) {
this.mailboxMessage = mailboxMessage;
assert protocol != null;
protocol.setMailboxMessage(mailboxMessage);
}
public void setStorage(@NotNull Storage<? extends TradeProcessModel> storage) {
this.storage = storage;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Storage
///////////////////////////////////////////////////////////////////////////////////////////
// Get called from taskRunner after each completed task // Get called from taskRunner after each completed task
@Override @Override
@ -118,56 +187,37 @@ abstract public class Trade extends Model implements Serializable {
storage.queueUpForSave(); storage.queueUpForSave();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Protocol
///////////////////////////////////////////////////////////////////////////////////////////
public void disposeProtocol() {
if (protocol != null) {
protocol.cleanup();
protocol = null;
}
}
public void setMailboxMessage(MailboxMessage mailboxMessage) {
this.mailboxMessage = mailboxMessage;
if (protocol != null)
protocol.setMailboxMessage(mailboxMessage);
}
public void setStorage(Storage storage) {
this.storage = storage;
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Setters // Setters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void setTakerContractSignature(String takerSignature) { protected abstract void setConfidenceListener();
public void setTakerContractSignature(@NotNull String takerSignature) {
this.takerContractSignature = takerSignature; this.takerContractSignature = takerSignature;
} }
public void setOffererContractSignature(String offererContractSignature) { public void setOffererContractSignature(@NotNull String offererContractSignature) {
this.offererContractSignature = offererContractSignature; this.offererContractSignature = offererContractSignature;
} }
public void setContractAsJson(String contractAsJson) { public void setContractAsJson(@NotNull String contractAsJson) {
this.contractAsJson = contractAsJson; this.contractAsJson = contractAsJson;
} }
public void setContract(Contract contract) { public void setContract(@NotNull Contract contract) {
this.contract = contract; this.contract = contract;
} }
public void setPayoutTx(Transaction tx) { public void setPayoutTx(@NotNull Transaction tx) {
this.payoutTx = tx; this.payoutTx = tx;
} }
public void setErrorMessage(String errorMessage) { public void setErrorMessage(@NotNull String errorMessage) {
this.errorMessage = errorMessage; this.errorMessage = errorMessage;
} }
public void setThrowable(Throwable throwable) { public void setThrowable(@NotNull Throwable throwable) {
this.throwable = throwable; this.throwable = throwable;
} }
@ -176,22 +226,27 @@ abstract public class Trade extends Model implements Serializable {
// Getters // Getters
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
public String getTakerContractSignature() { public String getTakerContractSignature() {
return takerContractSignature; return takerContractSignature;
} }
@Nullable
public String getOffererContractSignature() { public String getOffererContractSignature() {
return offererContractSignature; return offererContractSignature;
} }
@Nullable
public Transaction getDepositTx() { public Transaction getDepositTx() {
return depositTx; return depositTx;
} }
@Nullable
public Transaction getPayoutTx() { public Transaction getPayoutTx() {
return payoutTx; return payoutTx;
} }
@Nullable
public Contract getContract() { public Contract getContract() {
return contract; return contract;
} }
@ -208,41 +263,54 @@ abstract public class Trade extends Model implements Serializable {
return offer; return offer;
} }
@Nullable
public String getContractAsJson() { public String getContractAsJson() {
return contractAsJson; return contractAsJson;
} }
@NotNull
public Date getDate() { public Date getDate() {
return date; return date;
} }
@Nullable
public String getErrorMessage() { public String getErrorMessage() {
return errorMessage; return errorMessage;
} }
@Nullable
public Throwable getThrowable() { public Throwable getThrowable() {
return throwable; return throwable;
} }
@NotNull
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() { public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
return tradeAmountProperty; return tradeAmountProperty;
} }
@NotNull
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() { public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
return tradeVolumeProperty; return tradeVolumeProperty;
} }
abstract void createProtocol();
@NotNull
public abstract ReadOnlyObjectProperty<? extends ProcessState> processStateProperty(); public abstract ReadOnlyObjectProperty<? extends ProcessState> processStateProperty();
@NotNull
public abstract ReadOnlyObjectProperty<? extends LifeCycleState> lifeCycleStateProperty(); public abstract ReadOnlyObjectProperty<? extends LifeCycleState> lifeCycleStateProperty();
@org.jetbrains.annotations.Nullable
public abstract Coin getTradeAmount(); public abstract Coin getTradeAmount();
@org.jetbrains.annotations.Nullable
public abstract Fiat getTradeVolume(); public abstract Fiat getTradeVolume();
@org.jetbrains.annotations.Nullable
public abstract Peer getTradingPeer(); public abstract Peer getTradingPeer();
@NotNull
@Override @Override
public String toString() { public String toString() {
return "Trade{" + return "Trade{" +
@ -256,15 +324,7 @@ abstract public class Trade extends Model implements Serializable {
", offererContractSignature='" + offererContractSignature + '\'' + ", offererContractSignature='" + offererContractSignature + '\'' +
", depositTx=" + depositTx + ", depositTx=" + depositTx +
", payoutTx=" + payoutTx + ", payoutTx=" + payoutTx +
", depthInBlocks=" + depthInBlocks +
'}'; '}';
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////
protected abstract void setConfidenceListener();
} }

View file

@ -44,8 +44,6 @@ import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityProtocol;
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferModel; import io.bitsquare.trade.protocol.placeoffer.PlaceOfferModel;
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferProtocol; import io.bitsquare.trade.protocol.placeoffer.PlaceOfferProtocol;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.OffererTradeProcessModel;
import io.bitsquare.trade.protocol.trade.taker.models.TakerTradeProcessModel;
import io.bitsquare.user.AccountSettings; import io.bitsquare.user.AccountSettings;
import io.bitsquare.user.User; import io.bitsquare.user.User;
@ -84,20 +82,19 @@ public class TradeManager {
private final AddressService addressService; private final AddressService addressService;
private final BlockChainService blockChainService; private final BlockChainService blockChainService;
private final WalletService walletService; private final WalletService walletService;
private final Storage pendingTradesStorage; private final TradeWalletService tradeWalletService;
private final Storage openOfferTradesStorage;
private TradeWalletService tradeWalletService;
private final SignatureService signatureService; private final SignatureService signatureService;
private final EncryptionService<MailboxMessage> encryptionService; private final EncryptionService<MailboxMessage> encryptionService;
private final OfferBookService offerBookService; private final OfferBookService offerBookService;
private final ArbitrationRepository arbitrationRepository; private final ArbitrationRepository arbitrationRepository;
private final File storageDir;
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>(); private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
private final Storage pendingTradesStorage;
private final Storage openOfferTradesStorage;
private final TradeList<OffererTrade> openOfferTrades; private final TradeList<OffererTrade> openOfferTrades;
private final TradeList<Trade> pendingTrades; private final TradeList<Trade> pendingTrades;
private final TradeList<Trade> closedTrades; private final TradeList<Trade> closedTrades;
private boolean shutDownRequested; private boolean shutDownRequested;
@ -106,11 +103,19 @@ public class TradeManager {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public TradeManager(User user, AccountSettings accountSettings, public TradeManager(User user,
MessageService messageService, MailboxService mailboxService, AddressService addressService, BlockChainService blockChainService, AccountSettings accountSettings,
WalletService walletService, TradeWalletService tradeWalletService, SignatureService signatureService, MessageService messageService,
MailboxService mailboxService,
AddressService addressService,
BlockChainService blockChainService,
WalletService walletService,
TradeWalletService tradeWalletService,
SignatureService signatureService,
EncryptionService<MailboxMessage> encryptionService, EncryptionService<MailboxMessage> encryptionService,
OfferBookService offerBookService, ArbitrationRepository arbitrationRepository, @Named("storage.dir") File storageDir) { OfferBookService offerBookService,
ArbitrationRepository arbitrationRepository,
@Named("storage.dir") File storageDir) {
this.user = user; this.user = user;
this.accountSettings = accountSettings; this.accountSettings = accountSettings;
this.messageService = messageService; this.messageService = messageService;
@ -123,7 +128,6 @@ public class TradeManager {
this.encryptionService = encryptionService; this.encryptionService = encryptionService;
this.offerBookService = offerBookService; this.offerBookService = offerBookService;
this.arbitrationRepository = arbitrationRepository; this.arbitrationRepository = arbitrationRepository;
this.storageDir = storageDir;
openOfferTradesStorage = new Storage(storageDir); openOfferTradesStorage = new Storage(storageDir);
pendingTradesStorage = new Storage(storageDir); pendingTradesStorage = new Storage(storageDir);
@ -167,36 +171,30 @@ public class TradeManager {
() -> log.debug("Successful removed open offer from DHT"), () -> log.debug("Successful removed open offer from DHT"),
(message, throwable) -> log.error("Remove open offer from DHT failed. " + message)); (message, throwable) -> log.error("Remove open offer from DHT failed. " + message));
offererTrade.setStorage(openOfferTradesStorage); offererTrade.setStorage(openOfferTradesStorage);
offererTrade.reActivate(messageService, offererTrade.initProcessModel(messageService,
mailboxService, mailboxService,
walletService, walletService,
tradeWalletService, tradeWalletService,
blockChainService, blockChainService,
signatureService); signatureService,
arbitrationRepository,
user);
} }
for (Trade trade : pendingTrades) { for (Trade trade : pendingTrades) {
// We continue an interrupted trade. // We continue an interrupted trade.
// TODO if the peer has changed its IP address, we need to make another findPeer request. At the moment we use the peer stored in trade to // TODO if the peer has changed its IP address, we need to make another findPeer request. At the moment we use the peer stored in trade to
// continue the trade, but that might fail. // continue the trade, but that might fail.
trade.initProcessModel(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
trade.syncDepositTxWithWallet(tradeWalletService); trade.syncDepositTxWithWallet(tradeWalletService);
trade.setStorage(pendingTradesStorage); trade.setStorage(pendingTradesStorage);
if (trade instanceof TakerTrade) {
((TakerTrade) trade).reActivate(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService);
}
else if (trade instanceof OffererTrade) {
((OffererTrade) trade).reActivate(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService);
}
} }
mailboxService.getAllMessages(user.getP2PSigPubKey(), mailboxService.getAllMessages(user.getP2PSigPubKey(),
@ -235,14 +233,21 @@ public class TradeManager {
accountSettings.getAcceptedCountries(), accountSettings.getAcceptedCountries(),
accountSettings.getAcceptedLanguageLocaleCodes()); accountSettings.getAcceptedLanguageLocaleCodes());
PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService); PlaceOfferModel model = new PlaceOfferModel(offer, walletService, tradeWalletService, offerBookService);
PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol( PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol(
model, model,
(transaction) -> { (transaction) -> {
OffererTradeProcessModel processModel = createOffererTradeProcessModel(offer); OffererTrade offererTrade = new OffererTrade(offer, openOfferTradesStorage);
OffererTrade offererTrade = new OffererTrade(offer, processModel, openOfferTradesStorage);
openOfferTrades.add(offererTrade); openOfferTrades.add(offererTrade);
offererTrade.initProcessModel(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("offererTrade state = " + newValue); log.debug("offererTrade state = " + newValue);
@ -430,37 +435,20 @@ public class TradeManager {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
private TakerTrade takeAvailableOffer(Coin amount, Offer offer, Peer peer) { private TakerTrade takeAvailableOffer(Coin amount, Offer offer, Peer peer) {
TakerTradeProcessModel takerTradeProcessModel = createTakerTradeProcessModel(offer); TakerTrade takerTrade = new TakerTrade(offer, amount, peer, pendingTradesStorage);
TakerTrade takerTrade = new TakerTrade(offer, amount, peer, takerTradeProcessModel, pendingTradesStorage); takerTrade.initProcessModel(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
pendingTrades.add(takerTrade); pendingTrades.add(takerTrade);
takerTrade.takeAvailableOffer();
return takerTrade; return takerTrade;
} }
private TakerTradeProcessModel createTakerTradeProcessModel(Offer offer) {
return new TakerTradeProcessModel(
offer,
messageService,
mailboxService,
walletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
}
private OffererTradeProcessModel createOffererTradeProcessModel(Offer offer) {
return new OffererTradeProcessModel(offer,
messageService,
mailboxService,
walletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Mailbox // Mailbox
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -17,6 +17,7 @@
package io.bitsquare.trade.protocol.placeoffer; package io.bitsquare.trade.protocol.placeoffer;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.common.taskrunner.Model; import io.bitsquare.common.taskrunner.Model;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
@ -32,15 +33,18 @@ public class PlaceOfferModel extends Model {
public final Offer offer; public final Offer offer;
public final WalletService walletService; public final WalletService walletService;
public TradeWalletService tradeWalletService;
public final OfferBookService offerBookService; public final OfferBookService offerBookService;
private Transaction transaction; private Transaction transaction;
public PlaceOfferModel(Offer offer, public PlaceOfferModel(Offer offer,
WalletService walletService, WalletService walletService,
TradeWalletService tradeWalletService,
OfferBookService offerBookService) { OfferBookService offerBookService) {
this.offer = offer; this.offer = offer;
this.walletService = walletService; this.walletService = walletService;
this.tradeWalletService = tradeWalletService;
this.offerBookService = offerBookService; this.offerBookService = offerBookService;
} }

View file

@ -54,7 +54,7 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
Coin balance = model.walletService.getBalanceForAddress(addressEntry.getAddress()); Coin balance = model.walletService.getBalanceForAddress(addressEntry.getAddress());
if (balance.compareTo(totalsNeeded) >= 0) { if (balance.compareTo(totalsNeeded) >= 0) {
model.walletService.getTradeWalletService().broadcastCreateOfferFeeTx(model.getTransaction(), new FutureCallback<Transaction>() { model.tradeWalletService.broadcastCreateOfferFeeTx(model.getTransaction(), new FutureCallback<Transaction>() {
@Override @Override
public void onSuccess(Transaction transaction) { public void onSuccess(Transaction transaction) {
log.info("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString()); log.info("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString());

View file

@ -36,7 +36,7 @@ public class CreateOfferFeeTx extends Task<PlaceOfferModel> {
@Override @Override
protected void doRun() { protected void doRun() {
try { try {
Transaction transaction = model.walletService.getTradeWalletService().createOfferFeeTx( Transaction transaction = model.tradeWalletService.createOfferFeeTx(
model.walletService.getAddressEntry(model.offer.getId())); model.walletService.getAddressEntry(model.offer.getId()));
// We assume there will be no tx malleability. We add a check later in case the published offer has a different hash. // We assume there will be no tx malleability. We add a check later in case the published offer has a different hash.

View file

@ -28,9 +28,14 @@ import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MailboxService;
import io.bitsquare.p2p.MessageService; import io.bitsquare.p2p.MessageService;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.user.User;
import java.io.Serializable; import java.io.Serializable;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -40,46 +45,62 @@ public class TradeProcessModel extends Model implements Serializable {
protected static final Logger log = LoggerFactory.getLogger(TradeProcessModel.class); protected static final Logger log = LoggerFactory.getLogger(TradeProcessModel.class);
public final String id; // those fields are re-assigned in case of deserialized object after backend is ready.
public final Offer offer; // Therefore they are not final but annotated with @NotNull
public byte[] arbitratorPubKey; @NotNull transient public MessageService messageService;
@NotNull transient public MailboxService mailboxService;
@NotNull transient public WalletService walletService;
@NotNull transient public TradeWalletService tradeWalletService;
@NotNull transient public BlockChainService blockChainService;
@NotNull transient public SignatureService signatureService;
@NotNull public Offer offer;
@NotNull public String id;
@NotNull public byte[] arbitratorPubKey;
transient public MessageService messageService; @Nullable private transient MailboxMessage mailboxMessage;
transient public MailboxService mailboxService; @Nullable transient private TradeMessage tradeMessage;
transient public WalletService walletService;
transient public TradeWalletService tradeWalletService;
transient public BlockChainService blockChainService;
transient public SignatureService signatureService;
transient public MailboxMessage mailboxMessage; protected TradeProcessModel() {
transient private TradeMessage tradeMessage; }
protected TradeProcessModel(Offer offer, public void init(@NotNull Offer offer,
MessageService messageService, @NotNull MessageService messageService,
MailboxService mailboxService, @NotNull MailboxService mailboxService,
WalletService walletService, @NotNull WalletService walletService,
BlockChainService blockChainService, @NotNull TradeWalletService tradeWalletService,
SignatureService signatureService, @NotNull BlockChainService blockChainService,
ArbitrationRepository arbitrationRepository) { @NotNull SignatureService signatureService,
@NotNull ArbitrationRepository arbitrationRepository,
@NotNull User user) {
this.offer = offer; this.offer = offer;
this.messageService = messageService; this.messageService = messageService;
this.mailboxService = mailboxService; this.mailboxService = mailboxService;
this.walletService = walletService; this.walletService = walletService;
this.tradeWalletService = tradeWalletService;
this.blockChainService = blockChainService; this.blockChainService = blockChainService;
this.signatureService = signatureService; this.signatureService = signatureService;
id = offer.getId(); id = offer.getId();
tradeWalletService = walletService.getTradeWalletService();
arbitratorPubKey = arbitrationRepository.getDefaultArbitrator().getPubKey(); arbitratorPubKey = arbitrationRepository.getDefaultArbitrator().getPubKey();
assert arbitratorPubKey != null;
} }
public void setTradeMessage(TradeMessage tradeMessage) { public void setTradeMessage(@NotNull TradeMessage tradeMessage) {
this.tradeMessage = tradeMessage; this.tradeMessage = tradeMessage;
} }
public void setMailboxMessage(@NotNull MailboxMessage mailboxMessage) {
this.mailboxMessage = mailboxMessage;
}
@Nullable
public TradeMessage getTradeMessage() { public TradeMessage getTradeMessage() {
return tradeMessage; return tradeMessage;
} }
@Nullable
public MailboxMessage getMailboxMessage() {
return mailboxMessage;
}
} }

View file

@ -78,8 +78,8 @@ public class OffererProtocol implements Protocol {
public void setMailboxMessage(MailboxMessage mailboxMessage) { public void setMailboxMessage(MailboxMessage mailboxMessage) {
log.debug("setMailboxMessage " + mailboxMessage); log.debug("setMailboxMessage " + mailboxMessage);
// Might be called twice, so check that its only processed once // Might be called twice, so check that its only processed once
if (offererTradeProcessModel.mailboxMessage == null) { if (offererTradeProcessModel.getMailboxMessage() == null) {
offererTradeProcessModel.mailboxMessage = mailboxMessage; offererTradeProcessModel.setMailboxMessage(mailboxMessage);
if (mailboxMessage instanceof PayoutTxPublishedMessage) { if (mailboxMessage instanceof PayoutTxPublishedMessage) {
handlePayoutTxPublishedMessage((PayoutTxPublishedMessage) mailboxMessage); handlePayoutTxPublishedMessage((PayoutTxPublishedMessage) mailboxMessage);
} }

View file

@ -19,6 +19,7 @@ package io.bitsquare.trade.protocol.trade.offerer.models;
import io.bitsquare.arbitration.ArbitrationRepository; import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BlockChainService; import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.SignatureService; import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
@ -29,6 +30,8 @@ import io.bitsquare.user.User;
import java.io.Serializable; import java.io.Serializable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -44,21 +47,27 @@ public class OffererTradeProcessModel extends TradeProcessModel implements Seria
// written by tasks // written by tasks
private String takeOfferFeeTxId; private String takeOfferFeeTxId;
public OffererTradeProcessModel(Offer offer, public OffererTradeProcessModel() {
MessageService messageService, }
MailboxService mailboxService,
WalletService walletService, public void init(@NotNull Offer offer,
BlockChainService blockChainService, @NotNull MessageService messageService,
SignatureService signatureService, @NotNull MailboxService mailboxService,
ArbitrationRepository arbitrationRepository, @NotNull WalletService walletService,
User user) { @NotNull TradeWalletService tradeWalletService,
super(offer, @NotNull BlockChainService blockChainService,
@NotNull SignatureService signatureService,
@NotNull ArbitrationRepository arbitrationRepository,
@NotNull User user) {
super.init(offer,
messageService, messageService,
mailboxService, mailboxService,
walletService, walletService,
tradeWalletService,
blockChainService, blockChainService,
signatureService, signatureService,
arbitrationRepository); arbitrationRepository,
user);
offerer.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey(); offerer.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
offerer.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair(); offerer.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();

View file

@ -83,8 +83,8 @@ public class TakerProtocol implements Protocol {
public void setMailboxMessage(MailboxMessage mailboxMessage) { public void setMailboxMessage(MailboxMessage mailboxMessage) {
log.debug("setMailboxMessage " + mailboxMessage); log.debug("setMailboxMessage " + mailboxMessage);
// Might be called twice, so check that its only processed once // Might be called twice, so check that its only processed once
if (takerTradeProcessModel.mailboxMessage == null) { if (takerTradeProcessModel.getMailboxMessage() == null) {
takerTradeProcessModel.mailboxMessage = mailboxMessage; takerTradeProcessModel.setMailboxMessage(mailboxMessage);
if (mailboxMessage instanceof FiatTransferStartedMessage) { if (mailboxMessage instanceof FiatTransferStartedMessage) {
handleFiatTransferStartedMessage((FiatTransferStartedMessage) mailboxMessage); handleFiatTransferStartedMessage((FiatTransferStartedMessage) mailboxMessage);
} }

View file

@ -32,6 +32,9 @@ public class Offerer implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization. // That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public Offerer() {
}
// written by tasks // written by tasks
public byte[] tradeWalletPubKey; public byte[] tradeWalletPubKey;
public Coin payoutAmount; public Coin payoutAmount;

View file

@ -35,6 +35,9 @@ public class Taker implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization. // That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public Taker() {
}
public FiatAccount fiatAccount; public FiatAccount fiatAccount;
public String accountId; public String accountId;
public PublicKey p2pSigPubKey; public PublicKey p2pSigPubKey;

View file

@ -19,6 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.models;
import io.bitsquare.arbitration.ArbitrationRepository; import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BlockChainService; import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.SignatureService; import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
@ -31,6 +32,10 @@ import org.bitcoinj.core.Transaction;
import java.io.Serializable; import java.io.Serializable;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -47,24 +52,31 @@ public class TakerTradeProcessModel extends TradeProcessModel implements Seriali
public final Offerer offerer = new Offerer(); public final Offerer offerer = new Offerer();
// written by tasks // written by tasks
private Transaction takeOfferFeeTx; @Nullable private Transaction takeOfferFeeTx;
private Transaction payoutTx; @Nullable private Transaction payoutTx;
public TakerTradeProcessModel(Offer offer, public TakerTradeProcessModel(){
MessageService messageService, }
MailboxService mailboxService,
WalletService walletService, public void init(@NotNull Offer offer,
BlockChainService blockChainService, @NotNull MessageService messageService,
SignatureService signatureService, @NotNull MailboxService mailboxService,
ArbitrationRepository arbitrationRepository, @NotNull WalletService walletService,
User user) { @NotNull TradeWalletService tradeWalletService,
super(offer, @NotNull BlockChainService blockChainService,
@NotNull SignatureService signatureService,
@NotNull ArbitrationRepository arbitrationRepository,
@NotNull User user) {
super.init(offer,
messageService, messageService,
mailboxService, mailboxService,
walletService, walletService,
tradeWalletService,
blockChainService, blockChainService,
signatureService, signatureService,
arbitrationRepository); arbitrationRepository,
user);
taker.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey(); taker.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
taker.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair(); taker.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();
@ -76,20 +88,22 @@ public class TakerTradeProcessModel extends TradeProcessModel implements Seriali
taker.tradeWalletPubKey = taker.addressEntry.getPubKey(); taker.tradeWalletPubKey = taker.addressEntry.getPubKey();
} }
public void setPayoutTx(@NotNull Transaction payoutTx) {
this.payoutTx = payoutTx;
}
public void setTakeOfferFeeTx(@NotNull Transaction takeOfferFeeTx) {
this.takeOfferFeeTx = takeOfferFeeTx;
}
@Nullable
public Transaction getTakeOfferFeeTx() { public Transaction getTakeOfferFeeTx() {
return takeOfferFeeTx; return takeOfferFeeTx;
} }
public void setTakeOfferFeeTx(Transaction takeOfferFeeTx) { @Nullable
this.takeOfferFeeTx = takeOfferFeeTx;
}
public Transaction getPayoutTx() { public Transaction getPayoutTx() {
return payoutTx; return payoutTx;
} }
public void setPayoutTx(Transaction payoutTx) {
this.payoutTx = payoutTx;
}
} }