mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-02 20:36:44 +00:00
minor whirlpool related fixes
This commit is contained in:
parent
4ebee8a8f3
commit
67179127e3
7 changed files with 52 additions and 63 deletions
|
@ -91,7 +91,7 @@ dependencies {
|
||||||
implementation('org.slf4j:jul-to-slf4j:1.7.30') {
|
implementation('org.slf4j:jul-to-slf4j:1.7.30') {
|
||||||
exclude group: 'org.slf4j'
|
exclude group: 'org.slf4j'
|
||||||
}
|
}
|
||||||
implementation('com.sparrowwallet.nightjar:nightjar:0.2.17-SNAPSHOT')
|
implementation('com.sparrowwallet.nightjar:nightjar:0.2.18-SNAPSHOT')
|
||||||
testImplementation('junit:junit:4.12')
|
testImplementation('junit:junit:4.12')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ extraJavaModuleInfo {
|
||||||
module('cbor-0.9.jar', 'co.nstant.in.cbor', '0.9') {
|
module('cbor-0.9.jar', 'co.nstant.in.cbor', '0.9') {
|
||||||
exports('co.nstant.in.cbor')
|
exports('co.nstant.in.cbor')
|
||||||
}
|
}
|
||||||
module('nightjar-0.2.17-SNAPSHOT.jar', 'com.sparrowwallet.nightjar', '0.2.17-SNAPSHOT') {
|
module('nightjar-0.2.18-SNAPSHOT.jar', 'com.sparrowwallet.nightjar', '0.2.18-SNAPSHOT') {
|
||||||
requires('com.google.common')
|
requires('com.google.common')
|
||||||
requires('net.sourceforge.streamsupport')
|
requires('net.sourceforge.streamsupport')
|
||||||
requires('org.slf4j')
|
requires('org.slf4j')
|
||||||
|
|
|
@ -40,12 +40,6 @@ public class MixStatusCell extends TreeTableCell<Entry, UtxoEntry.MixStatus> {
|
||||||
setContextMenu(null);
|
setContextMenu(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mixStatus.getMixProgress() != null) {
|
|
||||||
Tooltip tooltip = new Tooltip();
|
|
||||||
tooltip.setText("Pool: " + mixStatus.getMixProgress().getPoolId().replace("btc", " BTC"));
|
|
||||||
setTooltip(tooltip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mixStatus.getNextMixUtxo() != null) {
|
if(mixStatus.getNextMixUtxo() != null) {
|
||||||
setMixSuccess(mixStatus.getNextMixUtxo());
|
setMixSuccess(mixStatus.getNextMixUtxo());
|
||||||
} else if(mixStatus.getMixFailReason() != null) {
|
} else if(mixStatus.getMixFailReason() != null) {
|
||||||
|
@ -54,6 +48,7 @@ public class MixStatusCell extends TreeTableCell<Entry, UtxoEntry.MixStatus> {
|
||||||
setMixProgress(mixStatus.getMixProgress());
|
setMixProgress(mixStatus.getMixProgress());
|
||||||
} else {
|
} else {
|
||||||
setGraphic(null);
|
setGraphic(null);
|
||||||
|
setTooltip(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +70,7 @@ public class MixStatusCell extends TreeTableCell<Entry, UtxoEntry.MixStatus> {
|
||||||
setTooltip(tt);
|
setTooltip(tt);
|
||||||
} else {
|
} else {
|
||||||
setGraphic(null);
|
setGraphic(null);
|
||||||
|
setTooltip(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +84,7 @@ public class MixStatusCell extends TreeTableCell<Entry, UtxoEntry.MixStatus> {
|
||||||
setTooltip(tt);
|
setTooltip(tt);
|
||||||
} else {
|
} else {
|
||||||
setGraphic(null);
|
setGraphic(null);
|
||||||
|
setTooltip(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -705,7 +705,7 @@ public class ElectrumServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyPostmixLabels(Wallet wallet, Set<BlockTransactionHashIndex> newTransactionOutputs) {
|
public void copyPostmixLabels(Wallet wallet, Set<BlockTransactionHashIndex> newTransactionOutputs) {
|
||||||
if(wallet.getStandardAccountType() == StandardAccount.WHIRLPOOL_POSTMIX) {
|
if(wallet.getStandardAccountType() == StandardAccount.WHIRLPOOL_POSTMIX && wallet.getMasterWallet() != null) {
|
||||||
for(BlockTransactionHashIndex newRef : newTransactionOutputs) {
|
for(BlockTransactionHashIndex newRef : newTransactionOutputs) {
|
||||||
BlockTransactionHashIndex prevRef = wallet.getWalletTxos().keySet().stream()
|
BlockTransactionHashIndex prevRef = wallet.getWalletTxos().keySet().stream()
|
||||||
.filter(txo -> wallet.getMasterWallet().getUtxoMixData(txo) != null && txo.isSpent() && txo.getSpentBy().getHash().equals(newRef.getHash())).findFirst().orElse(null);
|
.filter(txo -> wallet.getMasterWallet().getUtxoMixData(txo) != null && txo.isSpent() && txo.getSpentBy().getHash().equals(newRef.getHash())).findFirst().orElse(null);
|
||||||
|
|
|
@ -92,6 +92,20 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
mixTo.setDisable(newValue);
|
mixTo.setDisable(newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final ChangeListener<Boolean> mixingListener = (observable, oldValue, newValue) -> {
|
||||||
|
if(!newValue) {
|
||||||
|
WalletUtxosEntry walletUtxosEntry = getWalletForm().getWalletUtxosEntry();
|
||||||
|
for(Entry entry : walletUtxosEntry.getChildren()) {
|
||||||
|
UtxoEntry utxoEntry = (UtxoEntry)entry;
|
||||||
|
if(utxoEntry.getMixStatus() != null && utxoEntry.getMixStatus().getMixProgress() != null
|
||||||
|
&& utxoEntry.getMixStatus().getMixProgress().getMixStep() != null
|
||||||
|
&& utxoEntry.getMixStatus().getMixProgress().getMixStep().isInterruptable()) {
|
||||||
|
utxoEntry.setMixProgress(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
EventManager.get().register(this);
|
EventManager.get().register(this);
|
||||||
|
@ -120,6 +134,7 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
stopMix.visibleProperty().bind(whirlpool.mixingProperty());
|
stopMix.visibleProperty().bind(whirlpool.mixingProperty());
|
||||||
whirlpool.startingProperty().addListener(new WeakChangeListener<>(mixingStartingListener));
|
whirlpool.startingProperty().addListener(new WeakChangeListener<>(mixingStartingListener));
|
||||||
whirlpool.stoppingProperty().addListener(new WeakChangeListener<>(mixingStoppingListener));
|
whirlpool.stoppingProperty().addListener(new WeakChangeListener<>(mixingStoppingListener));
|
||||||
|
whirlpool.mixingProperty().addListener(new WeakChangeListener<>(mixingListener));
|
||||||
updateMixToButton();
|
updateMixToButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,11 +378,8 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
|
|
||||||
updateMixToButton();
|
updateMixToButton();
|
||||||
if(whirlpool.isStarted()) {
|
if(whirlpool.isStarted()) {
|
||||||
Whirlpool.RestartService restartService = new Whirlpool.RestartService(whirlpool);
|
//Will automatically restart
|
||||||
restartService.setOnFailed(workerStateEvent -> {
|
AppServices.getWhirlpoolServices().stopWhirlpool(whirlpool, false);
|
||||||
log.error("Failed to restart whirlpool", workerStateEvent.getSource().getException());
|
|
||||||
});
|
|
||||||
restartService.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ import com.sparrowwallet.sparrow.whirlpool.dataSource.SparrowPostmixHandler;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.concurrent.ScheduledService;
|
||||||
import javafx.concurrent.Service;
|
import javafx.concurrent.Service;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -467,6 +468,15 @@ public class Whirlpool {
|
||||||
public void onWalletStop(WalletStopEvent e) {
|
public void onWalletStop(WalletStopEvent e) {
|
||||||
if(e.getWhirlpoolWallet() == whirlpoolWalletService.whirlpoolWallet()) {
|
if(e.getWhirlpoolWallet() == whirlpoolWalletService.whirlpoolWallet()) {
|
||||||
mixingProperty.set(false);
|
mixingProperty.set(false);
|
||||||
|
|
||||||
|
Wallet wallet = AppServices.get().getWallet(walletId);
|
||||||
|
if(wallet != null) {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
if(AppServices.isConnected()) {
|
||||||
|
AppServices.getWhirlpoolServices().startWhirlpool(wallet, this, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +549,7 @@ public class Whirlpool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StartupService extends Service<WhirlpoolWallet> {
|
public static class StartupService extends ScheduledService<WhirlpoolWallet> {
|
||||||
private final Whirlpool whirlpool;
|
private final Whirlpool whirlpool;
|
||||||
|
|
||||||
public StartupService(Whirlpool whirlpool) {
|
public StartupService(Whirlpool whirlpool) {
|
||||||
|
@ -588,37 +598,6 @@ public class Whirlpool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RestartService extends Service<Boolean> {
|
|
||||||
private final Whirlpool whirlpool;
|
|
||||||
|
|
||||||
public RestartService(Whirlpool whirlpool) {
|
|
||||||
this.whirlpool = whirlpool;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Task<Boolean> createTask() {
|
|
||||||
return new Task<>() {
|
|
||||||
protected Boolean call() throws Exception {
|
|
||||||
updateProgress(-1, 1);
|
|
||||||
updateMessage("Disconnecting from Whirlpool...");
|
|
||||||
whirlpool.stoppingProperty.set(true);
|
|
||||||
whirlpool.shutdown();
|
|
||||||
whirlpool.stoppingProperty.set(false);
|
|
||||||
|
|
||||||
updateMessage("Starting Whirlpool...");
|
|
||||||
whirlpool.startingProperty.set(true);
|
|
||||||
WhirlpoolWallet whirlpoolWallet = whirlpool.getWhirlpoolWallet();
|
|
||||||
if(AppServices.onlineProperty().get()) {
|
|
||||||
whirlpoolWallet.start();
|
|
||||||
}
|
|
||||||
whirlpool.startingProperty.set(false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class WalletUtxo {
|
public static class WalletUtxo {
|
||||||
public final Wallet wallet;
|
public final Wallet wallet;
|
||||||
public final BlockTransactionHashIndex utxo;
|
public final BlockTransactionHashIndex utxo;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import com.sparrowwallet.sparrow.event.*;
|
||||||
import com.sparrowwallet.sparrow.io.Config;
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
import com.sparrowwallet.sparrow.io.Storage;
|
import com.sparrowwallet.sparrow.io.Storage;
|
||||||
import com.sparrowwallet.sparrow.net.TorService;
|
import com.sparrowwallet.sparrow.net.TorService;
|
||||||
|
import javafx.util.Duration;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ public class WhirlpoolServices {
|
||||||
private static final Logger log = LoggerFactory.getLogger(WhirlpoolServices.class);
|
private static final Logger log = LoggerFactory.getLogger(WhirlpoolServices.class);
|
||||||
|
|
||||||
private final Map<String, Whirlpool> whirlpoolMap = new HashMap<>();
|
private final Map<String, Whirlpool> whirlpoolMap = new HashMap<>();
|
||||||
|
private Whirlpool.StartupService startupService;
|
||||||
|
|
||||||
public Whirlpool getWhirlpool(Wallet wallet) {
|
public Whirlpool getWhirlpool(Wallet wallet) {
|
||||||
Wallet masterWallet = wallet.isMasterWallet() ? wallet : wallet.getMasterWallet();
|
Wallet masterWallet = wallet.isMasterWallet() ? wallet : wallet.getMasterWallet();
|
||||||
|
@ -86,7 +88,15 @@ public class WhirlpoolServices {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Whirlpool.StartupService startupService = new Whirlpool.StartupService(whirlpool);
|
if(startupService != null) {
|
||||||
|
startupService.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
startupService = new Whirlpool.StartupService(whirlpool);
|
||||||
|
startupService.setPeriod(Duration.minutes(2));
|
||||||
|
startupService.setOnSucceeded(workerStateEvent -> {
|
||||||
|
startupService.cancel();
|
||||||
|
});
|
||||||
startupService.setOnFailed(workerStateEvent -> {
|
startupService.setOnFailed(workerStateEvent -> {
|
||||||
log.error("Failed to start whirlpool", workerStateEvent.getSource().getException());
|
log.error("Failed to start whirlpool", workerStateEvent.getSource().getException());
|
||||||
});
|
});
|
||||||
|
@ -175,11 +185,8 @@ public class WhirlpoolServices {
|
||||||
if(mixFromWhirlpool != null) {
|
if(mixFromWhirlpool != null) {
|
||||||
mixFromWhirlpool.setMixToWallet(walletId, AppServices.get().getWallet(mixFromWhirlpool.getWalletId()).getMasterMixConfig().getMinMixes());
|
mixFromWhirlpool.setMixToWallet(walletId, AppServices.get().getWallet(mixFromWhirlpool.getWalletId()).getMasterMixConfig().getMinMixes());
|
||||||
if(mixFromWhirlpool.isStarted()) {
|
if(mixFromWhirlpool.isStarted()) {
|
||||||
Whirlpool.RestartService restartService = new Whirlpool.RestartService(mixFromWhirlpool);
|
//Will automatically restart
|
||||||
restartService.setOnFailed(workerStateEvent -> {
|
stopWhirlpool(mixFromWhirlpool, false);
|
||||||
log.error("Failed to restart whirlpool", workerStateEvent.getSource().getException());
|
|
||||||
});
|
|
||||||
restartService.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,11 +217,8 @@ public class WhirlpoolServices {
|
||||||
if(mixToWhirlpool != null && event.getClosedWalletTabData().stream().noneMatch(walletTabData1 -> walletTabData1.getWalletForm().getWalletId().equals(mixToWhirlpool.getWalletId()))) {
|
if(mixToWhirlpool != null && event.getClosedWalletTabData().stream().noneMatch(walletTabData1 -> walletTabData1.getWalletForm().getWalletId().equals(mixToWhirlpool.getWalletId()))) {
|
||||||
mixToWhirlpool.setMixToWallet(null, null);
|
mixToWhirlpool.setMixToWallet(null, null);
|
||||||
if(mixToWhirlpool.isStarted()) {
|
if(mixToWhirlpool.isStarted()) {
|
||||||
Whirlpool.RestartService restartService = new Whirlpool.RestartService(mixToWhirlpool);
|
//Will automatically restart
|
||||||
restartService.setOnFailed(workerStateEvent -> {
|
stopWhirlpool(mixToWhirlpool, false);
|
||||||
log.error("Failed to restart whirlpool", workerStateEvent.getSource().getException());
|
|
||||||
});
|
|
||||||
restartService.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,7 @@ import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionInput;
|
import com.sparrowwallet.drongo.protocol.TransactionInput;
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
import com.sparrowwallet.drongo.wallet.*;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex;
|
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
|
||||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
|
||||||
import com.sparrowwallet.sparrow.AppServices;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.NewBlockEvent;
|
import com.sparrowwallet.sparrow.event.NewBlockEvent;
|
||||||
|
@ -99,7 +96,7 @@ public class SparrowDataSource extends WalletResponseDataSource {
|
||||||
|
|
||||||
for(Map.Entry<BlockTransactionHashIndex, WalletNode> utxo : wallet.getWalletUtxos().entrySet()) {
|
for(Map.Entry<BlockTransactionHashIndex, WalletNode> utxo : wallet.getWalletUtxos().entrySet()) {
|
||||||
BlockTransaction blockTransaction = wallet.getTransactions().get(utxo.getKey().getHash());
|
BlockTransaction blockTransaction = wallet.getTransactions().get(utxo.getKey().getHash());
|
||||||
if(blockTransaction != null) {
|
if(blockTransaction != null && utxo.getKey().getStatus() != Status.FROZEN) {
|
||||||
unspentOutputs.add(Whirlpool.getUnspentOutput(wallet, utxo.getValue(), blockTransaction, (int)utxo.getKey().getIndex()));
|
unspentOutputs.add(Whirlpool.getUnspentOutput(wallet, utxo.getValue(), blockTransaction, (int)utxo.getKey().getIndex()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,13 +176,13 @@ public class SparrowDataSource extends WalletResponseDataSource {
|
||||||
|
|
||||||
static Wallet getWallet(String zpub) {
|
static Wallet getWallet(String zpub) {
|
||||||
return AppServices.get().getOpenWallets().keySet().stream()
|
return AppServices.get().getOpenWallets().keySet().stream()
|
||||||
.filter(Wallet::isValid)
|
|
||||||
.filter(wallet -> {
|
.filter(wallet -> {
|
||||||
List<ExtendedKey.Header> headers = ExtendedKey.Header.getHeaders(Network.get());
|
List<ExtendedKey.Header> headers = ExtendedKey.Header.getHeaders(Network.get());
|
||||||
ExtendedKey.Header header = headers.stream().filter(head -> head.getDefaultScriptType().equals(wallet.getScriptType()) && !head.isPrivateKey()).findFirst().orElse(ExtendedKey.Header.xpub);
|
ExtendedKey.Header header = headers.stream().filter(head -> head.getDefaultScriptType().equals(wallet.getScriptType()) && !head.isPrivateKey()).findFirst().orElse(ExtendedKey.Header.xpub);
|
||||||
ExtendedKey extPubKey = wallet.getKeystores().get(0).getExtendedPublicKey();
|
ExtendedKey extPubKey = wallet.getKeystores().get(0).getExtendedPublicKey();
|
||||||
return extPubKey.toString(header).equals(zpub);
|
return extPubKey.toString(header).equals(zpub);
|
||||||
})
|
})
|
||||||
|
.filter(Wallet::isValid)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue