From c53695ae609119580a2cb74f3c838cb47bf3f11a Mon Sep 17 00:00:00 2001 From: Chris Beams Date: Wed, 24 Jan 2018 02:50:09 +0100 Subject: [PATCH] Remove provider module after extracting to new repo See bisq-network/pricenode#2 --- pom.xml | 1 - provider/pom.xml | 152 ----------- .../java/io/bisq/provider/ProviderMain.java | 130 ---------- .../io/bisq/provider/ProviderVersion.java | 22 -- .../bisq/provider/fee/FeeRequestService.java | 102 -------- .../fee/providers/BtcFeesProvider.java | 68 ----- .../io/bisq/provider/price/PriceData.java | 28 -- .../provider/price/PriceRequestService.java | 240 ------------------ .../price/providers/BtcAverageProvider.java | 101 -------- .../providers/CoinmarketcapProvider.java | 45 ---- .../price/providers/PoloniexProvider.java | 69 ----- provider/src/main/resources/logback.xml | 30 --- .../fee/providers/BtcFeesProviderTest.java | 55 ---- 13 files changed, 1043 deletions(-) delete mode 100644 provider/pom.xml delete mode 100644 provider/src/main/java/io/bisq/provider/ProviderMain.java delete mode 100644 provider/src/main/java/io/bisq/provider/ProviderVersion.java delete mode 100644 provider/src/main/java/io/bisq/provider/fee/FeeRequestService.java delete mode 100644 provider/src/main/java/io/bisq/provider/fee/providers/BtcFeesProvider.java delete mode 100644 provider/src/main/java/io/bisq/provider/price/PriceData.java delete mode 100644 provider/src/main/java/io/bisq/provider/price/PriceRequestService.java delete mode 100644 provider/src/main/java/io/bisq/provider/price/providers/BtcAverageProvider.java delete mode 100644 provider/src/main/java/io/bisq/provider/price/providers/CoinmarketcapProvider.java delete mode 100644 provider/src/main/java/io/bisq/provider/price/providers/PoloniexProvider.java delete mode 100644 provider/src/main/resources/logback.xml delete mode 100644 provider/src/test/java/io/bisq/provider/fee/providers/BtcFeesProviderTest.java diff --git a/pom.xml b/pom.xml index 67d9769dad..b30a6fca12 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,6 @@ gui seednode statistics - provider consensus monitor diff --git a/provider/pom.xml b/provider/pom.xml deleted file mode 100644 index a385bada81..0000000000 --- a/provider/pom.xml +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - parent - io.bisq - 0.6.4 - - 4.0.0 - - provider - - - - - - false - ${basedir}/src/main/java - - **/*.fxml - **/*.css - - - - false - ${basedir}/src/main/resources - - **/*.* - - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.0.1 - - - copy-bouncycastle - package - - copy - - - true - - - org.bouncycastle - bcprov-jdk15on - true - ${project.build.directory}/lib - - - org.bouncycastle - bcpg-jdk15on - true - ${project.build.directory}/lib - - - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.1.0 - - - - org.bouncycastle:*:*:* - - - - false - - - - io.bisq.provider.ProviderMain - - lib/bcpg-jdk15on.jar lib/bcprov-jdk15on.jar - - - - true - - - - *:* - - META-INF/maven/**/pom.properties - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - package - - shade - - - true - bundled - provider - - - - - - - - - - - io.bisq - core - ${project.version} - - - - com.sparkjava - spark-core - 2.5.2 - - - diff --git a/provider/src/main/java/io/bisq/provider/ProviderMain.java b/provider/src/main/java/io/bisq/provider/ProviderMain.java deleted file mode 100644 index 80df3a4d36..0000000000 --- a/provider/src/main/java/io/bisq/provider/ProviderMain.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package io.bisq.provider; - -import ch.qos.logback.classic.Level; -import io.bisq.common.app.Log; -import io.bisq.common.app.Version; -import io.bisq.common.util.Utilities; -import io.bisq.network.http.HttpException; -import io.bisq.provider.fee.FeeRequestService; -import io.bisq.provider.fee.providers.BtcFeesProvider; -import io.bisq.provider.price.PriceRequestService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.spec.InvalidKeySpecException; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - -import static spark.Spark.get; -import static spark.Spark.port; - -public class ProviderMain { - private static final Logger log = LoggerFactory.getLogger(ProviderMain.class); - - static { - // Need to set default locale initially otherwise we get problems at non-english OS - Locale.setDefault(new Locale("en", Locale.getDefault().getCountry())); - - Utilities.removeCryptographyRestrictions(); - } - - public static void main(String[] args) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException, HttpException { - final String logPath = System.getProperty("user.home") + File.separator + "provider"; - Log.setup(logPath); - Log.setLevel(Level.INFO); - log.info("Log files under: " + logPath); - log.info("ProviderVersion.VERSION: " + ProviderVersion.VERSION); - log.info("Bisq exchange Version{" + - "VERSION=" + Version.VERSION + - ", P2P_NETWORK_VERSION=" + Version.P2P_NETWORK_VERSION + - ", LOCAL_DB_VERSION=" + Version.LOCAL_DB_VERSION + - ", TRADE_PROTOCOL_VERSION=" + Version.TRADE_PROTOCOL_VERSION + - ", BASE_CURRENCY_NETWORK=NOT SET" + - ", getP2PNetworkId()=NOT SET" + - '}'); - Utilities.printSysInfo(); - - String bitcoinAveragePrivKey = null; - String bitcoinAveragePubKey = null; - int capacity = BtcFeesProvider.CAPACITY; - int maxBlocks = BtcFeesProvider.MAX_BLOCKS; - long requestIntervalInMs = TimeUnit.MINUTES.toMillis(FeeRequestService.REQUEST_INTERVAL_MIN); - - // extract command line arguments - if (args.length < 2) { - log.error("You need to provide the BitcoinAverage API keys. Private key as first argument, public key as second argument."); - System.exit(1); - } - if (args.length >= 2) { - bitcoinAveragePrivKey = args[0]; - bitcoinAveragePubKey = args[1]; - } - if (args.length >= 4) { - capacity = Integer.valueOf(args[2]); - maxBlocks = Integer.valueOf(args[3]); - } - if (args.length >= 5) { - requestIntervalInMs = TimeUnit.MINUTES.toMillis(Long.valueOf(args[4])); - } - - port(8080); - - handleGetAllMarketPrices(bitcoinAveragePrivKey, bitcoinAveragePubKey); - handleGetFees(capacity, maxBlocks, requestIntervalInMs); - handleGetVersion(); - handleGetParams(capacity, maxBlocks, requestIntervalInMs); - } - - private static void handleGetAllMarketPrices(String bitcoinAveragePrivKey, String bitcoinAveragePubKey) - throws IOException, NoSuchAlgorithmException, InvalidKeyException { - PriceRequestService priceRequestService = new PriceRequestService(bitcoinAveragePrivKey, bitcoinAveragePubKey); - get("/getAllMarketPrices", (req, res) -> { - log.info("Incoming getAllMarketPrices request from: " + req.userAgent()); - return priceRequestService.getJson(); - }); - } - - private static void handleGetFees(int capacity, int maxBlocks, long requestIntervalInMs) throws IOException { - FeeRequestService feeRequestService = new FeeRequestService(capacity, maxBlocks, requestIntervalInMs); - get("/getFees", (req, res) -> { - log.info("Incoming getFees request from: " + req.userAgent()); - return feeRequestService.getJson(); - }); - } - - private static void handleGetVersion() throws IOException { - get("/getVersion", (req, res) -> { - log.info("Incoming getVersion request from: " + req.userAgent()); - return ProviderVersion.VERSION; - }); - } - - private static void handleGetParams(int capacity, int maxBlocks, long requestIntervalInMs) throws IOException { - get("/getParams", (req, res) -> { - log.info("Incoming getParams request from: " + req.userAgent()); - return capacity + ";" + maxBlocks + ";" + requestIntervalInMs; - }); - } -} diff --git a/provider/src/main/java/io/bisq/provider/ProviderVersion.java b/provider/src/main/java/io/bisq/provider/ProviderVersion.java deleted file mode 100644 index fa132b98bb..0000000000 --- a/provider/src/main/java/io/bisq/provider/ProviderVersion.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file is part of bisq. - * - * bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with bisq. If not, see . - */ - -package io.bisq.provider; - -public class ProviderVersion { - public static final String VERSION = "0.6.4"; -} diff --git a/provider/src/main/java/io/bisq/provider/fee/FeeRequestService.java b/provider/src/main/java/io/bisq/provider/fee/FeeRequestService.java deleted file mode 100644 index 05c198a0e3..0000000000 --- a/provider/src/main/java/io/bisq/provider/fee/FeeRequestService.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package io.bisq.provider.fee; - -import io.bisq.common.util.Utilities; -import io.bisq.core.provider.fee.FeeService; -import io.bisq.provider.fee.providers.BtcFeesProvider; -import lombok.extern.slf4j.Slf4j; - -import java.io.IOException; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; - -@Slf4j -public class FeeRequestService { - public static int REQUEST_INTERVAL_MIN = 5; - - public static final long BTC_MIN_TX_FEE = 10; // satoshi/byte - public static final long BTC_MAX_TX_FEE = 1000; - - private final Timer timerBitcoinFeesLocal = new Timer(); - - private final BtcFeesProvider btcFeesProvider; - private final Map dataMap = new ConcurrentHashMap<>(); - private long bitcoinFeesTs; - private String json; - - public FeeRequestService(int capacity, int maxBlocks, long requestIntervalInMs) throws IOException { - btcFeesProvider = new BtcFeesProvider(capacity, maxBlocks); - - // For now we don't need a fee estimation for LTC so we set it fixed, but we keep it in the provider to - // be flexible if fee pressure grows on LTC - dataMap.put("ltcTxFee", FeeService.LTC_DEFAULT_TX_FEE); - dataMap.put("dogeTxFee", FeeService.DOGE_DEFAULT_TX_FEE); - dataMap.put("dashTxFee", FeeService.DASH_DEFAULT_TX_FEE); - - writeToJson(); - startRequests(requestIntervalInMs); - } - - private void startRequests(long requestIntervalInMs) throws IOException { - timerBitcoinFeesLocal.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - try { - requestBitcoinFees(); - } catch (IOException e) { - log.warn(e.toString()); - e.printStackTrace(); - } - } - }, requestIntervalInMs, requestIntervalInMs); - - - requestBitcoinFees(); - } - - private void requestBitcoinFees() throws IOException { - long ts = System.currentTimeMillis(); - long btcFee = btcFeesProvider.getFee(); - log.info("requestBitcoinFees took {} ms.", (System.currentTimeMillis() - ts)); - if (btcFee < FeeRequestService.BTC_MIN_TX_FEE) { - log.warn("Response for fee is lower as min fee. Fee=" + btcFee); - } else if (btcFee > FeeRequestService.BTC_MAX_TX_FEE) { - log.warn("Response for fee is larger as max fee. Fee=" + btcFee); - } else { - bitcoinFeesTs = Instant.now().getEpochSecond(); - dataMap.put("btcTxFee", btcFee); - writeToJson(); - } - } - - private void writeToJson() { - Map map = new HashMap<>(); - map.put("bitcoinFeesTs", bitcoinFeesTs); - map.put("dataMap", dataMap); - json = Utilities.objectToJson(map); - } - - public String getJson() { - return json; - } -} diff --git a/provider/src/main/java/io/bisq/provider/fee/providers/BtcFeesProvider.java b/provider/src/main/java/io/bisq/provider/fee/providers/BtcFeesProvider.java deleted file mode 100644 index 5c620f379b..0000000000 --- a/provider/src/main/java/io/bisq/provider/fee/providers/BtcFeesProvider.java +++ /dev/null @@ -1,68 +0,0 @@ -package io.bisq.provider.fee.providers; - -import com.google.gson.Gson; -import com.google.gson.internal.LinkedTreeMap; -import io.bisq.common.util.MathUtils; -import io.bisq.network.http.HttpClient; -import io.bisq.provider.fee.FeeRequestService; -import lombok.extern.slf4j.Slf4j; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.LinkedList; - -//TODO consider alternative https://www.bitgo.com/api/v1/tx/fee?numBlocks=3 -@Slf4j -public class BtcFeesProvider { - public static int CAPACITY = 4; // if we request each 5 min. we take average of last 20 min. - public static int MAX_BLOCKS = 10; - - private final HttpClient httpClient; - LinkedList fees = new LinkedList<>(); - private final int capacity; - private final int maxBlocks; - - // other: https://estimatefee.com/n/2 - public BtcFeesProvider(int capacity, int maxBlocks) { - this.capacity = capacity; - this.maxBlocks = maxBlocks; - this.httpClient = new HttpClient("https://bitcoinfees.earn.com/api/v1/fees/"); - } - - public Long getFee() throws IOException { - // prev. used: https://bitcoinfees.earn.com/api/v1/fees/recommended - // but was way too high - - // https://bitcoinfees.earn.com/api/v1/fees/list - String response = httpClient.requestWithGET("list", "User-Agent", ""); - log.info("Get recommended fee response: " + response); - - LinkedTreeMap>> treeMap = new Gson().fromJson(response, LinkedTreeMap.class); - final long[] fee = new long[1]; - // we want a fee which is at least in 20 blocks in (21.co estimation seem to be way too high, so we get - // prob much faster in - treeMap.entrySet().stream() - .flatMap(e -> e.getValue().stream()) - .forEach(e -> { - Double maxDelay = e.get("maxDelay"); - if (maxDelay <= maxBlocks && fee[0] == 0) - fee[0] = MathUtils.roundDoubleToLong(e.get("maxFee")); - }); - fee[0] = Math.min(Math.max(fee[0], FeeRequestService.BTC_MIN_TX_FEE), FeeRequestService.BTC_MAX_TX_FEE); - - return getAverage(fee[0]); - } - - // We take the average of the last 12 calls (every 5 minute) so we smooth extreme values. - // We observed very radical jumps in the fee estimations, so that should help to avoid that. - long getAverage(long newFee) { - log.info("new fee " + newFee); - fees.add(newFee); - long average = ((Double) fees.stream().mapToDouble(e -> e).average().getAsDouble()).longValue(); - log.info("average of last {} calls: {}", fees.size(), average); - if (fees.size() == capacity) - fees.removeFirst(); - - return average; - } -} diff --git a/provider/src/main/java/io/bisq/provider/price/PriceData.java b/provider/src/main/java/io/bisq/provider/price/PriceData.java deleted file mode 100644 index 4bf848d6de..0000000000 --- a/provider/src/main/java/io/bisq/provider/price/PriceData.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package io.bisq.provider.price; - -import lombok.Value; - -@Value -public class PriceData { - private final String currencyCode; - private final double price; - private final long timestampSec; - private final String provider; -} diff --git a/provider/src/main/java/io/bisq/provider/price/PriceRequestService.java b/provider/src/main/java/io/bisq/provider/price/PriceRequestService.java deleted file mode 100644 index 02ef8fff2f..0000000000 --- a/provider/src/main/java/io/bisq/provider/price/PriceRequestService.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package io.bisq.provider.price; - -import io.bisq.common.util.Utilities; -import io.bisq.provider.price.providers.BtcAverageProvider; -import io.bisq.provider.price.providers.CoinmarketcapProvider; -import io.bisq.provider.price.providers.PoloniexProvider; -import lombok.extern.slf4j.Slf4j; - -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -@Slf4j -public class PriceRequestService { - public static final String POLO_PROVIDER = "POLO"; - public static final String COINMKTC_PROVIDER = "CMC"; - public static final String BTCAVERAGE_LOCAL_PROVIDER = "BTCA_L"; - public static final String BTCAVERAGE_GLOBAL_PROVIDER = "BTCA_G"; - - // We adjust request time to fit into BitcoinAverage developer plan (45k request per month). - // We get 42514 (29760+12754) request with below numbers. - private static final long INTERVAL_BTC_AV_LOCAL_MS = 90_000; // 90 sec; 29760 requests for 31 days - private static final long INTERVAL_BTC_AV_GLOBAL_MS = 210_000; // 3.5 min; 12754 requests for 31 days - - private static final long INTERVAL_POLONIEX_MS = 60_000; // 1 min - private static final long INTERVAL_COIN_MARKET_CAP_MS = 300_000; // 5 min that data structure is quite heavy so we don't request too often. - private static final long MARKET_PRICE_TTL_SEC = 1800; // 30 min - - private final Timer timerBtcAverageLocal = new Timer(); - private final Timer timerBtcAverageGlobal = new Timer(); - private final Timer timerPoloniex = new Timer(); - private final Timer timerCoinmarketcap = new Timer(); - - private final BtcAverageProvider btcAverageProvider; - private final PoloniexProvider poloniexProvider; - private final CoinmarketcapProvider coinmarketcapProvider; - - private final Map allPricesMap = new ConcurrentHashMap<>(); - private Map btcAverageLocalMap; - private Map poloniexMap; - - private long btcAverageTs; - private long poloniexTs; - private long coinmarketcapTs; - private long btcAverageLCount; - private long btcAverageGCount; - private long poloniexCount; - private long coinmarketcapCount; - - private String json; - - public PriceRequestService(String bitcoinAveragePrivKey, String bitcoinAveragePubKey) throws IOException, NoSuchAlgorithmException, InvalidKeyException { - btcAverageProvider = new BtcAverageProvider(bitcoinAveragePrivKey, bitcoinAveragePubKey); - poloniexProvider = new PoloniexProvider(); - coinmarketcapProvider = new CoinmarketcapProvider(); - - startRequests(); - } - - public String getJson() { - return json; - } - - private void startRequests() throws InvalidKeyException, NoSuchAlgorithmException, IOException { - timerBtcAverageLocal.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - try { - requestBtcAverageLocalPrices(); - } catch (Throwable e) { - log.warn(e.toString()); - e.printStackTrace(); - } - } - }, INTERVAL_BTC_AV_LOCAL_MS, INTERVAL_BTC_AV_LOCAL_MS); - - timerBtcAverageGlobal.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - try { - requestBtcAverageGlobalPrices(); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - log.error(e.toString()); - e.printStackTrace(); - } catch (IOException e) { - log.warn(e.toString()); - e.printStackTrace(); - } - } - }, INTERVAL_BTC_AV_GLOBAL_MS, INTERVAL_BTC_AV_GLOBAL_MS); - - timerPoloniex.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - try { - requestPoloniexPrices(); - } catch (IOException e) { - log.warn(e.toString()); - e.printStackTrace(); - } - } - }, INTERVAL_POLONIEX_MS, INTERVAL_POLONIEX_MS); - - timerCoinmarketcap.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - try { - requestCoinmarketcapPrices(); - } catch (IOException e) { - log.warn(e.toString()); - e.printStackTrace(); - } - } - }, INTERVAL_COIN_MARKET_CAP_MS, INTERVAL_COIN_MARKET_CAP_MS); - - requestBtcAverageLocalPrices(); - requestBtcAverageGlobalPrices(); - requestPoloniexPrices(); - requestCoinmarketcapPrices(); - } - - - private void requestCoinmarketcapPrices() throws IOException { - long ts = System.currentTimeMillis(); - Map map = coinmarketcapProvider.request(); - log.info("requestCoinmarketcapPrices took {} ms.", (System.currentTimeMillis() - ts)); - removeOutdatedPrices(poloniexMap); - removeOutdatedPrices(allPricesMap); - // we don't replace prices which we got form the Poloniex request, just in case the Coinmarketcap data are - // received earlier at startup we allow them but Poloniex will overwrite them. - map.entrySet().stream() - .filter(e -> poloniexMap == null || !poloniexMap.containsKey(e.getKey())) - .forEach(e -> allPricesMap.put(e.getKey(), e.getValue())); - coinmarketcapTs = Instant.now().getEpochSecond(); - coinmarketcapCount = map.size(); - - if (map.get("LTC") != null) - log.info("Coinmarketcap LTC (last): " + map.get("LTC").getPrice()); - - writeToJson(); - } - - - private void requestPoloniexPrices() throws IOException { - long ts = System.currentTimeMillis(); - poloniexMap = poloniexProvider.request(); - log.info("requestPoloniexPrices took {} ms.", (System.currentTimeMillis() - ts)); - removeOutdatedPrices(allPricesMap); - allPricesMap.putAll(poloniexMap); - poloniexTs = Instant.now().getEpochSecond(); - poloniexCount = poloniexMap.size(); - - if (poloniexMap.get("LTC") != null) - log.info("Poloniex LTC (last): " + poloniexMap.get("LTC").getPrice()); - - writeToJson(); - } - - private void requestBtcAverageLocalPrices() throws NoSuchAlgorithmException, InvalidKeyException, IOException { - long ts = System.currentTimeMillis(); - btcAverageLocalMap = btcAverageProvider.getLocal(); - - if (btcAverageLocalMap.get("USD") != null) - log.info("BTCAverage local USD (last):" + btcAverageLocalMap.get("USD").getPrice()); - log.info("requestBtcAverageLocalPrices took {} ms.", (System.currentTimeMillis() - ts)); - - removeOutdatedPrices(allPricesMap); - allPricesMap.putAll(btcAverageLocalMap); - btcAverageTs = Instant.now().getEpochSecond(); - btcAverageLCount = btcAverageLocalMap.size(); - writeToJson(); - } - - private void requestBtcAverageGlobalPrices() throws NoSuchAlgorithmException, InvalidKeyException, IOException { - long ts = System.currentTimeMillis(); - Map map = btcAverageProvider.getGlobal(); - - if (map.get("USD") != null) - log.info("BTCAverage global USD (last):" + map.get("USD").getPrice()); - log.info("requestBtcAverageGlobalPrices took {} ms.", (System.currentTimeMillis() - ts)); - - removeOutdatedPrices(btcAverageLocalMap); - removeOutdatedPrices(allPricesMap); - // we don't replace prices which we got form the local request, just in case the global data are received - // earlier at startup we allow them but the local request will overwrite them. - map.entrySet().stream() - .filter(e -> btcAverageLocalMap == null || !btcAverageLocalMap.containsKey(e.getKey())) - .forEach(e -> allPricesMap.put(e.getKey(), e.getValue())); - btcAverageTs = Instant.now().getEpochSecond(); - btcAverageGCount = map.size(); - writeToJson(); - } - - private void writeToJson() { - Map map = new LinkedHashMap<>(); - map.put("btcAverageTs", btcAverageTs); - map.put("poloniexTs", poloniexTs); - map.put("coinmarketcapTs", coinmarketcapTs); - map.put("btcAverageLCount", btcAverageLCount); - map.put("btcAverageGCount", btcAverageGCount); - map.put("poloniexCount", poloniexCount); - map.put("coinmarketcapCount", coinmarketcapCount); - map.put("data", allPricesMap.values().toArray()); - json = Utilities.objectToJson(map); - } - - private void removeOutdatedPrices(Map map) { - long now = Instant.now().getEpochSecond(); - long limit = now - MARKET_PRICE_TTL_SEC; - Map filtered = map.entrySet().stream() - .filter(e -> e.getValue().getTimestampSec() > limit) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - map.clear(); - map.putAll(filtered); - } -} diff --git a/provider/src/main/java/io/bisq/provider/price/providers/BtcAverageProvider.java b/provider/src/main/java/io/bisq/provider/price/providers/BtcAverageProvider.java deleted file mode 100644 index 8d649b5b2f..0000000000 --- a/provider/src/main/java/io/bisq/provider/price/providers/BtcAverageProvider.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package io.bisq.provider.price.providers; - -import com.google.gson.Gson; -import com.google.gson.internal.LinkedTreeMap; -import io.bisq.network.http.HttpClient; -import io.bisq.provider.price.PriceData; -import io.bisq.provider.price.PriceRequestService; -import org.bouncycastle.util.encoders.Hex; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; - -public class BtcAverageProvider { - private static final Logger log = LoggerFactory.getLogger(BtcAverageProvider.class); - - private final HttpClient httpClient; - private final String pubKey; - private final SecretKey secretKey; - - public BtcAverageProvider(String privKey, String pubKey) { - this.httpClient = new HttpClient("https://apiv2.bitcoinaverage.com/"); - this.pubKey = pubKey; - this.secretKey = new SecretKeySpec(privKey.getBytes(), "HmacSHA256"); - } - - private String getHeader() throws NoSuchAlgorithmException, InvalidKeyException { - String payload = Instant.now().getEpochSecond() + "." + pubKey; - Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(secretKey); - return payload + "." + Hex.toHexString(mac.doFinal(payload.getBytes())); - } - - public Map getLocal() throws NoSuchAlgorithmException, InvalidKeyException, IOException { - return getMap(httpClient.requestWithGETNoProxy("indices/local/ticker/all?crypto=BTC", "X-signature", getHeader()), PriceRequestService.BTCAVERAGE_LOCAL_PROVIDER); - } - - public Map getGlobal() throws NoSuchAlgorithmException, InvalidKeyException, IOException { - return getMap(httpClient.requestWithGETNoProxy("indices/global/ticker/all?crypto=BTC", "X-signature", getHeader()), PriceRequestService.BTCAVERAGE_GLOBAL_PROVIDER); - } - - private Map getMap(String json, String provider) { - Map marketPriceMap = new HashMap<>(); - LinkedTreeMap treeMap = new Gson().>fromJson(json, LinkedTreeMap.class); - long ts = Instant.now().getEpochSecond(); - treeMap.entrySet().stream().forEach(e -> { - Object value = e.getValue(); - // We need to check the type as we get an unexpected "timestamp" object at the end: - if (value instanceof LinkedTreeMap) { - //noinspection unchecked - LinkedTreeMap data = (LinkedTreeMap) value; - String currencyCode = e.getKey().substring(3); - // We ignore venezuelan currency as the official exchange rate is wishful thinking only.... - // We should use that api with a custom provider: http://api.bitcoinvenezuela.com/1 - if (!("VEF".equals(currencyCode))) { - try { - final Object lastAsObject = data.get("last"); - double last = 0; - if (lastAsObject instanceof String) - last = Double.valueOf((String) lastAsObject); - else if (lastAsObject instanceof Double) - last = (double) lastAsObject; - else - log.warn("Unexpected data type: lastAsObject=" + lastAsObject); - - marketPriceMap.put(currencyCode, - new PriceData(currencyCode, last, ts, provider)); - } catch (Throwable exception) { - log.error("Error converting btcaverage data: " + currencyCode, exception); - } - } - } - }); - return marketPriceMap; - } -} diff --git a/provider/src/main/java/io/bisq/provider/price/providers/CoinmarketcapProvider.java b/provider/src/main/java/io/bisq/provider/price/providers/CoinmarketcapProvider.java deleted file mode 100644 index de7acf3c37..0000000000 --- a/provider/src/main/java/io/bisq/provider/price/providers/CoinmarketcapProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -package io.bisq.provider.price.providers; - -import com.google.gson.Gson; -import com.google.gson.internal.LinkedTreeMap; -import io.bisq.common.locale.CurrencyUtil; -import io.bisq.common.locale.TradeCurrency; -import io.bisq.network.http.HttpClient; -import io.bisq.provider.price.PriceData; -import io.bisq.provider.price.PriceRequestService; - -import java.io.IOException; -import java.time.Instant; -import java.util.*; -import java.util.stream.Collectors; - -import static java.lang.Double.parseDouble; - -public class CoinmarketcapProvider { - private final Set supportedAltcoins; - - private final HttpClient httpClient; - - public CoinmarketcapProvider() { - this.httpClient = new HttpClient("https://api.coinmarketcap.com/"); - supportedAltcoins = CurrencyUtil.getAllSortedCryptoCurrencies().stream() - .map(TradeCurrency::getCode) - .collect(Collectors.toSet()); - } - - public Map request() throws IOException { - Map marketPriceMap = new HashMap<>(); - String response = httpClient.requestWithGET("v1/ticker/?limit=200", "User-Agent", ""); - //noinspection unchecked - List> list = new Gson().fromJson(response, ArrayList.class); - long ts = Instant.now().getEpochSecond(); - list.stream().forEach(treeMap -> { - String code = (String) treeMap.get("symbol"); - if (supportedAltcoins.contains(code)) { - double price_btc = parseDouble((String) treeMap.get("price_btc")); - marketPriceMap.put(code, new PriceData(code, price_btc, ts, PriceRequestService.COINMKTC_PROVIDER)); - } - }); - return marketPriceMap; - } -} diff --git a/provider/src/main/java/io/bisq/provider/price/providers/PoloniexProvider.java b/provider/src/main/java/io/bisq/provider/price/providers/PoloniexProvider.java deleted file mode 100644 index 48cb9e4e0b..0000000000 --- a/provider/src/main/java/io/bisq/provider/price/providers/PoloniexProvider.java +++ /dev/null @@ -1,69 +0,0 @@ -package io.bisq.provider.price.providers; - -import com.google.gson.Gson; -import com.google.gson.internal.LinkedTreeMap; -import io.bisq.common.locale.CurrencyUtil; -import io.bisq.common.locale.TradeCurrency; -import io.bisq.network.http.HttpClient; -import io.bisq.provider.price.PriceData; -import io.bisq.provider.price.PriceRequestService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import static java.lang.Double.parseDouble; - -public class PoloniexProvider { - private static final Logger log = LoggerFactory.getLogger(PoloniexProvider.class); - - private final Set supportedAltcoins; - private final HttpClient httpClient; - - public PoloniexProvider() { - this.httpClient = new HttpClient("https://poloniex.com/public"); - - supportedAltcoins = CurrencyUtil.getAllSortedCryptoCurrencies().stream() - .map(TradeCurrency::getCode) - .collect(Collectors.toSet()); - } - - public Map request() throws IOException { - Map marketPriceMap = new HashMap<>(); - String response = httpClient.requestWithGET("?command=returnTicker", "User-Agent", ""); - //noinspection unchecked - LinkedTreeMap treeMap = new Gson().fromJson(response, LinkedTreeMap.class); - long ts = Instant.now().getEpochSecond(); - treeMap.entrySet().stream().forEach(e -> { - Object value = e.getValue(); - String invertedCurrencyPair = e.getKey(); - String altcoinCurrency = null; - if (invertedCurrencyPair.startsWith("BTC")) { - String[] tokens = invertedCurrencyPair.split("_"); - if (tokens.length == 2) { - altcoinCurrency = tokens[1]; - if (supportedAltcoins.contains(altcoinCurrency)) { - if (value instanceof LinkedTreeMap) { - //noinspection unchecked - LinkedTreeMap data = (LinkedTreeMap) value; - marketPriceMap.put(altcoinCurrency, - new PriceData(altcoinCurrency, - parseDouble((String) data.get("last")), - ts, - PriceRequestService.POLO_PROVIDER) - ); - } - } - } else { - log.error("invertedCurrencyPair has invalid format: invertedCurrencyPair=" + invertedCurrencyPair); - } - } - }); - return marketPriceMap; - } -} diff --git a/provider/src/main/resources/logback.xml b/provider/src/main/resources/logback.xml deleted file mode 100644 index 0dac7c4753..0000000000 --- a/provider/src/main/resources/logback.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - %highlight(%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{15}: %msg %xEx%n) - - - - - - - - diff --git a/provider/src/test/java/io/bisq/provider/fee/providers/BtcFeesProviderTest.java b/provider/src/test/java/io/bisq/provider/fee/providers/BtcFeesProviderTest.java deleted file mode 100644 index f289698969..0000000000 --- a/provider/src/test/java/io/bisq/provider/fee/providers/BtcFeesProviderTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of bisq. - * - * bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with bisq. If not, see . - */ - -package io.bisq.provider.fee.providers; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class BtcFeesProviderTest { - - @Test - public void testGetAverage() { - BtcFeesProvider btcFeesProvider = new BtcFeesProvider(BtcFeesProvider.CAPACITY, BtcFeesProvider.MAX_BLOCKS); - - assertEquals(0, btcFeesProvider.getAverage(0)); - - btcFeesProvider = new BtcFeesProvider(BtcFeesProvider.CAPACITY, BtcFeesProvider.MAX_BLOCKS); - assertEquals(1, btcFeesProvider.getAverage(1)); - - btcFeesProvider = new BtcFeesProvider(BtcFeesProvider.CAPACITY, BtcFeesProvider.MAX_BLOCKS); - assertEquals(0, btcFeesProvider.getAverage(0)); - assertEquals(0, btcFeesProvider.getAverage(1)); - - btcFeesProvider = new BtcFeesProvider(BtcFeesProvider.CAPACITY, BtcFeesProvider.MAX_BLOCKS); - assertEquals(0, btcFeesProvider.getAverage(0)); - assertEquals(1, btcFeesProvider.getAverage(2)); - - BtcFeesProvider.CAPACITY = 5; - btcFeesProvider = new BtcFeesProvider(BtcFeesProvider.CAPACITY, BtcFeesProvider.MAX_BLOCKS); - assertEquals(10, btcFeesProvider.getAverage(10)); - assertEquals(15, btcFeesProvider.getAverage(20)); - assertEquals(20, btcFeesProvider.getAverage(30)); - assertEquals(20, btcFeesProvider.getAverage(20)); - assertEquals(20, btcFeesProvider.getAverage(20)); //5th - - assertEquals(22, btcFeesProvider.getAverage(20)); // first removed - assertEquals(28, btcFeesProvider.getAverage(50)); // second removed - assertEquals(30, btcFeesProvider.getAverage(40)); // third removed - } -}