mirror of
https://github.com/retoaccess1/haveno-reto.git
synced 2024-12-12 04:43:32 +01:00
progress notifications during take offer are more frequent and reliable
This commit is contained in:
parent
cffbfa8aaa
commit
427c762620
@ -333,7 +333,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
stopped = true;
|
stopped = true;
|
||||||
p2PService.getPeerManager().removeListener(this);
|
p2PService.getPeerManager().removeListener(this);
|
||||||
p2PService.removeDecryptedDirectMessageListener(this);
|
p2PService.removeDecryptedDirectMessageListener(this);
|
||||||
signedOfferKeyImagePoller.clearKeyImages();
|
if (signedOfferKeyImagePoller != null) signedOfferKeyImagePoller.clearKeyImages();
|
||||||
|
|
||||||
stopPeriodicRefreshOffersTimer();
|
stopPeriodicRefreshOffersTimer();
|
||||||
stopPeriodicRepublishOffersTimer();
|
stopPeriodicRepublishOffersTimer();
|
||||||
|
@ -54,10 +54,13 @@ import haveno.core.xmr.wallet.XmrWalletService;
|
|||||||
import haveno.network.p2p.AckMessage;
|
import haveno.network.p2p.AckMessage;
|
||||||
import haveno.network.p2p.NodeAddress;
|
import haveno.network.p2p.NodeAddress;
|
||||||
import haveno.network.p2p.P2PService;
|
import haveno.network.p2p.P2PService;
|
||||||
|
import javafx.beans.property.DoubleProperty;
|
||||||
import javafx.beans.property.IntegerProperty;
|
import javafx.beans.property.IntegerProperty;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
import javafx.beans.property.ReadOnlyStringProperty;
|
import javafx.beans.property.ReadOnlyStringProperty;
|
||||||
|
import javafx.beans.property.SimpleDoubleProperty;
|
||||||
import javafx.beans.property.SimpleIntegerProperty;
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
@ -333,6 +336,10 @@ public abstract class Trade implements Tradable, Model {
|
|||||||
private long amount;
|
private long amount;
|
||||||
@Setter
|
@Setter
|
||||||
private long price;
|
private long price;
|
||||||
|
private int initStep = 0;
|
||||||
|
private static final int TOTAL_INIT_STEPS = 15; // total estimated steps
|
||||||
|
@Getter
|
||||||
|
private double initProgress = 0;
|
||||||
@Nullable
|
@Nullable
|
||||||
@Getter
|
@Getter
|
||||||
private State state = State.PREPARATION;
|
private State state = State.PREPARATION;
|
||||||
@ -368,6 +375,7 @@ public abstract class Trade implements Tradable, Model {
|
|||||||
@Getter
|
@Getter
|
||||||
transient final private XmrWalletService xmrWalletService;
|
transient final private XmrWalletService xmrWalletService;
|
||||||
|
|
||||||
|
transient final private DoubleProperty initProgressProperty = new SimpleDoubleProperty(0.0);
|
||||||
transient final private ObjectProperty<State> stateProperty = new SimpleObjectProperty<>(state);
|
transient final private ObjectProperty<State> stateProperty = new SimpleObjectProperty<>(state);
|
||||||
transient final private ObjectProperty<Phase> phaseProperty = new SimpleObjectProperty<>(state.phase);
|
transient final private ObjectProperty<Phase> phaseProperty = new SimpleObjectProperty<>(state.phase);
|
||||||
transient final private ObjectProperty<PayoutState> payoutStateProperty = new SimpleObjectProperty<>(payoutState);
|
transient final private ObjectProperty<PayoutState> payoutStateProperty = new SimpleObjectProperty<>(payoutState);
|
||||||
@ -1167,7 +1175,10 @@ public abstract class Trade implements Tradable, Model {
|
|||||||
isInitialized = false;
|
isInitialized = false;
|
||||||
isShutDown = true;
|
isShutDown = true;
|
||||||
synchronized (walletLock) {
|
synchronized (walletLock) {
|
||||||
if (wallet != null) closeWallet();
|
if (wallet != null) {
|
||||||
|
saveWallet();
|
||||||
|
stopWallet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tradePhaseSubscription != null) tradePhaseSubscription.unsubscribe();
|
if (tradePhaseSubscription != null) tradePhaseSubscription.unsubscribe();
|
||||||
if (payoutStateSubscription != null) payoutStateSubscription.unsubscribe();
|
if (payoutStateSubscription != null) payoutStateSubscription.unsubscribe();
|
||||||
@ -1206,6 +1217,11 @@ public abstract class Trade implements Tradable, Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addInitProgressStep() {
|
||||||
|
initProgress = Math.min(1.0, (double) ++initStep / TOTAL_INIT_STEPS);
|
||||||
|
UserThread.execute(() -> initProgressProperty.set(initProgress));
|
||||||
|
}
|
||||||
|
|
||||||
public void setState(State state) {
|
public void setState(State state) {
|
||||||
if (isInitialized) {
|
if (isInitialized) {
|
||||||
// We don't want to log at startup the setState calls from all persisted trades
|
// We don't want to log at startup the setState calls from all persisted trades
|
||||||
@ -1551,6 +1567,10 @@ public abstract class Trade implements Tradable, Model {
|
|||||||
return getPayoutState().ordinal() >= PayoutState.PAYOUT_UNLOCKED.ordinal();
|
return getPayoutState().ordinal() >= PayoutState.PAYOUT_UNLOCKED.ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReadOnlyDoubleProperty initProgressProperty() {
|
||||||
|
return initProgressProperty;
|
||||||
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<State> stateProperty() {
|
public ReadOnlyObjectProperty<State> stateProperty() {
|
||||||
return stateProperty;
|
return stateProperty;
|
||||||
}
|
}
|
||||||
|
@ -834,6 +834,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
trade.getMaker().setPubKeyRing(trade.getOffer().getPubKeyRing());
|
trade.getMaker().setPubKeyRing(trade.getOffer().getPubKeyRing());
|
||||||
trade.getSelf().setPubKeyRing(model.getPubKeyRing());
|
trade.getSelf().setPubKeyRing(model.getPubKeyRing());
|
||||||
trade.getSelf().setPaymentAccountId(paymentAccountId);
|
trade.getSelf().setPaymentAccountId(paymentAccountId);
|
||||||
|
trade.addInitProgressStep();
|
||||||
|
|
||||||
// ensure trade is not already open
|
// ensure trade is not already open
|
||||||
Optional<Trade> tradeOptional = getOpenTrade(offer.getId());
|
Optional<Trade> tradeOptional = getOpenTrade(offer.getId());
|
||||||
|
@ -72,6 +72,7 @@ public class MaybeSendSignContractRequest extends TradeTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create deposit tx and freeze inputs
|
// create deposit tx and freeze inputs
|
||||||
|
trade.addInitProgressStep();
|
||||||
MoneroTxWallet depositTx = trade.getXmrWalletService().createDepositTx(trade);
|
MoneroTxWallet depositTx = trade.getXmrWalletService().createDepositTx(trade);
|
||||||
|
|
||||||
// collect reserved key images
|
// collect reserved key images
|
||||||
@ -142,6 +143,7 @@ public class MaybeSendSignContractRequest extends TradeTask {
|
|||||||
|
|
||||||
private void completeAux() {
|
private void completeAux() {
|
||||||
trade.setState(State.CONTRACT_SIGNATURE_REQUESTED);
|
trade.setState(State.CONTRACT_SIGNATURE_REQUESTED);
|
||||||
|
trade.addInitProgressStep();
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ public class ProcessDepositResponse extends TradeTask {
|
|||||||
|
|
||||||
// set success state
|
// set success state
|
||||||
trade.setStateIfValidTransitionTo(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
trade.setStateIfValidTransitionTo(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
||||||
|
trade.addInitProgressStep();
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -76,6 +76,7 @@ public class ProcessInitMultisigRequest extends TradeTask {
|
|||||||
// prepare multisig if applicable
|
// prepare multisig if applicable
|
||||||
boolean updateParticipants = false;
|
boolean updateParticipants = false;
|
||||||
if (trade.getSelf().getPreparedMultisigHex() == null) {
|
if (trade.getSelf().getPreparedMultisigHex() == null) {
|
||||||
|
trade.addInitProgressStep();
|
||||||
log.info("Preparing multisig wallet for {} {}", trade.getClass().getSimpleName(), trade.getId());
|
log.info("Preparing multisig wallet for {} {}", trade.getClass().getSimpleName(), trade.getId());
|
||||||
multisigWallet = trade.createWallet();
|
multisigWallet = trade.createWallet();
|
||||||
trade.getSelf().setPreparedMultisigHex(multisigWallet.prepareMultisig());
|
trade.getSelf().setPreparedMultisigHex(multisigWallet.prepareMultisig());
|
||||||
@ -217,6 +218,7 @@ public class ProcessInitMultisigRequest extends TradeTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void completeAux() {
|
private void completeAux() {
|
||||||
|
trade.addInitProgressStep();
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ public class ProcessInitTradeRequest extends TradeTask {
|
|||||||
checkArgument(request.getTradeAmount() == trade.getAmount().longValueExact(), "Trade amount does not match request's trade amount");
|
checkArgument(request.getTradeAmount() == trade.getAmount().longValueExact(), "Trade amount does not match request's trade amount");
|
||||||
|
|
||||||
// persist trade
|
// persist trade
|
||||||
|
trade.addInitProgressStep();
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -162,6 +162,7 @@ public class ProcessSignContractRequest extends TradeTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void completeAux() {
|
private void completeAux() {
|
||||||
|
trade.addInitProgressStep();
|
||||||
trade.setState(State.CONTRACT_SIGNED);
|
trade.setState(State.CONTRACT_SIGNED);
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
|
@ -104,6 +104,7 @@ public class ProcessSignContractResponse extends TradeTask {
|
|||||||
|
|
||||||
// deposit is requested
|
// deposit is requested
|
||||||
trade.setState(Trade.State.SENT_PUBLISH_DEPOSIT_TX_REQUEST);
|
trade.setState(Trade.State.SENT_PUBLISH_DEPOSIT_TX_REQUEST);
|
||||||
|
trade.addInitProgressStep();
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
} else {
|
} else {
|
||||||
log.info("Waiting for another contract signatures to send deposit request");
|
log.info("Waiting for another contract signatures to send deposit request");
|
||||||
|
@ -54,6 +54,7 @@ public class TakerReserveTradeFunds extends TradeTask {
|
|||||||
processModel.setReserveTx(reserveTx);
|
processModel.setReserveTx(reserveTx);
|
||||||
processModel.getTaker().setReserveTxKeyImages(reservedKeyImages);
|
processModel.getTaker().setReserveTxKeyImages(reservedKeyImages);
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
|
trade.addInitProgressStep();
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
trade.setErrorMessage("An error occurred.\n" +
|
trade.setErrorMessage("An error occurred.\n" +
|
||||||
|
@ -47,6 +47,7 @@ public class TakerSendInitTradeRequestToArbitrator extends TradeTask {
|
|||||||
|
|
||||||
// send request to signing arbitrator then least used arbitrators until success
|
// send request to signing arbitrator then least used arbitrators until success
|
||||||
sendInitTradeRequests(trade.getOffer().getOfferPayload().getArbitratorSigner(), new HashSet<NodeAddress>(), () -> {
|
sendInitTradeRequests(trade.getOffer().getOfferPayload().getArbitratorSigner(), new HashSet<NodeAddress>(), () -> {
|
||||||
|
trade.addInitProgressStep();
|
||||||
complete();
|
complete();
|
||||||
}, (errorMessage) -> {
|
}, (errorMessage) -> {
|
||||||
log.warn("Cannot initialize trade with arbitrators: " + errorMessage);
|
log.warn("Cannot initialize trade with arbitrators: " + errorMessage);
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
package haveno.desktop.main.overlays.windows;
|
package haveno.desktop.main.overlays.windows;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import haveno.common.UserThread;
|
|
||||||
import haveno.common.crypto.KeyRing;
|
import haveno.common.crypto.KeyRing;
|
||||||
import haveno.common.util.Tuple2;
|
import haveno.common.util.Tuple2;
|
||||||
import haveno.common.util.Tuple4;
|
import haveno.common.util.Tuple4;
|
||||||
@ -31,7 +30,6 @@ import haveno.core.payment.PaymentAccount;
|
|||||||
import haveno.core.payment.payload.PaymentMethod;
|
import haveno.core.payment.payload.PaymentMethod;
|
||||||
import haveno.core.trade.HavenoUtils;
|
import haveno.core.trade.HavenoUtils;
|
||||||
import haveno.core.trade.Trade;
|
import haveno.core.trade.Trade;
|
||||||
import haveno.core.trade.Trade.State;
|
|
||||||
import haveno.core.trade.TradeManager;
|
import haveno.core.trade.TradeManager;
|
||||||
import haveno.core.user.User;
|
import haveno.core.user.User;
|
||||||
import haveno.core.util.FormattingUtils;
|
import haveno.core.util.FormattingUtils;
|
||||||
@ -85,7 +83,8 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||||||
private Optional<Runnable> takeOfferHandlerOptional = Optional.empty();
|
private Optional<Runnable> takeOfferHandlerOptional = Optional.empty();
|
||||||
private BusyAnimation busyAnimation;
|
private BusyAnimation busyAnimation;
|
||||||
private TradeManager tradeManager;
|
private TradeManager tradeManager;
|
||||||
private Subscription tradeStateSubscription;
|
private Subscription numTradesSubscription;
|
||||||
|
private Subscription initProgressSubscription;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Public API
|
// Public API
|
||||||
@ -145,6 +144,16 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||||||
protected void onHidden() {
|
protected void onHidden() {
|
||||||
if (busyAnimation != null)
|
if (busyAnimation != null)
|
||||||
busyAnimation.stop();
|
busyAnimation.stop();
|
||||||
|
|
||||||
|
if (numTradesSubscription != null) {
|
||||||
|
numTradesSubscription.unsubscribe();
|
||||||
|
numTradesSubscription = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initProgressSubscription != null) {
|
||||||
|
initProgressSubscription.unsubscribe();
|
||||||
|
initProgressSubscription = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -407,31 +416,25 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||||||
spinnerInfoLabel.setText(Res.get("createOffer.fundsBox.placeOfferSpinnerInfo"));
|
spinnerInfoLabel.setText(Res.get("createOffer.fundsBox.placeOfferSpinnerInfo"));
|
||||||
placeOfferHandlerOptional.ifPresent(Runnable::run);
|
placeOfferHandlerOptional.ifPresent(Runnable::run);
|
||||||
} else {
|
} else {
|
||||||
State lastState = Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS;
|
|
||||||
spinnerInfoLabel.setText(Res.get("takeOffer.fundsBox.takeOfferSpinnerInfo") + " " + getPercentString(0, lastState.ordinal()));
|
// subscribe to trade progress
|
||||||
|
spinnerInfoLabel.setText(Res.get("takeOffer.fundsBox.takeOfferSpinnerInfo") + " 0%");
|
||||||
|
numTradesSubscription = EasyBind.subscribe(tradeManager.getNumPendingTrades(), newNum -> {
|
||||||
|
subscribeToProgress(spinnerInfoLabel);
|
||||||
|
});
|
||||||
|
|
||||||
takeOfferHandlerOptional.ifPresent(Runnable::run);
|
takeOfferHandlerOptional.ifPresent(Runnable::run);
|
||||||
|
|
||||||
// update trade state progress
|
|
||||||
UserThread.runAfter(() -> {
|
|
||||||
Trade trade = tradeManager.getTrade(offer.getId());
|
|
||||||
if (trade == null) return;
|
|
||||||
tradeStateSubscription = EasyBind.subscribe(trade.stateProperty(), newState -> {
|
|
||||||
String progress = getPercentString(newState.ordinal(), lastState.ordinal());
|
|
||||||
spinnerInfoLabel.setText(Res.get("takeOffer.fundsBox.takeOfferSpinnerInfo") + " " + progress);
|
|
||||||
|
|
||||||
// unsubscribe when done
|
|
||||||
if (newState == lastState) {
|
|
||||||
tradeStateSubscription.unsubscribe();
|
|
||||||
tradeStateSubscription = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getPercentString(int newOrdinal, int lastOrdinal) {
|
private void subscribeToProgress(Label spinnerInfoLabel) {
|
||||||
return (int) ((double) newOrdinal / (double) lastOrdinal * 100) + "%";
|
Trade trade = tradeManager.getTrade(offer.getId());
|
||||||
|
if (trade == null || initProgressSubscription != null) return;
|
||||||
|
initProgressSubscription = EasyBind.subscribe(trade.initProgressProperty(), newProgress -> {
|
||||||
|
String progress = (int) (newProgress.doubleValue() * 100.0) + "%";
|
||||||
|
spinnerInfoLabel.setText(Res.get("takeOffer.fundsBox.takeOfferSpinnerInfo") + " " + progress);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user