mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-14 04:53:00 -04:00
Remove fault property from trade, handle offerer protocol at startup
This commit is contained in:
parent
d1920b6e38
commit
f5a7391cb5
@ -195,16 +195,16 @@ class MainViewModel implements ViewModel {
|
||||
log.trace("updateProcess completed");
|
||||
});
|
||||
|
||||
Observable<?> allTasks = Observable.merge(messageObservable, walletServiceObservable, updateProcessObservable);
|
||||
allTasks.subscribe(
|
||||
Observable<?> allServices = Observable.merge(messageObservable, walletServiceObservable, updateProcessObservable);
|
||||
allServices.subscribe(
|
||||
next -> {
|
||||
},
|
||||
error -> log.error(error.toString()),
|
||||
() -> Platform.runLater(() -> allTasksCompleted())
|
||||
() -> Platform.runLater(() -> onAllServicesInitialized())
|
||||
);
|
||||
}
|
||||
|
||||
private void allTasksCompleted() {
|
||||
private void onAllServicesInitialized() {
|
||||
log.trace("backend completed");
|
||||
|
||||
tradeManager.getPendingTrades().addListener(
|
||||
@ -232,6 +232,8 @@ class MainViewModel implements ViewModel {
|
||||
user.setAccountID(walletService.getRegistrationAddressEntry().toString());
|
||||
persistence.write(user.getClass().getName(), user);
|
||||
}
|
||||
|
||||
tradeManager.onAllServicesInitialized();
|
||||
}
|
||||
|
||||
private void applyUpdateState(UpdateProcess.State state) {
|
||||
|
@ -70,12 +70,10 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||
private TxConfidenceListener txConfidenceListener;
|
||||
|
||||
private final ChangeListener<Trade.State> stateChangeListener;
|
||||
private final ChangeListener<Throwable> faultChangeListener;
|
||||
private final MapChangeListener<String, Trade> mapChangeListener;
|
||||
|
||||
final StringProperty txId = new SimpleStringProperty();
|
||||
final ObjectProperty<Trade.State> tradeState = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Throwable> fault = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
@Inject
|
||||
@ -85,7 +83,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||
this.user = user;
|
||||
|
||||
this.stateChangeListener = (ov, oldValue, newValue) -> tradeState.set(newValue);
|
||||
this.faultChangeListener = (ov, oldValue, newValue) -> fault.set(newValue);
|
||||
|
||||
this.mapChangeListener = change -> {
|
||||
if (change.wasAdded())
|
||||
@ -151,9 +148,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||
};
|
||||
walletService.addTxConfidenceListener(txConfidenceListener);
|
||||
updateConfidence(walletService.getConfidenceForTxId(txId.get()));
|
||||
|
||||
trade.faultProperty().addListener(faultChangeListener);
|
||||
fault.set(trade.faultProperty().get());
|
||||
}
|
||||
else {
|
||||
txId.set(null);
|
||||
@ -296,7 +290,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||
if (selectedItem != null) {
|
||||
Trade trade = getTrade();
|
||||
trade.stateProperty().removeListener(stateChangeListener);
|
||||
trade.faultProperty().removeListener(faultChangeListener);
|
||||
}
|
||||
|
||||
if (txConfidenceListener != null)
|
||||
|
@ -87,7 +87,6 @@ public class PendingTradesView extends ActivatableViewAndModel<AnchorPane, Pendi
|
||||
private ChangeListener<String> txIdChangeListener;
|
||||
private ChangeListener<PendingTradesViewModel.State> offererStateChangeListener;
|
||||
private ChangeListener<PendingTradesViewModel.State> takerStateChangeListener;
|
||||
private ChangeListener<Throwable> faultChangeListener;
|
||||
|
||||
private final Navigation navigation;
|
||||
|
||||
@ -129,7 +128,6 @@ public class PendingTradesView extends ActivatableViewAndModel<AnchorPane, Pendi
|
||||
|
||||
offererStateChangeListener = (ov, oldValue, newValue) -> applyOffererState(newValue);
|
||||
takerStateChangeListener = (ov, oldValue, newValue) -> applyTakerState(newValue);
|
||||
faultChangeListener = (ov, oldValue, newValue) -> onFault(newValue);
|
||||
|
||||
withdrawAddressTextField.setValidator(model.getBtcAddressValidator());
|
||||
withdrawButton.disableProperty().bind(model.withdrawalButtonDisable);
|
||||
@ -141,7 +139,6 @@ public class PendingTradesView extends ActivatableViewAndModel<AnchorPane, Pendi
|
||||
|
||||
model.getList().addListener(listChangeListener);
|
||||
model.txId.addListener(txIdChangeListener);
|
||||
model.fault.addListener(faultChangeListener);
|
||||
|
||||
txIdTextField.setup(model.getWalletService(), model.txId.get());
|
||||
table.getSelectionModel().select(model.getSelectedItem());
|
||||
@ -163,7 +160,6 @@ public class PendingTradesView extends ActivatableViewAndModel<AnchorPane, Pendi
|
||||
table.getSelectionModel().selectedItemProperty().removeListener(selectedItemChangeListener);
|
||||
model.getList().removeListener(listChangeListener);
|
||||
model.txId.removeListener(txIdChangeListener);
|
||||
model.fault.removeListener(faultChangeListener);
|
||||
|
||||
model.state.removeListener(offererStateChangeListener);
|
||||
model.state.removeListener(takerStateChangeListener);
|
||||
@ -414,12 +410,6 @@ public class PendingTradesView extends ActivatableViewAndModel<AnchorPane, Pendi
|
||||
}
|
||||
}
|
||||
|
||||
private void onFault(Throwable fault) {
|
||||
// TODO error handling not implemented yet
|
||||
if (fault != null)
|
||||
log.error(fault.toString());
|
||||
}
|
||||
|
||||
private void setPaymentsControlsVisible(boolean visible) {
|
||||
paymentsGroupBg.setVisible(visible);
|
||||
paymentMethodLabel.setVisible(visible);
|
||||
|
@ -65,7 +65,6 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
|
||||
|
||||
final StringProperty txId = new SimpleStringProperty();
|
||||
final ObjectProperty<State> state = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Throwable> fault = new SimpleObjectProperty<>();
|
||||
final BooleanProperty withdrawalButtonDisable = new SimpleBooleanProperty(true);
|
||||
|
||||
|
||||
@ -82,7 +81,6 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
|
||||
@Override
|
||||
public void doActivate() {
|
||||
txId.bind(dataModel.txId);
|
||||
fault.bind(dataModel.fault);
|
||||
|
||||
dataModel.tradeState.addListener(stateChangeListener);
|
||||
updateState();
|
||||
@ -91,7 +89,6 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
|
||||
@Override
|
||||
public void doDeactivate() {
|
||||
txId.unbind();
|
||||
fault.unbind();
|
||||
|
||||
dataModel.tradeState.removeListener(stateChangeListener);
|
||||
}
|
||||
@ -236,7 +233,7 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
|
||||
case PAYOUT_PUBLISHED:
|
||||
state.set(dataModel.isOfferer() ? State.OFFERER_BUYER_COMPLETED : State.TAKER_SELLER_COMPLETED);
|
||||
break;
|
||||
case FAILED:
|
||||
case MESSAGE_SENDING_FAILED:
|
||||
// TODO error states not implemented yet
|
||||
break;
|
||||
default:
|
||||
|
@ -163,8 +163,9 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||
break;
|
||||
case FIAT_PAYMENT_STARTED:
|
||||
break;
|
||||
case FAILED:
|
||||
requestTakeOfferErrorMessage.set("An error occurred. Error: " + trade.getFault().getMessage());
|
||||
case MESSAGE_SENDING_FAILED:
|
||||
requestTakeOfferErrorMessage.set("An error occurred when sending a message to the offerer. Maybe there are connection problems. Please " +
|
||||
"try later again.");
|
||||
break;
|
||||
case PAYOUT_PUBLISHED:
|
||||
break;
|
||||
|
@ -151,6 +151,12 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
offerIsAvailableChangeListener = (ov, oldValue, newValue) -> handleOfferIsAvailableState(newValue);
|
||||
model.offerIsAvailable.addListener(offerIsAvailableChangeListener);
|
||||
handleOfferIsAvailableState(model.offerIsAvailable.get());
|
||||
|
||||
// In case of returning to a canceled or failed take offer request and if trade wallet is sufficient funded we display directly the payment screen
|
||||
if (!model.isTakeOfferButtonDisabled.get()) {
|
||||
showPayFundsScreen();
|
||||
showPaymentInfoScreenButton.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCloseHandler(TradeView.CloseHandler closeHandler) {
|
||||
@ -167,7 +173,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
isOfferAvailableProgressIndicator.setProgress(0);
|
||||
isOfferAvailableProgressIndicator.setVisible(false);
|
||||
isOfferAvailableProgressIndicator.setManaged(false);
|
||||
showPaymentInfoScreenButton.setVisible(true);
|
||||
if (model.isTakeOfferButtonDisabled.get())
|
||||
showPaymentInfoScreenButton.setVisible(true);
|
||||
break;
|
||||
case OFFERER_OFFLINE:
|
||||
Popups.openWarningPopup("You cannot take that offer", "The offerer is offline.");
|
||||
@ -195,6 +202,10 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
|
||||
@FXML
|
||||
void onShowPayFundsScreen() {
|
||||
showPayFundsScreen();
|
||||
}
|
||||
|
||||
private void showPayFundsScreen() {
|
||||
// TODO deactivate for testing the moment
|
||||
/* if (model.displaySecurityDepositInfo()) {
|
||||
overlayManager.blurContent();
|
||||
|
@ -47,7 +47,7 @@ public class Trade implements Serializable {
|
||||
FIAT_PAYMENT_STARTED,
|
||||
FIAT_PAYMENT_RECEIVED,
|
||||
PAYOUT_PUBLISHED,
|
||||
FAILED
|
||||
MESSAGE_SENDING_FAILED
|
||||
}
|
||||
|
||||
private final Offer offer;
|
||||
@ -61,7 +61,6 @@ public class Trade implements Serializable {
|
||||
|
||||
private Coin tradeAmount;
|
||||
private State state;
|
||||
private Throwable fault;
|
||||
|
||||
// For changing values we use properties to get binding support in the UI (table)
|
||||
// When serialized those transient properties are not instantiated, so we instantiate them in the getters at first
|
||||
@ -69,8 +68,7 @@ public class Trade implements Serializable {
|
||||
transient private ObjectProperty<Coin> _tradeAmount;
|
||||
transient private ObjectProperty<Fiat> _tradeVolume;
|
||||
transient private ObjectProperty<State> _state;
|
||||
transient private ObjectProperty<Throwable> _fault;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
@ -131,11 +129,6 @@ public class Trade implements Serializable {
|
||||
stateProperty().set(state);
|
||||
}
|
||||
|
||||
public void setFault(Throwable fault) {
|
||||
this.fault = fault;
|
||||
faultProperty().set(fault);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
@ -161,10 +154,6 @@ public class Trade implements Serializable {
|
||||
return state;
|
||||
}
|
||||
|
||||
public Throwable getFault() {
|
||||
return fault;
|
||||
}
|
||||
|
||||
public Coin getSecurityDeposit() {
|
||||
return offer.getSecurityDeposit();
|
||||
}
|
||||
@ -210,10 +199,4 @@ public class Trade implements Serializable {
|
||||
|
||||
return _state;
|
||||
}
|
||||
|
||||
public ObjectProperty<Throwable> faultProperty() {
|
||||
if (_fault == null)
|
||||
_fault = new SimpleObjectProperty<>(fault);
|
||||
return _fault;
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ public class TradeManager {
|
||||
private final SignatureService signatureService;
|
||||
private final OfferBookService offerBookService;
|
||||
|
||||
private final Map<String, SellerAsTakerProtocol> takerAsSellerProtocolMap = new HashMap<>();
|
||||
private final Map<String, BuyerAsOffererProtocol> offererAsBuyerProtocolMap = new HashMap<>();
|
||||
private final Map<String, SellerAsTakerProtocol> sellerAsTakerProtocolMap = new HashMap<>();
|
||||
private final Map<String, BuyerAsOffererProtocol> buyerAcceptsOfferProtocolMap = new HashMap<>();
|
||||
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
|
||||
|
||||
private final ObservableMap<String, OpenOffer> openOffers = FXCollections.observableHashMap();
|
||||
@ -123,6 +123,13 @@ public class TradeManager {
|
||||
tradeMessageService.addMessageHandler(messageHandler);
|
||||
}
|
||||
|
||||
// When all services are initialized we create the protocols for our open offers (which will listen for take offer requests)
|
||||
public void onAllServicesInitialized() {
|
||||
for (Map.Entry<String, OpenOffer> entry : openOffers.entrySet()) {
|
||||
createBuyerAcceptsOfferProtocol(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Called from UI
|
||||
@ -180,7 +187,7 @@ public class TradeManager {
|
||||
model,
|
||||
(transaction) -> {
|
||||
OpenOffer openOffer = createOpenOffer(offer);
|
||||
createOffererAsBuyerProtocol(openOffer);
|
||||
createBuyerAcceptsOfferProtocol(openOffer);
|
||||
resultHandler.handleResult(transaction);
|
||||
},
|
||||
(message) -> {
|
||||
@ -214,7 +221,7 @@ public class TradeManager {
|
||||
persistPendingTrades();
|
||||
break;
|
||||
case OFFERER_REJECTED:
|
||||
case FAILED:
|
||||
case MESSAGE_SENDING_FAILED:
|
||||
removeFailedTrade(trade);
|
||||
break;
|
||||
default:
|
||||
@ -232,7 +239,7 @@ public class TradeManager {
|
||||
user);
|
||||
|
||||
SellerAsTakerProtocol sellerTakesOfferProtocol = new SellerAsTakerProtocol(model);
|
||||
takerAsSellerProtocolMap.put(trade.getId(), sellerTakesOfferProtocol);
|
||||
sellerAsTakerProtocolMap.put(trade.getId(), sellerTakesOfferProtocol);
|
||||
|
||||
sellerTakesOfferProtocol.takeOffer();
|
||||
|
||||
@ -241,14 +248,14 @@ public class TradeManager {
|
||||
|
||||
public void onFiatPaymentStarted(String tradeId) {
|
||||
// TODO remove if check when peristence is impl.
|
||||
if (offererAsBuyerProtocolMap.containsKey(tradeId)) {
|
||||
offererAsBuyerProtocolMap.get(tradeId).onFiatPaymentStarted();
|
||||
if (buyerAcceptsOfferProtocolMap.containsKey(tradeId)) {
|
||||
buyerAcceptsOfferProtocolMap.get(tradeId).onFiatPaymentStarted();
|
||||
persistPendingTrades();
|
||||
}
|
||||
}
|
||||
|
||||
public void onFiatPaymentReceived(String tradeId) {
|
||||
takerAsSellerProtocolMap.get(tradeId).onFiatPaymentReceived();
|
||||
sellerAsTakerProtocolMap.get(tradeId).onFiatPaymentReceived();
|
||||
}
|
||||
|
||||
|
||||
@ -315,9 +322,9 @@ public class TradeManager {
|
||||
OpenOffer openOffer = openOffers.remove(offerId);
|
||||
disposeCheckOfferAvailabilityRequest(openOffer.getOffer());
|
||||
persistOpenOffers();
|
||||
if (removeFromOffererAsBuyerProtocolMap && offererAsBuyerProtocolMap.containsKey(offerId)) {
|
||||
offererAsBuyerProtocolMap.get(offerId).cleanup();
|
||||
offererAsBuyerProtocolMap.remove(offerId);
|
||||
if (removeFromOffererAsBuyerProtocolMap && buyerAcceptsOfferProtocolMap.containsKey(offerId)) {
|
||||
buyerAcceptsOfferProtocolMap.get(offerId).cleanup();
|
||||
buyerAcceptsOfferProtocolMap.remove(offerId);
|
||||
}
|
||||
|
||||
resultHandler.handleResult();
|
||||
@ -343,7 +350,7 @@ public class TradeManager {
|
||||
return trade;
|
||||
}
|
||||
|
||||
private void createOffererAsBuyerProtocol(OpenOffer openOffer) {
|
||||
private void createBuyerAcceptsOfferProtocol(OpenOffer openOffer) {
|
||||
BuyerAsOffererModel model = new BuyerAsOffererModel(
|
||||
openOffer,
|
||||
tradeMessageService,
|
||||
@ -383,9 +390,9 @@ public class TradeManager {
|
||||
persistPendingTrades();
|
||||
break;
|
||||
case OFFERER_REJECTED:
|
||||
case FAILED:
|
||||
case MESSAGE_SENDING_FAILED:
|
||||
removeFailedTrade(trade);
|
||||
offererAsBuyerProtocolMap.get(trade.getId()).cleanup();
|
||||
buyerAcceptsOfferProtocolMap.get(trade.getId()).cleanup();
|
||||
break;
|
||||
default:
|
||||
log.error("Unhandled trade state: " + newValue);
|
||||
@ -400,7 +407,7 @@ public class TradeManager {
|
||||
});
|
||||
|
||||
BuyerAsOffererProtocol buyerAcceptsOfferProtocol = new BuyerAsOffererProtocol(model);
|
||||
offererAsBuyerProtocolMap.put(openOffer.getId(), buyerAcceptsOfferProtocol);
|
||||
buyerAcceptsOfferProtocolMap.put(openOffer.getId(), buyerAcceptsOfferProtocol);
|
||||
}
|
||||
|
||||
private void removeFailedTrade(Trade trade) {
|
||||
@ -414,13 +421,13 @@ public class TradeManager {
|
||||
pendingTrades.remove(trade.getId());
|
||||
persistPendingTrades();
|
||||
|
||||
if (takerAsSellerProtocolMap.containsKey(trade.getId())) {
|
||||
takerAsSellerProtocolMap.get(trade.getId()).cleanup();
|
||||
takerAsSellerProtocolMap.remove(trade.getId());
|
||||
if (sellerAsTakerProtocolMap.containsKey(trade.getId())) {
|
||||
sellerAsTakerProtocolMap.get(trade.getId()).cleanup();
|
||||
sellerAsTakerProtocolMap.remove(trade.getId());
|
||||
}
|
||||
else if (offererAsBuyerProtocolMap.containsKey(trade.getId())) {
|
||||
offererAsBuyerProtocolMap.get(trade.getId()).cleanup();
|
||||
offererAsBuyerProtocolMap.remove(trade.getId());
|
||||
else if (buyerAcceptsOfferProtocolMap.containsKey(trade.getId())) {
|
||||
buyerAcceptsOfferProtocolMap.get(trade.getId()).cleanup();
|
||||
buyerAcceptsOfferProtocolMap.remove(trade.getId());
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
|
@ -55,6 +55,6 @@ public class ProcessRespondToTakeOfferRequestMessage extends Task<SellerAsTakerM
|
||||
|
||||
@Override
|
||||
protected void applyStateOnFault() {
|
||||
// do nothing
|
||||
model.getTrade().setState(Trade.State.MESSAGE_SENDING_FAILED);
|
||||
}
|
||||
}
|
@ -21,14 +21,18 @@ import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerModel;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestTakeOfferMessage;
|
||||
import io.bitsquare.util.Utilities;
|
||||
import io.bitsquare.util.taskrunner.Task;
|
||||
import io.bitsquare.util.taskrunner.TaskRunner;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RequestTakeOffer extends Task<SellerAsTakerModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(RequestTakeOffer.class);
|
||||
private AnimationTimer timeoutTimer;
|
||||
|
||||
public RequestTakeOffer(TaskRunner taskHandler, SellerAsTakerModel model) {
|
||||
super(taskHandler, model);
|
||||
@ -36,10 +40,18 @@ public class RequestTakeOffer extends Task<SellerAsTakerModel> {
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
timeoutTimer = Utilities.setTimeout(10000, animationTimer -> {
|
||||
failed("Timeout reached. We did not get any response form the offerer.");
|
||||
model.getOffer().setState(Offer.State.OFFERER_OFFLINE);
|
||||
return null;
|
||||
});
|
||||
timeoutTimer.start();
|
||||
|
||||
model.getTradeMessageService().sendMessage(model.getPeer(), new RequestTakeOfferMessage(model.getTrade().getId()),
|
||||
new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
timeoutTimer.stop();
|
||||
complete();
|
||||
}
|
||||
|
||||
@ -53,6 +65,7 @@ public class RequestTakeOffer extends Task<SellerAsTakerModel> {
|
||||
|
||||
@Override
|
||||
protected void applyStateOnFault() {
|
||||
timeoutTimer.stop();
|
||||
if (model.getOffer().getState() != Offer.State.OFFERER_OFFLINE)
|
||||
model.getOffer().setState(Offer.State.AVAILABILITY_CHECK_FAILED);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user