mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-23 20:36:44 +00:00
add fee rate selection for premix
This commit is contained in:
parent
813e0f3ab1
commit
1497b3d3bb
9 changed files with 90 additions and 8 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
|||
Subproject commit 57290a20a143bc0f0d8440fb3c14592c2e204e6b
|
||||
Subproject commit eb49c9713375ac5f909d8ec3fa4dfddaf7d63ffe
|
|
@ -11,6 +11,7 @@ public class SpendUtxoEvent {
|
|||
private final Wallet wallet;
|
||||
private final List<BlockTransactionHashIndex> utxos;
|
||||
private final List<Payment> payments;
|
||||
private final List<byte[]> opReturns;
|
||||
private final Long fee;
|
||||
private final boolean includeSpentMempoolOutputs;
|
||||
private final Pool pool;
|
||||
|
@ -23,15 +24,17 @@ public class SpendUtxoEvent {
|
|||
this.wallet = wallet;
|
||||
this.utxos = utxos;
|
||||
this.payments = payments;
|
||||
this.opReturns = null;
|
||||
this.fee = fee;
|
||||
this.includeSpentMempoolOutputs = includeSpentMempoolOutputs;
|
||||
this.pool = null;
|
||||
}
|
||||
|
||||
public SpendUtxoEvent(Wallet wallet, List<BlockTransactionHashIndex> utxos, List<Payment> payments, Long fee, Pool pool) {
|
||||
public SpendUtxoEvent(Wallet wallet, List<BlockTransactionHashIndex> utxos, List<Payment> payments, List<byte[]> opReturns, Long fee, Pool pool) {
|
||||
this.wallet = wallet;
|
||||
this.utxos = utxos;
|
||||
this.payments = payments;
|
||||
this.opReturns = opReturns;
|
||||
this.fee = fee;
|
||||
this.includeSpentMempoolOutputs = false;
|
||||
this.pool = pool;
|
||||
|
@ -49,6 +52,10 @@ public class SpendUtxoEvent {
|
|||
return payments;
|
||||
}
|
||||
|
||||
public List<byte[]> getOpReturns() {
|
||||
return opReturns;
|
||||
}
|
||||
|
||||
public Long getFee() {
|
||||
return fee;
|
||||
}
|
||||
|
|
|
@ -162,6 +162,8 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
|
||||
private final BooleanProperty includeSpentMempoolOutputsProperty = new SimpleBooleanProperty(false);
|
||||
|
||||
private final List<byte[]> opReturnsList = new ArrayList<>();
|
||||
|
||||
private final Set<WalletNode> excludedChangeNodes = new HashSet<>();
|
||||
|
||||
private final ChangeListener<String> feeListener = new ChangeListener<>() {
|
||||
|
@ -556,7 +558,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
boolean includeMempoolOutputs = Config.get().isIncludeMempoolOutputs();
|
||||
boolean includeSpentMempoolOutputs = includeSpentMempoolOutputsProperty.get();
|
||||
|
||||
walletTransactionService = new WalletTransactionService(wallet, getUtxoSelectors(payments), getUtxoFilters(), payments, excludedChangeNodes, feeRate, getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
|
||||
walletTransactionService = new WalletTransactionService(wallet, getUtxoSelectors(payments), getUtxoFilters(), payments, opReturnsList, excludedChangeNodes, feeRate, getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
|
||||
walletTransactionService.setOnSucceeded(event -> {
|
||||
if(!walletTransactionService.isIgnoreResult()) {
|
||||
walletTransactionProperty.setValue(walletTransactionService.getValue());
|
||||
|
@ -616,6 +618,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
private final List<UtxoSelector> utxoSelectors;
|
||||
private final List<UtxoFilter> utxoFilters;
|
||||
private final List<Payment> payments;
|
||||
private final List<byte[]> opReturns;
|
||||
private final Set<WalletNode> excludedChangeNodes;
|
||||
private final double feeRate;
|
||||
private final double longTermFeeRate;
|
||||
|
@ -626,11 +629,12 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
private final boolean includeSpentMempoolOutputs;
|
||||
private boolean ignoreResult;
|
||||
|
||||
public WalletTransactionService(Wallet wallet, List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters, List<Payment> payments, Set<WalletNode> excludedChangeNodes, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) {
|
||||
public WalletTransactionService(Wallet wallet, List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters, List<Payment> payments, List<byte[]> opReturns, Set<WalletNode> excludedChangeNodes, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) {
|
||||
this.wallet = wallet;
|
||||
this.utxoSelectors = utxoSelectors;
|
||||
this.utxoFilters = utxoFilters;
|
||||
this.payments = payments;
|
||||
this.opReturns = opReturns;
|
||||
this.excludedChangeNodes = excludedChangeNodes;
|
||||
this.feeRate = feeRate;
|
||||
this.longTermFeeRate = longTermFeeRate;
|
||||
|
@ -645,7 +649,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
protected Task<WalletTransaction> createTask() {
|
||||
return new Task<>() {
|
||||
protected WalletTransaction call() throws InsufficientFundsException {
|
||||
return wallet.createWalletTransaction(utxoSelectors, utxoFilters, payments, excludedChangeNodes, feeRate, longTermFeeRate, fee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
|
||||
return wallet.createWalletTransaction(utxoSelectors, utxoFilters, payments, opReturns, excludedChangeNodes, feeRate, longTermFeeRate, fee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1014,6 +1018,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
utxoSelectorProperty.setValue(null);
|
||||
utxoFilterProperty.setValue(null);
|
||||
includeSpentMempoolOutputsProperty.set(false);
|
||||
opReturnsList.clear();
|
||||
excludedChangeNodes.clear();
|
||||
walletTransactionProperty.setValue(null);
|
||||
createdWalletTransactionProperty.set(null);
|
||||
|
@ -1239,6 +1244,10 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
setPayments(List.of(payment));
|
||||
}
|
||||
|
||||
if(event.getOpReturns() != null) {
|
||||
opReturnsList.addAll(event.getOpReturns());
|
||||
}
|
||||
|
||||
if(event.getFee() != null) {
|
||||
setFeeValueSats(event.getFee());
|
||||
userFeeSet.set(true);
|
||||
|
|
|
@ -320,10 +320,12 @@ public class UtxosController extends WalletFormController implements Initializab
|
|||
payments.add(new Payment(premixAddress, "Premix #" + i, tx0Preview.getPremixValue(), false));
|
||||
}
|
||||
|
||||
List<byte[]> opReturns = List.of(new byte[64]);
|
||||
|
||||
final List<BlockTransactionHashIndex> utxos = utxoEntries.stream().map(HashIndexEntry::getHashIndex).collect(Collectors.toList());
|
||||
Platform.runLater(() -> {
|
||||
EventManager.get().post(new SendActionEvent(getWalletForm().getWallet(), utxos));
|
||||
Platform.runLater(() -> EventManager.get().post(new SpendUtxoEvent(getWalletForm().getWallet(), utxos, payments, tx0Preview.getTx0MinerFee(), tx0Preview.getPool())));
|
||||
Platform.runLater(() -> EventManager.get().post(new SpendUtxoEvent(getWalletForm().getWallet(), utxos, payments, opReturns, tx0Preview.getTx0MinerFee(), tx0Preview.getPool())));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ public class Whirlpool {
|
|||
private final Tx0ParamService tx0ParamService;
|
||||
private final ExpirablePoolSupplier poolSupplier;
|
||||
private final Tx0Service tx0Service;
|
||||
private Tx0FeeTarget tx0FeeTarget = Tx0FeeTarget.BLOCKS_4;
|
||||
private HD_Wallet hdWallet;
|
||||
private String walletId;
|
||||
private String mixToWalletId;
|
||||
|
@ -140,7 +141,6 @@ public class Whirlpool {
|
|||
}
|
||||
|
||||
private Tx0Config computeTx0Config() {
|
||||
Tx0FeeTarget tx0FeeTarget = Tx0FeeTarget.BLOCKS_4;
|
||||
Tx0FeeTarget mixFeeTarget = Tx0FeeTarget.BLOCKS_4;
|
||||
return new Tx0Config(tx0ParamService, poolSupplier, tx0FeeTarget, mixFeeTarget, WhirlpoolAccount.BADBANK);
|
||||
}
|
||||
|
@ -385,6 +385,14 @@ public class Whirlpool {
|
|||
config.setScode(scode);
|
||||
}
|
||||
|
||||
public Tx0FeeTarget getTx0FeeTarget() {
|
||||
return tx0FeeTarget;
|
||||
}
|
||||
|
||||
public void setTx0FeeTarget(Tx0FeeTarget tx0FeeTarget) {
|
||||
this.tx0FeeTarget = tx0FeeTarget;
|
||||
}
|
||||
|
||||
public String getWalletId() {
|
||||
return walletId;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.whirlpool;
|
|||
|
||||
import com.samourai.whirlpool.client.tx0.Tx0Preview;
|
||||
import com.samourai.whirlpool.client.tx0.Tx0Previews;
|
||||
import com.samourai.whirlpool.client.wallet.beans.Tx0FeeTarget;
|
||||
import com.samourai.whirlpool.client.whirlpool.beans.Pool;
|
||||
import com.sparrowwallet.drongo.BitcoinUnit;
|
||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||
|
@ -10,10 +11,12 @@ import com.sparrowwallet.drongo.wallet.Wallet;
|
|||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.control.CoinLabel;
|
||||
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
||||
import com.sparrowwallet.sparrow.event.WalletMasterMixConfigChangedEvent;
|
||||
import com.sparrowwallet.sparrow.io.Config;
|
||||
import com.sparrowwallet.sparrow.wallet.Entry;
|
||||
import com.sparrowwallet.sparrow.wallet.UtxoEntry;
|
||||
import com.sparrowwallet.sparrow.whirlpool.dataSource.SparrowMinerFeeSupplier;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
|
@ -26,6 +29,8 @@ import javafx.util.StringConverter;
|
|||
import java.util.*;
|
||||
|
||||
public class WhirlpoolController {
|
||||
private static final List<Tx0FeeTarget> FEE_TARGETS = List.of(Tx0FeeTarget.MIN, Tx0FeeTarget.BLOCKS_4, Tx0FeeTarget.BLOCKS_2);
|
||||
|
||||
@FXML
|
||||
private VBox whirlpoolBox;
|
||||
|
||||
|
@ -44,6 +49,12 @@ public class WhirlpoolController {
|
|||
@FXML
|
||||
private TextField scode;
|
||||
|
||||
@FXML
|
||||
private Slider premixPriority;
|
||||
|
||||
@FXML
|
||||
private CopyableLabel premixFeeRate;
|
||||
|
||||
@FXML
|
||||
private ComboBox<Pool> pool;
|
||||
|
||||
|
@ -108,6 +119,30 @@ public class WhirlpoolController {
|
|||
EventManager.get().post(new WalletMasterMixConfigChangedEvent(wallet));
|
||||
});
|
||||
|
||||
premixPriority.setMin(0);
|
||||
premixPriority.setMax(FEE_TARGETS.size() - 1);
|
||||
premixPriority.setMajorTickUnit(1);
|
||||
premixPriority.setMinorTickCount(0);
|
||||
premixPriority.setLabelFormatter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(Double object) {
|
||||
return object.intValue() == 0 ? "Low" : (object.intValue() == 1 ? "Normal" : "High");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double fromString(String string) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
premixPriority.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||
pool.setItems(FXCollections.emptyObservableList());
|
||||
tx0Previews = null;
|
||||
tx0PreviewProperty.set(null);
|
||||
Tx0FeeTarget tx0FeeTarget = FEE_TARGETS.get(newValue.intValue());
|
||||
premixFeeRate.setText(SparrowMinerFeeSupplier.getMinimumFeeForTarget(Integer.parseInt(tx0FeeTarget.getFeeTarget().getValue())) + " sats/vB");
|
||||
});
|
||||
premixPriority.setValue(1);
|
||||
|
||||
if(mixConfig.getScode() != null) {
|
||||
step1.setVisible(false);
|
||||
step3.setVisible(true);
|
||||
|
@ -280,6 +315,7 @@ public class WhirlpoolController {
|
|||
} else {
|
||||
tx0Previews = null;
|
||||
whirlpool.setScode(mixConfig.getScode());
|
||||
whirlpool.setTx0FeeTarget(FEE_TARGETS.get(premixPriority.valueProperty().intValue()));
|
||||
|
||||
Whirlpool.Tx0PreviewsService tx0PreviewsService = new Whirlpool.Tx0PreviewsService(whirlpool, wallet, utxoEntries);
|
||||
tx0PreviewsService.setOnRunning(workerStateEvent -> {
|
||||
|
|
|
@ -32,7 +32,7 @@ public class SparrowMinerFeeSupplier implements MinerFeeSupplier {
|
|||
return getMinimumFeeForTarget(Integer.parseInt(feeTarget.getValue()));
|
||||
}
|
||||
|
||||
private Integer getMinimumFeeForTarget(int targetBlocks) {
|
||||
public static Integer getMinimumFeeForTarget(int targetBlocks) {
|
||||
List<Map.Entry<Integer, Double>> feeRates = new ArrayList<>(AppServices.getTargetBlockFeeRates().entrySet());
|
||||
Collections.reverse(feeRates);
|
||||
for(Map.Entry<Integer, Double> feeRate : feeRates) {
|
||||
|
@ -40,6 +40,7 @@ public class SparrowMinerFeeSupplier implements MinerFeeSupplier {
|
|||
return feeRate.getValue().intValue();
|
||||
}
|
||||
}
|
||||
|
||||
return feeRates.get(0).getValue().intValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -39,4 +39,8 @@
|
|||
|
||||
.field-label {
|
||||
-fx-pref-width: 120px;
|
||||
}
|
||||
|
||||
.field-control {
|
||||
-fx-pref-width: 160px;
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import com.sparrowwallet.sparrow.control.CoinLabel?>
|
||||
<?import com.sparrowwallet.sparrow.control.CopyableLabel?>
|
||||
<StackPane prefHeight="460.0" prefWidth="600.0" stylesheets="@whirlpool.css, @../general.css" styleClass="whirlpool-pane" fx:controller="com.sparrowwallet.sparrow.whirlpool.WhirlpoolController" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml">
|
||||
<VBox spacing="20">
|
||||
<HBox styleClass="title-area">
|
||||
|
@ -93,6 +94,20 @@
|
|||
<Label text="SCODE:" styleClass="field-label" />
|
||||
<TextField fx:id="scode" />
|
||||
</HBox>
|
||||
<HBox styleClass="field-box">
|
||||
<padding>
|
||||
<Insets top="10" />
|
||||
</padding>
|
||||
<Label text="Premix Priority:" styleClass="field-label" />
|
||||
<Slider fx:id="premixPriority" snapToTicks="true" showTickLabels="true" showTickMarks="true" styleClass="field-control" />
|
||||
</HBox>
|
||||
<HBox styleClass="field-box">
|
||||
<padding>
|
||||
<Insets top="10" />
|
||||
</padding>
|
||||
<Label text="Premix Fee Rate:" styleClass="field-label" />
|
||||
<CopyableLabel fx:id="premixFeeRate" />
|
||||
</HBox>
|
||||
</VBox>
|
||||
<VBox fx:id="step4" spacing="15">
|
||||
<Label text="Select Pool" styleClass="title-text">
|
||||
|
|
Loading…
Reference in a new issue