mirror of
https://github.com/boldsuck/haveno.git
synced 2024-12-22 20:19:21 +00:00
progress notifications during take offer are more frequent and reliable
This commit is contained in:
parent
cffbfa8aaa
commit
427c762620
12 changed files with 59 additions and 25 deletions
|
@ -333,7 +333,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
stopped = true;
|
||||
p2PService.getPeerManager().removeListener(this);
|
||||
p2PService.removeDecryptedDirectMessageListener(this);
|
||||
signedOfferKeyImagePoller.clearKeyImages();
|
||||
if (signedOfferKeyImagePoller != null) signedOfferKeyImagePoller.clearKeyImages();
|
||||
|
||||
stopPeriodicRefreshOffersTimer();
|
||||
stopPeriodicRepublishOffersTimer();
|
||||
|
|
|
@ -54,10 +54,13 @@ import haveno.core.xmr.wallet.XmrWalletService;
|
|||
import haveno.network.p2p.AckMessage;
|
||||
import haveno.network.p2p.NodeAddress;
|
||||
import haveno.network.p2p.P2PService;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyStringProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
@ -333,6 +336,10 @@ public abstract class Trade implements Tradable, Model {
|
|||
private long amount;
|
||||
@Setter
|
||||
private long price;
|
||||
private int initStep = 0;
|
||||
private static final int TOTAL_INIT_STEPS = 15; // total estimated steps
|
||||
@Getter
|
||||
private double initProgress = 0;
|
||||
@Nullable
|
||||
@Getter
|
||||
private State state = State.PREPARATION;
|
||||
|
@ -368,6 +375,7 @@ public abstract class Trade implements Tradable, Model {
|
|||
@Getter
|
||||
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<Phase> phaseProperty = new SimpleObjectProperty<>(state.phase);
|
||||
transient final private ObjectProperty<PayoutState> payoutStateProperty = new SimpleObjectProperty<>(payoutState);
|
||||
|
@ -1167,7 +1175,10 @@ public abstract class Trade implements Tradable, Model {
|
|||
isInitialized = false;
|
||||
isShutDown = true;
|
||||
synchronized (walletLock) {
|
||||
if (wallet != null) closeWallet();
|
||||
if (wallet != null) {
|
||||
saveWallet();
|
||||
stopWallet();
|
||||
}
|
||||
}
|
||||
if (tradePhaseSubscription != null) tradePhaseSubscription.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) {
|
||||
if (isInitialized) {
|
||||
// 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();
|
||||
}
|
||||
|
||||
public ReadOnlyDoubleProperty initProgressProperty() {
|
||||
return initProgressProperty;
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<State> stateProperty() {
|
||||
return stateProperty;
|
||||
}
|
||||
|
|
|
@ -834,6 +834,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||
trade.getMaker().setPubKeyRing(trade.getOffer().getPubKeyRing());
|
||||
trade.getSelf().setPubKeyRing(model.getPubKeyRing());
|
||||
trade.getSelf().setPaymentAccountId(paymentAccountId);
|
||||
trade.addInitProgressStep();
|
||||
|
||||
// ensure trade is not already open
|
||||
Optional<Trade> tradeOptional = getOpenTrade(offer.getId());
|
||||
|
|
|
@ -72,6 +72,7 @@ public class MaybeSendSignContractRequest extends TradeTask {
|
|||
}
|
||||
|
||||
// create deposit tx and freeze inputs
|
||||
trade.addInitProgressStep();
|
||||
MoneroTxWallet depositTx = trade.getXmrWalletService().createDepositTx(trade);
|
||||
|
||||
// collect reserved key images
|
||||
|
@ -142,6 +143,7 @@ public class MaybeSendSignContractRequest extends TradeTask {
|
|||
|
||||
private void completeAux() {
|
||||
trade.setState(State.CONTRACT_SIGNATURE_REQUESTED);
|
||||
trade.addInitProgressStep();
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
complete();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ public class ProcessDepositResponse extends TradeTask {
|
|||
|
||||
// set success state
|
||||
trade.setStateIfValidTransitionTo(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
||||
trade.addInitProgressStep();
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
complete();
|
||||
} catch (Throwable t) {
|
||||
|
|
|
@ -76,6 +76,7 @@ public class ProcessInitMultisigRequest extends TradeTask {
|
|||
// prepare multisig if applicable
|
||||
boolean updateParticipants = false;
|
||||
if (trade.getSelf().getPreparedMultisigHex() == null) {
|
||||
trade.addInitProgressStep();
|
||||
log.info("Preparing multisig wallet for {} {}", trade.getClass().getSimpleName(), trade.getId());
|
||||
multisigWallet = trade.createWallet();
|
||||
trade.getSelf().setPreparedMultisigHex(multisigWallet.prepareMultisig());
|
||||
|
@ -217,6 +218,7 @@ public class ProcessInitMultisigRequest extends TradeTask {
|
|||
}
|
||||
|
||||
private void completeAux() {
|
||||
trade.addInitProgressStep();
|
||||
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");
|
||||
|
||||
// persist trade
|
||||
trade.addInitProgressStep();
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
complete();
|
||||
} catch (Throwable t) {
|
||||
|
|
|
@ -162,6 +162,7 @@ public class ProcessSignContractRequest extends TradeTask {
|
|||
}
|
||||
|
||||
private void completeAux() {
|
||||
trade.addInitProgressStep();
|
||||
trade.setState(State.CONTRACT_SIGNED);
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
complete();
|
||||
|
|
|
@ -104,6 +104,7 @@ public class ProcessSignContractResponse extends TradeTask {
|
|||
|
||||
// deposit is requested
|
||||
trade.setState(Trade.State.SENT_PUBLISH_DEPOSIT_TX_REQUEST);
|
||||
trade.addInitProgressStep();
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
} else {
|
||||
log.info("Waiting for another contract signatures to send deposit request");
|
||||
|
|
|
@ -54,6 +54,7 @@ public class TakerReserveTradeFunds extends TradeTask {
|
|||
processModel.setReserveTx(reserveTx);
|
||||
processModel.getTaker().setReserveTxKeyImages(reservedKeyImages);
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
trade.addInitProgressStep();
|
||||
complete();
|
||||
} catch (Throwable t) {
|
||||
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
|
||||
sendInitTradeRequests(trade.getOffer().getOfferPayload().getArbitratorSigner(), new HashSet<NodeAddress>(), () -> {
|
||||
trade.addInitProgressStep();
|
||||
complete();
|
||||
}, (errorMessage) -> {
|
||||
log.warn("Cannot initialize trade with arbitrators: " + errorMessage);
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package haveno.desktop.main.overlays.windows;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.common.crypto.KeyRing;
|
||||
import haveno.common.util.Tuple2;
|
||||
import haveno.common.util.Tuple4;
|
||||
|
@ -31,7 +30,6 @@ import haveno.core.payment.PaymentAccount;
|
|||
import haveno.core.payment.payload.PaymentMethod;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.trade.Trade;
|
||||
import haveno.core.trade.Trade.State;
|
||||
import haveno.core.trade.TradeManager;
|
||||
import haveno.core.user.User;
|
||||
import haveno.core.util.FormattingUtils;
|
||||
|
@ -85,7 +83,8 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
private Optional<Runnable> takeOfferHandlerOptional = Optional.empty();
|
||||
private BusyAnimation busyAnimation;
|
||||
private TradeManager tradeManager;
|
||||
private Subscription tradeStateSubscription;
|
||||
private Subscription numTradesSubscription;
|
||||
private Subscription initProgressSubscription;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public API
|
||||
|
@ -145,6 +144,16 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
protected void onHidden() {
|
||||
if (busyAnimation != null)
|
||||
busyAnimation.stop();
|
||||
|
||||
if (numTradesSubscription != null) {
|
||||
numTradesSubscription.unsubscribe();
|
||||
numTradesSubscription = null;
|
||||
}
|
||||
|
||||
if (initProgressSubscription != null) {
|
||||
initProgressSubscription.unsubscribe();
|
||||
initProgressSubscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -407,31 +416,25 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
spinnerInfoLabel.setText(Res.get("createOffer.fundsBox.placeOfferSpinnerInfo"));
|
||||
placeOfferHandlerOptional.ifPresent(Runnable::run);
|
||||
} 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);
|
||||
|
||||
// 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) {
|
||||
return (int) ((double) newOrdinal / (double) lastOrdinal * 100) + "%";
|
||||
private void subscribeToProgress(Label spinnerInfoLabel) {
|
||||
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 a new issue