mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
recount mixes if mix data unavailable, correct mix status cell to remove mix progress from non-mixing utxos, show registered inputs total in tooltip
This commit is contained in:
parent
2a0412320a
commit
4b39316821
10 changed files with 231 additions and 28 deletions
|
@ -10,8 +10,10 @@ import com.sparrowwallet.sparrow.wallet.Entry;
|
|||
import com.sparrowwallet.sparrow.wallet.UtxoEntry;
|
||||
import com.sparrowwallet.sparrow.whirlpool.Whirlpool;
|
||||
import com.sparrowwallet.sparrow.whirlpool.WhirlpoolException;
|
||||
import javafx.animation.FadeTransition;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.util.Duration;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
import org.controlsfx.tools.Platform;
|
||||
|
||||
|
@ -46,7 +48,7 @@ public class MixStatusCell extends TreeTableCell<Entry, UtxoEntry.MixStatus> {
|
|||
} else if(mixStatus.getMixFailReason() != null) {
|
||||
setMixFail(mixStatus.getMixFailReason(), mixStatus.getMixError());
|
||||
} else if(mixStatus.getMixProgress() != null) {
|
||||
setMixProgress(mixStatus.getMixProgress());
|
||||
setMixProgress(mixStatus.getUtxoEntry(), mixStatus.getMixProgress());
|
||||
} else {
|
||||
setGraphic(null);
|
||||
setTooltip(null);
|
||||
|
@ -65,13 +67,28 @@ public class MixStatusCell extends TreeTableCell<Entry, UtxoEntry.MixStatus> {
|
|||
|
||||
private void setMixFail(MixFailReason mixFailReason, String mixError) {
|
||||
if(mixFailReason != MixFailReason.CANCEL) {
|
||||
setGraphic(getFailGlyph());
|
||||
if(getGraphic() != null && getGraphic().getUserData() == mixFailReason) {
|
||||
//Fade transition already set
|
||||
return;
|
||||
}
|
||||
|
||||
Glyph failGlyph = getFailGlyph();
|
||||
setGraphic(failGlyph);
|
||||
Tooltip tt = new Tooltip();
|
||||
tt.setText(mixFailReason.getMessage() + (mixError == null ? "" : ": " + mixError) +
|
||||
"\nMix failures are generally caused by peers disconnecting during a mix." +
|
||||
"\nMake sure your internet connection is stable and the computer is configured to prevent sleeping." +
|
||||
"\nTo prevent sleeping, use the " + getPlatformSleepConfig() + " or enable the function in the Tools menu.");
|
||||
setTooltip(tt);
|
||||
|
||||
FadeTransition ft = new FadeTransition(Duration.hours(1), failGlyph);
|
||||
ft.setFromValue(1);
|
||||
ft.setToValue(0);
|
||||
ft.setOnFinished(event -> {
|
||||
setTooltip(null);
|
||||
});
|
||||
ft.play();
|
||||
failGlyph.setUserData(mixFailReason);
|
||||
} else {
|
||||
setGraphic(null);
|
||||
setTooltip(null);
|
||||
|
@ -89,14 +106,28 @@ public class MixStatusCell extends TreeTableCell<Entry, UtxoEntry.MixStatus> {
|
|||
return "system power settings";
|
||||
}
|
||||
|
||||
private void setMixProgress(MixProgress mixProgress) {
|
||||
private void setMixProgress(UtxoEntry utxoEntry, MixProgress mixProgress) {
|
||||
if(mixProgress.getMixStep() != MixStep.FAIL) {
|
||||
ProgressIndicator progressIndicator = getProgressIndicator();
|
||||
progressIndicator.setProgress(mixProgress.getMixStep().getProgressPercent() == 100 ? -1 : mixProgress.getMixStep().getProgressPercent() / 100.0);
|
||||
setGraphic(progressIndicator);
|
||||
Tooltip tt = new Tooltip();
|
||||
tt.setText(mixProgress.getMixStep().getMessage().substring(0, 1).toUpperCase() + mixProgress.getMixStep().getMessage().substring(1));
|
||||
String status = mixProgress.getMixStep().getMessage().substring(0, 1).toUpperCase() + mixProgress.getMixStep().getMessage().substring(1);
|
||||
tt.setText(status);
|
||||
setTooltip(tt);
|
||||
|
||||
if(mixProgress.getMixStep() == MixStep.REGISTERED_INPUT) {
|
||||
tt.setOnShowing(event -> {
|
||||
Whirlpool whirlpool = AppServices.getWhirlpoolServices().getWhirlpool(utxoEntry.getWallet());
|
||||
Whirlpool.RegisteredInputsService registeredInputsService = new Whirlpool.RegisteredInputsService(whirlpool, mixProgress.getPoolId());
|
||||
registeredInputsService.setOnSucceeded(eventStateHandler -> {
|
||||
if(registeredInputsService.getValue() != null) {
|
||||
tt.setText(status + " (1 of " + registeredInputsService.getValue() + ")");
|
||||
}
|
||||
});
|
||||
registeredInputsService.start();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
setGraphic(null);
|
||||
setTooltip(null);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.samourai.whirlpool.client.wallet.beans.IndexRange;
|
||||
import com.sparrowwallet.drongo.BitcoinUnit;
|
||||
import com.sparrowwallet.sparrow.Mode;
|
||||
import com.sparrowwallet.sparrow.Theme;
|
||||
|
@ -40,9 +41,10 @@ public class Config {
|
|||
private boolean openWalletsInNewWindows = false;
|
||||
private boolean hideEmptyUsedAddresses = false;
|
||||
private boolean showTransactionHex = true;
|
||||
private boolean showLoadingLog = false;
|
||||
private boolean showLoadingLog = true;
|
||||
private boolean showUtxosChart = true;
|
||||
private boolean preventSleep = false;
|
||||
private IndexRange postmixIndexRange = IndexRange.FULL;
|
||||
private List<File> recentWalletFiles;
|
||||
private Integer keyDerivationPeriod;
|
||||
private File hwi;
|
||||
|
@ -288,6 +290,15 @@ public class Config {
|
|||
this.preventSleep = preventSleep;
|
||||
}
|
||||
|
||||
public IndexRange getPostmixIndexRange() {
|
||||
return postmixIndexRange;
|
||||
}
|
||||
|
||||
public void setPostmixIndexRange(IndexRange postmixIndexRange) {
|
||||
this.postmixIndexRange = postmixIndexRange;
|
||||
flush();
|
||||
}
|
||||
|
||||
public List<File> getRecentWalletFiles() {
|
||||
return recentWalletFiles;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.google.common.eventbus.Subscribe;
|
|||
import com.samourai.whirlpool.client.whirlpool.beans.Pool;
|
||||
import com.sparrowwallet.drongo.BitcoinUnit;
|
||||
import com.sparrowwallet.drongo.KeyPurpose;
|
||||
import com.sparrowwallet.drongo.SecureString;
|
||||
import com.sparrowwallet.drongo.address.InvalidAddressException;
|
||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.samourai.whirlpool.client.mix.listener.MixFailReason;
|
|||
import com.samourai.whirlpool.client.mix.listener.MixStep;
|
||||
import com.samourai.whirlpool.client.wallet.beans.MixProgress;
|
||||
import com.samourai.whirlpool.protocol.beans.Utxo;
|
||||
import com.sparrowwallet.drongo.KeyPurpose;
|
||||
import com.sparrowwallet.drongo.address.Address;
|
||||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
|
@ -151,12 +152,12 @@ public class UtxoEntry extends HashIndexEntry {
|
|||
return wallet.getUtxoMixData(getHashIndex());
|
||||
}
|
||||
|
||||
//Mix data not available - recount (and store if WhirlpoolWallet is running)
|
||||
Whirlpool whirlpool = AppServices.getWhirlpoolServices().getWhirlpool(wallet);
|
||||
if(whirlpool != null) {
|
||||
UtxoMixData utxoMixData = whirlpool.getMixData(getHashIndex());
|
||||
if(utxoMixData != null) {
|
||||
return utxoMixData;
|
||||
}
|
||||
if(whirlpool != null && getUtxoEntry().getWallet().getStandardAccountType() == StandardAccount.WHIRLPOOL_POSTMIX && node.getKeyPurpose() == KeyPurpose.RECEIVE) {
|
||||
int mixesDone = whirlpool.recountMixesDone(getUtxoEntry().getWallet(), getHashIndex());
|
||||
whirlpool.setMixesDone(getHashIndex(), mixesDone);
|
||||
return new UtxoMixData(mixesDone, null);
|
||||
}
|
||||
|
||||
return new UtxoMixData(getUtxoEntry().getWallet().getStandardAccountType() == StandardAccount.WHIRLPOOL_POSTMIX ? 1 : 0, null);
|
||||
|
|
|
@ -502,6 +502,10 @@ public class UtxosController extends WalletFormController implements Initializab
|
|||
utxosTable.updateHistoryStatus(event);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void newBlock(NewBlockEvent event) {
|
||||
getWalletForm().getWalletUtxosEntry().updateMixProgress();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void bwtSyncStatus(BwtSyncStatusEvent event) {
|
||||
|
|
|
@ -12,7 +12,7 @@ public class WalletUtxosEntry extends Entry {
|
|||
public WalletUtxosEntry(Wallet wallet) {
|
||||
super(wallet, wallet.getName(), wallet.getWalletUtxos().entrySet().stream().map(entry -> new UtxoEntry(wallet, entry.getKey(), HashIndexEntry.Type.OUTPUT, entry.getValue())).collect(Collectors.toList()));
|
||||
calculateDuplicates();
|
||||
retrieveMixProgress();
|
||||
updateMixProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,16 +38,18 @@ public class WalletUtxosEntry extends Entry {
|
|||
}
|
||||
}
|
||||
|
||||
protected void retrieveMixProgress() {
|
||||
public void updateMixProgress() {
|
||||
Whirlpool whirlpool = AppServices.getWhirlpoolServices().getWhirlpool(getWallet());
|
||||
if(whirlpool != null) {
|
||||
for(Entry entry : getChildren()) {
|
||||
UtxoEntry utxoEntry = (UtxoEntry)entry;
|
||||
MixProgress mixProgress = whirlpool.getMixProgress(utxoEntry.getHashIndex());
|
||||
if(mixProgress != null || utxoEntry.getMixStatus() == null || (utxoEntry.getMixStatus().getMixFailReason() == null && utxoEntry.getMixStatus().getNextMixUtxo() == null)) {
|
||||
utxoEntry.setMixProgress(mixProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUtxos() {
|
||||
List<Entry> current = getWallet().getWalletUtxos().entrySet().stream().map(entry -> new UtxoEntry(getWallet(), entry.getKey(), HashIndexEntry.Type.OUTPUT, entry.getValue())).collect(Collectors.toList());
|
||||
|
@ -62,6 +64,6 @@ public class WalletUtxosEntry extends Entry {
|
|||
getChildren().removeAll(entriesRemoved);
|
||||
|
||||
calculateDuplicates();
|
||||
retrieveMixProgress();
|
||||
updateMixProgress();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,18 +25,15 @@ import com.sparrowwallet.drongo.ExtendedKey;
|
|||
import com.sparrowwallet.drongo.KeyPurpose;
|
||||
import com.sparrowwallet.drongo.Network;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
||||
import com.sparrowwallet.drongo.protocol.*;
|
||||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.nightjar.http.JavaHttpClientService;
|
||||
import com.sparrowwallet.nightjar.stomp.JavaStompClientService;
|
||||
import com.sparrowwallet.nightjar.tor.WhirlpoolTorClientService;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.WhirlpoolMixEvent;
|
||||
import com.sparrowwallet.sparrow.event.WhirlpoolMixSuccessEvent;
|
||||
import com.sparrowwallet.sparrow.io.Config;
|
||||
import com.sparrowwallet.sparrow.wallet.UtxoEntry;
|
||||
import com.sparrowwallet.sparrow.whirlpool.dataPersister.SparrowDataPersister;
|
||||
import com.sparrowwallet.sparrow.whirlpool.dataSource.SparrowDataSource;
|
||||
|
@ -49,6 +46,7 @@ import javafx.beans.property.SimpleBooleanProperty;
|
|||
import javafx.concurrent.ScheduledService;
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.util.Duration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -75,6 +73,7 @@ public class Whirlpool {
|
|||
private HD_Wallet hdWallet;
|
||||
private String walletId;
|
||||
private String mixToWalletId;
|
||||
private boolean resyncMixesDone;
|
||||
|
||||
private StartupService startupService;
|
||||
|
||||
|
@ -95,10 +94,14 @@ public class Whirlpool {
|
|||
this.tx0Service = new Tx0Service(config);
|
||||
|
||||
WhirlpoolEventService.getInstance().register(this);
|
||||
|
||||
StatusReporterService statusReporterService = new StatusReporterService(this);
|
||||
statusReporterService.setPeriod(Duration.minutes(1));
|
||||
statusReporterService.start();
|
||||
}
|
||||
|
||||
private WhirlpoolWalletConfig computeWhirlpoolWalletConfig(HostAndPort torProxy) {
|
||||
DataPersisterFactory dataPersisterFactory = (whirlpoolWallet, bip44w) -> new SparrowDataPersister(whirlpoolWallet);
|
||||
DataPersisterFactory dataPersisterFactory = (whirlpoolWallet, bip44w) -> new SparrowDataPersister(whirlpoolWallet, config.getPersistDelaySeconds());
|
||||
DataSourceFactory dataSourceFactory = (whirlpoolWallet, bip44w, dataPersister) -> new SparrowDataSource(whirlpoolWallet, bip44w, dataPersister);
|
||||
|
||||
boolean onion = (torProxy != null);
|
||||
|
@ -108,9 +111,20 @@ public class Whirlpool {
|
|||
WhirlpoolWalletConfig whirlpoolWalletConfig = new WhirlpoolWalletConfig(dataSourceFactory, httpClientService, stompClientService, torClientService, serverApi, whirlpoolServer.getParams(), false);
|
||||
whirlpoolWalletConfig.setDataPersisterFactory(dataPersisterFactory);
|
||||
whirlpoolWalletConfig.setPartner("SPARROW");
|
||||
whirlpoolWalletConfig.setIndexRangePostmix(Config.get().getPostmixIndexRange());
|
||||
return whirlpoolWalletConfig;
|
||||
}
|
||||
|
||||
public Pool getPool(String poolId) {
|
||||
try {
|
||||
return getPools(null).stream().filter(pool -> pool.getPoolId().equals(poolId)).findFirst().orElse(null);
|
||||
} catch(Exception e) {
|
||||
log.error("Error retrieving pools", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<Pool> getPools(Long totalUtxoValue) throws Exception {
|
||||
this.poolSupplier.load();
|
||||
if(totalUtxoValue == null) {
|
||||
|
@ -233,18 +247,73 @@ public class Whirlpool {
|
|||
|
||||
WhirlpoolUtxo whirlpoolUtxo = whirlpoolWalletService.whirlpoolWallet().getUtxoSupplier().findUtxo(utxo.getHashAsString(), (int)utxo.getIndex());
|
||||
if(whirlpoolUtxo != null && whirlpoolUtxo.getUtxoState() != null) {
|
||||
return whirlpoolUtxo.getUtxoState().getMixProgress();
|
||||
MixProgress mixProgress = whirlpoolUtxo.getUtxoState().getMixProgress();
|
||||
if(mixProgress != null && !isMixing(utxo)) {
|
||||
log.debug("Utxo " + utxo + " mix state is " + whirlpoolUtxo.getUtxoState() + " but utxo is not mixing");
|
||||
return null;
|
||||
}
|
||||
|
||||
return mixProgress;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isMixing(BlockTransactionHashIndex utxo) {
|
||||
if(whirlpoolWalletService.whirlpoolWallet() == null || !whirlpoolWalletService.whirlpoolWallet().isStarted()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return whirlpoolWalletService.whirlpoolWallet().getMixingState().getUtxosMixing().stream().map(WhirlpoolUtxo::getUtxo).anyMatch(uo -> uo.tx_hash.equals(utxo.getHashAsString()) && uo.tx_output_n == (int)utxo.getIndex());
|
||||
}
|
||||
|
||||
public void refreshUtxos() {
|
||||
if(whirlpoolWalletService.whirlpoolWallet() != null) {
|
||||
whirlpoolWalletService.whirlpoolWallet().refreshUtxos();
|
||||
}
|
||||
}
|
||||
|
||||
private void resyncMixesDone(Whirlpool whirlpool, Wallet postmixWallet) {
|
||||
Set<BlockTransactionHashIndex> receiveUtxos = postmixWallet.getWalletUtxos().entrySet().stream()
|
||||
.filter(entry -> entry.getValue().getKeyPurpose() == KeyPurpose.RECEIVE).map(Map.Entry::getKey).collect(Collectors.toSet());
|
||||
for(BlockTransactionHashIndex utxo : receiveUtxos) {
|
||||
int mixesDone = recountMixesDone(postmixWallet, utxo);
|
||||
whirlpool.setMixesDone(utxo, mixesDone);
|
||||
}
|
||||
}
|
||||
|
||||
public int recountMixesDone(Wallet postmixWallet, BlockTransactionHashIndex postmixUtxo) {
|
||||
int mixesDone = 0;
|
||||
Set<BlockTransactionHashIndex> walletTxos = postmixWallet.getWalletTxos().entrySet().stream()
|
||||
.filter(entry -> entry.getValue().getKeyPurpose() == KeyPurpose.RECEIVE).map(Map.Entry::getKey).collect(Collectors.toSet());
|
||||
BlockTransaction blkTx = postmixWallet.getTransactions().get(postmixUtxo.getHash());
|
||||
|
||||
while(blkTx != null) {
|
||||
mixesDone++;
|
||||
List<TransactionInput> inputs = blkTx.getTransaction().getInputs();
|
||||
blkTx = null;
|
||||
for(TransactionInput txInput : inputs) {
|
||||
BlockTransaction inputTx = postmixWallet.getTransactions().get(txInput.getOutpoint().getHash());
|
||||
if(inputTx != null && walletTxos.stream().anyMatch(txo -> txo.getHash().equals(inputTx.getHash()) && txo.getIndex() == txInput.getOutpoint().getIndex()) && inputTx.getTransaction() != null) {
|
||||
blkTx = inputTx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mixesDone;
|
||||
}
|
||||
|
||||
public void setMixesDone(BlockTransactionHashIndex utxo, int mixesDone) {
|
||||
if(whirlpoolWalletService.whirlpoolWallet() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
WhirlpoolUtxo whirlpoolUtxo = whirlpoolWalletService.whirlpoolWallet().getUtxoSupplier().findUtxo(utxo.getHashAsString(), (int)utxo.getIndex());
|
||||
if(whirlpoolUtxo != null) {
|
||||
whirlpoolUtxo.setMixsDone(mixesDone);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasWallet() {
|
||||
return hdWallet != null;
|
||||
}
|
||||
|
@ -385,10 +454,6 @@ public class Whirlpool {
|
|||
config.setScode(scode);
|
||||
}
|
||||
|
||||
public Tx0FeeTarget getTx0FeeTarget() {
|
||||
return tx0FeeTarget;
|
||||
}
|
||||
|
||||
public void setTx0FeeTarget(Tx0FeeTarget tx0FeeTarget) {
|
||||
this.tx0FeeTarget = tx0FeeTarget;
|
||||
}
|
||||
|
@ -401,6 +466,10 @@ public class Whirlpool {
|
|||
return mixToWalletId;
|
||||
}
|
||||
|
||||
public void setResyncMixesDone(boolean resyncMixesDone) {
|
||||
this.resyncMixesDone = resyncMixesDone;
|
||||
}
|
||||
|
||||
public void setMixToWallet(String mixToWalletId, Integer minMixes) {
|
||||
if(mixToWalletId == null) {
|
||||
config.setExternalDestination(null);
|
||||
|
@ -488,6 +557,15 @@ public class Whirlpool {
|
|||
if(e.getWhirlpoolWallet() == whirlpoolWalletService.whirlpoolWallet()) {
|
||||
log.info("Mixing to " + e.getWhirlpoolWallet().getConfig().getExternalDestination());
|
||||
mixingProperty.set(true);
|
||||
|
||||
if(resyncMixesDone) {
|
||||
Wallet wallet = AppServices.get().getWallet(walletId);
|
||||
if(wallet != null) {
|
||||
Wallet postmixWallet = getStandardAccountWallet(WhirlpoolAccount.POSTMIX, wallet);
|
||||
resyncMixesDone(this, postmixWallet);
|
||||
resyncMixesDone = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,6 +710,54 @@ public class Whirlpool {
|
|||
}
|
||||
}
|
||||
|
||||
public static class RegisteredInputsService extends Service<Integer> {
|
||||
private final Whirlpool whirlpool;
|
||||
private final String poolId;
|
||||
|
||||
public RegisteredInputsService(Whirlpool whirlpool, String poolId) {
|
||||
this.whirlpool = whirlpool;
|
||||
this.poolId = poolId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Task<Integer> createTask() {
|
||||
return new Task<>() {
|
||||
protected Integer call() {
|
||||
Pool pool = whirlpool.getPool(poolId);
|
||||
if(pool != null) {
|
||||
return pool.getNbRegistered();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class StatusReporterService extends ScheduledService<Boolean> {
|
||||
private final Whirlpool whirlpool;
|
||||
|
||||
public StatusReporterService(Whirlpool whirlpool) {
|
||||
this.whirlpool = whirlpool;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Task<Boolean> createTask() {
|
||||
return new Task<>() {
|
||||
protected Boolean call() throws Exception {
|
||||
if(whirlpool.mixingProperty().get()) {
|
||||
WhirlpoolWallet whirlpoolWallet = whirlpool.getWhirlpoolWallet();
|
||||
log.debug(whirlpool.walletId + ": " + whirlpoolWallet.getMixingState());
|
||||
} else {
|
||||
log.debug(whirlpool.walletId + ": Not mixing");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class WalletUtxo {
|
||||
public final Wallet wallet;
|
||||
public final BlockTransactionHashIndex utxo;
|
||||
|
|
|
@ -156,6 +156,7 @@ public class WhirlpoolServices {
|
|||
Whirlpool whirlpool = AppServices.getWhirlpoolServices().getWhirlpool(walletId);
|
||||
whirlpool.setScode(decryptedWallet.getMasterMixConfig().getScode());
|
||||
whirlpool.setHDWallet(walletId, decryptedWallet);
|
||||
whirlpool.setResyncMixesDone(true);
|
||||
|
||||
for(StandardAccount whirlpoolAccount : StandardAccount.WHIRLPOOL_ACCOUNTS) {
|
||||
if(decryptedWallet.getChildWallet(whirlpoolAccount) == null) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.sparrowwallet.sparrow.whirlpool.dataPersister;
|
||||
|
||||
import com.samourai.wallet.util.AbstractOrchestrator;
|
||||
import com.samourai.whirlpool.client.wallet.WhirlpoolWallet;
|
||||
import com.samourai.whirlpool.client.wallet.WhirlpoolWalletConfig;
|
||||
import com.samourai.whirlpool.client.wallet.data.dataPersister.DataPersister;
|
||||
|
@ -7,24 +8,49 @@ import com.samourai.whirlpool.client.wallet.data.utxoConfig.UtxoConfigPersistedS
|
|||
import com.samourai.whirlpool.client.wallet.data.utxoConfig.UtxoConfigSupplier;
|
||||
import com.samourai.whirlpool.client.wallet.data.walletState.WalletStateSupplier;
|
||||
import com.sparrowwallet.sparrow.whirlpool.dataSource.SparrowWalletStateSupplier;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SparrowDataPersister implements DataPersister {
|
||||
private static final Logger log = LoggerFactory.getLogger(SparrowDataPersister.class);
|
||||
|
||||
private final WalletStateSupplier walletStateSupplier;
|
||||
private final UtxoConfigSupplier utxoConfigSupplier;
|
||||
|
||||
public SparrowDataPersister(WhirlpoolWallet whirlpoolWallet) throws Exception {
|
||||
private AbstractOrchestrator persistOrchestrator;
|
||||
private final int persistDelaySeconds;
|
||||
|
||||
public SparrowDataPersister(WhirlpoolWallet whirlpoolWallet, int persistDelaySeconds) throws Exception {
|
||||
WhirlpoolWalletConfig config = whirlpoolWallet.getConfig();
|
||||
String walletIdentifier = whirlpoolWallet.getWalletIdentifier();
|
||||
this.walletStateSupplier = new SparrowWalletStateSupplier(walletIdentifier, config);
|
||||
this.utxoConfigSupplier = new UtxoConfigPersistedSupplier(new SparrowUtxoConfigPersister(walletIdentifier));
|
||||
this.persistDelaySeconds = persistDelaySeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() throws Exception {
|
||||
startPersistOrchestrator();
|
||||
}
|
||||
|
||||
protected void startPersistOrchestrator() {
|
||||
persistOrchestrator = new AbstractOrchestrator(persistDelaySeconds * 1000) {
|
||||
@Override
|
||||
protected void runOrchestrator() {
|
||||
try {
|
||||
persist(false);
|
||||
} catch (Exception e) {
|
||||
log.error("Error persisting Whirlpool data", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
persistOrchestrator.start(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
persistOrchestrator.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -62,8 +62,10 @@ public class SparrowUtxoConfigPersister extends UtxoConfigPersister {
|
|||
wallet.getUtxoMixes().putAll(changedUtxoMixes);
|
||||
wallet.getUtxoMixes().keySet().removeAll(removedUtxoMixes.keySet());
|
||||
|
||||
if(!changedUtxoMixes.isEmpty() || !removedUtxoMixes.isEmpty()) {
|
||||
EventManager.get().post(new WalletUtxoMixesChangedEvent(wallet, changedUtxoMixes, removedUtxoMixes));
|
||||
}
|
||||
}
|
||||
|
||||
private Wallet getWallet() {
|
||||
return AppServices.get().getOpenWallets().entrySet().stream().filter(entry -> entry.getValue().getWalletId(entry.getKey()).equals(walletId)).map(Map.Entry::getKey).findFirst().orElse(null);
|
||||
|
|
Loading…
Reference in a new issue