mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
fix tor proxy switching for whirlpool client and mixing bip47 utxos
This commit is contained in:
parent
a9fd7c263f
commit
9ba4458f48
10 changed files with 65 additions and 10 deletions
|
@ -189,6 +189,8 @@ application {
|
|||
"--add-opens=java.base/java.net=com.sparrowwallet.sparrow",
|
||||
"--add-opens=java.base/java.io=com.google.gson",
|
||||
"--add-opens=java.smartcardio/sun.security.smartcardio=com.sparrowwallet.sparrow",
|
||||
"--add-opens=com.samourai.whirlpool.client/com.samourai.whirlpool.client.whirlpool=com.sparrowwallet.sparrow",
|
||||
"--add-opens=com.samourai.soroban.client/com.samourai.soroban.client.rpc=com.sparrowwallet.sparrow",
|
||||
"--add-reads=kotlin.stdlib=kotlinx.coroutines.core"]
|
||||
|
||||
if(os.macOsX) {
|
||||
|
@ -238,6 +240,8 @@ jlink {
|
|||
"--add-opens=java.base/java.net=com.sparrowwallet.sparrow",
|
||||
"--add-opens=java.base/java.io=com.google.gson",
|
||||
"--add-opens=java.smartcardio/sun.security.smartcardio=com.sparrowwallet.sparrow",
|
||||
"--add-opens=com.samourai.whirlpool.client/com.samourai.whirlpool.client.whirlpool=com.sparrowwallet.sparrow",
|
||||
"--add-opens=com.samourai.soroban.client/com.samourai.soroban.client.rpc=com.sparrowwallet.sparrow",
|
||||
"--add-reads=com.sparrowwallet.merged.module=java.desktop",
|
||||
"--add-reads=com.sparrowwallet.merged.module=java.sql",
|
||||
"--add-reads=com.sparrowwallet.merged.module=com.sparrowwallet.sparrow",
|
||||
|
|
|
@ -167,6 +167,11 @@ public class AppServices {
|
|||
connectionService.cancel();
|
||||
ratesService.cancel();
|
||||
versionCheckService.cancel();
|
||||
|
||||
if(httpClientService != null) {
|
||||
HttpClientService.ShutdownService shutdownService = new HttpClientService.ShutdownService(httpClientService);
|
||||
shutdownService.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.sparrowwallet.sparrow.soroban;
|
|||
|
||||
import com.samourai.soroban.client.SorobanConfig;
|
||||
import com.samourai.soroban.client.wallet.SorobanWalletService;
|
||||
import com.samourai.wallet.chain.ChainSupplier;
|
||||
import com.samourai.wallet.hd.HD_Wallet;
|
||||
import com.sparrowwallet.drongo.Network;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
|
@ -10,8 +9,6 @@ import com.sparrowwallet.drongo.wallet.Wallet;
|
|||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.whirlpool.Whirlpool;
|
||||
import com.sparrowwallet.sparrow.whirlpool.dataSource.SparrowChainSupplier;
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -28,6 +25,7 @@ public class Soroban {
|
|||
|
||||
private HD_Wallet hdWallet;
|
||||
private int bip47Account;
|
||||
private SparrowChainSupplier chainSupplier;
|
||||
|
||||
public Soroban() {
|
||||
SorobanConfig sorobanConfig = AppServices.getWhirlpoolServices().getSorobanConfig();
|
||||
|
@ -63,7 +61,10 @@ public class Soroban {
|
|||
}
|
||||
|
||||
try {
|
||||
ChainSupplier chainSupplier = new SparrowChainSupplier(wallet.getStoredBlockHeight());
|
||||
if(chainSupplier == null) {
|
||||
chainSupplier = new SparrowChainSupplier(wallet.getStoredBlockHeight());
|
||||
chainSupplier.open();
|
||||
}
|
||||
return new SparrowCahootsWallet(chainSupplier, wallet, hdWallet, bip47Account);
|
||||
} catch(Exception e) {
|
||||
log.error("Could not create cahoots wallet", e);
|
||||
|
@ -79,4 +80,10 @@ public class Soroban {
|
|||
public SorobanWalletService getSorobanWalletService() {
|
||||
return sorobanWalletService;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if(chainSupplier != null) {
|
||||
chainSupplier.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,10 @@ public class SorobanServices {
|
|||
public void walletTabsClosed(WalletTabsClosedEvent event) {
|
||||
for(WalletTabData walletTabData : event.getClosedWalletTabData()) {
|
||||
String walletId = walletTabData.getStorage().getWalletId(walletTabData.getWallet());
|
||||
sorobanMap.remove(walletId);
|
||||
Soroban soroban = sorobanMap.remove(walletId);
|
||||
if(soroban != null) {
|
||||
soroban.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ public class MixTableCell extends TableCell {
|
|||
|
||||
private String getMixFail(UtxoEntry.MixStatus mixStatus) {
|
||||
long elapsed = mixStatus.getMixErrorTimestamp() == null ? 0L : System.currentTimeMillis() - mixStatus.getMixErrorTimestamp();
|
||||
if(mixStatus.getMixFailReason() == MixFailReason.STOP_UTXO || !mixStatus.getMixFailReason().isError() || elapsed >= ERROR_DISPLAY_MILLIS) {
|
||||
if(!mixStatus.getMixFailReason().isError() || elapsed >= ERROR_DISPLAY_MILLIS) {
|
||||
return getMixCountOnly(mixStatus);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import com.samourai.whirlpool.client.wallet.data.dataPersister.DataPersisterFact
|
|||
import com.samourai.whirlpool.client.wallet.data.dataSource.DataSourceConfig;
|
||||
import com.samourai.whirlpool.client.wallet.data.dataSource.DataSourceFactory;
|
||||
import com.samourai.whirlpool.client.wallet.data.utxo.UtxoSupplier;
|
||||
import com.samourai.whirlpool.client.whirlpool.WhirlpoolClientConfig;
|
||||
import com.samourai.whirlpool.client.whirlpool.beans.Pool;
|
||||
import com.sparrowwallet.drongo.ExtendedKey;
|
||||
import com.sparrowwallet.drongo.KeyPurpose;
|
||||
|
@ -60,6 +61,7 @@ import org.bitcoinj.core.NetworkParameters;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -110,6 +112,18 @@ public class Whirlpool {
|
|||
return whirlpoolWalletConfig;
|
||||
}
|
||||
|
||||
void setOnion(boolean onion) {
|
||||
if(config.isTorOnionCoordinator() ^ onion) {
|
||||
try {
|
||||
Field torField = WhirlpoolClientConfig.class.getDeclaredField("torOnionCoordinator");
|
||||
torField.setAccessible(true);
|
||||
torField.set(config, onion);
|
||||
} catch(Exception e) {
|
||||
log.warn("Error changing onion on WhirlpoolWalletConfig", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DataSourceConfig computeDataSourceConfig(Integer storedBlockHeight) {
|
||||
return new DataSourceConfig(SparrowMinerFeeSupplier.getInstance(), new SparrowChainSupplier(storedBlockHeight), BIP_FORMAT.PROVIDER, BIP_WALLETS.WHIRLPOOL);
|
||||
}
|
||||
|
@ -469,7 +483,7 @@ public class Whirlpool {
|
|||
UnspentOutput.Xpub xpub = new UnspentOutput.Xpub();
|
||||
ExtendedKey.Header header = testnet ? ExtendedKey.Header.tpub : ExtendedKey.Header.xpub;
|
||||
xpub.m = wallet.getKeystores().get(0).getExtendedPublicKey().toString(header);
|
||||
xpub.path = node.getDerivationPath().toUpperCase(Locale.ROOT);
|
||||
xpub.path = node.getWallet().isBip47() ? null : node.getDerivationPath().toUpperCase(Locale.ROOT);
|
||||
|
||||
out.xpub = xpub;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow.whirlpool;
|
|||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.common.net.HostAndPort;
|
||||
import com.samourai.soroban.client.SorobanConfig;
|
||||
import com.samourai.soroban.client.rpc.RpcClientService;
|
||||
import com.samourai.wallet.constants.SamouraiNetwork;
|
||||
import com.samourai.wallet.util.ExtLibJConfig;
|
||||
import com.samourai.whirlpool.client.wallet.WhirlpoolEventService;
|
||||
|
@ -29,11 +30,13 @@ import javafx.util.Duration;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.sparrowwallet.sparrow.AppServices.getHttpClientService;
|
||||
import static com.sparrowwallet.sparrow.AppServices.getTorProxy;
|
||||
import static org.bitcoinj.crypto.MnemonicCode.SPARROW_FIX_NFKD_MNEMONIC;
|
||||
|
||||
|
@ -52,7 +55,7 @@ public class WhirlpoolServices {
|
|||
|
||||
private ExtLibJConfig computeExtLibJConfig() {
|
||||
HttpClientService httpClientService = AppServices.getHttpClientService();
|
||||
boolean onion = (AppServices.getTorProxy() != null);
|
||||
boolean onion = (getTorProxy() != null);
|
||||
SamouraiNetwork samouraiNetwork = getSamouraiNetwork();
|
||||
return new ExtLibJConfig(samouraiNetwork, onion, Drongo.getProvider(), httpClientService);
|
||||
}
|
||||
|
@ -107,6 +110,8 @@ public class WhirlpoolServices {
|
|||
|
||||
public void startWhirlpool(Wallet wallet, Whirlpool whirlpool, boolean notifyIfMixToMissing) {
|
||||
if(wallet.getMasterMixConfig().getMixOnStartup() != Boolean.FALSE) {
|
||||
whirlpool.setOnion(sorobanConfig.getExtLibJConfig().isOnion());
|
||||
|
||||
try {
|
||||
String mixToWalletId = getWhirlpoolMixToWalletId(wallet.getMasterMixConfig());
|
||||
whirlpool.setMixToWallet(mixToWalletId, wallet.getMasterMixConfig().getMinMixes());
|
||||
|
@ -221,6 +226,18 @@ public class WhirlpoolServices {
|
|||
|
||||
@Subscribe
|
||||
public void newConnection(ConnectionEvent event) {
|
||||
ExtLibJConfig extLibJConfig = sorobanConfig.getExtLibJConfig();
|
||||
extLibJConfig.setOnion(getTorProxy() != null);
|
||||
getHttpClientService(); //Ensure proxy is updated
|
||||
|
||||
try {
|
||||
Field onionField = RpcClientService.class.getDeclaredField("onion");
|
||||
onionField.setAccessible(true);
|
||||
onionField.set(sorobanConfig.getRpcClientService(), getTorProxy() != null);
|
||||
} catch(Exception e) {
|
||||
log.warn("Error changing onion on RpcClientService", e);
|
||||
}
|
||||
|
||||
startAllWhirlpool();
|
||||
bindDebugAccelerator();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ public class SparrowChainSupplier implements ChainSupplier {
|
|||
public SparrowChainSupplier(Integer storedBlockHeight) {
|
||||
this.storedBlockHeight = AppServices.getCurrentBlockHeight() == null ? (storedBlockHeight != null ? storedBlockHeight : 0) : AppServices.getCurrentBlockHeight();
|
||||
this.latestBlock = computeLatestBlock();
|
||||
}
|
||||
|
||||
public void open() {
|
||||
EventManager.get().register(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ public class SparrowDataSource extends AbstractDataSource {
|
|||
public void open(CoordinatorSupplier coordinatorSupplier) throws Exception {
|
||||
super.open(coordinatorSupplier);
|
||||
EventManager.get().register(this);
|
||||
((SparrowChainSupplier)getDataSourceConfig().getChainSupplier()).open();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -128,7 +128,8 @@ public class SparrowUtxoSupplier extends BasicUtxoSupplier {
|
|||
|
||||
@Override
|
||||
public byte[] _getPrivKeyBip47(UnspentOutput utxo) throws Exception {
|
||||
Wallet wallet = SparrowDataSource.getWallet(utxo.xpub.m);
|
||||
BipWallet bipWallet = getWalletSupplier().getWalletByXPub(utxo.xpub.m);
|
||||
Wallet wallet = SparrowDataSource.getWallet(bipWallet.getBipPub());
|
||||
Map<BlockTransactionHashIndex, WalletNode> walletUtxos = wallet.getWalletUtxos();
|
||||
WalletNode node = walletUtxos.entrySet().stream()
|
||||
.filter(entry -> entry.getKey().getHash().equals(Sha256Hash.wrap(utxo.tx_hash)) && entry.getKey().getIndex() == utxo.tx_output_n)
|
||||
|
|
Loading…
Reference in a new issue