retrieve min fee rate, adjust block target rates and dont create txes with insufficient fee rate

This commit is contained in:
Craig Raw 2020-09-25 15:22:52 +02:00
parent e878c4ea78
commit e48e40da0d
8 changed files with 58 additions and 6 deletions

2
drongo

@ -1 +1 @@
Subproject commit 2650dafa66623c1205582c555369a5118a343ccf
Subproject commit 79eb8b002d01be5195bb7fc7eba6bb34bf3366e3

View file

@ -137,6 +137,8 @@ public class AppController implements Initializable {
private static Map<Integer, Double> targetBlockFeeRates;
private static Double minimumRelayFeeRate;
private static CurrencyRate fiatCurrencyExchangeRate;
private static List<Device> devices;
@ -643,6 +645,10 @@ public class AppController implements Initializable {
return targetBlockFeeRates;
}
public static Double getMinimumRelayFeeRate() {
return minimumRelayFeeRate;
}
public static CurrencyRate getFiatCurrencyExchangeRate() {
return fiatCurrencyExchangeRate;
}
@ -1305,6 +1311,7 @@ public class AppController implements Initializable {
public void newConnection(ConnectionEvent event) {
currentBlockHeight = event.getBlockHeight();
targetBlockFeeRates = event.getTargetBlockFeeRates();
minimumRelayFeeRate = event.getMinimumRelayFeeRate();
String banner = event.getServerBanner();
String status = "Connected to " + Config.get().getElectrumServer() + " at height " + event.getBlockHeight();
EventManager.get().post(new StatusEvent(status));

View file

@ -10,13 +10,15 @@ public class ConnectionEvent extends FeeRatesUpdatedEvent {
private final String serverBanner;
private final int blockHeight;
private final BlockHeader blockHeader;
private final Double minimumRelayFeeRate;
public ConnectionEvent(List<String> serverVersion, String serverBanner, int blockHeight, BlockHeader blockHeader, Map<Integer, Double> targetBlockFeeRates) {
public ConnectionEvent(List<String> serverVersion, String serverBanner, int blockHeight, BlockHeader blockHeader, Map<Integer, Double> targetBlockFeeRates, Double minimumRelayFeeRate) {
super(targetBlockFeeRates);
this.serverVersion = serverVersion;
this.serverBanner = serverBanner;
this.blockHeight = blockHeight;
this.blockHeader = blockHeader;
this.minimumRelayFeeRate = minimumRelayFeeRate;
}
public List<String> getServerVersion() {
@ -34,4 +36,8 @@ public class ConnectionEvent extends FeeRatesUpdatedEvent {
public BlockHeader getBlockHeader() {
return blockHeader;
}
public Double getMinimumRelayFeeRate() {
return minimumRelayFeeRate;
}
}

View file

@ -205,6 +205,16 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
}
}
@Override
public Double getMinimumRelayFee(Transport transport) {
try {
JsonRpcClient client = new JsonRpcClient(transport);
return client.createRequest().returnAs(Double.class).method("blockchain.relayfee").id(1).execute();
} catch(JsonRpcException e) {
throw new ElectrumServerRpcException("Error getting minimum relay fee", e);
}
}
@Override
public String broadcastTransaction(Transport transport, String txHex) {
try {

View file

@ -528,7 +528,7 @@ public class ElectrumServer {
Map<Integer, Double> targetBlocksFeeRatesSats = new TreeMap<>();
for(Integer target : targetBlocksFeeRatesBtcKb.keySet()) {
targetBlocksFeeRatesSats.put(target, targetBlocksFeeRatesBtcKb.get(target) * Transaction.SATOSHIS_PER_BITCOIN / 1024);
targetBlocksFeeRatesSats.put(target, targetBlocksFeeRatesBtcKb.get(target) * Transaction.SATOSHIS_PER_BITCOIN / 1000);
}
return targetBlocksFeeRatesSats;
@ -537,6 +537,16 @@ public class ElectrumServer {
}
}
public Double getMinimumRelayFee() throws ServerException {
Double minFeeRateBtcKb = electrumServerRpc.getMinimumRelayFee(getTransport());
if(minFeeRateBtcKb != null) {
long minFeeRateSatsKb = (long)(minFeeRateBtcKb * Transaction.SATOSHIS_PER_BITCOIN);
return minFeeRateSatsKb / 1000d;
}
return Transaction.DEFAULT_MIN_RELAY_FEE;
}
public Sha256Hash broadcastTransaction(Transaction transaction) throws ServerException {
byte[] rawtxBytes = transaction.bitcoinSerialize();
String rawtxHex = Utils.bytesToHex(rawtxBytes);
@ -667,7 +677,12 @@ public class ElectrumServer {
Map<Integer, Double> blockTargetFeeRates = electrumServer.getFeeEstimates(SendController.TARGET_BLOCKS_RANGE);
feeRatesRetrievedAt = System.currentTimeMillis();
return new ConnectionEvent(serverVersion, banner, tip.height, tip.getBlockHeader(), blockTargetFeeRates);
Double minimumRelayFeeRate = electrumServer.getMinimumRelayFee();
for(Integer blockTarget : blockTargetFeeRates.keySet()) {
blockTargetFeeRates.computeIfPresent(blockTarget, (blocks, feeRate) -> feeRate < minimumRelayFeeRate ? minimumRelayFeeRate : feeRate);
}
return new ConnectionEvent(serverVersion, banner, tip.height, tip.getBlockHeader(), blockTargetFeeRates, minimumRelayFeeRate);
} else {
if(reader.isAlive()) {
electrumServer.ping();

View file

@ -29,5 +29,7 @@ public interface ElectrumServerRpc {
Map<Integer, Double> getFeeEstimates(Transport transport, List<Integer> targetBlocks);
Double getMinimumRelayFee(Transport transport);
String broadcastTransaction(Transport transport, String txHex);
}

View file

@ -229,6 +229,16 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
return result;
}
@Override
public Double getMinimumRelayFee(Transport transport) {
try {
JsonRpcClient client = new JsonRpcClient(transport);
return client.createRequest().returnAs(Double.class).method("blockchain.relayfee").id(1).execute();
} catch(JsonRpcException e) {
throw new ElectrumServerRpcException("Error getting minimum relay fee", e);
}
}
@Override
public String broadcastTransaction(Transport transport, String txHex) {
try {

View file

@ -306,7 +306,9 @@ public class SendController extends WalletFormController implements Initializabl
));
validationSupport.registerValidator(fee, Validator.combine(
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Insufficient Inputs", userFeeSet.get() && insufficientInputsProperty.get()),
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Insufficient Fee", getFeeValueSats() != null && getFeeValueSats() == 0)
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Insufficient Fee", getFeeValueSats() != null && getFeeValueSats() == 0),
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Insufficient Fee Rate", walletTransactionProperty.get() != null &&
(double)walletTransactionProperty.get().getFee() / walletTransactionProperty.get().getTransaction().getVirtualSize() < AppController.getMinimumRelayFeeRate())
));
validationSupport.setValidationDecorator(new StyleClassValidationDecoration());
@ -445,7 +447,7 @@ public class SendController extends WalletFormController implements Initializabl
LinkedHashMap::new));
}
return retrievedFeeRates;
return retrievedFeeRates;
}
private Double getFeeRate() {