Handle data init after trade interruption

This commit is contained in:
Manfred Karrer 2015-03-27 10:53:50 +01:00
parent 4a2cb8dc7e
commit fcf9523aba
50 changed files with 236 additions and 202 deletions

View file

@ -88,7 +88,7 @@ public class ArbitrationRepository implements Serializable {
arbitratorsMap.putAll(persisted.getArbitratorsMap()); arbitratorsMap.putAll(persisted.getArbitratorsMap());
} }
arbitratorsObservableMap.putAll(arbitratorsMap); arbitratorsObservableMap.putAll(arbitratorsMap);
arbitratorsObservableMap.addListener((MapChangeListener<String, Arbitrator>) change -> storage.save()); arbitratorsObservableMap.addListener((MapChangeListener<String, Arbitrator>) change -> storage.queueUpForSave());
allArbitratorsSynced = false; allArbitratorsSynced = false;
} }

View file

@ -112,7 +112,7 @@ public class Arbitrator implements Serializable {
} }
public void save() { public void save() {
storage.save(); storage.queueUpForSave();
} }
@Override @Override

View file

@ -67,7 +67,7 @@ public class AddressEntryList extends ArrayList<AddressEntry> implements Seriali
DeterministicKey key = wallet.freshReceiveKey(); DeterministicKey key = wallet.freshReceiveKey();
AddressEntry addressEntry = new AddressEntry(key, wallet.getParams(), context, offerId); AddressEntry addressEntry = new AddressEntry(key, wallet.getParams(), context, offerId);
add(addressEntry); add(addressEntry);
storage.save(); storage.queueUpForSave();
return addressEntry; return addressEntry;
} }
@ -75,7 +75,7 @@ public class AddressEntryList extends ArrayList<AddressEntry> implements Seriali
DeterministicKey registrationKey = wallet.currentReceiveKey(); DeterministicKey registrationKey = wallet.currentReceiveKey();
AddressEntry registrationAddressEntry = new AddressEntry(registrationKey, wallet.getParams(), AddressEntry.Context.REGISTRATION_FEE); AddressEntry registrationAddressEntry = new AddressEntry(registrationKey, wallet.getParams(), AddressEntry.Context.REGISTRATION_FEE);
add(registrationAddressEntry); add(registrationAddressEntry);
storage.save(); storage.queueUpForSave();
} }
public AddressEntry getRegistrationAddressEntry() { public AddressEntry getRegistrationAddressEntry() {

View file

@ -104,7 +104,7 @@ public class Navigation implements Serializable {
currentPath = newPath; currentPath = newPath;
previousPath = currentPath; previousPath = currentPath;
storage.save(); storage.queueUpForSave();
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath)); listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
} }

View file

@ -235,7 +235,7 @@ public class FileManager<T> {
private void saveNowInternal(T serializable) throws IOException { private void saveNowInternal(T serializable) throws IOException {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
saveToFile(serializable, dir, storageFile); saveToFile(serializable, dir, storageFile);
log.info("Save completed in {}msec", System.currentTimeMillis() - now); log.info("Save {} completed in {}msec", storageFile, System.currentTimeMillis() - now);
} }
private void saveToFile(T serializable, File dir, File storageFile) throws IOException { private void saveToFile(T serializable, File dir, File storageFile) throws IOException {
@ -268,10 +268,13 @@ public class FileManager<T> {
objectOutputStream.close(); objectOutputStream.close();
renameTempFileToFile(tempFile, storageFile); renameTempFileToFile(tempFile, storageFile);
} catch (Throwable t) {
t.printStackTrace();
} finally { } finally {
if (tempFile != null && tempFile.exists()) { if (tempFile != null && tempFile.exists()) {
log.warn("Temp file still exists after failed save."); log.warn("Temp file still exists after failed save. storageFile=" + storageFile);
if (!tempFile.delete()) log.error("Cannot delete temp file."); if (!tempFile.delete())
log.error("Cannot delete temp file.");
} }
try { try {

View file

@ -20,7 +20,6 @@ package io.bitsquare.storage;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InvalidClassException; import java.io.InvalidClassException;
import java.io.Serializable; import java.io.Serializable;
@ -78,13 +77,14 @@ public class Storage<T extends Serializable> {
this.serializable = serializable; this.serializable = serializable;
this.fileName = fileName; this.fileName = fileName;
storageFile = new File(dir, fileName); storageFile = new File(dir, fileName);
fileManager = new FileManager<>(dir, storageFile, 500, TimeUnit.MILLISECONDS); fileManager = new FileManager<>(dir, storageFile, 600, TimeUnit.MILLISECONDS);
return getPersisted(serializable); return getPersisted(serializable);
} }
// Save delayed and on a background thread // Save delayed and on a background thread
public void save() { public void queueUpForSave() {
log.debug("save " + fileName);
if (storageFile == null) if (storageFile == null)
throw new RuntimeException("storageFile = null. Call setupFileStorage before using read/write."); throw new RuntimeException("storageFile = null. Call setupFileStorage before using read/write.");
@ -103,11 +103,9 @@ 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.
private T getPersisted(T serializable) { private T getPersisted(T serializable) {
if (storageFile == null) if (storageFile.exists()) {
throw new RuntimeException("storageFile = null. Call init before using read/write.");
try {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
try {
T persistedObject = (T) fileManager.read(storageFile); T persistedObject = (T) fileManager.read(storageFile);
log.info("Read {} completed in {}msec", serializable.getClass().getSimpleName(), System.currentTimeMillis() - now); log.info("Read {} completed in {}msec", serializable.getClass().getSimpleName(), System.currentTimeMillis() - now);
@ -118,7 +116,8 @@ public class Storage<T extends Serializable> {
return persistedObject; return persistedObject;
} catch (InvalidClassException e) { } catch (InvalidClassException e) {
log.error("Version of persisted class has changed. We cannot read the persisted data anymore. We make a backup and remove the inconsistent file."); log.error("Version of persisted class has changed. We cannot read the persisted data anymore. We make a backup and remove the inconsistent " +
"file.");
try { try {
// In case the persisted data have been critical (keys) we keep a backup which might be used for recovery // In case the persisted data have been critical (keys) we keep a backup which might be used for recovery
fileManager.removeAndBackupFile(fileName); fileManager.removeAndBackupFile(fileName);
@ -127,14 +126,13 @@ public class Storage<T extends Serializable> {
log.error(e1.getMessage()); log.error(e1.getMessage());
// We swallow Exception if backup fails // We swallow Exception if backup fails
} }
} catch (FileNotFoundException e) {
log.info("File not available. That is OK for the first run.");
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {
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,7 +17,13 @@
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.offerer.OffererProtocol; import io.bitsquare.trade.protocol.trade.offerer.OffererProtocol;
@ -78,7 +84,7 @@ public class OffererTrade extends Trade implements Serializable {
private Peer tradingPeer; private Peer tradingPeer;
private OffererProcessState processState; private OffererProcessState processState;
private OffererLifeCycleState lifeCycleState; private OffererLifeCycleState lifeCycleState;
private OffererTradeProcessModel offererTradeProcessModel; private OffererTradeProcessModel processModel;
transient private ObjectProperty<OffererProcessState> processStateProperty = new SimpleObjectProperty<>(); transient private ObjectProperty<OffererProcessState> processStateProperty = new SimpleObjectProperty<>();
transient private ObjectProperty<OffererLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>(); transient private ObjectProperty<OffererLifeCycleState> lifeCycleStateProperty = new SimpleObjectProperty<>();
@ -88,10 +94,10 @@ public class OffererTrade extends Trade implements Serializable {
// Constructor // Constructor
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public OffererTrade(Offer offer, OffererTradeProcessModel offererTradeProcessModel, Storage storage) { public OffererTrade(Offer offer, OffererTradeProcessModel processModel, Storage storage) {
super(offer, storage); super(offer, storage);
this.offererTradeProcessModel = offererTradeProcessModel; this.processModel = processModel;
protocol = new OffererProtocol(this); protocol = new OffererProtocol(this);
setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
} }
@ -102,17 +108,44 @@ public class OffererTrade extends Trade implements Serializable {
processStateProperty = new SimpleObjectProperty<>(processState); processStateProperty = new SimpleObjectProperty<>(processState);
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState); lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
protocol = new OffererProtocol(this); tradeAmountProperty = new SimpleObjectProperty<>();
tradeVolumeProperty = new SimpleObjectProperty<>();
if (tradeAmount != null) {
tradeAmountProperty.set(tradeAmount);
tradeVolumeProperty.set(getTradeVolume());
}
} }
public void onFiatPaymentStarted() { public void onFiatPaymentStarted() {
((OffererProtocol) protocol).onFiatPaymentStarted(); ((OffererProtocol) protocol).onFiatPaymentStarted();
} }
public OffererTradeProcessModel getOffererTradeProcessModel() { public OffererTradeProcessModel getProcessModel() {
return offererTradeProcessModel; 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

View file

@ -17,7 +17,13 @@
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.taker.TakerProtocol; import io.bitsquare.trade.protocol.trade.taker.TakerProtocol;
@ -47,8 +53,8 @@ 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 getTakerTradeProcessModel() { public TakerTradeProcessModel getProcessModel() {
return takerTradeProcessModel; return processModel;
} }
@ -81,7 +87,7 @@ public class TakerTrade extends Trade implements Serializable {
private final Coin tradeAmount; private final Coin tradeAmount;
private final Peer tradingPeer; private final Peer tradingPeer;
private final TakerTradeProcessModel takerTradeProcessModel; private TakerTradeProcessModel processModel;
private TakerProcessState processState; private TakerProcessState processState;
private TakerLifeCycleState lifeCycleState; private TakerLifeCycleState lifeCycleState;
@ -94,12 +100,12 @@ public class TakerTrade extends Trade implements Serializable {
// Constructor // Constructor
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public TakerTrade(Offer offer, Coin tradeAmount, Peer peer, TakerTradeProcessModel takerTradeProcessModel, Storage storage) { public TakerTrade(Offer offer, Coin tradeAmount, Peer peer, TakerTradeProcessModel processModel, Storage storage) {
super(offer, storage); super(offer, storage);
this.tradeAmount = tradeAmount; this.tradeAmount = tradeAmount;
this.tradingPeer = peer; this.tradingPeer = peer;
this.takerTradeProcessModel = takerTradeProcessModel; this.processModel = processModel;
protocol = new TakerProtocol(this); protocol = new TakerProtocol(this);
setLifeCycleState(TakerTrade.TakerLifeCycleState.PENDING); setLifeCycleState(TakerTrade.TakerLifeCycleState.PENDING);
@ -117,9 +123,29 @@ public class TakerTrade extends Trade implements Serializable {
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState); lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount); tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume()); tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
protocol = new TakerProtocol(this);
} }
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() {
((TakerProtocol) protocol).onFiatPaymentReceived(); ((TakerProtocol) protocol).onFiatPaymentReceived();

View file

@ -63,7 +63,6 @@ abstract public class Trade extends Model implements Serializable {
protected final Offer offer; protected final Offer offer;
protected final Date date; protected final Date date;
protected Protocol protocol;
protected Contract contract; protected Contract contract;
protected String contractAsJson; protected String contractAsJson;
protected String takerContractSignature; protected String takerContractSignature;
@ -78,7 +77,7 @@ abstract public class Trade extends Model implements Serializable {
transient protected ObjectProperty<Fiat> tradeVolumeProperty = new SimpleObjectProperty<>(); transient protected ObjectProperty<Fiat> tradeVolumeProperty = new SimpleObjectProperty<>();
transient private Storage<TakerTradeProcessModel> storage; transient private Storage<TakerTradeProcessModel> storage;
transient protected Protocol protocol;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor // Constructor
@ -91,12 +90,13 @@ abstract public class Trade extends Model implements Serializable {
date = new Date(); date = new Date();
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// 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 updateTxFromWallet(TradeWalletService tradeWalletService) { public void syncDepositTxWithWallet(TradeWalletService tradeWalletService) {
if (depositTx != null) if (depositTx != null)
setDepositTx(tradeWalletService.commitsDepositTx(depositTx)); setDepositTx(tradeWalletService.commitsDepositTx(depositTx));
} }
@ -106,20 +106,16 @@ abstract public class Trade extends Model implements Serializable {
setConfidenceListener(); setConfidenceListener();
} }
public void reActivate() {
if (mailboxMessage != null)
protocol.setMailboxMessage(mailboxMessage);
}
// Get called from taskRunner after each completed task // Get called from taskRunner after each completed task
@Override @Override
public void persist() { public void persist() {
storage.save(); storage.queueUpForSave();
} }
@Override @Override
public void onComplete() { public void onComplete() {
storage.save(); storage.queueUpForSave();
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -58,7 +58,7 @@ public class TradeList<T> extends ArrayList<T> implements Serializable {
public boolean add(T trade) { public boolean add(T trade) {
boolean result = super.add(trade); boolean result = super.add(trade);
observableList.add(trade); observableList.add(trade);
storage.save(); storage.queueUpForSave();
return result; return result;
} }
@ -66,7 +66,7 @@ public class TradeList<T> extends ArrayList<T> implements Serializable {
public boolean remove(Object trade) { public boolean remove(Object trade) {
boolean result = super.remove(trade); boolean result = super.remove(trade);
observableList.remove(trade); observableList.remove(trade);
storage.save(); storage.queueUpForSave();
return result; return result;
} }

View file

@ -85,6 +85,7 @@ public class TradeManager {
private final BlockChainService blockChainService; private final BlockChainService blockChainService;
private final WalletService walletService; private final WalletService walletService;
private final Storage pendingTradesStorage; private final Storage pendingTradesStorage;
private final Storage openOfferTradesStorage;
private TradeWalletService tradeWalletService; private TradeWalletService tradeWalletService;
private final SignatureService signatureService; private final SignatureService signatureService;
private final EncryptionService<MailboxMessage> encryptionService; private final EncryptionService<MailboxMessage> encryptionService;
@ -124,14 +125,16 @@ public class TradeManager {
this.arbitrationRepository = arbitrationRepository; this.arbitrationRepository = arbitrationRepository;
this.storageDir = storageDir; this.storageDir = storageDir;
openOfferTradesStorage = new Storage(storageDir);
pendingTradesStorage = new Storage(storageDir); pendingTradesStorage = new Storage(storageDir);
this.openOfferTrades = new TradeList<>(pendingTradesStorage, "OpenOfferTrades");
this.pendingTrades = new TradeList<>(new Storage(storageDir), "PendingTrades"); this.openOfferTrades = new TradeList<>(openOfferTradesStorage, "OpenOfferTrades");
this.pendingTrades = new TradeList<>(pendingTradesStorage, "PendingTrades");
this.closedTrades = new TradeList<>(new Storage(storageDir), "ClosedTrades"); this.closedTrades = new TradeList<>(new Storage(storageDir), "ClosedTrades");
// In case the app did get killed the shutDown from the modules is not called, so we use a shutdown hook // In case the app did get killed the shutDown from the modules is not called, so we use a shutdown hook
Thread shutDownHookThread = new Thread(TradeManager.this::shutDown, "TradeManager:ShutDownHook"); Thread shutDownHookThread = new Thread(TradeManager.this::shutDown, "TradeManager.ShutDownHook");
Runtime.getRuntime().addShutdownHook(shutDownHookThread); Runtime.getRuntime().addShutdownHook(shutDownHookThread);
} }
@ -163,17 +166,37 @@ public class TradeManager {
offerBookService.addOffer(offer, offerBookService.addOffer(offer,
() -> 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.reActivate(); offererTrade.reActivate(messageService,
mailboxService,
walletService,
tradeWalletService,
blockChainService,
signatureService);
} }
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.reActivate(); trade.syncDepositTxWithWallet(tradeWalletService);
trade.updateTxFromWallet(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(),
@ -218,7 +241,7 @@ public class TradeManager {
model, model,
(transaction) -> { (transaction) -> {
OffererTradeProcessModel processModel = createOffererTradeProcessModel(offer); OffererTradeProcessModel processModel = createOffererTradeProcessModel(offer);
OffererTrade offererTrade = new OffererTrade(offer, processModel, pendingTradesStorage); OffererTrade offererTrade = new OffererTrade(offer, processModel, openOfferTradesStorage);
openOfferTrades.add(offererTrade); openOfferTrades.add(offererTrade);
offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> { offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
@ -229,6 +252,7 @@ public class TradeManager {
(message) -> log.error(message), (message) -> log.error(message),
false); false);
pendingTrades.add(offererTrade); pendingTrades.add(offererTrade);
offererTrade.setStorage(pendingTradesStorage);
} }
}); });
@ -406,14 +430,14 @@ public class TradeManager {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
private TakerTrade takeAvailableOffer(Coin amount, Offer offer, Peer peer) { private TakerTrade takeAvailableOffer(Coin amount, Offer offer, Peer peer) {
TakerTradeProcessModel takerTradeProcessModel = createTakerProcessModel(offer); TakerTradeProcessModel takerTradeProcessModel = createTakerTradeProcessModel(offer);
TakerTrade takerTrade = new TakerTrade(offer, amount, peer, takerTradeProcessModel, pendingTradesStorage); TakerTrade takerTrade = new TakerTrade(offer, amount, peer, takerTradeProcessModel, pendingTradesStorage);
pendingTrades.add(takerTrade); pendingTrades.add(takerTrade);
return takerTrade; return takerTrade;
} }
private TakerTradeProcessModel createTakerProcessModel(Offer offer) { private TakerTradeProcessModel createTakerTradeProcessModel(Offer offer) {
return new TakerTradeProcessModel( return new TakerTradeProcessModel(
offer, offer,
messageService, messageService,
@ -433,8 +457,7 @@ public class TradeManager {
blockChainService, blockChainService,
signatureService, signatureService,
arbitrationRepository, arbitrationRepository,
user, user);
storageDir);
} }

View file

@ -40,23 +40,19 @@ 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;
public final Offer offer;
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;
transient public MailboxMessage mailboxMessage; transient public MailboxMessage mailboxMessage;
// provided
transient public final Offer offer;
transient public final MessageService messageService;
transient public final MailboxService mailboxService;
transient public final WalletService walletService;
transient public final BlockChainService blockChainService;
transient public final SignatureService signatureService;
// derived
transient public final String id;
transient public final TradeWalletService tradeWalletService;
// get set async when arbitrators are loaded from arbitratorService
transient public byte[] arbitratorPubKey;
// data written/read by tasks
transient private TradeMessage tradeMessage; transient private TradeMessage tradeMessage;
protected TradeProcessModel(Offer offer, protected TradeProcessModel(Offer offer,

View file

@ -62,9 +62,9 @@ public class OffererProtocol implements Protocol {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public OffererProtocol(OffererTrade model) { public OffererProtocol(OffererTrade model) {
log.debug("New BuyerAsOffererProtocol " + this); log.debug("New OffererProtocol " + this);
this.offererTrade = model; this.offererTrade = model;
offererTradeProcessModel = offererTrade.getOffererTradeProcessModel(); offererTradeProcessModel = offererTrade.getProcessModel();
messageHandler = this::handleMessage; messageHandler = this::handleMessage;
offererTradeProcessModel.messageService.addMessageHandler(messageHandler); offererTradeProcessModel.messageService.addMessageHandler(messageHandler);

View file

@ -34,16 +34,14 @@ 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;
// Those fields are set at constructor but not declared as final because constructor is not called in case model gets created from a persisted model public FiatAccount fiatAccount;
// Declared transient as they will be provided in any case at construction time public String accountId;
transient public FiatAccount fiatAccount; public PublicKey p2pSigPubKey;
transient public String accountId; public PublicKey p2pEncryptPubKey;
transient public PublicKey p2pSigPubKey; public byte[] registrationPubKey;
transient public PublicKey p2pEncryptPubKey;
transient public byte[] registrationPubKey;
transient public DeterministicKey registrationKeyPair; transient public DeterministicKey registrationKeyPair;
transient public AddressEntry addressEntry; public AddressEntry addressEntry;
transient public byte[] tradeWalletPubKey; public byte[] tradeWalletPubKey;
// written by tasks // written by tasks
public byte[] payoutTxSignature; public byte[] payoutTxSignature;

View file

@ -24,11 +24,9 @@ import io.bitsquare.crypto.SignatureService;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MailboxService;
import io.bitsquare.p2p.MessageService; import io.bitsquare.p2p.MessageService;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.protocol.trade.TradeProcessModel; import io.bitsquare.trade.protocol.trade.TradeProcessModel;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import java.io.File;
import java.io.Serializable; import java.io.Serializable;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -40,10 +38,8 @@ public class OffererTradeProcessModel extends TradeProcessModel implements Seria
transient private static final Logger log = LoggerFactory.getLogger(OffererTradeProcessModel.class); transient private static final Logger log = LoggerFactory.getLogger(OffererTradeProcessModel.class);
transient private Storage<OffererTradeProcessModel> storage; public final Taker taker = new Taker();
public final Offerer offerer = new Offerer();
public final Taker taker;
public final Offerer offerer;
// written by tasks // written by tasks
private String takeOfferFeeTxId; private String takeOfferFeeTxId;
@ -55,8 +51,7 @@ public class OffererTradeProcessModel extends TradeProcessModel implements Seria
BlockChainService blockChainService, BlockChainService blockChainService,
SignatureService signatureService, SignatureService signatureService,
ArbitrationRepository arbitrationRepository, ArbitrationRepository arbitrationRepository,
User user, User user) {
File storageDir) {
super(offer, super(offer,
messageService, messageService,
mailboxService, mailboxService,
@ -65,22 +60,6 @@ public class OffererTradeProcessModel extends TradeProcessModel implements Seria
signatureService, signatureService,
arbitrationRepository); arbitrationRepository);
this.storage = new Storage<>(storageDir);
OffererTradeProcessModel persisted = storage.initAndGetPersisted(this, getFileName());
if (persisted != null) {
log.debug("Model reconstructed form persisted model.");
setTakeOfferFeeTxId(persisted.takeOfferFeeTxId);
taker = persisted.taker;
offerer = persisted.offerer;
}
else {
taker = new Taker();
offerer = new Offerer();
}
offerer.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey(); offerer.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
offerer.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair(); offerer.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();
offerer.addressEntry = walletService.getAddressEntry(id); offerer.addressEntry = walletService.getAddressEntry(id);
@ -92,18 +71,6 @@ public class OffererTradeProcessModel extends TradeProcessModel implements Seria
log.debug("BuyerAsOffererModel addressEntry " + offerer.addressEntry); log.debug("BuyerAsOffererModel addressEntry " + offerer.addressEntry);
} }
// Get called form taskRunner after each completed task
@Override
public void persist() {
storage.save();
}
@Override
public void onComplete() {
// Just in case of successful completion we delete our persisted object
storage.remove(getFileName());
}
public String getTakeOfferFeeTxId() { public String getTakeOfferFeeTxId() {
return takeOfferFeeTxId; return takeOfferFeeTxId;
} }
@ -111,8 +78,4 @@ public class OffererTradeProcessModel extends TradeProcessModel implements Seria
public void setTakeOfferFeeTxId(String takeOfferFeeTxId) { public void setTakeOfferFeeTxId(String takeOfferFeeTxId) {
this.takeOfferFeeTxId = takeOfferFeeTxId; this.takeOfferFeeTxId = takeOfferFeeTxId;
} }
private String getFileName() {
return getClass().getSimpleName() + "_" + id;
}
} }

View file

@ -55,6 +55,7 @@ public class CreateAndSignPayoutTx extends OffererTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -47,6 +47,7 @@ public class CreateOffererDepositTxInputs extends OffererTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
failed(t); failed(t);

View file

@ -37,7 +37,7 @@ public class OffererTradeTask extends Task<OffererTrade> {
super(taskHandler, model); super(taskHandler, model);
offererTrade = model; offererTrade = model;
offererTradeProcessModel = offererTrade.getOffererTradeProcessModel(); offererTradeProcessModel = offererTrade.getProcessModel();
} }
@Override @Override

View file

@ -45,6 +45,7 @@ public class ProcessPayoutTxPublishedMessage extends OffererTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -46,6 +46,7 @@ public class ProcessRequestDepositTxInputsMessage extends OffererTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
failed(t); failed(t);

View file

@ -53,6 +53,7 @@ public class ProcessRequestOffererPublishDepositTxMessage extends OffererTradeTa
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
failed(t); failed(t);

View file

@ -62,6 +62,7 @@ public class RequestTakerDepositPayment extends OffererTradeTask {
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
failed(t); failed(t);

View file

@ -61,6 +61,7 @@ public class SendBankTransferStartedMessage extends OffererTradeTask {
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -53,6 +53,7 @@ public class SendDepositTxToTaker extends OffererTradeTask {
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -65,12 +65,14 @@ public class SignAndPublishDepositTx extends OffererTradeTask {
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
failed(t); failed(t);
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
failed(t); failed(t);

View file

@ -55,6 +55,7 @@ public class VerifyAndSignContract extends OffererTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
failed(t); failed(t);

View file

@ -41,6 +41,7 @@ public class VerifyTakeOfferFeePayment extends OffererTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -49,6 +49,7 @@ public class VerifyTakerAccount extends OffererTradeTask {
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
} }
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
offererTrade.setThrowable(t); offererTrade.setThrowable(t);
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN); offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
failed(t); failed(t);

View file

@ -64,7 +64,7 @@ public class TakerProtocol implements Protocol {
public TakerProtocol(TakerTrade takerTrade) { public TakerProtocol(TakerTrade takerTrade) {
log.debug("New SellerAsTakerProtocol " + this); log.debug("New SellerAsTakerProtocol " + this);
this.takerTrade = takerTrade; this.takerTrade = takerTrade;
takerTradeProcessModel = takerTrade.getTakerTradeProcessModel(); takerTradeProcessModel = takerTrade.getProcessModel();
messageHandler = this::handleMessage; messageHandler = this::handleMessage;
takerTradeProcessModel.messageService.addMessageHandler(messageHandler); takerTradeProcessModel.messageService.addMessageHandler(messageHandler);

View file

@ -35,16 +35,14 @@ 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;
// Those fields are set at constructor but not declared as final because constructor is not called in case model gets created from a persisted model public FiatAccount fiatAccount;
// Declared transient as they will be provided in any case at construction time public String accountId;
transient public FiatAccount fiatAccount; public PublicKey p2pSigPubKey;
transient public String accountId; public PublicKey p2pEncryptPublicKey;
transient public PublicKey p2pSigPubKey; public byte[] registrationPubKey; // TODO not read yet, missing impl.
transient public PublicKey p2pEncryptPublicKey;
transient public byte[] registrationPubKey; // TODO not read yet, missing impl.
transient public DeterministicKey registrationKeyPair; transient public DeterministicKey registrationKeyPair;
transient public AddressEntry addressEntry; public AddressEntry addressEntry;
transient public byte[] tradeWalletPubKey; public byte[] tradeWalletPubKey;
// written by tasks // written by tasks
public List<TransactionOutput> connectedOutputsForAllInputs; public List<TransactionOutput> connectedOutputsForAllInputs;

View file

@ -66,22 +66,6 @@ public class TakerTradeProcessModel extends TradeProcessModel implements Seriali
signatureService, signatureService,
arbitrationRepository); arbitrationRepository);
/*TakerProcessModel persisted = storage.initAndGetPersisted(this, getFileName());
if (persisted != null) {
log.debug("Model reconstructed from persisted model.");
setTakeOfferFeeTx(persisted.getTakeOfferFeeTx());
setPayoutTx(persisted.payoutTx);
taker = persisted.taker;
offerer = persisted.offerer;
}
else {
taker = new Taker();
offerer = new Offerer();
}*/
taker.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey(); taker.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
taker.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair(); taker.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();
taker.addressEntry = walletService.getAddressEntry(id); taker.addressEntry = walletService.getAddressEntry(id);
@ -92,18 +76,6 @@ public class TakerTradeProcessModel extends TradeProcessModel implements Seriali
taker.tradeWalletPubKey = taker.addressEntry.getPubKey(); taker.tradeWalletPubKey = taker.addressEntry.getPubKey();
} }
// Get called form taskRunner after each completed task
/* @Override
public void persist() {
storage.save();
}
@Override
public void onComplete() {
// Just in case of successful completion we delete our persisted object
storage.remove(getFileName());
}*/
public Transaction getTakeOfferFeeTx() { public Transaction getTakeOfferFeeTx() {
return takeOfferFeeTx; return takeOfferFeeTx;
} }
@ -120,8 +92,4 @@ public class TakerTradeProcessModel extends TradeProcessModel implements Seriali
this.payoutTx = payoutTx; this.payoutTx = payoutTx;
} }
/*private String getFileName() {
return getClass().getSimpleName() + "_" + id;
}*/
} }

View file

@ -52,6 +52,7 @@ public class BroadcastTakeOfferFeeTx extends TakerTradeTask {
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
t.printStackTrace();
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again."); appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again.");
takerTrade.setErrorMessage(errorMessage); takerTrade.setErrorMessage(errorMessage);
takerTrade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED); takerTrade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED);
@ -60,6 +61,7 @@ public class BroadcastTakeOfferFeeTx extends TakerTradeTask {
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -54,6 +54,7 @@ public class CreateAndSignContract extends TakerTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -42,6 +42,7 @@ public class CreateTakeOfferFeeTx extends TakerTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -45,6 +45,7 @@ public class ProcessDepositTxPublishedMessage extends TakerTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -48,6 +48,7 @@ public class ProcessFiatTransferStartedMessage extends TakerTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -51,6 +51,7 @@ public class ProcessRequestTakerDepositPaymentMessage extends TakerTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -56,6 +56,7 @@ public class SendPayoutTxToOfferer extends TakerTradeTask {
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -74,6 +74,7 @@ public class SendRequestDepositTxInputsMessage extends TakerTradeTask {
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -65,6 +65,7 @@ public class SendSignedTakerDepositTx extends TakerTradeTask {
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -60,11 +60,13 @@ public class SignAndPublishPayoutTx extends TakerTradeTask {
@Override @Override
public void onFailure(@NotNull Throwable t) { public void onFailure(@NotNull Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }
}); });
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -42,6 +42,7 @@ public class TakerCommitDepositTx extends TakerTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -57,6 +57,7 @@ public class TakerCreatesAndSignsDepositTx extends TakerTradeTask {
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -37,7 +37,7 @@ public class TakerTradeTask extends Task<TakerTrade> {
super(taskHandler, model); super(taskHandler, model);
takerTrade = model; takerTrade = model;
takerTradeProcessModel = takerTrade.getTakerTradeProcessModel(); takerTradeProcessModel = takerTrade.getProcessModel();
} }
@Override @Override

View file

@ -40,6 +40,7 @@ public class VerifyOfferFeePayment extends TakerTradeTask {
}*/ }*/
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -34,7 +34,8 @@ public class VerifyOffererAccount extends TakerTradeTask {
protected void doRun() { protected void doRun() {
try { try {
if (takerTradeProcessModel.blockChainService.verifyAccountRegistration()) { if (takerTradeProcessModel.blockChainService.verifyAccountRegistration()) {
if (takerTradeProcessModel.blockChainService.isAccountBlackListed(takerTradeProcessModel.offerer.accountId, takerTradeProcessModel.offerer.fiatAccount)) { if (takerTradeProcessModel.blockChainService.isAccountBlackListed(takerTradeProcessModel.offerer.accountId, takerTradeProcessModel.offerer
.fiatAccount)) {
failed("Taker is blacklisted."); failed("Taker is blacklisted.");
} }
else { else {
@ -45,6 +46,7 @@ public class VerifyOffererAccount extends TakerTradeTask {
failed("Account registration validation for peer faultHandler.onFault."); failed("Account registration validation for peer faultHandler.onFault.");
} }
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace();
takerTrade.setThrowable(t); takerTrade.setThrowable(t);
failed(t); failed(t);
} }

View file

@ -78,7 +78,7 @@ public class AccountSettings implements Serializable {
public void addAcceptedLanguageLocale(String localeCode) { public void addAcceptedLanguageLocale(String localeCode) {
if (!acceptedLanguageLocaleCodes.contains(localeCode)) { if (!acceptedLanguageLocaleCodes.contains(localeCode)) {
acceptedLanguageLocaleCodes.add(localeCode); acceptedLanguageLocaleCodes.add(localeCode);
storage.save(); storage.queueUpForSave();
} }
} }
@ -89,7 +89,7 @@ public class AccountSettings implements Serializable {
public void addAcceptedCountry(Country locale) { public void addAcceptedCountry(Country locale) {
if (!acceptedCountryLocales.contains(locale)) { if (!acceptedCountryLocales.contains(locale)) {
acceptedCountryLocales.add(locale); acceptedCountryLocales.add(locale);
storage.save(); storage.queueUpForSave();
} }
} }
@ -100,13 +100,13 @@ public class AccountSettings implements Serializable {
public void addAcceptedArbitrator(Arbitrator arbitrator) { public void addAcceptedArbitrator(Arbitrator arbitrator) {
if (!acceptedArbitrators.contains(arbitrator)) { if (!acceptedArbitrators.contains(arbitrator)) {
acceptedArbitrators.add(arbitrator); acceptedArbitrators.add(arbitrator);
storage.save(); storage.queueUpForSave();
} }
} }
public void removeAcceptedArbitrator(Arbitrator item) { public void removeAcceptedArbitrator(Arbitrator item) {
acceptedArbitrators.remove(item); acceptedArbitrators.remove(item);
storage.save(); storage.queueUpForSave();
} }

View file

@ -81,15 +81,15 @@ public class Preferences implements Serializable {
// Use that to guarantee update of the serializable field and to make a storage update in case of a change // Use that to guarantee update of the serializable field and to make a storage update in case of a change
btcDenominationProperty.addListener((ov) -> { btcDenominationProperty.addListener((ov) -> {
btcDenomination = btcDenominationProperty.get(); btcDenomination = btcDenominationProperty.get();
storage.save(); storage.queueUpForSave();
}); });
useAnimationsProperty.addListener((ov) -> { useAnimationsProperty.addListener((ov) -> {
useAnimations = useAnimationsProperty.get(); useAnimations = useAnimationsProperty.get();
storage.save(); storage.queueUpForSave();
}); });
useEffectsProperty.addListener((ov) -> { useEffectsProperty.addListener((ov) -> {
useEffects = useEffectsProperty.get(); useEffects = useEffectsProperty.get();
storage.save(); storage.queueUpForSave();
}); });
} }
@ -112,7 +112,7 @@ public class Preferences implements Serializable {
public void setDisplaySecurityDepositInfo(Boolean displaySecurityDepositInfo) { public void setDisplaySecurityDepositInfo(Boolean displaySecurityDepositInfo) {
this.displaySecurityDepositInfo = displaySecurityDepositInfo; this.displaySecurityDepositInfo = displaySecurityDepositInfo;
storage.save(); storage.queueUpForSave();
} }

View file

@ -98,15 +98,15 @@ public class User implements Serializable {
Throwables.propagate(e); Throwables.propagate(e);
} }
} }
storage.save(); storage.queueUpForSave();
// Use that to guarantee update of the serializable field and to make a storage update in case of a change // Use that to guarantee update of the serializable field and to make a storage update in case of a change
fiatAccountsObservableList.addListener((ListChangeListener<FiatAccount>) change -> { fiatAccountsObservableList.addListener((ListChangeListener<FiatAccount>) change -> {
fiatAccounts = new ArrayList<>(fiatAccountsObservableList); fiatAccounts = new ArrayList<>(fiatAccountsObservableList);
storage.save(); storage.queueUpForSave();
}); });
currentFiatAccountProperty.addListener((ov) -> { currentFiatAccountProperty.addListener((ov) -> {
currentFiatAccount = currentFiatAccountProperty.get(); currentFiatAccount = currentFiatAccountProperty.get();
storage.save(); storage.queueUpForSave();
}); });
} }
@ -153,7 +153,7 @@ public class User implements Serializable {
// Public key from the input for the registration payment tx (or address) will be used // Public key from the input for the registration payment tx (or address) will be used
public void setAccountID(String accountID) { public void setAccountID(String accountID) {
this.accountID = accountID; this.accountID = accountID;
storage.save(); storage.queueUpForSave();
} }
public void setCurrentFiatAccountProperty(@Nullable FiatAccount fiatAccount) { public void setCurrentFiatAccountProperty(@Nullable FiatAccount fiatAccount) {

View file

@ -29,6 +29,8 @@
</root> </root>
<logger name="io.bitsquare" level="TRACE"/> <logger name="io.bitsquare" level="TRACE"/>
<logger name="io.bitsquare.btc.AddressBasedCoinSelector" level="OFF"/>
<logger name="io.bitsquare.gui.util.Profiler" level="ERROR"/> <logger name="io.bitsquare.gui.util.Profiler" level="ERROR"/>
<!-- <logger name="io.bitsquare.persistence.Persistence" level="ERROR"/>--> <!-- <logger name="io.bitsquare.persistence.Persistence" level="ERROR"/>-->
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/> <logger name="io.bitsquare.locale.BSResources" level="ERROR"/>