diff --git a/pricenode/src/main/java/bisq/price/mining/FeeRateService.java b/pricenode/src/main/java/bisq/price/mining/FeeRateService.java index 5ebc810e775..843fbaabf6e 100644 --- a/pricenode/src/main/java/bisq/price/mining/FeeRateService.java +++ b/pricenode/src/main/java/bisq/price/mining/FeeRateService.java @@ -23,7 +23,6 @@ import java.time.Instant; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -39,8 +38,8 @@ class FeeRateService { private final List providers; /** - * Construct an {@link FeeRateService} with a list of all - * {@link FeeRateProvider} implementations discovered via classpath scanning. + * Construct a {@link FeeRateService} with a list of all {@link FeeRateProvider} + * implementations discovered via classpath scanning. * * @param providers all {@link FeeRateProvider} implementations in ascending * order of precedence @@ -76,7 +75,8 @@ public Map getFees() { averageFeeRate = Math.min(averageFeeRate, BitcoinFeeRateProvider.MAX_FEE_RATE); // Prepare response: Add timestamp of now - // Since this is an average, the timestamp is associated with when the moment in time when the avg was computed + // Since this is an average, the timestamp is associated with when the moment in + // time when the avg was computed metadata.put("bitcoinFeesTs", Instant.now().getEpochSecond()); // Prepare response: Add the fee average diff --git a/pricenode/src/main/java/bisq/price/mining/providers/BitcoinFeeRateProvider.java b/pricenode/src/main/java/bisq/price/mining/providers/BitcoinFeeRateProvider.java index b438a6daf1d..adf8d785f6f 100644 --- a/pricenode/src/main/java/bisq/price/mining/providers/BitcoinFeeRateProvider.java +++ b/pricenode/src/main/java/bisq/price/mining/providers/BitcoinFeeRateProvider.java @@ -31,21 +31,19 @@ import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.time.Duration; import java.time.Instant; -import java.time.temporal.ChronoUnit; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; /** - * Provider that specifically interprets the mempool.space API format to retrieve a mining fee estimate.

- * Other {@link FeeRateProvider}s can be created for other APIs. + * Provider that specifically interprets the mempool.space API format to retrieve a mining + * fee estimate. Other {@link FeeRateProvider}s can be created for other APIs. */ public abstract class BitcoinFeeRateProvider extends FeeRateProvider { @@ -55,8 +53,8 @@ public abstract class BitcoinFeeRateProvider extends FeeRateProvider { private static final int DEFAULT_MAX_BLOCKS = 2; private static final int DEFAULT_REFRESH_INTERVAL = 2; - // Keys of properties defining the available API endpoints - // To enable them, simply enable and adjust the corresponding lines in application.properties + // Keys of properties defining the available API endpoints. To enable them, simply + // uncomment and adjust the corresponding lines in application.properties private static final String API_ENDPOINT_HOSTNAME_KEY_1 = "service.mining.feeEstimate.apiEndpointHostname.1"; private static final String API_ENDPOINT_HOSTNAME_KEY_2 = "service.mining.feeEstimate.apiEndpointHostname.2"; private static final String API_ENDPOINT_HOSTNAME_KEY_3 = "service.mining.feeEstimate.apiEndpointHostname.3"; @@ -80,8 +78,8 @@ public BitcoinFeeRateProvider(Environment env) { } protected FeeRate doGet() { - // Default value is the minimum rate - // If the connection to the fee estimate provider fails, we fall back to this value + // Default value is the minimum rate. If the connection to the fee estimate + // provider fails, we fall back to this value. long estimatedFeeRate = MIN_FEE_RATE; try { estimatedFeeRate = getEstimatedFeeRate(); @@ -121,7 +119,8 @@ private Stream> getFeeRatePredictions() { } /** - * @return Hostname of the fee estimation API endpoint. No prefix (https://), no suffix (trailing slashes, etc) + * Return the hostname of the fee estimation API endpoint. No prefix (https://), no + * suffix (trailing slashes, etc). */ protected abstract String getMempoolApiHostname(); diff --git a/pricenode/src/test/java/bisq/price/mining/FeeRateServiceTest.java b/pricenode/src/test/java/bisq/price/mining/FeeRateServiceTest.java index f3e9147aafc..74e246554e4 100644 --- a/pricenode/src/test/java/bisq/price/mining/FeeRateServiceTest.java +++ b/pricenode/src/test/java/bisq/price/mining/FeeRateServiceTest.java @@ -20,8 +20,8 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; /** - * Tests the {@link bisq.price.mining.FeeRateService}, which can aggregate data from several {@link FeeRateProvider}s - *

+ * Tests the {@link bisq.price.mining.FeeRateService}, which can aggregate data from + * several {@link FeeRateProvider}s. * @see bisq.price.mining.providers.BitcoinFeeRateProviderTest */ public class FeeRateServiceTest extends TestBase { @@ -42,7 +42,8 @@ public void getFees_noWorkingProvider() { Map retrievedData = service.getFees(); - // Even with no working providers, we expect the service to return pre-configured minimum fee rate + // Even with no working providers, we expect the service to return pre-configured + // minimum fee rate doSanityChecksForRetrievedData(retrievedData, BitcoinFeeRateProvider.MIN_FEE_RATE); } @@ -56,7 +57,8 @@ public void getFees_singleProvider_feeBelowMin() { Map retrievedData = service.getFees(); - // When the provider returns a value below the expected min, the service should return the min + // When the provider returns a value below the expected min, the service should + // return the min doSanityChecksForRetrievedData(retrievedData, BitcoinFeeRateProvider.MIN_FEE_RATE); } @@ -70,18 +72,18 @@ public void getFees_singleProvider_feeAboveMax() { Map retrievedData = service.getFees(); - // When the provider returns a value above the expected max, the service should return the max + // When the provider returns a value above the expected max, the service should + // return the max doSanityChecksForRetrievedData(retrievedData, BitcoinFeeRateProvider.MAX_FEE_RATE); } @Test public void getFees_multipleProviders() { // 3 providers, returning 1xMIN, 2xMIN, 3xMIN - FeeRateService service = new FeeRateService( - asList( - buildDummyReachableBitcoinFeeRateProvider(BitcoinFeeRateProvider.MIN_FEE_RATE * 1), - buildDummyReachableBitcoinFeeRateProvider(BitcoinFeeRateProvider.MIN_FEE_RATE * 2), - buildDummyReachableBitcoinFeeRateProvider(BitcoinFeeRateProvider.MIN_FEE_RATE * 3))); + FeeRateService service = new FeeRateService(asList( + buildDummyReachableBitcoinFeeRateProvider(BitcoinFeeRateProvider.MIN_FEE_RATE * 1), + buildDummyReachableBitcoinFeeRateProvider(BitcoinFeeRateProvider.MIN_FEE_RATE * 2), + buildDummyReachableBitcoinFeeRateProvider(BitcoinFeeRateProvider.MIN_FEE_RATE * 3))); Map retrievedData = service.getFees(); @@ -96,9 +98,9 @@ public void getFees_multipleProviders() { * @param expectedFeeRate */ private void doSanityChecksForRetrievedData(Map retrievedData, long expectedFeeRate) { - // Check if the response has the expected format - // Since the timestamp is that of the average (not that of the individual fee rates reported - // by the individual providers), we always expect a non-zero timestamp + // Check if the response has the expected format. Since the timestamp is that of + // the average (not that of the individual fee rates reported by the individual + // providers), we always expect a non-zero timestamp assertNotEquals(0L, retrievedData.get("bitcoinFeesTs")); Map retrievedDataMap = (Map) retrievedData.get("dataMap"); @@ -108,8 +110,6 @@ private void doSanityChecksForRetrievedData(Map retrievedData, l /** * Simulates a reachable provider, which successfully returns an API response - * @param feeRate - * @return */ private BitcoinFeeRateProvider buildDummyReachableBitcoinFeeRateProvider(long feeRate) { GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); @@ -128,13 +128,11 @@ protected FeeRate doGet() { } /** - * Simulates an unreachable provider, which for whatever reason cannot deliver a response to the API.

- * Reasons for that could be: host went offline, connection timeout, connection cannot be established (expired - * certificate), etc. - * - * @return + * Simulates an unreachable provider, which for whatever reason cannot deliver a + * response to the API. Reasons for that could be: host went offline, connection + * timeout, connection cannot be established (expired certificate), etc. */ - private BitcoinFeeRateProvider buildDummyUnreachableBitcoinFeeRateProvider() throws RestClientException{ + private BitcoinFeeRateProvider buildDummyUnreachableBitcoinFeeRateProvider() throws RestClientException { GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); BitcoinFeeRateProvider dummyProvider = new BitcoinFeeRateProvider.First(ctx.getEnvironment()) { @Override diff --git a/pricenode/src/test/java/bisq/price/mining/providers/BitcoinFeeRateProviderTest.java b/pricenode/src/test/java/bisq/price/mining/providers/BitcoinFeeRateProviderTest.java index 43d53ba5b0b..bbfea4bd786 100644 --- a/pricenode/src/test/java/bisq/price/mining/providers/BitcoinFeeRateProviderTest.java +++ b/pricenode/src/test/java/bisq/price/mining/providers/BitcoinFeeRateProviderTest.java @@ -26,9 +26,9 @@ import static org.junit.Assert.assertTrue; /** - * Tests specific to a {@link BitcoinFeeRateProvider} which queries one API endpoint

- * - * For tests related to managing parallel fee API endpoints, see {@link bisq.price.mining.FeeRateServiceTest} + * Tests specific to a {@link BitcoinFeeRateProvider} which queries one API endpoint. For + * tests related to managing parallel fee API endpoints, see + * {@link bisq.price.mining.FeeRateServiceTest} */ public class BitcoinFeeRateProviderTest { diff --git a/pricenode/src/test/java/bisq/price/spot/ExchangeRateServiceTest.java b/pricenode/src/test/java/bisq/price/spot/ExchangeRateServiceTest.java index b72424317b0..38ecff4a7fc 100644 --- a/pricenode/src/test/java/bisq/price/spot/ExchangeRateServiceTest.java +++ b/pricenode/src/test/java/bisq/price/spot/ExchangeRateServiceTest.java @@ -47,20 +47,20 @@ public class ExchangeRateServiceTest extends TestBase { /** - * Logback version of the Slfj logger used by {@link ExchangeRateService}. This - * allows us to test if specific messages were logged

- * + * Logback version of the Slf4j logger used by {@link ExchangeRateService}. This + * allows us to test if specific messages were logged. * See https://stackoverflow.com/a/52229629 */ private static Logger exchangeRateServiceLogger; private static final String LIST_APPENDER_NAME = "testListAppender"; @BeforeAll - static void setup () { + static void setup() { // Get the logger object for logs in ExchangeRateService exchangeRateServiceLogger = (Logger) LoggerFactory.getLogger(ExchangeRateService.class); - // Initiate and append a ListAppender, which allows us to programmatically inspect log messages + // Initiate and append a ListAppender, which allows us to programmatically inspect + // log messages ListAppender listAppender = new ListAppender<>(); listAppender.setName(LIST_APPENDER_NAME); listAppender.start(); @@ -75,7 +75,8 @@ public void getAllMarketPrices_withNoExchangeRates_logs_Exception() { Map retrievedData = service.getAllMarketPrices(); - doSanityChecksForRetrievedDataSingleProvider(retrievedData, dummyProvider.getPrefix(), numberOfCurrencyPairsOnExchange); + doSanityChecksForRetrievedDataSingleProvider( + retrievedData, dummyProvider.getPrefix(), numberOfCurrencyPairsOnExchange); // No exchange rates provided by this exchange, two things should happen // A) the timestamp should be set to 0 @@ -86,7 +87,8 @@ public void getAllMarketPrices_withNoExchangeRates_logs_Exception() { assertEquals(0L, retrievedData.get(dummyProvider.getPrefix() + "Ts")); // B) Check that an error is logged - // Log msg has the format: java.lang.IllegalStateException: No exchange rate data found for ExchangeName-JzfP1 + // Log msg has the format: java.lang.IllegalStateException: No exchange rate data + // found for ExchangeName-JzfP1 List logsList = ((ListAppender) exchangeRateServiceLogger.getAppender(LIST_APPENDER_NAME)).list; assertEquals(Level.ERROR, logsList.get(0).getLevel()); assertTrue(logsList.get(0).getMessage().endsWith("No exchange rate data found for " + dummyProvider.getName())); @@ -100,7 +102,8 @@ public void getAllMarketPrices_withSingleExchangeRate() { Map retrievedData = service.getAllMarketPrices(); - doSanityChecksForRetrievedDataSingleProvider(retrievedData, dummyProvider.getPrefix(), numberOfCurrencyPairsOnExchange); + doSanityChecksForRetrievedDataSingleProvider( + retrievedData, dummyProvider.getPrefix(), numberOfCurrencyPairsOnExchange); // One rate was provided by this provider, so the timestamp should not be 0 assertNotEquals(0L, retrievedData.get(dummyProvider.getPrefix() + "Ts")); @@ -118,13 +121,14 @@ public void getAllMarketPrices_withMultipleProviders() { doSanityChecksForRetrievedDataMultipleProviders(retrievedData, asList(dummyProvider1.getPrefix(), dummyProvider2.getPrefix())); - // One rate was provided by each provider in this service, so the timestamp (for both providers) should not be 0 + // One rate was provided by each provider in this service, so the timestamp + // (for both providers) should not be 0 assertNotEquals(0L, retrievedData.get(dummyProvider1.getPrefix() + "Ts")); assertNotEquals(0L, retrievedData.get(dummyProvider2.getPrefix() + "Ts")); } /** - * Performs generic sanity checks on the response format and contents + * Performs generic sanity checks on the response format and contents. * * @param retrievedData Response data retrieved from the {@link ExchangeRateService} * @param providerPrefix {@link ExchangeRateProvider#getPrefix()} @@ -143,17 +147,18 @@ private void doSanityChecksForRetrievedDataSingleProvider(Map re } /** - * Performs generic sanity checks on the response format and contents + * Performs generic sanity checks on the response format and contents. * * @param retrievedData Response data retrieved from the {@link ExchangeRateService} - * @param providerPrefixes List of all {@link ExchangeRateProvider#getPrefix()} the {@link ExchangeRateService} uses + * @param providerPrefixes List of all {@link ExchangeRateProvider#getPrefix()} the + * {@link ExchangeRateService} uses */ private void doSanityChecksForRetrievedDataMultipleProviders(Map retrievedData, - List providerPrefixes) { + List providerPrefixes) { // Check the correct amount of entries were present in the service response: - // The timestamp and the count fields are per provider, so N providers means N times those fields - // timestamp (x N) + count (x N) + price data (stored as a list under the key "data") - // So expected size is Nx2 + 1 + // The timestamp and the count fields are per provider, so N providers means N + // times those fields timestamp (x N) + count (x N) + price data (stored as a list + // under the key "data"). So expected size is Nx2 + 1. int n = providerPrefixes.size(); assertEquals(n * 2 + 1, retrievedData.size()); for (String providerPrefix : providerPrefixes) { diff --git a/pricenode/src/test/java/bisq/price/util/VersionControllerTest.java b/pricenode/src/test/java/bisq/price/util/VersionControllerTest.java index 71de03dc2e9..86e4f9bb760 100644 --- a/pricenode/src/test/java/bisq/price/util/VersionControllerTest.java +++ b/pricenode/src/test/java/bisq/price/util/VersionControllerTest.java @@ -4,14 +4,11 @@ import java.io.IOException; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; - - -public class VersionControllerTest { +public class VersionControllerTest { @Test public void getVersion() throws IOException {