mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-02 19:56:23 -04:00
Remove listeners/unbind at views. Add more error handling
This commit is contained in:
parent
919e31f0d5
commit
3f6f8dd160
90 changed files with 1940 additions and 1610 deletions
|
@ -23,8 +23,7 @@ import org.slf4j.LoggerFactory;
|
|||
public abstract class Task<T extends Model> {
|
||||
private static final Logger log = LoggerFactory.getLogger(Task.class);
|
||||
|
||||
public static Class<? extends Task> taskToInterceptBeforeRun;
|
||||
public static Class<? extends Task> taskToInterceptAfterRun;
|
||||
public static Class<? extends Task> taskToIntercept;
|
||||
|
||||
private final TaskRunner taskHandler;
|
||||
protected final T model;
|
||||
|
@ -35,26 +34,11 @@ public abstract class Task<T extends Model> {
|
|||
this.model = model;
|
||||
}
|
||||
|
||||
protected void run() {
|
||||
try {
|
||||
interceptBeforeRun();
|
||||
doRun();
|
||||
} catch (Throwable t) {
|
||||
appendExceptionToErrorMessage(t);
|
||||
failed();
|
||||
}
|
||||
}
|
||||
abstract protected void run();
|
||||
|
||||
abstract protected void doRun();
|
||||
|
||||
private void interceptBeforeRun() {
|
||||
if (getClass() == taskToInterceptBeforeRun)
|
||||
throw new InterceptTaskException("Task intercepted before run got executed. Task = " + getClass().getSimpleName());
|
||||
}
|
||||
|
||||
private void interceptBeforeComplete() {
|
||||
if (getClass() == taskToInterceptAfterRun)
|
||||
throw new InterceptTaskException("Task intercepted before complete was called. Task = " + getClass().getSimpleName());
|
||||
protected void runInterceptHook() {
|
||||
if (getClass() == taskToIntercept)
|
||||
throw new InterceptTaskException("Task intercepted for testing purpose. Task = " + getClass().getSimpleName());
|
||||
}
|
||||
|
||||
protected void appendToErrorMessage(String message) {
|
||||
|
@ -69,12 +53,6 @@ public abstract class Task<T extends Model> {
|
|||
}
|
||||
|
||||
protected void complete() {
|
||||
try {
|
||||
interceptBeforeComplete();
|
||||
} catch (Throwable t) {
|
||||
appendExceptionToErrorMessage(t);
|
||||
failed();
|
||||
}
|
||||
taskHandler.handleComplete();
|
||||
}
|
||||
|
||||
|
@ -84,6 +62,7 @@ public abstract class Task<T extends Model> {
|
|||
}
|
||||
|
||||
protected void failed(Throwable t) {
|
||||
t.printStackTrace();
|
||||
appendExceptionToErrorMessage(t);
|
||||
failed();
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@ import com.google.common.base.Throwables;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidClassException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.Serializable;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -131,7 +129,7 @@ public class Storage<T extends Serializable> {
|
|||
log.info("Backup {} completed in {}msec", serializable.getClass().getSimpleName(), System.currentTimeMillis() - now);
|
||||
|
||||
return persistedObject;
|
||||
} catch (InvalidClassException | InvalidObjectException | ClassCastException | ClassNotFoundException e) {
|
||||
} catch (ClassCastException | ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error("Version of persisted class has changed. We cannot read the persisted data anymore. We make a backup and remove the inconsistent " +
|
||||
"file.");
|
||||
|
|
|
@ -33,6 +33,8 @@ import io.bitsquare.storage.Storage;
|
|||
import io.bitsquare.trade.offer.Offer;
|
||||
import io.bitsquare.trade.protocol.trade.ProcessModel;
|
||||
import io.bitsquare.trade.protocol.trade.TradeProtocol;
|
||||
import io.bitsquare.trade.states.BuyerTradeState;
|
||||
import io.bitsquare.trade.states.SellerTradeState;
|
||||
import io.bitsquare.trade.states.TradeState;
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
|
@ -245,6 +247,13 @@ abstract public class Trade implements Tradable, Model, Serializable {
|
|||
storage.queueUpForSave();
|
||||
}
|
||||
|
||||
public void setFaultState() {
|
||||
if (this instanceof SellerTrade)
|
||||
setProcessState(SellerTradeState.ProcessState.FAULT);
|
||||
else if (this instanceof BuyerTrade)
|
||||
setProcessState(BuyerTradeState.ProcessState.FAULT);
|
||||
}
|
||||
|
||||
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) {
|
||||
this.lifeCycleState = lifeCycleState;
|
||||
lifeCycleStateProperty.set(lifeCycleState);
|
||||
|
|
|
@ -59,7 +59,10 @@ public class Offer implements Serializable {
|
|||
AVAILABLE,
|
||||
NOT_AVAILABLE,
|
||||
REMOVED,
|
||||
OFFERER_OFFLINE
|
||||
OFFERER_OFFLINE,
|
||||
|
||||
TIMEOUT,
|
||||
FAULT
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import io.bitsquare.p2p.DHTService;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javafx.beans.property.LongProperty;
|
||||
import javafx.beans.property.ReadOnlyLongProperty;
|
||||
|
||||
public interface OfferBookService extends DHTService {
|
||||
|
||||
|
@ -39,7 +39,7 @@ public interface OfferBookService extends DHTService {
|
|||
|
||||
void removeListener(Listener listener);
|
||||
|
||||
LongProperty invalidationTimestampProperty();
|
||||
ReadOnlyLongProperty invalidationTimestampProperty();
|
||||
|
||||
void requestInvalidationTimeStampFromDHT(String fiatCode);
|
||||
|
||||
|
|
|
@ -21,14 +21,12 @@ import io.bitsquare.app.Version;
|
|||
import io.bitsquare.storage.Storage;
|
||||
import io.bitsquare.trade.Tradable;
|
||||
import io.bitsquare.trade.TradableList;
|
||||
|
||||
import org.bitcoinj.utils.Threading;
|
||||
import io.bitsquare.util.Utilities;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -95,26 +93,16 @@ public class OpenOffer implements Tradable, Serializable {
|
|||
|
||||
|
||||
private void startTimeout() {
|
||||
log.trace("startTimeout");
|
||||
stopTimeout();
|
||||
|
||||
timeoutTimer = new Timer();
|
||||
TimerTask task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
Threading.USER_THREAD.execute(() -> {
|
||||
log.debug("Timeout reached");
|
||||
if (state == State.RESERVED)
|
||||
setState(State.AVAILABLE);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
timeoutTimer.schedule(task, TIMEOUT);
|
||||
timeoutTimer = Utilities.setTimeout(TIMEOUT, () -> {
|
||||
log.debug("Timeout reached");
|
||||
if (state == State.RESERVED)
|
||||
setState(State.AVAILABLE);
|
||||
});
|
||||
}
|
||||
|
||||
protected void stopTimeout() {
|
||||
log.trace("stopTimeout");
|
||||
if (timeoutTimer != null) {
|
||||
timeoutTimer.cancel();
|
||||
timeoutTimer = null;
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.Map;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import javafx.beans.property.LongProperty;
|
||||
import javafx.beans.property.ReadOnlyLongProperty;
|
||||
import javafx.beans.property.SimpleLongProperty;
|
||||
|
||||
import net.tomp2p.dht.FutureGet;
|
||||
|
@ -220,7 +221,7 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
|
|||
if (offerDataObject instanceof Offer) {
|
||||
offers.add((Offer) offerDataObject);
|
||||
}
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
} catch (ClassCastException | ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
log.warn(e.getMessage());
|
||||
}
|
||||
|
@ -293,7 +294,7 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
|
|||
}
|
||||
}
|
||||
|
||||
public LongProperty invalidationTimestampProperty() {
|
||||
public ReadOnlyLongProperty invalidationTimestampProperty() {
|
||||
return invalidationTimestamp;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,11 +30,9 @@ import io.bitsquare.trade.protocol.availability.messages.OfferMessage;
|
|||
import io.bitsquare.trade.protocol.availability.tasks.GetPeerAddress;
|
||||
import io.bitsquare.trade.protocol.availability.tasks.ProcessOfferAvailabilityResponse;
|
||||
import io.bitsquare.trade.protocol.availability.tasks.SendOfferAvailabilityRequest;
|
||||
|
||||
import org.bitcoinj.utils.Threading;
|
||||
import io.bitsquare.util.Utilities;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -52,7 +50,6 @@ public class OfferAvailabilityProtocol {
|
|||
private final DecryptedMessageHandler decryptedMessageHandler;
|
||||
private Timer timeoutTimer;
|
||||
|
||||
private boolean isCanceled;
|
||||
private TaskRunner<OfferAvailabilityModel> taskRunner;
|
||||
|
||||
|
||||
|
@ -84,8 +81,14 @@ public class OfferAvailabilityProtocol {
|
|||
model.messageService.addDecryptedMessageHandler(decryptedMessageHandler);
|
||||
|
||||
taskRunner = new TaskRunner<>(model,
|
||||
() -> log.debug("sequence at onCheckOfferAvailability completed"),
|
||||
log::error
|
||||
() -> {
|
||||
log.debug("sequence at onCheckOfferAvailability completed");
|
||||
stopTimeout();
|
||||
},
|
||||
(errorMessage) -> {
|
||||
log.error(errorMessage);
|
||||
stopTimeout();
|
||||
}
|
||||
);
|
||||
taskRunner.addTasks(
|
||||
GetPeerAddress.class,
|
||||
|
@ -96,7 +99,6 @@ public class OfferAvailabilityProtocol {
|
|||
}
|
||||
|
||||
public void cancel() {
|
||||
isCanceled = true;
|
||||
taskRunner.cancel();
|
||||
cleanup();
|
||||
}
|
||||
|
@ -119,15 +121,18 @@ public class OfferAvailabilityProtocol {
|
|||
|
||||
private void handle(OfferAvailabilityResponse message) {
|
||||
stopTimeout();
|
||||
startTimeout();
|
||||
model.setMessage(message);
|
||||
|
||||
taskRunner = new TaskRunner<>(model,
|
||||
() -> {
|
||||
log.debug("sequence at handleReportOfferAvailabilityMessage completed");
|
||||
log.debug("sequence at handle OfferAvailabilityResponse completed");
|
||||
stopTimeout();
|
||||
resultHandler.handleResult();
|
||||
},
|
||||
(errorMessage) -> {
|
||||
log.error(errorMessage);
|
||||
stopTimeout();
|
||||
errorMessageHandler.handleErrorMessage(errorMessage);
|
||||
}
|
||||
);
|
||||
|
@ -136,26 +141,16 @@ public class OfferAvailabilityProtocol {
|
|||
}
|
||||
|
||||
protected void startTimeout() {
|
||||
log.debug("startTimeout");
|
||||
stopTimeout();
|
||||
|
||||
timeoutTimer = new Timer();
|
||||
TimerTask task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
Threading.USER_THREAD.execute(() -> {
|
||||
log.debug("Timeout reached");
|
||||
errorMessageHandler.handleErrorMessage("Timeout reached: Peer has not responded.");
|
||||
model.offer.setState(Offer.State.OFFERER_OFFLINE);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
timeoutTimer.schedule(task, TIMEOUT);
|
||||
timeoutTimer = Utilities.setTimeout(TIMEOUT, () -> {
|
||||
log.warn("Timeout reached");
|
||||
errorMessageHandler.handleErrorMessage("Timeout reached: Peer has not responded.");
|
||||
model.offer.setState(Offer.State.TIMEOUT);
|
||||
});
|
||||
}
|
||||
|
||||
protected void stopTimeout() {
|
||||
log.debug("stopTimeout");
|
||||
if (timeoutTimer != null) {
|
||||
timeoutTimer.cancel();
|
||||
timeoutTimer = null;
|
||||
|
|
|
@ -37,13 +37,13 @@ public class GetPeerAddress extends Task<OfferAvailabilityModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
model.addressService.findPeerAddress(model.offer.getPubKeyRing(), new GetPeerAddressListener() {
|
||||
@Override
|
||||
public void onResult(Peer peer) {
|
||||
model.setPeer(peer);
|
||||
|
||||
complete();
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@ public class GetPeerAddress extends Task<OfferAvailabilityModel> {
|
|||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
model.offer.setState(Offer.State.FAULT);
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,9 @@ public class ProcessOfferAvailabilityResponse extends Task<OfferAvailabilityMode
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
OfferAvailabilityResponse offerAvailabilityResponse = (OfferAvailabilityResponse) model.getMessage();
|
||||
|
||||
if (model.offer.getState() != Offer.State.REMOVED) {
|
||||
|
@ -47,6 +48,7 @@ public class ProcessOfferAvailabilityResponse extends Task<OfferAvailabilityMode
|
|||
|
||||
complete();
|
||||
} catch (Throwable t) {
|
||||
model.offer.setState(Offer.State.FAULT);
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,8 +35,9 @@ public class SendOfferAvailabilityRequest extends Task<OfferAvailabilityModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
OfferAvailabilityRequest message = new OfferAvailabilityRequest(model.offer.getId(), model.getPubKeyRing());
|
||||
model.messageService.sendEncryptedMessage(model.getPeer(),
|
||||
model.offer.getPubKeyRing(),
|
||||
|
@ -55,6 +56,7 @@ public class SendOfferAvailabilityRequest extends Task<OfferAvailabilityModel> {
|
|||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
model.offer.setState(Offer.State.FAULT);
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public class PlaceOfferModel implements Model {
|
|||
public final WalletService walletService;
|
||||
public final TradeWalletService tradeWalletService;
|
||||
public final OfferBookService offerBookService;
|
||||
|
||||
public boolean offerAddedToOfferBook;
|
||||
private Transaction transaction;
|
||||
|
||||
public PlaceOfferModel(Offer offer,
|
||||
|
|
|
@ -61,6 +61,15 @@ public class PlaceOfferProtocol {
|
|||
},
|
||||
(errorMessage) -> {
|
||||
log.error(errorMessage);
|
||||
|
||||
if (model.offerAddedToOfferBook) {
|
||||
model.offerBookService.removeOffer(model.offer,
|
||||
() -> {
|
||||
model.offerAddedToOfferBook = false;
|
||||
log.debug("Offer removed from offer book.");
|
||||
},
|
||||
(message, throwable) -> log.error(message));
|
||||
}
|
||||
errorMessageHandler.handleErrorMessage(errorMessage);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -33,9 +33,17 @@ public class AddOfferToRemoteOfferBook extends Task<PlaceOfferModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
model.offerBookService.addOffer(model.offer,
|
||||
this::complete,
|
||||
(message, throwable) -> failed(throwable));
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
model.offerBookService.addOffer(model.offer,
|
||||
() -> {
|
||||
model.offerAddedToOfferBook = true;
|
||||
complete();
|
||||
},
|
||||
(message, throwable) -> failed(throwable));
|
||||
} catch (Throwable t) {
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,58 +47,61 @@ public class BroadcastCreateOfferFeeTx extends Task<PlaceOfferModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
Coin totalsNeeded = model.offer.getSecurityDeposit().add(FeePolicy.CREATE_OFFER_FEE).add(FeePolicy.TX_FEE);
|
||||
AddressEntry addressEntry = model.walletService.getAddressEntry(model.offer.getId());
|
||||
Coin balance = model.walletService.getBalanceForAddress(addressEntry.getAddress());
|
||||
if (balance.compareTo(totalsNeeded) >= 0) {
|
||||
model.tradeWalletService.broadcastTx(model.getTransaction(), new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(Transaction transaction) {
|
||||
log.info("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString());
|
||||
|
||||
Coin totalsNeeded = model.offer.getSecurityDeposit().add(FeePolicy.CREATE_OFFER_FEE).add(FeePolicy.TX_FEE);
|
||||
AddressEntry addressEntry = model.walletService.getAddressEntry(model.offer.getId());
|
||||
Coin balance = model.walletService.getBalanceForAddress(addressEntry.getAddress());
|
||||
if (balance.compareTo(totalsNeeded) >= 0) {
|
||||
|
||||
model.tradeWalletService.broadcastTx(model.getTransaction(), new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(Transaction transaction) {
|
||||
log.info("Broadcast of offer fee payment succeeded: transaction = " + transaction.toString());
|
||||
|
||||
if (model.getTransaction().getHashAsString().equals(transaction.getHashAsString())) {
|
||||
// No tx malleability happened after broadcast (still not in blockchain)
|
||||
complete();
|
||||
if (model.getTransaction().getHashAsString().equals(transaction.getHashAsString())) {
|
||||
// No tx malleability happened after broadcast (still not in blockchain)
|
||||
complete();
|
||||
}
|
||||
else {
|
||||
log.warn("Tx malleability happened after broadcast. We publish the changed offer to the DHT again.");
|
||||
// Tx malleability happened after broadcast. We publish the changed offer to the DHT again.
|
||||
model.offerBookService.removeOffer(model.offer,
|
||||
() -> {
|
||||
log.info("We store now the changed txID to the offer and add that again.");
|
||||
// We store now the changed txID to the offer and add that again.
|
||||
model.offer.setOfferFeePaymentTxID(transaction.getHashAsString());
|
||||
model.offerBookService.addOffer(model.offer,
|
||||
BroadcastCreateOfferFeeTx.this::complete,
|
||||
(message, throwable) -> {
|
||||
log.error("addOffer failed");
|
||||
addOfferFailed = true;
|
||||
failed(throwable);
|
||||
updateStateOnFault();
|
||||
});
|
||||
},
|
||||
(message, throwable) -> {
|
||||
log.error("removeOffer failed");
|
||||
removeOfferFailed = true;
|
||||
failed(throwable);
|
||||
updateStateOnFault();
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("Tx malleability happened after broadcast. We publish the changed offer to the DHT again.");
|
||||
// Tx malleability happened after broadcast. We publish the changed offer to the DHT again.
|
||||
model.offerBookService.removeOffer(model.offer,
|
||||
() -> {
|
||||
log.info("We store now the changed txID to the offer and add that again.");
|
||||
// We store now the changed txID to the offer and add that again.
|
||||
model.offer.setOfferFeePaymentTxID(transaction.getHashAsString());
|
||||
model.offerBookService.addOffer(model.offer,
|
||||
BroadcastCreateOfferFeeTx.this::complete,
|
||||
(message, throwable) -> {
|
||||
log.error("addOffer failed");
|
||||
addOfferFailed = true;
|
||||
failed(throwable);
|
||||
updateStateOnFault();
|
||||
});
|
||||
},
|
||||
(message, throwable) -> {
|
||||
log.error("removeOffer failed");
|
||||
removeOfferFailed = true;
|
||||
failed(throwable);
|
||||
updateStateOnFault();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
failed(t);
|
||||
updateStateOnFault();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
failed("Not enough balance for placing the offer.");
|
||||
updateStateOnFault();
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
failed(t);
|
||||
updateStateOnFault();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
failed("Not enough balance for placing the offer.");
|
||||
updateStateOnFault();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,9 @@ public class CreateOfferFeeTx extends Task<PlaceOfferModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
Transaction transaction = model.tradeWalletService.createOfferFeeTx(
|
||||
model.walletService.getAddressEntry(model.offer.getId()));
|
||||
|
||||
|
|
|
@ -32,8 +32,9 @@ public class ValidateOffer extends Task<PlaceOfferModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
model.offer.validate();
|
||||
|
||||
complete();
|
||||
|
|
|
@ -102,8 +102,8 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
|
|||
CreateDepositTxInputs.class,
|
||||
SendPayDepositRequest.class
|
||||
);
|
||||
taskRunner.run();
|
||||
startTimeout();
|
||||
taskRunner.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -116,8 +116,8 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
|
|||
CreateDepositTxInputs.class,
|
||||
SendPayDepositRequest.class
|
||||
);
|
||||
taskRunner.run();
|
||||
startTimeout();
|
||||
taskRunner.run();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -100,8 +100,8 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
|
|||
CreateAndSignDepositTx.class,
|
||||
SendPublishDepositTxRequest.class
|
||||
);
|
||||
taskRunner.run();
|
||||
startTimeout();
|
||||
taskRunner.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -128,8 +128,8 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
|
|||
BroadcastTakeOfferFeeTx.class,
|
||||
SendDepositTxInputsRequest.class
|
||||
);
|
||||
taskRunner.run();
|
||||
startTimeout();
|
||||
taskRunner.run();
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,8 +153,8 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
|
|||
CreateAndSignDepositTx.class,
|
||||
SendPublishDepositTxRequest.class
|
||||
);
|
||||
taskRunner.run();
|
||||
startTimeout();
|
||||
taskRunner.run();
|
||||
}
|
||||
|
||||
private void handle(DepositTxPublishedMessage tradeMessage) {
|
||||
|
|
|
@ -32,11 +32,9 @@ import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
|
|||
import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener;
|
||||
import io.bitsquare.trade.states.BuyerTradeState;
|
||||
import io.bitsquare.trade.states.SellerTradeState;
|
||||
|
||||
import org.bitcoinj.utils.Threading;
|
||||
import io.bitsquare.util.Utilities;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -141,28 +139,18 @@ public abstract class TradeProtocol {
|
|||
}
|
||||
|
||||
protected void startTimeout() {
|
||||
log.debug("startTimeout");
|
||||
stopTimeout();
|
||||
|
||||
timeoutTimer = new Timer();
|
||||
TimerTask task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
Threading.USER_THREAD.execute(() -> {
|
||||
log.debug("Timeout reached");
|
||||
/* if (trade instanceof SellerTrade)
|
||||
trade.setProcessState(SellerTradeState.ProcessState.TIMEOUT);
|
||||
else if (trade instanceof BuyerTrade)
|
||||
trade.setProcessState(BuyerTradeState.ProcessState.TIMEOUT);*/
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
timeoutTimer.schedule(task, TIMEOUT);
|
||||
timeoutTimer = Utilities.setTimeout(TIMEOUT, () -> {
|
||||
log.debug("Timeout reached");
|
||||
if (trade instanceof SellerTrade)
|
||||
trade.setProcessState(SellerTradeState.ProcessState.TIMEOUT);
|
||||
else if (trade instanceof BuyerTrade)
|
||||
trade.setProcessState(BuyerTradeState.ProcessState.TIMEOUT);
|
||||
});
|
||||
}
|
||||
|
||||
protected void stopTimeout() {
|
||||
log.debug("stopTimeout");
|
||||
if (timeoutTimer != null) {
|
||||
timeoutTimer.cancel();
|
||||
timeoutTimer = null;
|
||||
|
|
|
@ -38,6 +38,16 @@ public class TradeTask extends Task<Trade> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void failed(Throwable t) {
|
||||
t.printStackTrace();
|
||||
appendExceptionToErrorMessage(t);
|
||||
trade.setThrowable(t);
|
||||
trade.setErrorMessage(errorMessage);
|
||||
trade.setFaultState();
|
||||
failed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,9 @@ public class CreateDepositTxInputs extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
log.debug("trade.id" + trade.getId());
|
||||
Coin inputAmount = trade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||
TradeWalletService.Result result = processModel.getTradeWalletService().createDepositTxInputs(inputAmount,
|
||||
|
|
|
@ -37,8 +37,9 @@ public class ProcessDepositTxInputsRequest extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
DepositTxInputsRequest message = (DepositTxInputsRequest) processModel.getTradeMessage();
|
||||
checkTradeId(processModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
|
|
@ -38,8 +38,9 @@ public class ProcessFinalizePayoutTxRequest extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
FinalizePayoutTxRequest message = (FinalizePayoutTxRequest) processModel.getTradeMessage();
|
||||
checkTradeId(processModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
|
|
@ -37,8 +37,9 @@ public class ProcessPublishDepositTxRequest extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
PublishDepositTxRequest message = (PublishDepositTxRequest) processModel.getTradeMessage();
|
||||
checkTradeId(processModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
|
|
@ -36,8 +36,9 @@ public class SendDepositTxPublishedMessage extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(processModel.getId(), trade.getDepositTx());
|
||||
|
||||
processModel.getMessageService().sendEncryptedMessage(
|
||||
|
|
|
@ -36,8 +36,9 @@ public class SendFiatTransferStartedMessage extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
FiatTransferStartedMessage tradeMessage = new FiatTransferStartedMessage(processModel.getId(),
|
||||
processModel.getAddressEntry().getAddressString()
|
||||
);
|
||||
|
|
|
@ -36,8 +36,9 @@ public class SendPayDepositRequest extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
boolean isInitialRequest = trade instanceof BuyerAsTakerTrade;
|
||||
PayDepositRequest tradeMessage = new PayDepositRequest(
|
||||
processModel.getId(),
|
||||
|
|
|
@ -36,8 +36,9 @@ public class SendPayoutTxFinalizedMessage extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
PayoutTxFinalizedMessage tradeMessage = new PayoutTxFinalizedMessage(processModel.getId(), trade.getPayoutTx());
|
||||
processModel.getMessageService().sendEncryptedMessage(
|
||||
trade.getTradingPeer(),
|
||||
|
|
|
@ -35,8 +35,9 @@ public class SignAndFinalizePayoutTx extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
assert trade.getTradeAmount() != null;
|
||||
assert trade.getSecurityDeposit() != null;
|
||||
Coin sellerPayoutAmount = trade.getSecurityDeposit();
|
||||
|
|
|
@ -44,8 +44,9 @@ public class SignAndPublishDepositTx extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
Coin inputAmount = trade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||
|
||||
processModel.getTradeWalletService().signAndPublishDepositTx(
|
||||
|
|
|
@ -35,8 +35,9 @@ public class VerifyAndSignContract extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
Contract contract = new Contract(
|
||||
processModel.getOffer(),
|
||||
trade.getTradeAmount(),
|
||||
|
|
|
@ -32,8 +32,9 @@ public class VerifyTakeOfferFeePayment extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
//TODO mocked yet, need a confidence listeners
|
||||
int numOfPeersSeenTx = processModel.getWalletService().getNumOfPeersSeenTx(processModel.getTakeOfferFeeTxId());
|
||||
/* if (numOfPeersSeenTx > 2) {
|
||||
|
|
|
@ -33,8 +33,9 @@ public class VerifyTakerAccount extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
//TODO mocked yet
|
||||
if (processModel.getBlockChainService().verifyAccountRegistration()) {
|
||||
if (processModel.getBlockChainService().isAccountBlackListed(processModel.tradingPeer.getAccountId(),
|
||||
|
|
|
@ -34,8 +34,9 @@ public class CommitDepositTx extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
// To access tx confidence we need to add that tx into our wallet.
|
||||
Transaction depositTx = processModel.getTradeWalletService().commitTx(trade.getDepositTx());
|
||||
|
||||
|
|
|
@ -34,8 +34,9 @@ public class CreateAndSignContract extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
assert processModel.getTakeOfferFeeTxId() != null;
|
||||
Contract contract = new Contract(
|
||||
processModel.getOffer(),
|
||||
|
|
|
@ -36,8 +36,9 @@ public class CreateAndSignDepositTx extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
assert trade.getTradeAmount() != null;
|
||||
Coin inputAmount = trade.getSecurityDeposit().add(FeePolicy.TX_FEE).add(trade.getTradeAmount());
|
||||
Coin msOutputAmount = inputAmount.add(trade.getSecurityDeposit());
|
||||
|
|
|
@ -37,8 +37,9 @@ public class ProcessDepositTxPublishedMessage extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
DepositTxPublishedMessage message = (DepositTxPublishedMessage) processModel.getTradeMessage();
|
||||
checkTradeId(processModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
|
|
@ -37,8 +37,9 @@ public class ProcessFiatTransferStartedMessage extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
FiatTransferStartedMessage message = (FiatTransferStartedMessage) processModel.getTradeMessage();
|
||||
checkTradeId(processModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
|
|
@ -36,8 +36,9 @@ public class ProcessPayDepositRequest extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
PayDepositRequest message = (PayDepositRequest) processModel.getTradeMessage();
|
||||
checkTradeId(processModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
|
|
@ -37,8 +37,9 @@ public class ProcessPayoutTxFinalizedMessage extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
PayoutTxFinalizedMessage message = (PayoutTxFinalizedMessage) processModel.getTradeMessage();
|
||||
checkTradeId(processModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
|
|
@ -39,8 +39,9 @@ public class SendDepositTxInputsRequest extends TradeTask {
|
|||
private int retryCounter = 0;
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
assert processModel.getTakeOfferFeeTx() != null;
|
||||
DepositTxInputsRequest message = new DepositTxInputsRequest(
|
||||
processModel.getId(),
|
||||
|
@ -67,7 +68,7 @@ public class SendDepositTxInputsRequest extends TradeTask {
|
|||
// We try to repeat once and if that fails as well we persist the state for a later retry.
|
||||
if (retryCounter == 0) {
|
||||
retryCounter++;
|
||||
Threading.USER_THREAD.execute(SendDepositTxInputsRequest.this::doRun);
|
||||
Threading.USER_THREAD.execute(SendDepositTxInputsRequest.this::run);
|
||||
}
|
||||
else {
|
||||
appendToErrorMessage("Sending TakeOfferFeePayedMessage to offerer failed. Maybe the network connection was " +
|
||||
|
|
|
@ -36,8 +36,9 @@ public class SendFinalizePayoutTxRequest extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
FinalizePayoutTxRequest message = new FinalizePayoutTxRequest(
|
||||
processModel.getId(),
|
||||
processModel.getPayoutTxSignature(),
|
||||
|
|
|
@ -35,8 +35,9 @@ public class SendPublishDepositTxRequest extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
PublishDepositTxRequest tradeMessage = new PublishDepositTxRequest(
|
||||
processModel.getId(),
|
||||
processModel.getFiatAccount(),
|
||||
|
|
|
@ -34,8 +34,9 @@ public class SignPayoutTx extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
assert trade.getTradeAmount() != null;
|
||||
assert trade.getSecurityDeposit() != null;
|
||||
Coin sellerPayoutAmount = trade.getSecurityDeposit();
|
||||
|
|
|
@ -38,8 +38,9 @@ public class CommitPayoutTx extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
Transaction transaction = processModel.getTradeWalletService().commitTx(trade.getPayoutTx());
|
||||
|
||||
trade.setPayoutTx(transaction);
|
||||
|
|
|
@ -47,8 +47,9 @@ public class SetupPayoutTxLockTimeReachedListener extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
log.debug("ChainHeight/LockTime: {} / {}", processModel.getTradeWalletService().getBestChainHeight(), trade.getLockTime());
|
||||
if (processModel.getTradeWalletService().getBestChainHeight() >= trade.getLockTime()) {
|
||||
broadcastTx();
|
||||
|
|
|
@ -38,35 +38,25 @@ public class BroadcastTakeOfferFeeTx extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
processModel.getTradeWalletService().broadcastTx(processModel.getTakeOfferFeeTx(),
|
||||
new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(Transaction transaction) {
|
||||
log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString());
|
||||
|
||||
/* if (trade instanceof SellerTrade)
|
||||
trade.setProcessState(TakerTradeState.ProcessState.TAKE_OFFER_FEE_PUBLISHED);*/
|
||||
|
||||
complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
t.printStackTrace();
|
||||
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again.");
|
||||
trade.setErrorMessage(errorMessage);
|
||||
|
||||
/* if (trade instanceof SellerTrade)
|
||||
trade.setProcessState(TakerTradeState.ProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED);*/
|
||||
|
||||
failed(t);
|
||||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
trade.setThrowable(t);
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,20 +34,16 @@ public class CreateTakeOfferFeeTx extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
Transaction createTakeOfferFeeTx = processModel.getTradeWalletService().createTakeOfferFeeTx(processModel.getAddressEntry());
|
||||
|
||||
processModel.setTakeOfferFeeTx(createTakeOfferFeeTx);
|
||||
processModel.setTakeOfferFeeTxId(createTakeOfferFeeTx.getHashAsString());
|
||||
|
||||
/*if (trade instanceof SellerTrade)
|
||||
trade.setProcessState(TakerTradeState.ProcessState.TAKE_OFFER_FEE_TX_CREATED);*/
|
||||
|
||||
complete();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
trade.setThrowable(t);
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,9 @@ public class VerifyOfferFeePayment extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
//TODO impl. missing
|
||||
int numOfPeersSeenTx = processModel.getWalletService().getNumOfPeersSeenTx(processModel.getTakeOfferFeeTx().getHashAsString());
|
||||
/* if (numOfPeersSeenTx > 2) {
|
||||
|
|
|
@ -32,8 +32,9 @@ public class VerifyOffererAccount extends TradeTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
if (processModel.getBlockChainService().verifyAccountRegistration()) {
|
||||
if (processModel.getBlockChainService().isAccountBlackListed(processModel.tradingPeer.getAccountId(),
|
||||
processModel.tradingPeer.getFiatAccount())) {
|
||||
|
|
|
@ -38,6 +38,9 @@ public class BuyerTradeState {
|
|||
PAYOUT_TX_COMMITTED,
|
||||
PAYOUT_TX_SENT,
|
||||
|
||||
PAYOUT_BROAD_CASTED
|
||||
PAYOUT_BROAD_CASTED,
|
||||
|
||||
TIMEOUT,
|
||||
FAULT
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ public class SellerTradeState {
|
|||
PAYOUT_TX_RECEIVED,
|
||||
PAYOUT_TX_COMMITTED,
|
||||
|
||||
PAYOUT_BROAD_CASTED
|
||||
PAYOUT_BROAD_CASTED,
|
||||
|
||||
TIMEOUT,
|
||||
FAULT
|
||||
}
|
||||
}
|
||||
|
|
26
core/src/main/java/io/bitsquare/trade/states/TradePhase.java
Normal file
26
core/src/main/java/io/bitsquare/trade/states/TradePhase.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.states;
|
||||
|
||||
public enum TradePhase {
|
||||
PREPARATION, // No damage
|
||||
TAKE_OFFER__FEE_PAID, // Offer fee can be lost
|
||||
DEPOSIT_BROAD_CASTED, // Need arbitrator
|
||||
PAYOUT_BROAD_CASTED // Only charge back risk open
|
||||
|
||||
}
|
|
@ -54,9 +54,9 @@ public class Preferences implements Serializable {
|
|||
|
||||
// Persisted fields
|
||||
private String btcDenomination = MonetaryFormat.CODE_BTC;
|
||||
private Boolean useAnimations = true;
|
||||
private Boolean useEffects = true;
|
||||
private Boolean displaySecurityDepositInfo = true;
|
||||
private boolean useAnimations = true;
|
||||
private boolean useEffects = true;
|
||||
private boolean displaySecurityDepositInfo = true;
|
||||
|
||||
// Observable wrappers
|
||||
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
|
||||
|
@ -111,7 +111,7 @@ public class Preferences implements Serializable {
|
|||
this.useEffectsProperty.set(useEffectsProperty);
|
||||
}
|
||||
|
||||
public void setDisplaySecurityDepositInfo(Boolean displaySecurityDepositInfo) {
|
||||
public void setDisplaySecurityDepositInfo(boolean displaySecurityDepositInfo) {
|
||||
this.displaySecurityDepositInfo = displaySecurityDepositInfo;
|
||||
storage.queueUpForSave();
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ public class Preferences implements Serializable {
|
|||
return useAnimationsProperty.get();
|
||||
}
|
||||
|
||||
public Boolean getDisplaySecurityDepositInfo() {
|
||||
public boolean getDisplaySecurityDepositInfo() {
|
||||
return displaySecurityDepositInfo;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
package io.bitsquare.util;
|
||||
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
|
||||
import org.bitcoinj.utils.Threading;
|
||||
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
@ -36,6 +40,9 @@ import java.io.Serializable;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -47,6 +54,31 @@ public class Utilities {
|
|||
private static final Logger log = LoggerFactory.getLogger(Utilities.class);
|
||||
private static long lastTimeStamp = System.currentTimeMillis();
|
||||
|
||||
|
||||
public static Timer setTimeout(long delay, ResultHandler handler) {
|
||||
Timer timer = new Timer();
|
||||
TimerTask task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
Threading.USER_THREAD.execute(() -> handler.handleResult());
|
||||
}
|
||||
};
|
||||
timer.schedule(task, delay);
|
||||
return timer;
|
||||
}
|
||||
|
||||
public static Timer setInterval(long delay, ResultHandler handler) {
|
||||
Timer timer = new Timer();
|
||||
TimerTask task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
Threading.USER_THREAD.execute(() -> handler.handleResult());
|
||||
}
|
||||
};
|
||||
timer.scheduleAtFixedRate(task, delay, delay);
|
||||
return timer;
|
||||
}
|
||||
|
||||
public static String objectToJson(Object object) {
|
||||
Gson gson =
|
||||
new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).setPrettyPrinting().create();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue