Commit b55c7537 authored by zeroleak's avatar zeroleak
Browse files

rename --reconstruct to --resync

parent e8892044
......@@ -7,8 +7,8 @@
| --init | Initialize CLI (by setting wallet seed and generating API key) |
| --authenticate | Enable interactive authentication on startup |
| --listen | Enable CLI API for remote commands & GUI (see [API.md](API.md))|
| --resync | Resynchronize mix counters on startup (useful when mixing simultaneously with Android) |
| --list-pools | List pools and exit|
| --reconstruct | Reconstruct mix counters and exit |
| --dump-payload | Dump pairing-payload of current wallet and exit |
......
......@@ -34,7 +34,7 @@ public class ApplicationArgs {
private static final String ARG_AUTHENTICATE = "authenticate";
private static final String ARG_MIXS_TARGET = "mixs-target";
private static final String ARG_DUMP_PAYLOAD = "dump-payload";
private static final String ARG_RECONSTRUCT = "reconstruct";
private static final String ARG_RESYNC = "resync";
private ApplicationArguments args;
......@@ -110,8 +110,8 @@ public class ApplicationArgs {
return args.containsOption(ARG_DUMP_PAYLOAD);
}
public boolean isReconstruct() {
return args.containsOption(ARG_RECONSTRUCT);
public boolean isResync() {
return args.containsOption(ARG_RESYNC);
}
public String getAggregatePostmix() {
......
......@@ -8,5 +8,5 @@ public abstract class CliUpgradeAuth extends CliUpgrade {
super();
}
public abstract void run(CliWallet cliWallet) throws Exception;
public abstract boolean run(CliWallet cliWallet) throws Exception;
}
......@@ -4,5 +4,5 @@ public abstract class CliUpgradeUnauth extends CliUpgrade {
public CliUpgradeUnauth() {}
public abstract void run() throws Exception;
public abstract boolean run() throws Exception;
}
......@@ -45,9 +45,6 @@ public class RunCliCommand {
} else if (appArgs.isListPools()) {
CliWallet cliWallet = cliWalletService.getSessionWallet();
new RunListPools(cliWallet).run();
} else if (appArgs.isReconstruct()) {
CliWallet cliWallet = cliWalletService.getSessionWallet();
new RunReconstruct(cliWallet).run();
} else {
throw new Exception("Unknown command.");
}
......@@ -58,9 +55,6 @@ public class RunCliCommand {
}
public static boolean hasCommandToRun(ApplicationArgs appArgs, CliConfig cliConfig) {
return appArgs.isDumpPayload()
|| appArgs.isAggregatePostmix()
|| appArgs.isListPools()
|| appArgs.isReconstruct();
return appArgs.isDumpPayload() || appArgs.isAggregatePostmix() || appArgs.isListPools();
}
}
package com.samourai.whirlpool.cli.run;
import com.samourai.wallet.api.backend.beans.TxsResponse;
import com.samourai.whirlpool.cli.utils.CliUtils;
import com.samourai.whirlpool.cli.wallet.CliWallet;
import com.samourai.whirlpool.client.wallet.beans.WhirlpoolAccount;
import com.samourai.whirlpool.client.wallet.beans.WhirlpoolUtxo;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RunReconstruct {
private static final int TXS_PER_PAGE = 1000;
private Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private CliWallet cliWallet;
public RunReconstruct(CliWallet cliWallet) {
this.cliWallet = cliWallet;
}
public void run() throws Exception {
log.info(CliUtils.LOG_SEPARATOR);
log.info("⣿ RECONSTRUCT");
log.info("⣿ This will reconstruct mix counters.");
log.info("⣿ • Continue?");
String userInput =
CliUtils.readUserInputRequired("Continue? (y/n)", false, new String[] {"y", "n", "Y", "N"});
if (!userInput.toLowerCase().equals("y")) {
return;
}
reconstruct();
}
public void reconstruct() throws Exception {
Collection<WhirlpoolUtxo> whirlpoolUtxos =
cliWallet.getUtxoSupplier().findUtxos(WhirlpoolAccount.POSTMIX);
log.info("Reconstructing mix counters...");
Map<String, TxsResponse.Tx> txs = fetchTxs();
int fixedUtxos = 0;
for (WhirlpoolUtxo whirlpoolUtxo : whirlpoolUtxos) {
int mixsDone = recount(whirlpoolUtxo, txs);
if (mixsDone != whirlpoolUtxo.getMixsDone()) {
log.info(
"Fixed "
+ whirlpoolUtxo.getUtxo().tx_hash
+ ":"
+ whirlpoolUtxo.getUtxo().tx_output_n
+ ": "
+ whirlpoolUtxo.getMixsDone()
+ " => "
+ mixsDone);
whirlpoolUtxo.setMixsDone(mixsDone);
fixedUtxos++;
}
}
log.info(CliUtils.LOG_SEPARATOR);
log.info("⣿ RECONSTRUCT SUCCESS");
log.info("⣿ " + fixedUtxos + "/" + whirlpoolUtxos.size() + " utxos updated.");
log.info(CliUtils.LOG_SEPARATOR);
}
private Map<String, TxsResponse.Tx> fetchTxs() throws Exception {
Map<String, TxsResponse.Tx> txs = new LinkedHashMap<>();
int page = -1;
String[] zpubs = new String[] {cliWallet.getWalletPostmix().getZpub()};
TxsResponse txsResponse;
do {
page++;
txsResponse = cliWallet.getConfig().getBackendApi().fetchTxs(zpubs, page, TXS_PER_PAGE);
if (txsResponse.txs != null) {
for (TxsResponse.Tx tx : txsResponse.txs) {
txs.put(tx.hash, tx);
}
}
log.info("Fetching postmix history... " + txs.size() + "/" + txsResponse.n_tx);
} while ((page * TXS_PER_PAGE) < txsResponse.n_tx);
return txs;
}
private int recount(WhirlpoolUtxo whirlpoolUtxo, Map<String, TxsResponse.Tx> txs) {
int mixsDone = 0;
String txid = whirlpoolUtxo.getUtxo().tx_hash;
while (true) {
TxsResponse.Tx tx = txs.get(txid);
mixsDone++;
if (tx == null || tx.inputs == null || tx.inputs.length == 0) {
return mixsDone;
}
txid = tx.inputs[0].prev_out.txid;
}
}
}
......@@ -210,11 +210,17 @@ public class CliConfigService {
}
public synchronized void setVersion(int version) throws Exception {
if (log.isDebugEnabled()) {
log.debug("setVersion: " + version);
}
Properties props = loadProperties();
props.put(KEY_VERSION, Integer.toString(version));
// save
save(props);
// update runtime
cliConfig.setVersion(version);
}
public synchronized void resetConfiguration() throws Exception {
......@@ -233,6 +239,7 @@ public class CliConfigService {
public void setCliStatusNotReady(String error) {
this.setCliStatus(CliStatus.NOT_READY, error);
log.warn("status -> " + error);
}
protected synchronized void save(Properties props) throws Exception {
......
......@@ -200,6 +200,11 @@ public class CliService {
new RunCliCommand(appArgs, cliWalletService, walletAggregateService).run();
return CliResult.EXIT_SUCCESS;
} else {
// resync?
if (appArgs.isResync()) {
cliWallet.resync();
}
// start wallet
cliWallet.start();
keepRunning();
......
......@@ -5,7 +5,6 @@ import com.samourai.whirlpool.cli.beans.CliUpgradeAuth;
import com.samourai.whirlpool.cli.beans.CliUpgradeUnauth;
import com.samourai.whirlpool.cli.beans.CliVersion;
import com.samourai.whirlpool.cli.config.CliConfig;
import com.samourai.whirlpool.cli.run.RunReconstruct;
import com.samourai.whirlpool.cli.wallet.CliWallet;
import java.lang.invoke.MethodHandles;
import java.util.LinkedHashMap;
......@@ -34,13 +33,15 @@ public class CliUpgradeService {
CliVersion.VERSION_4.getVersion(),
new CliUpgradeUnauth() {
@Override
public void run() throws Exception {
public boolean run() throws Exception {
// set cli.mix.clients=5 when missing
if (cliConfig.getMix().getClients() == 0) {
Properties props = cliConfigService.loadProperties();
props.put(CliConfigService.KEY_MIX_CLIENTS, "5");
cliConfigService.saveProperties(props);
return true; // restart
}
return false;
}
});
......@@ -49,9 +50,10 @@ public class CliUpgradeService {
CliVersion.VERSION_5.getVersion(),
new CliUpgradeAuth() {
@Override
public void run(CliWallet cliWallet) throws Exception {
// reconstruct postmix counters
new RunReconstruct(cliWallet).reconstruct();
public boolean run(CliWallet cliWallet) throws Exception {
// resync postmix counters
cliWallet.resync();
return false;
}
});
}
......@@ -70,9 +72,9 @@ public class CliUpgradeService {
if (log.isDebugEnabled()) {
log.debug(" • Upgrading CLI (unauth): " + localVersion + " -> " + nextVersion);
}
cliUpgrade.run();
afterUpgrade(nextVersion);
return true;
boolean shouldRestart = cliUpgrade.run();
afterUpgrade(nextVersion, shouldRestart);
return shouldRestart;
}
public boolean upgradeAuthenticated(CliWallet cliWallet) throws Exception {
......@@ -89,9 +91,9 @@ public class CliUpgradeService {
if (log.isDebugEnabled()) {
log.debug(" • Upgrading CLI (auth): " + localVersion + " -> " + nextVersion);
}
cliUpgrade.run(cliWallet);
afterUpgrade(nextVersion);
return true;
boolean shouldRestart = cliUpgrade.run(cliWallet);
afterUpgrade(nextVersion, shouldRestart);
return shouldRestart;
}
private CliUpgrade getNextUpgrade(int nextVersion, boolean authenticated) {
......@@ -121,8 +123,10 @@ public class CliUpgradeService {
return cliUpgrade;
}
private void afterUpgrade(int nextVersion) throws Exception {
private void afterUpgrade(int nextVersion, boolean shouldRestart) throws Exception {
cliConfigService.setVersion(nextVersion);
cliConfigService.setCliStatusNotReady("Upgrade success. Restarting CLI...");
if (shouldRestart) {
cliConfigService.setCliStatusNotReady("Upgrade success. Restarting CLI...");
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment