mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Switch to more accurate fee estimation endpoint
The API endpoint for fee estimations has been changed to one that delivers more accurate fee estimations. This is a temporary solution, until a more decentralized approach is found. Fixes projects/issues/27
This commit is contained in:
parent
bb2484ab3e
commit
e18f0406af
@ -83,7 +83,7 @@ public class AboutView extends ActivatableView<GridPane, Void> {
|
|||||||
"Poloniex (https://poloniex.com)",
|
"Poloniex (https://poloniex.com)",
|
||||||
"Coinmarketcap (https://coinmarketcap.com)"));
|
"Coinmarketcap (https://coinmarketcap.com)"));
|
||||||
if (isBtc)
|
if (isBtc)
|
||||||
addCompactTopLabelTextField(root, ++gridRow, Res.get("setting.about.feeEstimation.label"), "Earn.com (https://bitcoinfees.earn.com)");
|
addCompactTopLabelTextField(root, ++gridRow, Res.get("setting.about.feeEstimation.label"), "mempool.space (https://mempool.space)");
|
||||||
|
|
||||||
addTitledGroupBg(root, ++gridRow, 2, Res.get("setting.about.versionDetails"), Layout.GROUP_DISTANCE);
|
addTitledGroupBg(root, ++gridRow, 2, Res.get("setting.about.versionDetails"), Layout.GROUP_DISTANCE);
|
||||||
addCompactTopLabelTextField(root, gridRow, Res.get("setting.about.version"), Version.VERSION, Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
addCompactTopLabelTextField(root, gridRow, Res.get("setting.about.version"), Version.VERSION, Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||||
|
@ -42,8 +42,8 @@ import java.util.stream.Stream;
|
|||||||
@Component
|
@Component
|
||||||
class BitcoinFeeRateProvider extends FeeRateProvider {
|
class BitcoinFeeRateProvider extends FeeRateProvider {
|
||||||
|
|
||||||
private static final long MIN_FEE_RATE = 10; // satoshi/byte
|
protected static final long MIN_FEE_RATE = 10; // satoshi/byte
|
||||||
private static final long MAX_FEE_RATE = 1000;
|
protected static final long MAX_FEE_RATE = 1000;
|
||||||
|
|
||||||
private static final int DEFAULT_MAX_BLOCKS = 2;
|
private static final int DEFAULT_MAX_BLOCKS = 2;
|
||||||
private static final int DEFAULT_REFRESH_INTERVAL = 2;
|
private static final int DEFAULT_REFRESH_INTERVAL = 2;
|
||||||
@ -63,9 +63,9 @@ class BitcoinFeeRateProvider extends FeeRateProvider {
|
|||||||
|
|
||||||
private long getEstimatedFeeRate() {
|
private long getEstimatedFeeRate() {
|
||||||
return getFeeRatePredictions()
|
return getFeeRatePredictions()
|
||||||
.filter(p -> p.get("maxDelay") <= maxBlocks)
|
.filter(p -> p.getKey().equalsIgnoreCase("halfHourFee"))
|
||||||
|
.map(Map.Entry::getValue)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(p -> p.get("maxFee"))
|
|
||||||
.map(r -> {
|
.map(r -> {
|
||||||
log.info("latest fee rate prediction is {} sat/byte", r);
|
log.info("latest fee rate prediction is {} sat/byte", r);
|
||||||
return r;
|
return r;
|
||||||
@ -75,19 +75,18 @@ class BitcoinFeeRateProvider extends FeeRateProvider {
|
|||||||
.orElse(MIN_FEE_RATE);
|
.orElse(MIN_FEE_RATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<Map<String, Long>> getFeeRatePredictions() {
|
private Stream<Map.Entry<String, Long>> getFeeRatePredictions() {
|
||||||
return restTemplate.exchange(
|
return restTemplate.exchange(
|
||||||
RequestEntity
|
RequestEntity
|
||||||
.get(UriComponentsBuilder
|
.get(UriComponentsBuilder
|
||||||
// now using /fees/list because /fees/recommended estimates were too high
|
// Temporarily call mempool.space centralized API endpoint
|
||||||
.fromUriString("https://bitcoinfees.earn.com/api/v1/fees/list")
|
// A more de-centralized solution discussed in https://github.com/bisq-network/projects/issues/27
|
||||||
|
.fromUriString("https://mempool.space/api/v1/fees/recommended")
|
||||||
.build().toUri())
|
.build().toUri())
|
||||||
.header("User-Agent", "") // required to avoid 403
|
.header("User-Agent", "") // required to avoid 403
|
||||||
.build(),
|
.build(),
|
||||||
new ParameterizedTypeReference<Map<String, List<Map<String, Long>>>>() {
|
new ParameterizedTypeReference<Map<String, Long>>() { }
|
||||||
}
|
).getBody().entrySet().stream();
|
||||||
).getBody().entrySet().stream()
|
|
||||||
.flatMap(e -> e.getValue().stream());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<String[]> args(Environment env) {
|
private static Optional<String[]> args(Environment env) {
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.price.mining.providers;
|
||||||
|
|
||||||
|
import bisq.price.mining.FeeRate;
|
||||||
|
|
||||||
|
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class BitcoinFeeRateProviderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doGet_successfulCall() {
|
||||||
|
|
||||||
|
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
|
||||||
|
BitcoinFeeRateProvider feeRateProvider = new BitcoinFeeRateProvider(ctx.getEnvironment());
|
||||||
|
|
||||||
|
// Make a call to the API, retrieve the recommended fee rate
|
||||||
|
// If the API call fails, or the response body cannot be parsed, the test will fail with an exception
|
||||||
|
FeeRate retrievedFeeRate = feeRateProvider.doGet();
|
||||||
|
|
||||||
|
// Check that the FeeRateProvider returns a fee within the defined parameters
|
||||||
|
assertTrue(retrievedFeeRate.getPrice() >= BitcoinFeeRateProvider.MIN_FEE_RATE);
|
||||||
|
assertTrue(retrievedFeeRate.getPrice() <= BitcoinFeeRateProvider.MAX_FEE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user