Commit a0f8ba21 authored by zeroleak's avatar zeroleak
Browse files

fix lockDirectory

parent da4fc84b
......@@ -17,7 +17,7 @@
<dependency>
<groupId>io.samourai.code.whirlpool</groupId>
<artifactId>whirlpool-client</artifactId>
<version>0.23.28-SNAPSHOT</version>
<version>0.23.28</version>
<scope>compile</scope>
</dependency>
<dependency>
......
......@@ -85,7 +85,7 @@ public class TorOnionProxyInstance {
waitReady();
} catch (Exception e) {
log.error("Tor failed to start", e);
Application.exitError(1);
Application.exit(1);
}
},
"TorOnionProxyInstance-start");
......@@ -141,7 +141,7 @@ public class TorOnionProxyInstance {
onionProxyManager.stop();
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.error("", e);
log.warn("", e);
}
}
......
......@@ -7,6 +7,7 @@ import com.samourai.whirlpool.cli.utils.CliUtils;
import com.samourai.whirlpool.client.exception.NotifiableException;
import com.samourai.whirlpool.protocol.WhirlpoolProtocol;
import java.lang.invoke.MethodHandles;
import java.nio.channels.FileLock;
import java.util.Arrays;
import javax.annotation.PreDestroy;
import org.apache.commons.lang3.ArrayUtils;
......@@ -36,6 +37,7 @@ public class Application implements ApplicationRunner {
private static ApplicationArguments applicationArguments;
private static boolean restart;
private static Integer exitCode;
private static FileLock fileLock;
@Autowired Environment env;
@Autowired CliService cliService;
......@@ -63,10 +65,9 @@ public class Application implements ApplicationRunner {
// restart
restart();
} else {
// exit
if (exitCode != null) {
// error
exitError(exitCode);
// exit
exit(exitCode);
} else {
// success
if (log.isDebugEnabled()) {
......@@ -78,6 +79,16 @@ public class Application implements ApplicationRunner {
@PreDestroy
public void preDestroy() {
// unlock directory
if (fileLock != null) {
try {
cliService.unlockDirectory(fileLock);
} catch (Exception e) {
log.error("", e);
}
}
// shutdown
cliService.shutdown();
}
......@@ -106,6 +117,8 @@ public class Application implements ApplicationRunner {
return;
}
fileLock = cliService.lockDirectory();
CliResult cliResult = cliService.run(listen);
switch (cliResult) {
case RESTART:
......@@ -157,9 +170,9 @@ public class Application implements ApplicationRunner {
thread.start();
}
public static void exitError(int exitCode) {
public static void exit(int exitCode) {
if (log.isDebugEnabled()) {
log.debug("Exit with error: " + exitCode);
log.debug("Exit: " + exitCode);
}
if (applicationContext != null) {
SpringApplication.exit(applicationContext, () -> exitCode);
......
......@@ -82,17 +82,17 @@ public class CliService {
return CliUtils.computeFile(path);
}
private FileLock lockDirectory() throws Exception {
public FileLock lockDirectory() throws Exception {
File dirLockFile = computeDirLockFile();
dirLockFile.deleteOnExit();
String lockErrorMsg =
"Another Whirlpool instance seems already running in current directory. Otherwise, you may manually delete "
"Another Whirlpool instance seems already running in same directory. If not, please delete "
+ dirLockFile.getAbsolutePath();
FileLock dirFileLock = ClientUtils.lockFile(dirLockFile, lockErrorMsg);
return dirFileLock;
}
private void unlockDirectory(FileLock dirFileLock) throws Exception {
public void unlockDirectory(FileLock dirFileLock) throws Exception {
ClientUtils.unlockFile(dirFileLock);
File dirLockFile = computeDirLockFile();
dirLockFile.delete();
......@@ -107,126 +107,120 @@ public class CliService {
System.getProperty("java.version"),
Arrays.toString(args));
// get dir lock
FileLock dirFileLock = lockDirectory();
try {
// log config
if (log.isDebugEnabled()) {
for (Map.Entry<String, String> entry : cliConfig.getConfigInfo().entrySet()) {
log.debug("[cliConfig/" + entry.getKey() + "] " + entry.getValue());
}
// log config
if (log.isDebugEnabled()) {
for (Map.Entry<String, String> entry : cliConfig.getConfigInfo().entrySet()) {
log.debug("[cliConfig/" + entry.getKey() + "] " + entry.getValue());
}
if (listen) {
String info = "API is listening on https://127.0.0.1:" + cliConfig.getApi().getPort();
if (cliConfig.getApi().isHttpEnable()) {
info += " and http://127.0.0.1:" + cliConfig.getApi().getHttpPort();
}
log.info(info);
}
if (listen) {
String info = "API is listening on https://127.0.0.1:" + cliConfig.getApi().getPort();
if (cliConfig.getApi().isHttpEnable()) {
info += " and http://127.0.0.1:" + cliConfig.getApi().getHttpPort();
}
log.info(info);
}
// connect Tor
cliTorClientService.connect();
// initialize bitcoinj context
NetworkParameters params = cliConfig.getServer().getParams();
new Context(params);
// connect Tor
cliTorClientService.connect();
// check init
if (appArgs.isInit() || (cliConfigService.isCliStatusNotInitialized() && !listen)) {
new RunCliInit(cliConfigService).run();
return CliResult.RESTART;
}
// initialize bitcoinj context
NetworkParameters params = cliConfig.getServer().getParams();
new Context(params);
// check cli initialized
if (cliConfigService.isCliStatusNotInitialized()) {
// not initialized
if (log.isDebugEnabled()) {
log.debug("CliStatus=" + cliConfigService.getCliStatus());
}
// check init
if (appArgs.isInit() || (cliConfigService.isCliStatusNotInitialized() && !listen)) {
new RunCliInit(cliConfigService).run();
return CliResult.RESTART;
}
// keep cli running for remote initialization
log.warn(CliUtils.LOG_SEPARATOR);
log.warn("⣿ INITIALIZATION REQUIRED");
log.warn("⣿ Please start GUI to initialize CLI.");
log.warn("⣿ Or initialize with --init");
log.warn(CliUtils.LOG_SEPARATOR);
keepRunning();
return CliResult.KEEP_RUNNING;
// check cli initialized
if (cliConfigService.isCliStatusNotInitialized()) {
// not initialized
if (log.isDebugEnabled()) {
log.debug("CliStatus=" + cliConfigService.getCliStatus());
}
// check upgrade (before authentication)
boolean shouldRestart = cliUpgradeService.upgradeUnauthenticated();
if (shouldRestart) {
log.warn(CliUtils.LOG_SEPARATOR);
log.warn("⣿ UPGRADE SUCCESS");
log.warn("⣿ Restarting CLI...");
log.warn(CliUtils.LOG_SEPARATOR);
return CliResult.RESTART;
}
cliConfigService.setCliStatus(CliStatus.READY);
// keep cli running for remote initialization
log.warn(CliUtils.LOG_SEPARATOR);
log.warn("⣿ INITIALIZATION REQUIRED");
log.warn("⣿ Please start GUI to initialize CLI.");
log.warn("⣿ Or initialize with --init");
log.warn(CliUtils.LOG_SEPARATOR);
keepRunning();
return CliResult.KEEP_RUNNING;
}
boolean isXpub = appArgs.isSetExternalXpub();
String commandToRun = RunCliCommand.getCommandToRun(appArgs);
boolean hasCommandToRun = (commandToRun != null);
if (!appArgs.isAuthenticate() && listen && commandToRun == null && !isXpub) {
// no passphrase but listening => keep listening
log.info(CliUtils.LOG_SEPARATOR);
log.info("⣿ AUTHENTICATION REQUIRED");
log.info("⣿ Whirlpool wallet is CLOSED.");
log.info("⣿ Please start GUI to authenticate and start mixing.");
log.info("⣿ Or authenticate with --authenticate");
log.info(CliUtils.LOG_SEPARATOR);
keepRunning();
return CliResult.KEEP_RUNNING;
}
// check upgrade (before authentication)
boolean shouldRestart = cliUpgradeService.upgradeUnauthenticated();
if (shouldRestart) {
log.warn(CliUtils.LOG_SEPARATOR);
log.warn("⣿ UPGRADE SUCCESS");
log.warn("⣿ Restarting CLI...");
log.warn(CliUtils.LOG_SEPARATOR);
return CliResult.RESTART;
}
cliConfigService.setCliStatus(CliStatus.READY);
// authenticate
CliWallet cliWallet = null;
while (cliWallet == null) {
// authenticate to open wallet when passphrase providen through arguments
String reason = null;
if (isXpub) {
reason = "to run --" + ApplicationArgs.ARG_SET_EXTERNAL_XPUB;
} else if (commandToRun != null) {
reason = "to run --" + commandToRun;
}
String seedPassphrase = authenticate(reason);
try {
// we may have authenticated from API in the meantime...
cliWallet =
cliWalletService.hasSessionWallet()
? cliWalletService.getSessionWallet()
: cliWalletService.openWallet(seedPassphrase);
boolean isXpub = appArgs.isSetExternalXpub();
String commandToRun = RunCliCommand.getCommandToRun(appArgs);
boolean hasCommandToRun = (commandToRun != null);
if (!appArgs.isAuthenticate() && listen && commandToRun == null && !isXpub) {
// no passphrase but listening => keep listening
log.info(CliUtils.LOG_SEPARATOR);
log.info("⣿ AUTHENTICATION REQUIRED");
log.info("⣿ Whirlpool wallet is CLOSED.");
log.info("⣿ Please start GUI to authenticate and start mixing.");
log.info("⣿ Or authenticate with --authenticate");
log.info(CliUtils.LOG_SEPARATOR);
keepRunning();
return CliResult.KEEP_RUNNING;
}
// set-destination
if (appArgs.isSetExternalXpub()) {
new RunSetExternalXpub(cliConfigService).run(params, seedPassphrase);
return CliResult.RESTART;
}
// authenticate
CliWallet cliWallet = null;
while (cliWallet == null) {
// authenticate to open wallet when passphrase providen through arguments
String reason = null;
if (isXpub) {
reason = "to run --" + ApplicationArgs.ARG_SET_EXTERNAL_XPUB;
} else if (commandToRun != null) {
reason = "to run --" + commandToRun;
}
String seedPassphrase = authenticate(reason);
try {
// we may have authenticated from API in the meantime...
cliWallet =
cliWalletService.hasSessionWallet()
? cliWalletService.getSessionWallet()
: cliWalletService.openWallet(seedPassphrase);
log.info(CliUtils.LOG_SEPARATOR);
log.info("⣿ AUTHENTICATION SUCCESS");
log.info(CliUtils.LOG_SEPARATOR);
} catch (AuthenticationException e) {
log.error(e.getMessage());
} catch (CliRestartException e) {
log.error(e.getMessage());
// set-destination
if (appArgs.isSetExternalXpub()) {
new RunSetExternalXpub(cliConfigService).run(params, seedPassphrase);
return CliResult.RESTART;
}
log.info(CliUtils.LOG_SEPARATOR);
log.info("⣿ AUTHENTICATION SUCCESS");
log.info(CliUtils.LOG_SEPARATOR);
} catch (AuthenticationException e) {
log.error(e.getMessage());
} catch (CliRestartException e) {
log.error(e.getMessage());
return CliResult.RESTART;
}
if (hasCommandToRun) {
// execute specific command
new RunCliCommand(appArgs, cliWalletService, walletAggregateService).run();
return CliResult.EXIT_SUCCESS;
} else {
// start wallet
log.info("⣿ Whirlpool is starting...");
cliWallet.start();
keepRunning();
return CliResult.KEEP_RUNNING;
}
} finally {
unlockDirectory(dirFileLock);
}
if (hasCommandToRun) {
// execute specific command
new RunCliCommand(appArgs, cliWalletService, walletAggregateService).run();
return CliResult.EXIT_SUCCESS;
} else {
// start wallet
log.info("⣿ Whirlpool is starting...");
cliWallet.start();
keepRunning();
return CliResult.KEEP_RUNNING;
}
}
......
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