From fec45356a29a7ff0f5aad575ddc41dcdda2bf432 Mon Sep 17 00:00:00 2001 From: zeroleak Date: Sun, 22 Aug 2021 11:26:11 +0200 Subject: [PATCH] upgrade to whirlpool-client 0.23.30-early4 + extlibj 0.0.19-dsk3 --- build.gradle | 7 +- .../sparrowwallet/sparrow/AppServices.java | 4 +- ...BackendApi.java => SparrowDataSource.java} | 210 +++++++----------- .../whirlpool/SparrowMinerFeeSupplier.java | 45 +++- .../sparrow/whirlpool/Whirlpool.java | 51 +++-- 5 files changed, 164 insertions(+), 153 deletions(-) rename src/main/java/com/sparrowwallet/sparrow/whirlpool/{SparrowBackendApi.java => SparrowDataSource.java} (83%) diff --git a/build.gradle b/build.gradle index 184aff00..e22b91e0 100644 --- a/build.gradle +++ b/build.gradle @@ -395,25 +395,28 @@ extraJavaModuleInfo { requires('com.fasterxml.jackson.databind') requires('logback.classic') requires('org.json') - exports('com.sparrowwallet.nightjar') exports('com.samourai.http.client') exports('com.samourai.tor.client') exports('com.samourai.wallet.api.backend') exports('com.samourai.wallet.api.backend.beans') exports('com.samourai.wallet.hd') - exports('com.samourai.wallet.hd.java') exports('com.samourai.whirlpool.client.event') exports('com.samourai.whirlpool.client.wallet') exports('com.samourai.whirlpool.client.wallet.beans') + exports('com.samourai.whirlpool.client.wallet.data.dataSource') + exports('com.samourai.whirlpool.client.wallet.data.dataPersister') exports('com.samourai.whirlpool.client.whirlpool') exports('com.samourai.whirlpool.client.whirlpool.beans') exports('com.samourai.whirlpool.client.wallet.data.pool') exports('com.samourai.whirlpool.client.wallet.data.utxo') + exports('com.samourai.whirlpool.client.wallet.data.utxoConfig') + exports('com.samourai.whirlpool.client.wallet.data.supplier') exports('com.samourai.whirlpool.client.mix.listener') exports('com.samourai.whirlpool.protocol.beans') exports('com.samourai.whirlpool.protocol.rest') exports('com.samourai.whirlpool.client.tx0') exports('com.samourai.wallet.segwit.bech32') + exports('com.samourai.whirlpool.client.wallet.data.wallet') exports('com.samourai.whirlpool.client.wallet.data.minerFee') exports('com.samourai.whirlpool.client.wallet.data.walletState') exports('com.sparrowwallet.nightjar.http') diff --git a/src/main/java/com/sparrowwallet/sparrow/AppServices.java b/src/main/java/com/sparrowwallet/sparrow/AppServices.java index f7ce3089..8a6f67ff 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppServices.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppServices.java @@ -455,8 +455,8 @@ public class AppServices { public Whirlpool getWhirlpool(String walletId) { Whirlpool whirlpool = whirlpoolMap.get(walletId); if(whirlpool == null) { - HostAndPort torProxy = AppServices.isTorRunning() ? HostAndPort.fromParts("localhost", TorService.PROXY_PORT) : (Config.get().getProxyServer().isEmpty() || !Config.get().isUseProxy() ? null : HostAndPort.fromString(Config.get().getProxyServer())); - whirlpool = new Whirlpool(Network.get(), torProxy, Config.get().getScode(), 1, 15); + HostAndPort torProxy = AppServices.isTorRunning() ? HostAndPort.fromParts("localhost", TorService.PROXY_PORT) : (Config.get().getProxyServer() == null || Config.get().getProxyServer().isEmpty() || !Config.get().isUseProxy() ? null : HostAndPort.fromString(Config.get().getProxyServer())); + whirlpool = new Whirlpool(Network.get(), torProxy, Config.get().getScode(), 1); whirlpoolMap.put(walletId, whirlpool); } diff --git a/src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowBackendApi.java b/src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowDataSource.java similarity index 83% rename from src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowBackendApi.java rename to src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowDataSource.java index 6a23b79e..1c42d1c2 100644 --- a/src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowBackendApi.java +++ b/src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowDataSource.java @@ -1,9 +1,14 @@ package com.sparrowwallet.sparrow.whirlpool; -import com.samourai.wallet.api.backend.BackendApi; -import com.samourai.wallet.api.backend.MinerFee; import com.samourai.wallet.api.backend.MinerFeeTarget; -import com.samourai.wallet.api.backend.beans.*; +import com.samourai.wallet.api.backend.beans.TxsResponse; +import com.samourai.wallet.api.backend.beans.UnspentOutput; +import com.samourai.wallet.api.backend.beans.WalletResponse; +import com.samourai.wallet.hd.HD_Wallet; +import com.samourai.whirlpool.client.wallet.WhirlpoolWalletConfig; +import com.samourai.whirlpool.client.wallet.data.dataPersister.DataPersister; +import com.samourai.whirlpool.client.wallet.data.dataSource.WalletResponseDataSource; +import com.samourai.whirlpool.client.wallet.data.minerFee.MinerFeeSupplier; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.Network; @@ -21,88 +26,20 @@ import org.slf4j.LoggerFactory; import java.util.*; -@SuppressWarnings("deprecation") -public class SparrowBackendApi extends BackendApi { - private static final Logger log = LoggerFactory.getLogger(SparrowBackendApi.class); - private static final int FALLBACK_FEE_RATE = 75; +public class SparrowDataSource extends WalletResponseDataSource { + private static final Logger log = LoggerFactory.getLogger(SparrowDataSource.class); - public SparrowBackendApi() { - super(null, null); + public SparrowDataSource( + WhirlpoolWalletConfig config, + HD_Wallet bip44w, + String walletIdentifier, + DataPersister dataPersister) + throws Exception { + super(config, bip44w, walletIdentifier, dataPersister); } @Override - public TxsResponse fetchTxs(String[] zpubs, int page, int count) throws Exception { - List txes = new ArrayList<>(); - - for(String zpub : zpubs) { - Wallet wallet = getWallet(zpub); - if(wallet == null) { - log.debug("No wallet for " + zpub + " found"); - continue; - } - - for(BlockTransaction blockTransaction : wallet.getTransactions().values()) { - TxsResponse.Tx tx = new TxsResponse.Tx(); - tx.block_height = blockTransaction.getHeight(); - tx.hash = blockTransaction.getHashAsString(); - tx.locktime = blockTransaction.getTransaction().getLocktime(); - tx.time = blockTransaction.getDate().getTime(); - tx.version = (int)blockTransaction.getTransaction().getVersion(); - - tx.inputs = new TxsResponse.TxInput[blockTransaction.getTransaction().getInputs().size()]; - for(int i = 0; i < blockTransaction.getTransaction().getInputs().size(); i++) { - TransactionInput txInput = blockTransaction.getTransaction().getInputs().get(i); - tx.inputs[i] = new TxsResponse.TxInput(); - tx.inputs[i].vin = txInput.getIndex(); - tx.inputs[i].sequence = txInput.getSequenceNumber(); - tx.inputs[i].prev_out = new TxsResponse.TxOut(); - tx.inputs[i].prev_out.txid = txInput.getOutpoint().getHash().toString(); - tx.inputs[i].prev_out.vout = (int)txInput.getOutpoint().getIndex(); - - BlockTransaction spentTransaction = wallet.getTransactions().get(txInput.getOutpoint().getHash()); - if(spentTransaction != null) { - TransactionOutput spentOutput = spentTransaction.getTransaction().getOutputs().get((int)txInput.getOutpoint().getIndex()); - tx.inputs[i].prev_out.value = spentOutput.getValue(); - Address[] addresses = spentOutput.getScript().getToAddresses(); - if(addresses.length > 0) { - tx.inputs[i].prev_out.addr = addresses[0].toString(); - } - } - } - - tx.out = new TxsResponse.TxOutput[blockTransaction.getTransaction().getOutputs().size()]; - for(int i = 0; i < blockTransaction.getTransaction().getOutputs().size(); i++) { - TransactionOutput txOutput = blockTransaction.getTransaction().getOutputs().get(i); - tx.out[i].n = txOutput.getIndex(); - tx.out[i].value = txOutput.getValue(); - Address[] addresses = txOutput.getScript().getToAddresses(); - if(addresses.length > 0) { - tx.out[i].addr = addresses[0].toString(); - } - } - - txes.add(tx); - } - } - - List pageTxes; - if(txes.size() < count) { - pageTxes = txes; - } else { - pageTxes = txes.subList(page * count, Math.min((page * count) + count, txes.size())); - } - - TxsResponse txsResponse = new TxsResponse(); - txsResponse.n_tx = txes.size(); - txsResponse.page = page; - txsResponse.n_tx_page = pageTxes.size(); - txsResponse.txs = pageTxes.toArray(new TxsResponse.Tx[0]); - - return txsResponse; - } - - @Override - public WalletResponse fetchWallet(String[] zpubs) throws Exception { + protected WalletResponse fetchWalletResponse() throws Exception { WalletResponse walletResponse = new WalletResponse(); walletResponse.wallet = new WalletResponse.Wallet(); @@ -113,6 +50,7 @@ public class SparrowBackendApi extends BackendApi { List unspentOutputs = new ArrayList<>(); int storedBlockHeight = 0; + String[] zpubs = getWalletSupplier().getPubs(true); for(String zpub : zpubs) { Wallet wallet = getWallet(zpub); if(wallet == null) { @@ -197,22 +135,12 @@ public class SparrowBackendApi extends BackendApi { walletResponse.info.fees = new LinkedHashMap<>(); for(MinerFeeTarget target : MinerFeeTarget.values()) { - walletResponse.info.fees.put(target.getValue(), AppServices.getTargetBlockFeeRates() == null ? FALLBACK_FEE_RATE : getMinimumFeeForTarget(Integer.parseInt(target.getValue()))); + walletResponse.info.fees.put(target.getValue(), getMinerFeeSupplier().getFee(target)); } return walletResponse; } - @Override - public MinerFee fetchMinerFee() throws Exception { - Map fees = new LinkedHashMap<>(); - for(MinerFeeTarget target : MinerFeeTarget.values()) { - fees.put(target.getValue(), AppServices.getTargetBlockFeeRates() == null ? FALLBACK_FEE_RATE : getMinimumFeeForTarget(Integer.parseInt(target.getValue()))); - } - - return new MinerFee(fees); - } - @Override public void pushTx(String txHex) throws Exception { Transaction transaction = new Transaction(Utils.hexToBytes(txHex)); @@ -221,25 +149,79 @@ public class SparrowBackendApi extends BackendApi { } @Override - public boolean testConnectivity() { - return AppServices.isConnected(); - } + public TxsResponse fetchTxs(String[] zpubs, int page, int count) throws Exception { + List txes = new ArrayList<>(); - private Integer getMinimumFeeForTarget(int targetBlocks) { - List> feeRates = new ArrayList<>(AppServices.getTargetBlockFeeRates().entrySet()); - Collections.reverse(feeRates); - for(Map.Entry feeRate : feeRates) { - if(feeRate.getKey() <= targetBlocks) { - return feeRate.getValue().intValue(); + for(String zpub : zpubs) { + Wallet wallet = getWallet(zpub); + if(wallet == null) { + log.debug("No wallet for " + zpub + " found"); + continue; + } + + for(BlockTransaction blockTransaction : wallet.getTransactions().values()) { + TxsResponse.Tx tx = new TxsResponse.Tx(); + tx.block_height = blockTransaction.getHeight(); + tx.hash = blockTransaction.getHashAsString(); + tx.locktime = blockTransaction.getTransaction().getLocktime(); + tx.time = blockTransaction.getDate().getTime(); + tx.version = (int)blockTransaction.getTransaction().getVersion(); + + tx.inputs = new TxsResponse.TxInput[blockTransaction.getTransaction().getInputs().size()]; + for(int i = 0; i < blockTransaction.getTransaction().getInputs().size(); i++) { + TransactionInput txInput = blockTransaction.getTransaction().getInputs().get(i); + tx.inputs[i] = new TxsResponse.TxInput(); + tx.inputs[i].vin = txInput.getIndex(); + tx.inputs[i].sequence = txInput.getSequenceNumber(); + tx.inputs[i].prev_out = new TxsResponse.TxOut(); + tx.inputs[i].prev_out.txid = txInput.getOutpoint().getHash().toString(); + tx.inputs[i].prev_out.vout = (int)txInput.getOutpoint().getIndex(); + + BlockTransaction spentTransaction = wallet.getTransactions().get(txInput.getOutpoint().getHash()); + if(spentTransaction != null) { + TransactionOutput spentOutput = spentTransaction.getTransaction().getOutputs().get((int)txInput.getOutpoint().getIndex()); + tx.inputs[i].prev_out.value = spentOutput.getValue(); + Address[] addresses = spentOutput.getScript().getToAddresses(); + if(addresses.length > 0) { + tx.inputs[i].prev_out.addr = addresses[0].toString(); + } + } + } + + tx.out = new TxsResponse.TxOutput[blockTransaction.getTransaction().getOutputs().size()]; + for(int i = 0; i < blockTransaction.getTransaction().getOutputs().size(); i++) { + TransactionOutput txOutput = blockTransaction.getTransaction().getOutputs().get(i); + tx.out[i].n = txOutput.getIndex(); + tx.out[i].value = txOutput.getValue(); + Address[] addresses = txOutput.getScript().getToAddresses(); + if(addresses.length > 0) { + tx.out[i].addr = addresses[0].toString(); + } + } + + txes.add(tx); } } - return feeRates.get(0).getValue().intValue(); + List pageTxes; + if(txes.size() < count) { + pageTxes = txes; + } else { + pageTxes = txes.subList(page * count, Math.min((page * count) + count, txes.size())); + } + + TxsResponse txsResponse = new TxsResponse(); + txsResponse.n_tx = txes.size(); + txsResponse.page = page; + txsResponse.n_tx_page = pageTxes.size(); + txsResponse.txs = pageTxes.toArray(new TxsResponse.Tx[0]); + + return txsResponse; } @Override - public void initBip84(String zpub) throws Exception { - //nothing required + public MinerFeeSupplier getMinerFeeSupplier() { + return SparrowMinerFeeSupplier.getInstance(); } private Wallet getWallet(String zpub) { @@ -254,24 +236,4 @@ public class SparrowBackendApi extends BackendApi { .findFirst() .orElse(null); } - - @Override - public List fetchUtxos(String zpub) throws Exception { - throw new UnsupportedOperationException(); - } - - @Override - public List fetchUtxos(String[] zpubs) throws Exception { - throw new UnsupportedOperationException(); - } - - @Override - public Map fetchAddresses(String[] zpubs) throws Exception { - throw new UnsupportedOperationException(); - } - - @Override - public MultiAddrResponse.Address fetchAddress(String zpub) throws Exception { - throw new UnsupportedOperationException(); - } } diff --git a/src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowMinerFeeSupplier.java b/src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowMinerFeeSupplier.java index 68cd7569..1883d9b5 100644 --- a/src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowMinerFeeSupplier.java +++ b/src/main/java/com/sparrowwallet/sparrow/whirlpool/SparrowMinerFeeSupplier.java @@ -1,11 +1,46 @@ package com.sparrowwallet.sparrow.whirlpool; -import com.samourai.wallet.api.backend.MinerFee; +import com.samourai.wallet.api.backend.MinerFeeTarget; import com.samourai.whirlpool.client.wallet.data.minerFee.MinerFeeSupplier; +import com.sparrowwallet.sparrow.AppServices; -public class SparrowMinerFeeSupplier extends MinerFeeSupplier { - public SparrowMinerFeeSupplier(int feeMin, int feeMax, int feeFallback, MinerFee currentMinerFee) { - super(feeMin, feeMax, feeFallback); - setValue(currentMinerFee); +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class SparrowMinerFeeSupplier implements MinerFeeSupplier { + private static final int FALLBACK_FEE_RATE = 75; + + public static SparrowMinerFeeSupplier instance; + + public static SparrowMinerFeeSupplier getInstance() { + if (instance == null) { + instance = new SparrowMinerFeeSupplier(); + } + return instance; } + + private SparrowMinerFeeSupplier() { + } + + @Override + public int getFee(MinerFeeTarget feeTarget) { + if (AppServices.getTargetBlockFeeRates() == null) { + return FALLBACK_FEE_RATE; + } + return getMinimumFeeForTarget(Integer.parseInt(feeTarget.getValue())); + } + + private Integer getMinimumFeeForTarget(int targetBlocks) { + List> feeRates = new ArrayList<>(AppServices.getTargetBlockFeeRates().entrySet()); + Collections.reverse(feeRates); + for(Map.Entry feeRate : feeRates) { + if(feeRate.getKey() <= targetBlocks) { + return feeRate.getValue().intValue(); + } + } + return feeRates.get(0).getValue().intValue(); + } + } diff --git a/src/main/java/com/sparrowwallet/sparrow/whirlpool/Whirlpool.java b/src/main/java/com/sparrowwallet/sparrow/whirlpool/Whirlpool.java index 01184f65..496c750d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/whirlpool/Whirlpool.java +++ b/src/main/java/com/sparrowwallet/sparrow/whirlpool/Whirlpool.java @@ -3,17 +3,25 @@ package com.sparrowwallet.sparrow.whirlpool; import com.google.common.eventbus.Subscribe; import com.google.common.net.HostAndPort; import com.samourai.tor.client.TorClientService; -import com.samourai.wallet.api.backend.BackendApi; import com.samourai.wallet.api.backend.beans.UnspentOutput; import com.samourai.wallet.hd.HD_Wallet; -import com.samourai.wallet.hd.java.HD_WalletFactoryJava; -import com.samourai.whirlpool.client.event.*; +import com.samourai.wallet.hd.HD_WalletFactoryGeneric; +import com.samourai.whirlpool.client.event.MixFailEvent; +import com.samourai.whirlpool.client.event.MixSuccessEvent; +import com.samourai.whirlpool.client.event.WalletStartEvent; +import com.samourai.whirlpool.client.event.WalletStopEvent; import com.samourai.whirlpool.client.tx0.*; import com.samourai.whirlpool.client.wallet.WhirlpoolEventService; import com.samourai.whirlpool.client.wallet.WhirlpoolWallet; import com.samourai.whirlpool.client.wallet.WhirlpoolWalletConfig; import com.samourai.whirlpool.client.wallet.WhirlpoolWalletService; -import com.samourai.whirlpool.client.wallet.beans.*; +import com.samourai.whirlpool.client.wallet.beans.Tx0FeeTarget; +import com.samourai.whirlpool.client.wallet.beans.WhirlpoolAccount; +import com.samourai.whirlpool.client.wallet.beans.WhirlpoolServer; +import com.samourai.whirlpool.client.wallet.beans.WhirlpoolUtxo; +import com.samourai.whirlpool.client.wallet.data.dataPersister.DataPersisterFactory; +import com.samourai.whirlpool.client.wallet.data.dataPersister.FileDataPersister; +import com.samourai.whirlpool.client.wallet.data.dataSource.DataSourceFactory; import com.samourai.whirlpool.client.wallet.data.pool.PoolData; import com.samourai.whirlpool.client.wallet.data.utxo.UtxoSupplier; import com.samourai.whirlpool.client.whirlpool.ServerApi; @@ -36,7 +44,9 @@ import javafx.concurrent.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; public class Whirlpool { @@ -51,26 +61,27 @@ public class Whirlpool { private final WhirlpoolWalletConfig config; private HD_Wallet hdWallet; - public Whirlpool(Network network, HostAndPort torProxy, String sCode, int maxClients, int clientDelay) { + public Whirlpool(Network network, HostAndPort torProxy, String sCode, int maxClients) { this.torProxy = torProxy; this.whirlpoolServer = WhirlpoolServer.valueOf(network.getName().toUpperCase()); this.httpClientService = new JavaHttpClientService(torProxy); this.stompClientService = new JavaStompClientService(httpClientService); this.torClientService = new WhirlpoolTorClientService(); - this.whirlpoolWalletService = new WhirlpoolWalletService(); - this.config = computeWhirlpoolWalletConfig(sCode, maxClients, clientDelay); + + DataPersisterFactory dataPersisterFactory = (config, bip44w, walletIdentifier) -> new FileDataPersister(config, bip44w, walletIdentifier); + DataSourceFactory dataSourceFactory = (config, bip44w, walletIdentifier, dataPersister) -> new SparrowDataSource(config, bip44w, walletIdentifier, dataPersister); + this.whirlpoolWalletService = new WhirlpoolWalletService(dataPersisterFactory, dataSourceFactory); + this.config = computeWhirlpoolWalletConfig(sCode, maxClients); WhirlpoolEventService.getInstance().register(this); } - private WhirlpoolWalletConfig computeWhirlpoolWalletConfig(String sCode, int maxClients, int clientDelay) { + private WhirlpoolWalletConfig computeWhirlpoolWalletConfig(String sCode, int maxClients) { boolean onion = (torProxy != null); String serverUrl = whirlpoolServer.getServerUrl(onion); - ServerApi serverApi = new ServerApi(serverUrl, httpClientService); - BackendApi backendApi = new SparrowBackendApi(); - WhirlpoolWalletConfig whirlpoolWalletConfig = new WhirlpoolWalletConfig(httpClientService, stompClientService, torClientService, serverApi, whirlpoolServer, false, backendApi); + WhirlpoolWalletConfig whirlpoolWalletConfig = new WhirlpoolWalletConfig(httpClientService, stompClientService, torClientService, serverApi, whirlpoolServer.getParams(), false); whirlpoolWalletConfig.setScode(sCode); return whirlpoolWalletConfig; @@ -114,7 +125,7 @@ public class Whirlpool { private Tx0ParamService getTx0ParamService() { try { - SparrowMinerFeeSupplier minerFeeSupplier = new SparrowMinerFeeSupplier(config.getFeeMin(), config.getFeeMax(), config.getFeeFallback(), config.getBackendApi().fetchMinerFee()); + SparrowMinerFeeSupplier minerFeeSupplier = SparrowMinerFeeSupplier.getInstance(); return new Tx0ParamService(minerFeeSupplier, config); } catch(Exception e) { log.error("Error fetching miner fees", e); @@ -134,17 +145,17 @@ public class Whirlpool { int purpose = scriptType.getDefaultDerivation().get(0).num(); List words = keystore.getSeed().getMnemonicCode(); String passphrase = keystore.getSeed().getPassphrase().asString(); - HD_WalletFactoryJava hdWalletFactory = HD_WalletFactoryJava.getInstance(); + HD_WalletFactoryGeneric hdWalletFactory = HD_WalletFactoryGeneric.getInstance(); byte[] seed = hdWalletFactory.computeSeedFromWords(words); - hdWallet = new HD_Wallet(purpose, words, whirlpoolServer, seed, passphrase, 1); + hdWallet = new HD_Wallet(purpose, words, config.getNetworkParameters(), seed, passphrase, 1); } catch(Exception e) { throw new IllegalStateException("Could not create Whirlpool HD wallet ", e); } } public WhirlpoolWallet getWhirlpoolWallet() throws WhirlpoolException { - if(whirlpoolWalletService.whirlpoolWallet() != null) { - return whirlpoolWalletService.whirlpoolWallet(); + if(whirlpoolWalletService.getWhirlpoolWalletOrNull() != null) { + return whirlpoolWalletService.getWhirlpoolWalletOrNull(); } if(hdWallet == null) { @@ -167,11 +178,11 @@ public class Whirlpool { } public boolean isStarted() { - if(whirlpoolWalletService.whirlpoolWallet() == null) { + if(whirlpoolWalletService.getWhirlpoolWalletOrNull() == null) { return false; } - return whirlpoolWalletService.whirlpoolWallet().isStarted(); + return whirlpoolWalletService.getWhirlpoolWalletOrNull().isStarted(); } public void shutdown() { @@ -226,7 +237,7 @@ public class Whirlpool { @Subscribe public void onMixFail(MixFailEvent e) { - log.info("Mix failed for utxo " + e.getWhirlpoolUtxo().getUtxo().tx_hash + ":" + e.getWhirlpoolUtxo().getUtxo().tx_output_n); + log.info("Mix failed for utxo " + e.getMixFail().getWhirlpoolUtxo().getUtxo().tx_hash + ":" + e.getMixFail().getWhirlpoolUtxo().getUtxo().tx_output_n); } @Subscribe