mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-02-26 09:21:26 -05:00
re-enable triggered offers if within trigger price again
This commit is contained in:
parent
4a82c69507
commit
290a3738b7
@ -110,6 +110,10 @@ public final class OpenOffer implements Tradable {
|
||||
@Getter
|
||||
@Setter
|
||||
transient int numProcessingAttempts = 0;
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean deactivatedByTrigger;
|
||||
|
||||
public OpenOffer(Offer offer) {
|
||||
this(offer, 0, false);
|
||||
}
|
||||
@ -141,6 +145,7 @@ public final class OpenOffer implements Tradable {
|
||||
this.reserveTxHex = openOffer.reserveTxHex;
|
||||
this.reserveTxKey = openOffer.reserveTxKey;
|
||||
this.challenge = openOffer.challenge;
|
||||
this.deactivatedByTrigger = openOffer.deactivatedByTrigger;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -158,7 +163,8 @@ public final class OpenOffer implements Tradable {
|
||||
@Nullable String reserveTxHash,
|
||||
@Nullable String reserveTxHex,
|
||||
@Nullable String reserveTxKey,
|
||||
@Nullable String challenge) {
|
||||
@Nullable String challenge,
|
||||
boolean deactivatedByTrigger) {
|
||||
this.offer = offer;
|
||||
this.state = state;
|
||||
this.triggerPrice = triggerPrice;
|
||||
@ -170,6 +176,7 @@ public final class OpenOffer implements Tradable {
|
||||
this.reserveTxHex = reserveTxHex;
|
||||
this.reserveTxKey = reserveTxKey;
|
||||
this.challenge = challenge;
|
||||
this.deactivatedByTrigger = deactivatedByTrigger;
|
||||
|
||||
// reset reserved state to available
|
||||
if (this.state == State.RESERVED) setState(State.AVAILABLE);
|
||||
@ -182,7 +189,8 @@ public final class OpenOffer implements Tradable {
|
||||
.setTriggerPrice(triggerPrice)
|
||||
.setState(protobuf.OpenOffer.State.valueOf(state.name()))
|
||||
.setSplitOutputTxFee(splitOutputTxFee)
|
||||
.setReserveExactAmount(reserveExactAmount);
|
||||
.setReserveExactAmount(reserveExactAmount)
|
||||
.setDeactivatedByTrigger(deactivatedByTrigger);
|
||||
|
||||
Optional.ofNullable(scheduledAmount).ifPresent(e -> builder.setScheduledAmount(scheduledAmount));
|
||||
Optional.ofNullable(scheduledTxHashes).ifPresent(e -> builder.addAllScheduledTxHashes(scheduledTxHashes));
|
||||
@ -207,7 +215,8 @@ public final class OpenOffer implements Tradable {
|
||||
ProtoUtil.stringOrNullFromProto(proto.getReserveTxHash()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getReserveTxHex()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getReserveTxKey()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getChallenge()));
|
||||
ProtoUtil.stringOrNullFromProto(proto.getChallenge()),
|
||||
proto.getDeactivatedByTrigger());
|
||||
return openOffer;
|
||||
}
|
||||
|
||||
@ -234,6 +243,14 @@ public final class OpenOffer implements Tradable {
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
stateProperty.set(state);
|
||||
if (state == State.AVAILABLE) {
|
||||
deactivatedByTrigger = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void deactivate(boolean deactivatedByTrigger) {
|
||||
this.deactivatedByTrigger = deactivatedByTrigger;
|
||||
setState(State.DEACTIVATED);
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<State> stateProperty() {
|
||||
|
@ -604,13 +604,14 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
}
|
||||
|
||||
public void deactivateOpenOffer(OpenOffer openOffer,
|
||||
boolean deactivatedByTrigger,
|
||||
ResultHandler resultHandler,
|
||||
ErrorMessageHandler errorMessageHandler) {
|
||||
Offer offer = openOffer.getOffer();
|
||||
if (openOffer.isAvailable()) {
|
||||
offerBookService.deactivateOffer(offer.getOfferPayload(),
|
||||
() -> {
|
||||
openOffer.setState(OpenOffer.State.DEACTIVATED);
|
||||
openOffer.deactivate(deactivatedByTrigger);
|
||||
requestPersistence();
|
||||
log.debug("deactivateOpenOffer, offerId={}", offer.getId());
|
||||
resultHandler.handleResult();
|
||||
@ -661,6 +662,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
|
||||
if (openOffer.isAvailable()) {
|
||||
deactivateOpenOffer(openOffer,
|
||||
false,
|
||||
resultHandler,
|
||||
errorMessage -> {
|
||||
offersToBeEdited.remove(openOffer.getId());
|
||||
|
@ -92,12 +92,11 @@ public class TriggerPriceService {
|
||||
.filter(marketPrice -> openOffersByCurrency.containsKey(marketPrice.getCurrencyCode()))
|
||||
.forEach(marketPrice -> {
|
||||
openOffersByCurrency.get(marketPrice.getCurrencyCode()).stream()
|
||||
.filter(openOffer -> !openOffer.isDeactivated())
|
||||
.forEach(openOffer -> checkPriceThreshold(marketPrice, openOffer));
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean wasTriggered(MarketPrice marketPrice, OpenOffer openOffer) {
|
||||
public static boolean isTriggered(MarketPrice marketPrice, OpenOffer openOffer) {
|
||||
Price price = openOffer.getOffer().getPrice();
|
||||
if (price == null || marketPrice == null) {
|
||||
return false;
|
||||
@ -125,13 +124,12 @@ public class TriggerPriceService {
|
||||
}
|
||||
|
||||
private void checkPriceThreshold(MarketPrice marketPrice, OpenOffer openOffer) {
|
||||
if (wasTriggered(marketPrice, openOffer)) {
|
||||
String currencyCode = openOffer.getOffer().getCurrencyCode();
|
||||
int smallestUnitExponent = CurrencyUtil.isTraditionalCurrency(currencyCode) ?
|
||||
TraditionalMoney.SMALLEST_UNIT_EXPONENT :
|
||||
CryptoMoney.SMALLEST_UNIT_EXPONENT;
|
||||
long triggerPrice = openOffer.getTriggerPrice();
|
||||
String currencyCode = openOffer.getOffer().getCurrencyCode();
|
||||
int smallestUnitExponent = CurrencyUtil.isTraditionalCurrency(currencyCode) ?
|
||||
TraditionalMoney.SMALLEST_UNIT_EXPONENT :
|
||||
CryptoMoney.SMALLEST_UNIT_EXPONENT;
|
||||
|
||||
if (openOffer.getState() == OpenOffer.State.AVAILABLE && isTriggered(marketPrice, openOffer)) {
|
||||
log.info("Market price exceeded the trigger price of the open offer.\n" +
|
||||
"We deactivate the open offer with ID {}.\nCurrency: {};\nOffer direction: {};\n" +
|
||||
"Market price: {};\nTrigger price: {}",
|
||||
@ -139,14 +137,26 @@ public class TriggerPriceService {
|
||||
currencyCode,
|
||||
openOffer.getOffer().getDirection(),
|
||||
marketPrice.getPrice(),
|
||||
MathUtils.scaleDownByPowerOf10(triggerPrice, smallestUnitExponent)
|
||||
MathUtils.scaleDownByPowerOf10(openOffer.getTriggerPrice(), smallestUnitExponent)
|
||||
);
|
||||
|
||||
openOfferManager.deactivateOpenOffer(openOffer, () -> {
|
||||
openOfferManager.deactivateOpenOffer(openOffer, true, () -> {
|
||||
}, errorMessage -> {
|
||||
});
|
||||
} else if (openOffer.getState() == OpenOffer.State.DEACTIVATED && openOffer.isDeactivatedByTrigger() && !isTriggered(marketPrice, openOffer)) {
|
||||
log.info("Market price is back within the trigger price of the open offer.\n" +
|
||||
"We reactivate the open offer with ID {}.\nCurrency: {};\nOffer direction: {};\n" +
|
||||
"Market price: {};\nTrigger price: {}",
|
||||
openOffer.getOffer().getShortId(),
|
||||
currencyCode,
|
||||
openOffer.getOffer().getDirection(),
|
||||
marketPrice.getPrice(),
|
||||
MathUtils.scaleDownByPowerOf10(openOffer.getTriggerPrice(), smallestUnitExponent)
|
||||
);
|
||||
|
||||
openOfferManager.activateOpenOffer(openOffer, () -> {
|
||||
}, errorMessage -> {
|
||||
});
|
||||
} else if (openOffer.getState() == OpenOffer.State.AVAILABLE) {
|
||||
// TODO: check if open offer's reserve tx is failed or double spend seen
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ class OpenOffersDataModel extends ActivatableDataModel {
|
||||
}
|
||||
|
||||
void onDeactivateOpenOffer(OpenOffer openOffer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
openOfferManager.deactivateOpenOffer(openOffer, resultHandler, errorMessageHandler);
|
||||
openOfferManager.deactivateOpenOffer(openOffer, false, resultHandler, errorMessageHandler);
|
||||
}
|
||||
|
||||
void onRemoveOpenOffer(OpenOffer openOffer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
@ -94,7 +94,7 @@ class OpenOffersDataModel extends ActivatableDataModel {
|
||||
list.sort((o1, o2) -> o2.getOffer().getDate().compareTo(o1.getOffer().getDate()));
|
||||
}
|
||||
|
||||
boolean wasTriggered(OpenOffer openOffer) {
|
||||
return TriggerPriceService.wasTriggered(priceFeedService.getMarketPrice(openOffer.getOffer().getCurrencyCode()), openOffer);
|
||||
boolean isTriggered(OpenOffer openOffer) {
|
||||
return TriggerPriceService.isTriggered(priceFeedService.getMarketPrice(openOffer.getOffer().getCurrencyCode()), openOffer);
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
||||
}
|
||||
|
||||
private void onActivateOpenOffer(OpenOffer openOffer) {
|
||||
if (model.isBootstrappedOrShowPopup() && !model.dataModel.wasTriggered(openOffer)) {
|
||||
if (model.isBootstrappedOrShowPopup() && !model.dataModel.isTriggered(openOffer)) {
|
||||
model.onActivateOpenOffer(openOffer,
|
||||
() -> log.debug("Activate offer was successful"),
|
||||
(message) -> {
|
||||
@ -720,7 +720,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
||||
checkBox.setPadding(new Insets(-7, 0, -7, 0));
|
||||
checkBox.setGraphic(iconView);
|
||||
}
|
||||
checkBox.setDisable(model.dataModel.wasTriggered(openOffer));
|
||||
checkBox.setDisable(model.dataModel.isTriggered(openOffer));
|
||||
checkBox.setOnAction(event -> {
|
||||
if (openOffer.isDeactivated()) {
|
||||
onActivateOpenOffer(openOffer);
|
||||
@ -798,7 +798,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
||||
boolean triggerPriceSet = item.getOpenOffer().getTriggerPrice() > 0;
|
||||
button.setVisible(triggerPriceSet);
|
||||
|
||||
if (model.dataModel.wasTriggered(item.getOpenOffer())) {
|
||||
if (model.dataModel.isTriggered(item.getOpenOffer())) {
|
||||
button.getGraphic().getStyleClass().add("warning");
|
||||
button.setTooltip(new Tooltip(Res.get("openOffer.triggered")));
|
||||
} else {
|
||||
|
@ -1421,6 +1421,7 @@ message OpenOffer {
|
||||
string reserve_tx_hex = 10;
|
||||
string reserve_tx_key = 11;
|
||||
string challenge = 12;
|
||||
bool deactivated_by_trigger = 13;
|
||||
}
|
||||
|
||||
message Tradable {
|
||||
|
Loading…
x
Reference in New Issue
Block a user