Merge pull request #5489 from jmacxx/fix_pricenode_minfee

Fix the PriceNode lower bounds for MinFee
This commit is contained in:
Christoph Atteneder 2021-05-12 21:25:28 +02:00 committed by GitHub
commit c9166f9ae0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 19 additions and 18 deletions

View file

@ -26,7 +26,8 @@ import java.time.Duration;
*/
public abstract class FeeRateProvider extends PriceProvider<FeeRate> {
public static final long MIN_FEE_RATE = 10; // satoshi/vbyte
public static final long MIN_FEE_RATE_FOR_WITHDRAWAL = 2; // satoshi/vbyte
public static final long MIN_FEE_RATE_FOR_TRADING = 10; // satoshi/vbyte
public static final long MAX_FEE_RATE = 1000;
public FeeRateProvider(Duration refreshInterval) {

View file

@ -78,15 +78,15 @@ class FeeRateService {
// Calculate the average
long averageFeeRate = (amountOfFeeRates.intValue() > 0)
? sumOfAllFeeRates.longValue() / amountOfFeeRates.intValue()
: FeeRateProvider.MIN_FEE_RATE;
: FeeRateProvider.MIN_FEE_RATE_FOR_TRADING;
long averageMinFeeRate = (amountOfFeeRates.intValue() > 0)
? sumOfAllMinFeeRates.longValue() / amountOfFeeRates.intValue()
: FeeRateProvider.MIN_FEE_RATE;
: FeeRateProvider.MIN_FEE_RATE_FOR_WITHDRAWAL;
// Make sure the returned value is within the min-max range
averageFeeRate = Math.max(averageFeeRate, FeeRateProvider.MIN_FEE_RATE);
averageFeeRate = Math.max(averageFeeRate, FeeRateProvider.MIN_FEE_RATE_FOR_TRADING);
averageFeeRate = Math.min(averageFeeRate, FeeRateProvider.MAX_FEE_RATE);
averageMinFeeRate = Math.max(averageMinFeeRate, FeeRateProvider.MIN_FEE_RATE);
averageMinFeeRate = Math.max(averageMinFeeRate, FeeRateProvider.MIN_FEE_RATE_FOR_WITHDRAWAL);
averageMinFeeRate = Math.min(averageMinFeeRate, FeeRateProvider.MAX_FEE_RATE);
// Prepare response: Add timestamp of now

View file

@ -85,7 +85,7 @@ abstract class MempoolFeeRateProvider extends FeeRateProvider {
log.error("Error retrieving bitcoin mining fee estimation: " + e.getMessage());
}
return new FeeRate("BTC", MIN_FEE_RATE, MIN_FEE_RATE, Instant.now().getEpochSecond());
return new FeeRate("BTC", MIN_FEE_RATE_FOR_TRADING, MIN_FEE_RATE_FOR_WITHDRAWAL, Instant.now().getEpochSecond());
}
private FeeRate getEstimatedFeeRate() {
@ -94,15 +94,15 @@ abstract class MempoolFeeRateProvider extends FeeRateProvider {
.filter(p -> p.getKey().equalsIgnoreCase("halfHourFee"))
.map(Map.Entry::getValue)
.findFirst()
.map(r -> Math.max(r, MIN_FEE_RATE))
.map(r -> Math.max(r, MIN_FEE_RATE_FOR_TRADING))
.map(r -> Math.min(r, MAX_FEE_RATE))
.orElse(MIN_FEE_RATE);
.orElse(MIN_FEE_RATE_FOR_TRADING);
long minimumFee = feeRatePredictions.stream()
.filter(p -> p.getKey().equalsIgnoreCase("minimumFee"))
.map(Map.Entry::getValue)
.findFirst()
.map(r -> Math.multiplyExact(r, 2)) // multiply the minimumFee by 2 (per wiz)
.orElse(MIN_FEE_RATE);
.orElse(MIN_FEE_RATE_FOR_WITHDRAWAL);
log.info("Retrieved estimated mining fee of {} sat/vB and minimumFee of {} sat/vB from {}", estimatedFeeRate, minimumFee, getMempoolApiHostname());
return new FeeRate("BTC", estimatedFeeRate, minimumFee, Instant.now().getEpochSecond());
}

View file

@ -47,13 +47,13 @@ public class FeeRateServiceTest {
// Even with no working providers, we expect the service to return pre-configured
// minimum fee rate
doSanityChecksForRetrievedData(retrievedData, FeeRateProvider.MIN_FEE_RATE);
doSanityChecksForRetrievedData(retrievedData, FeeRateProvider.MIN_FEE_RATE_FOR_TRADING);
}
@Test
public void getFees_singleProvider_feeBelowMin() {
// One working provider, which returns a fee lower than the minimum
long providerFee = FeeRateProvider.MIN_FEE_RATE - 3;
long providerFee = FeeRateProvider.MIN_FEE_RATE_FOR_TRADING - 3;
FeeRateService service = new FeeRateService(
Collections.singletonList(
buildDummyReachableMempoolFeeRateProvider(providerFee)));
@ -62,7 +62,7 @@ public class FeeRateServiceTest {
// When the provider returns a value below the expected min, the service should
// return the min
doSanityChecksForRetrievedData(retrievedData, FeeRateProvider.MIN_FEE_RATE);
doSanityChecksForRetrievedData(retrievedData, FeeRateProvider.MIN_FEE_RATE_FOR_TRADING);
}
@Test
@ -84,14 +84,14 @@ public class FeeRateServiceTest {
public void getFees_multipleProviders() {
// 3 providers, returning 1xMIN, 2xMIN, 3xMIN
FeeRateService service = new FeeRateService(asList(
buildDummyReachableMempoolFeeRateProvider(FeeRateProvider.MIN_FEE_RATE * 1),
buildDummyReachableMempoolFeeRateProvider(FeeRateProvider.MIN_FEE_RATE * 2),
buildDummyReachableMempoolFeeRateProvider(FeeRateProvider.MIN_FEE_RATE * 3)));
buildDummyReachableMempoolFeeRateProvider(FeeRateProvider.MIN_FEE_RATE_FOR_TRADING * 1),
buildDummyReachableMempoolFeeRateProvider(FeeRateProvider.MIN_FEE_RATE_FOR_TRADING * 2),
buildDummyReachableMempoolFeeRateProvider(FeeRateProvider.MIN_FEE_RATE_FOR_TRADING * 3)));
Map<String, Object> retrievedData = service.getFees();
// The service should then return the average, which is 2xMIN
doSanityChecksForRetrievedData(retrievedData, FeeRateProvider.MIN_FEE_RATE * 2);
doSanityChecksForRetrievedData(retrievedData, FeeRateProvider.MIN_FEE_RATE_FOR_TRADING * 2);
}
/**

View file

@ -50,7 +50,7 @@ public class MempoolFeeRateProviderTest {
FeeRate retrievedFeeRate = feeRateProvider.doGet();
// Check that the FeeRateProvider returns a fee within the defined parameters
assertTrue(retrievedFeeRate.getPrice() >= FeeRateProvider.MIN_FEE_RATE);
assertTrue(retrievedFeeRate.getPrice() >= FeeRateProvider.MIN_FEE_RATE_FOR_TRADING);
assertTrue(retrievedFeeRate.getPrice() <= FeeRateProvider.MAX_FEE_RATE);
}
@ -61,7 +61,7 @@ public class MempoolFeeRateProviderTest {
MempoolFeeRateProvider dummyProvider = new MempoolFeeRateProvider.First(env) {
@Override
protected FeeRate doGet() {
return new FeeRate("BTC", feeRate, MIN_FEE_RATE, Instant.now().getEpochSecond());
return new FeeRate("BTC", feeRate, MIN_FEE_RATE_FOR_WITHDRAWAL, Instant.now().getEpochSecond());
}
};