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

View file

@ -28,6 +28,8 @@ import java.security.PublicKey;
import java.util.List;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
public class Arbitrator implements Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
@ -83,19 +85,19 @@ public class Arbitrator implements Serializable {
private String webUrl;
private String description;
public Arbitrator(Storage<Arbitrator> storage,
String id,
byte[] pubKey,
PublicKey p2pSigPubKey,
String name,
Reputation reputation,
ID_TYPE idType,
List<String> languageCodes,
Coin fee,
List<METHOD> arbitrationMethods,
List<ID_VERIFICATION> idVerifications,
String webUrl,
String description) {
public Arbitrator(@NotNull Storage<Arbitrator> storage,
@NotNull String id,
@NotNull byte[] pubKey,
@NotNull PublicKey p2pSigPubKey,
@NotNull String name,
@NotNull Reputation reputation,
@NotNull ID_TYPE idType,
@NotNull List<String> languageCodes,
@NotNull Coin fee,
@NotNull List<METHOD> arbitrationMethods,
@NotNull List<ID_VERIFICATION> idVerifications,
@NotNull String webUrl,
@NotNull String description) {
this.storage = storage;
this.id = id;
this.pubKey = pubKey;
@ -137,8 +139,6 @@ public class Arbitrator implements Serializable {
Arbitrator other = (Arbitrator) obj;
return id != null && id.equals(other.getId());
}
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -25,6 +25,8 @@ import java.io.Serializable;
import java.util.Arrays;
import org.jetbrains.annotations.NotNull;
/**
* Is a minimalistic wallet abstraction used to separate transactions between different activities like:
* Registration, trade and arbiter deposit.
@ -35,7 +37,7 @@ public class AddressEntry implements Serializable {
// that will be restored from the wallet at deserialisation
private transient DeterministicKey keyPair;
private final String offerId;
private final Context context;
private final byte[] pubKey;
@ -68,6 +70,7 @@ public class AddressEntry implements Serializable {
return getAddress().toString();
}
@NotNull
public DeterministicKey getKeyPair() {
return keyPair;
}

View file

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

View file

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

View file

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

View file

@ -17,15 +17,10 @@
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.p2p.MailboxService;
import io.bitsquare.p2p.MessageService;
import io.bitsquare.p2p.Peer;
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.models.OffererTradeProcessModel;
@ -41,10 +36,14 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.io.Serializable;
import javax.annotation.Nullable;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -68,6 +67,7 @@ public class OffererTrade extends Trade implements Serializable {
}
public enum OffererProcessState implements ProcessState {
UNDEFINED,
DEPOSIT_PUBLISHED,
DEPOSIT_CONFIRMED,
@ -78,36 +78,46 @@ public class OffererTrade extends Trade implements Serializable {
MESSAGE_SENDING_FAILED,
EXCEPTION
}
///////////////////////////////////////////////////////////////////////////////////////////
// Fields
///////////////////////////////////////////////////////////////////////////////////////////
private Coin tradeAmount;
private Peer tradingPeer;
private OffererProcessState processState;
private OffererLifeCycleState lifeCycleState;
private OffererTradeProcessModel processModel;
transient private ObjectProperty<OffererProcessState> processStateProperty = new SimpleObjectProperty<>();
transient private ObjectProperty<OffererLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>();
@Nullable private Coin tradeAmount;
@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
///////////////////////////////////////////////////////////////////////////////////////////
public OffererTrade(Offer offer, OffererTradeProcessModel processModel, Storage storage) {
public OffererTrade(@NotNull Offer offer, @NotNull Storage<? extends TradeProcessModel> 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
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
private void readObject(@NotNull java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
processStateProperty = new SimpleObjectProperty<>(processState);
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
tradeAmountProperty = new SimpleObjectProperty<>();
tradeVolumeProperty = new SimpleObjectProperty<>();
if (tradeAmount != null) {
@ -117,41 +127,16 @@ public class OffererTrade extends Trade implements Serializable {
}
public void onFiatPaymentStarted() {
assert protocol != null;
((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
///////////////////////////////////////////////////////////////////////////////////////////
public void setProcessState(OffererProcessState processState) {
public void setProcessState(@NotNull OffererProcessState processState) {
this.processState = 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) {
case FAILED:
disposeProtocol();
@ -176,13 +161,13 @@ public class OffererTrade extends Trade implements Serializable {
lifeCycleStateProperty.set(lifeCycleState);
}
public void setTradeAmount(Coin tradeAmount) {
public void setTradeAmount(@NotNull Coin tradeAmount) {
this.tradeAmount = tradeAmount;
tradeAmountProperty.set(tradeAmount);
tradeVolumeProperty.set(getTradeVolume());
}
public void setTradingPeer(Peer tradingPeer) {
public void setTradingPeer(@NotNull Peer tradingPeer) {
this.tradingPeer = tradingPeer;
}
@ -191,26 +176,36 @@ public class OffererTrade extends Trade implements Serializable {
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public OffererTradeProcessModel getProcessModel() {
return (OffererTradeProcessModel) processModel;
}
@NotNull
@Override
public ReadOnlyObjectProperty<OffererProcessState> processStateProperty() {
return processStateProperty;
}
@NotNull
@Override
public ReadOnlyObjectProperty<OffererLifeCycleState> lifeCycleStateProperty() {
return lifeCycleStateProperty;
}
@Nullable
@Override
public Coin getTradeAmount() {
return tradeAmount;
}
@Nullable
@Override
public Fiat getTradeVolume() {
return offer.getVolumeByAmount(tradeAmount);
}
@Nullable
@Override
public Peer getTradingPeer() {
return tradingPeer;
@ -223,6 +218,7 @@ public class OffererTrade extends Trade implements Serializable {
@Override
protected void setConfidenceListener() {
assert depositTx != null;
TransactionConfidence transactionConfidence = depositTx.getConfidence();
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@ -233,7 +229,7 @@ public class OffererTrade extends Trade implements Serializable {
}
@Override
public void onFailure(Throwable t) {
public void onFailure(@NotNull Throwable t) {
t.printStackTrace();
log.error(t.getMessage());
Throwables.propagate(t);

View file

@ -17,15 +17,10 @@
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.p2p.MailboxService;
import io.bitsquare.p2p.MessageService;
import io.bitsquare.p2p.Peer;
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.models.TakerTradeProcessModel;
@ -45,6 +40,8 @@ import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -53,10 +50,6 @@ public class TakerTrade extends Trade implements Serializable {
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class);
public TakerTradeProcessModel getProcessModel() {
return processModel;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Enum
@ -69,6 +62,7 @@ public class TakerTrade extends Trade implements Serializable {
}
public enum TakerProcessState implements ProcessState {
UNDEFINED,
TAKE_OFFER_FEE_TX_CREATED,
TAKE_OFFER_FEE_PUBLISHED,
TAKE_OFFER_FEE_PUBLISH_FAILED,
@ -85,38 +79,52 @@ public class TakerTrade extends Trade implements Serializable {
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<>();
transient private ObjectProperty<TakerLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>();
@NotNull private final Coin tradeAmount;
@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
///////////////////////////////////////////////////////////////////////////////////////////
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);
this.tradeAmount = tradeAmount;
this.tradingPeer = peer;
this.processModel = processModel;
protocol = new TakerProtocol(this);
setLifeCycleState(TakerTrade.TakerLifeCycleState.PENDING);
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
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();
}
// 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();
processStateProperty = new SimpleObjectProperty<>(processState);
@ -125,29 +133,8 @@ public class TakerTrade extends Trade implements Serializable {
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() {
assert protocol != null;
((TakerProtocol) protocol).onFiatPaymentReceived();
}
@ -156,12 +143,12 @@ public class TakerTrade extends Trade implements Serializable {
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setLifeCycleState(TakerLifeCycleState lifeCycleState) {
public void setLifeCycleState(@NotNull TakerLifeCycleState lifeCycleState) {
this.lifeCycleState = lifeCycleState;
lifeCycleStateProperty.set(lifeCycleState);
}
public void setProcessState(TakerProcessState processState) {
public void setProcessState(@NotNull TakerProcessState processState) {
this.processState = processState;
processStateProperty.set(processState);
@ -172,7 +159,7 @@ public class TakerTrade extends Trade implements Serializable {
}
@Override
public void setThrowable(Throwable throwable) {
public void setThrowable(@NotNull Throwable throwable) {
super.setThrowable(throwable);
setProcessState(TakerTrade.TakerProcessState.EXCEPTION);
}
@ -182,16 +169,24 @@ public class TakerTrade extends Trade implements Serializable {
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public TakerTradeProcessModel getProcessModel() {
return (TakerTradeProcessModel) processModel;
}
@NotNull
@Override
public ReadOnlyObjectProperty<TakerProcessState> processStateProperty() {
return processStateProperty;
}
@NotNull
@Override
public ReadOnlyObjectProperty<TakerLifeCycleState> lifeCycleStateProperty() {
return lifeCycleStateProperty;
}
@NotNull
@Override
public Coin getTradeAmount() {
return tradeAmount;
@ -202,6 +197,7 @@ public class TakerTrade extends Trade implements Serializable {
return offer.getVolumeByAmount(tradeAmount);
}
@NotNull
@Override
public Peer getTradingPeer() {
return tradingPeer;
@ -212,8 +208,11 @@ public class TakerTrade extends Trade implements Serializable {
// Private
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void setConfidenceListener() {
assert depositTx != null;
TransactionConfidence transactionConfidence = depositTx.getConfidence();
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
@ -224,7 +223,7 @@ public class TakerTrade extends Trade implements Serializable {
}
@Override
public void onFailure(Throwable t) {
public void onFailure(@NotNull Throwable t) {
t.printStackTrace();
log.error(t.getMessage());
Throwables.propagate(t);

View file

@ -17,14 +17,21 @@
package io.bitsquare.trade;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
import io.bitsquare.common.taskrunner.Model;
import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.MailboxService;
import io.bitsquare.p2p.MessageService;
import io.bitsquare.p2p.Peer;
import io.bitsquare.storage.Storage;
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.Transaction;
@ -34,10 +41,14 @@ import java.io.Serializable;
import java.util.Date;
import javax.annotation.Nullable;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
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);
public interface ProcessState {
///////////////////////////////////////////////////////////////////////////////////////////
// Interfaces
///////////////////////////////////////////////////////////////////////////////////////////
interface ProcessState {
}
public interface LifeCycleState {
}
protected MailboxMessage mailboxMessage;
///////////////////////////////////////////////////////////////////////////////////////////
// Fields
///////////////////////////////////////////////////////////////////////////////////////////
protected final Offer offer;
protected final Date date;
protected Contract contract;
protected String contractAsJson;
protected String takerContractSignature;
protected String offererContractSignature;
protected Transaction depositTx;
protected Transaction payoutTx;
protected int depthInBlocks = 0;
@NotNull private final Date date;
@NotNull protected TradeProcessModel processModel = createProcessModel();
transient protected String errorMessage;
transient protected Throwable throwable;
transient protected ObjectProperty<Coin> tradeAmountProperty = new SimpleObjectProperty<>();
transient protected ObjectProperty<Fiat> tradeVolumeProperty = new SimpleObjectProperty<>();
protected abstract TradeProcessModel createProcessModel();
@NotNull transient protected Protocol protocol;
@Nullable MailboxMessage mailboxMessage;
@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
///////////////////////////////////////////////////////////////////////////////////////////
public Trade(Offer offer, Storage storage) {
Trade(Offer offer, @NotNull Storage<? extends TradeProcessModel> storage) {
this.offer = offer;
this.storage = storage;
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
///////////////////////////////////////////////////////////////////////////////////////////
// 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)
setDepositTx(tradeWalletService.commitsDepositTx(depositTx));
}
public void setDepositTx(Transaction tx) {
public void setDepositTx(@NotNull Transaction tx) {
this.depositTx = tx;
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
@Override
@ -118,56 +187,37 @@ abstract public class Trade extends Model implements Serializable {
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
///////////////////////////////////////////////////////////////////////////////////////////
public void setTakerContractSignature(String takerSignature) {
protected abstract void setConfidenceListener();
public void setTakerContractSignature(@NotNull String takerSignature) {
this.takerContractSignature = takerSignature;
}
public void setOffererContractSignature(String offererContractSignature) {
public void setOffererContractSignature(@NotNull String offererContractSignature) {
this.offererContractSignature = offererContractSignature;
}
public void setContractAsJson(String contractAsJson) {
public void setContractAsJson(@NotNull String contractAsJson) {
this.contractAsJson = contractAsJson;
}
public void setContract(Contract contract) {
public void setContract(@NotNull Contract contract) {
this.contract = contract;
}
public void setPayoutTx(Transaction tx) {
public void setPayoutTx(@NotNull Transaction tx) {
this.payoutTx = tx;
}
public void setErrorMessage(String errorMessage) {
public void setErrorMessage(@NotNull String errorMessage) {
this.errorMessage = errorMessage;
}
public void setThrowable(Throwable throwable) {
public void setThrowable(@NotNull Throwable throwable) {
this.throwable = throwable;
}
@ -176,22 +226,27 @@ abstract public class Trade extends Model implements Serializable {
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
public String getTakerContractSignature() {
return takerContractSignature;
}
@Nullable
public String getOffererContractSignature() {
return offererContractSignature;
}
@Nullable
public Transaction getDepositTx() {
return depositTx;
}
@Nullable
public Transaction getPayoutTx() {
return payoutTx;
}
@Nullable
public Contract getContract() {
return contract;
}
@ -208,41 +263,54 @@ abstract public class Trade extends Model implements Serializable {
return offer;
}
@Nullable
public String getContractAsJson() {
return contractAsJson;
}
@NotNull
public Date getDate() {
return date;
}
@Nullable
public String getErrorMessage() {
return errorMessage;
}
@Nullable
public Throwable getThrowable() {
return throwable;
}
@NotNull
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
return tradeAmountProperty;
}
@NotNull
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
return tradeVolumeProperty;
}
abstract void createProtocol();
@NotNull
public abstract ReadOnlyObjectProperty<? extends ProcessState> processStateProperty();
@NotNull
public abstract ReadOnlyObjectProperty<? extends LifeCycleState> lifeCycleStateProperty();
@org.jetbrains.annotations.Nullable
public abstract Coin getTradeAmount();
@org.jetbrains.annotations.Nullable
public abstract Fiat getTradeVolume();
@org.jetbrains.annotations.Nullable
public abstract Peer getTradingPeer();
@NotNull
@Override
public String toString() {
return "Trade{" +
@ -256,15 +324,7 @@ abstract public class Trade extends Model implements Serializable {
", offererContractSignature='" + offererContractSignature + '\'' +
", depositTx=" + depositTx +
", 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.PlaceOfferProtocol;
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.User;
@ -84,20 +82,19 @@ public class TradeManager {
private final AddressService addressService;
private final BlockChainService blockChainService;
private final WalletService walletService;
private final Storage pendingTradesStorage;
private final Storage openOfferTradesStorage;
private TradeWalletService tradeWalletService;
private final TradeWalletService tradeWalletService;
private final SignatureService signatureService;
private final EncryptionService<MailboxMessage> encryptionService;
private final OfferBookService offerBookService;
private final ArbitrationRepository arbitrationRepository;
private final File storageDir;
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
private final Storage pendingTradesStorage;
private final Storage openOfferTradesStorage;
private final TradeList<OffererTrade> openOfferTrades;
private final TradeList<Trade> pendingTrades;
private final TradeList<Trade> closedTrades;
private boolean shutDownRequested;
@ -106,11 +103,19 @@ public class TradeManager {
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TradeManager(User user, AccountSettings accountSettings,
MessageService messageService, MailboxService mailboxService, AddressService addressService, BlockChainService blockChainService,
WalletService walletService, TradeWalletService tradeWalletService, SignatureService signatureService,
public TradeManager(User user,
AccountSettings accountSettings,
MessageService messageService,
MailboxService mailboxService,
AddressService addressService,
BlockChainService blockChainService,
WalletService walletService,
TradeWalletService tradeWalletService,
SignatureService signatureService,
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.accountSettings = accountSettings;
this.messageService = messageService;
@ -123,7 +128,6 @@ public class TradeManager {
this.encryptionService = encryptionService;
this.offerBookService = offerBookService;
this.arbitrationRepository = arbitrationRepository;
this.storageDir = storageDir;
openOfferTradesStorage = new Storage(storageDir);
pendingTradesStorage = new Storage(storageDir);
@ -167,36 +171,30 @@ public class TradeManager {
() -> log.debug("Successful removed open offer from DHT"),
(message, throwable) -> log.error("Remove open offer from DHT failed. " + message));
offererTrade.setStorage(openOfferTradesStorage);
offererTrade.reActivate(messageService,
offererTrade.initProcessModel(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService);
signatureService,
arbitrationRepository,
user);
}
for (Trade trade : pendingTrades) {
// 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
// continue the trade, but that might fail.
trade.initProcessModel(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
trade.syncDepositTxWithWallet(tradeWalletService);
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(),
@ -235,14 +233,21 @@ public class TradeManager {
accountSettings.getAcceptedCountries(),
accountSettings.getAcceptedLanguageLocaleCodes());
PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService);
PlaceOfferModel model = new PlaceOfferModel(offer, walletService, tradeWalletService, offerBookService);
PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol(
model,
(transaction) -> {
OffererTradeProcessModel processModel = createOffererTradeProcessModel(offer);
OffererTrade offererTrade = new OffererTrade(offer, processModel, openOfferTradesStorage);
OffererTrade offererTrade = new OffererTrade(offer, openOfferTradesStorage);
openOfferTrades.add(offererTrade);
offererTrade.initProcessModel(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
log.debug("offererTrade state = " + newValue);
@ -430,37 +435,20 @@ public class TradeManager {
///////////////////////////////////////////////////////////////////////////////////////////
private TakerTrade takeAvailableOffer(Coin amount, Offer offer, Peer peer) {
TakerTradeProcessModel takerTradeProcessModel = createTakerTradeProcessModel(offer);
TakerTrade takerTrade = new TakerTrade(offer, amount, peer, takerTradeProcessModel, pendingTradesStorage);
TakerTrade takerTrade = new TakerTrade(offer, amount, peer, pendingTradesStorage);
takerTrade.initProcessModel(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository,
user);
pendingTrades.add(takerTrade);
takerTrade.takeAvailableOffer();
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
///////////////////////////////////////////////////////////////////////////////////////////

View file

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

View file

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

View file

@ -36,7 +36,7 @@ public class CreateOfferFeeTx extends Task<PlaceOfferModel> {
@Override
protected void doRun() {
try {
Transaction transaction = model.walletService.getTradeWalletService().createOfferFeeTx(
Transaction transaction = model.tradeWalletService.createOfferFeeTx(
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.

View file

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

View file

@ -78,8 +78,8 @@ public class OffererProtocol implements Protocol {
public void setMailboxMessage(MailboxMessage mailboxMessage) {
log.debug("setMailboxMessage " + mailboxMessage);
// Might be called twice, so check that its only processed once
if (offererTradeProcessModel.mailboxMessage == null) {
offererTradeProcessModel.mailboxMessage = mailboxMessage;
if (offererTradeProcessModel.getMailboxMessage() == null) {
offererTradeProcessModel.setMailboxMessage(mailboxMessage);
if (mailboxMessage instanceof PayoutTxPublishedMessage) {
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.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer;
@ -29,6 +30,8 @@ import io.bitsquare.user.User;
import java.io.Serializable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -44,21 +47,27 @@ public class OffererTradeProcessModel extends TradeProcessModel implements Seria
// written by tasks
private String takeOfferFeeTxId;
public OffererTradeProcessModel(Offer offer,
MessageService messageService,
MailboxService mailboxService,
WalletService walletService,
BlockChainService blockChainService,
SignatureService signatureService,
ArbitrationRepository arbitrationRepository,
User user) {
super(offer,
public OffererTradeProcessModel() {
}
public void init(@NotNull Offer offer,
@NotNull MessageService messageService,
@NotNull MailboxService mailboxService,
@NotNull WalletService walletService,
@NotNull TradeWalletService tradeWalletService,
@NotNull BlockChainService blockChainService,
@NotNull SignatureService signatureService,
@NotNull ArbitrationRepository arbitrationRepository,
@NotNull User user) {
super.init(offer,
messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository);
arbitrationRepository,
user);
offerer.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
offerer.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();

View file

@ -83,8 +83,8 @@ public class TakerProtocol implements Protocol {
public void setMailboxMessage(MailboxMessage mailboxMessage) {
log.debug("setMailboxMessage " + mailboxMessage);
// Might be called twice, so check that its only processed once
if (takerTradeProcessModel.mailboxMessage == null) {
takerTradeProcessModel.mailboxMessage = mailboxMessage;
if (takerTradeProcessModel.getMailboxMessage() == null) {
takerTradeProcessModel.setMailboxMessage(mailboxMessage);
if (mailboxMessage instanceof FiatTransferStartedMessage) {
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.
private static final long serialVersionUID = 1L;
public Offerer() {
}
// written by tasks
public byte[] tradeWalletPubKey;
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.
private static final long serialVersionUID = 1L;
public Taker() {
}
public FiatAccount fiatAccount;
public String accountId;
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.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer;
@ -31,6 +32,10 @@ import org.bitcoinj.core.Transaction;
import java.io.Serializable;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -47,24 +52,31 @@ public class TakerTradeProcessModel extends TradeProcessModel implements Seriali
public final Offerer offerer = new Offerer();
// written by tasks
private Transaction takeOfferFeeTx;
private Transaction payoutTx;
@Nullable private Transaction takeOfferFeeTx;
@Nullable private Transaction payoutTx;
public TakerTradeProcessModel(Offer offer,
MessageService messageService,
MailboxService mailboxService,
WalletService walletService,
BlockChainService blockChainService,
SignatureService signatureService,
ArbitrationRepository arbitrationRepository,
User user) {
super(offer,
public TakerTradeProcessModel(){
}
public void init(@NotNull Offer offer,
@NotNull MessageService messageService,
@NotNull MailboxService mailboxService,
@NotNull WalletService walletService,
@NotNull TradeWalletService tradeWalletService,
@NotNull BlockChainService blockChainService,
@NotNull SignatureService signatureService,
@NotNull ArbitrationRepository arbitrationRepository,
@NotNull User user) {
super.init(offer,
messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService,
arbitrationRepository);
arbitrationRepository,
user);
taker.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
taker.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();
@ -76,20 +88,22 @@ public class TakerTradeProcessModel extends TradeProcessModel implements Seriali
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() {
return takeOfferFeeTx;
}
public void setTakeOfferFeeTx(Transaction takeOfferFeeTx) {
this.takeOfferFeeTx = takeOfferFeeTx;
}
@Nullable
public Transaction getPayoutTx() {
return payoutTx;
}
public void setPayoutTx(Transaction payoutTx) {
this.payoutTx = payoutTx;
}
}