From ba8a9ae21da6513b25cd5e107dd447f35fdc5b36 Mon Sep 17 00:00:00 2001 From: woodser Date: Tue, 2 Jan 2024 13:19:38 -0500 Subject: [PATCH] await external prices on startup --- .../haveno/core/offer/OpenOfferManager.java | 2 +- .../core/provider/price/PriceFeedService.java | 37 +++++++++++++------ .../core/support/dispute/DisputeManager.java | 2 +- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/haveno/core/offer/OpenOfferManager.java b/core/src/main/java/haveno/core/offer/OpenOfferManager.java index ce3a86a28d..27bf6fd9e9 100644 --- a/core/src/main/java/haveno/core/offer/OpenOfferManager.java +++ b/core/src/main/java/haveno/core/offer/OpenOfferManager.java @@ -403,7 +403,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe HavenoUtils.submitToThread(() -> { // Wait for prices to be available - priceFeedService.awaitPrices(); + priceFeedService.awaitExternalPrices(); // Republish means we send the complete offer object republishOffers(); diff --git a/core/src/main/java/haveno/core/provider/price/PriceFeedService.java b/core/src/main/java/haveno/core/provider/price/PriceFeedService.java index 4d2c4e08df..28cab49234 100644 --- a/core/src/main/java/haveno/core/provider/price/PriceFeedService.java +++ b/core/src/main/java/haveno/core/provider/price/PriceFeedService.java @@ -140,17 +140,24 @@ public class PriceFeedService { /** * Awaits prices to be available, but does not request them. */ - public void awaitPrices() { - if (hasPrices()) return; + public void awaitExternalPrices() { CountDownLatch latch = new CountDownLatch(1); - ChangeListener listener = (observable, oldValue, newValue) -> { latch.countDown(); }; + ChangeListener listener = (observable, oldValue, newValue) -> { + if (hasExternalPrices()) latch.countDown(); + }; updateCounter.addListener(listener); + if (hasExternalPrices()) { + updateCounter.removeListener(listener); + return; + } HavenoUtils.awaitLatch(latch); updateCounter.removeListener(listener); } - public boolean hasPrices() { - return !cache.isEmpty(); + public boolean hasExternalPrices() { + synchronized (cache) { + return cache.values().stream().anyMatch(MarketPrice::isExternallyProvidedPrice); + } } public void startRequestingPrices() { @@ -280,16 +287,20 @@ public class PriceFeedService { @Nullable public MarketPrice getMarketPrice(String currencyCode) { - return cache.getOrDefault(currencyCode, null); + synchronized (cache) { + return cache.getOrDefault(currencyCode, null); + } } private void setHavenoMarketPrice(String currencyCode, Price price) { UserThread.await(() -> { - if (!cache.containsKey(currencyCode) || !cache.get(currencyCode).isExternallyProvidedPrice()) { - cache.put(currencyCode, new MarketPrice(currencyCode, - MathUtils.scaleDownByPowerOf10(price.getValue(), CurrencyUtil.isCryptoCurrency(currencyCode) ? CryptoMoney.SMALLEST_UNIT_EXPONENT : TraditionalMoney.SMALLEST_UNIT_EXPONENT), - 0, - false)); + synchronized (cache) { + if (!cache.containsKey(currencyCode) || !cache.get(currencyCode).isExternallyProvidedPrice()) { + cache.put(currencyCode, new MarketPrice(currencyCode, + MathUtils.scaleDownByPowerOf10(price.getValue(), CurrencyUtil.isCryptoCurrency(currencyCode) ? CryptoMoney.SMALLEST_UNIT_EXPONENT : TraditionalMoney.SMALLEST_UNIT_EXPONENT), + 0, + false)); + } updateCounter.set(updateCounter.get() + 1); } }); @@ -456,7 +467,9 @@ public class PriceFeedService { Map priceMap = result; - cache.putAll(priceMap); + synchronized (cache) { + cache.putAll(priceMap); + } resultHandler.run(); }); diff --git a/core/src/main/java/haveno/core/support/dispute/DisputeManager.java b/core/src/main/java/haveno/core/support/dispute/DisputeManager.java index 7115540216..256ad8c42c 100644 --- a/core/src/main/java/haveno/core/support/dispute/DisputeManager.java +++ b/core/src/main/java/haveno/core/support/dispute/DisputeManager.java @@ -1022,7 +1022,7 @@ public abstract class DisputeManager> extends Sup // proposal). But if gain is larger than this loss he has economically an incentive to default in the trade. // We do all those calculations to give a hint to mediators to detect option trades. protected void addPriceInfoMessage(Dispute dispute, int counter) { - if (!priceFeedService.hasPrices()) { + if (!priceFeedService.hasExternalPrices()) { if (counter < 3) { log.info("Price provider has still no data. This is expected at startup. We try again in 10 sec."); UserThread.runAfter(() -> addPriceInfoMessage(dispute, counter + 1), 10);