mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-10-01 01:35:48 -04:00
Compare commits
17 Commits
346595dfd1
...
b3ddde4c2e
Author | SHA1 | Date | |
---|---|---|---|
|
b3ddde4c2e | ||
|
5bc2816491 | ||
|
11c0f7613b | ||
|
1329902a55 | ||
|
6c640ddbef | ||
|
50f3bd510a | ||
|
8d55abe3b9 | ||
|
c04fc7b2db | ||
|
0ed640be16 | ||
|
2a9bc87f65 | ||
|
2f310b420d | ||
|
d4f1dc5b8e | ||
|
a4e43f1045 | ||
|
7306972d19 | ||
|
1ea9a6f750 | ||
|
c08b4d0772 | ||
|
874075b371 |
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@ -78,6 +78,7 @@ jobs:
|
|||||||
else
|
else
|
||||||
mv desktop/build/temp-*/binaries/Haveno-*.dmg ${{ github.workspace }}/release/Haveno-x86_64.dmg
|
mv desktop/build/temp-*/binaries/Haveno-*.dmg ${{ github.workspace }}/release/Haveno-x86_64.dmg
|
||||||
fi
|
fi
|
||||||
|
cp desktop/build/temp-*/binaries/desktop-*.jar.SHA-256 ${{ github.workspace }}/release
|
||||||
cp desktop/build/temp-*/binaries/desktop-*.jar.SHA-256 ${{ github.workspace }}/release-deb
|
cp desktop/build/temp-*/binaries/desktop-*.jar.SHA-256 ${{ github.workspace }}/release-deb
|
||||||
cp desktop/build/temp-*/binaries/desktop-*.jar.SHA-256 ${{ github.workspace }}/release-rpm
|
cp desktop/build/temp-*/binaries/desktop-*.jar.SHA-256 ${{ github.workspace }}/release-rpm
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -72,7 +72,7 @@ To bring Haveno to life, we need resources. If you have the possibility, please
|
|||||||
### Monero
|
### Monero
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<img src="https://raw.githubusercontent.com/haveno-dex/haveno/master/media/donate_monero.png" alt="Donate Monero" width="150" height="150"><br>
|
<img src="https://raw.githubusercontent.com/haveno-dex/haveno/master/media/donate_monero.png" alt="Donate Monero" width="115" height="115"><br>
|
||||||
<code>42sjokkT9FmiWPqVzrWPFE5NCJXwt96bkBozHf4vgLR9hXyJDqKHEHKVscAARuD7in5wV1meEcSTJTanCTDzidTe2cFXS1F</code>
|
<code>42sjokkT9FmiWPqVzrWPFE5NCJXwt96bkBozHf4vgLR9hXyJDqKHEHKVscAARuD7in5wV1meEcSTJTanCTDzidTe2cFXS1F</code>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -81,6 +81,6 @@ If you are using a wallet that supports OpenAlias (like the 'official' CLI and G
|
|||||||
### Bitcoin
|
### Bitcoin
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<img src="https://raw.githubusercontent.com/haveno-dex/haveno/master/media/donate_bitcoin.png" alt="Donate Bitcoin" width="150" height="150"><br>
|
<img src="https://raw.githubusercontent.com/haveno-dex/haveno/master/media/donate_bitcoin.png" alt="Donate Bitcoin" width="115" height="115"><br>
|
||||||
<code>1AKq3CE1yBAnxGmHXbNFfNYStcByNDc5gQ</code>
|
<code>1AKq3CE1yBAnxGmHXbNFfNYStcByNDc5gQ</code>
|
||||||
</p>
|
</p>
|
||||||
|
@ -78,7 +78,7 @@ public class ApiTestMain {
|
|||||||
|
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
err.println("Fault: An unexpected error occurred. " +
|
err.println("Fault: An unexpected error occurred. " +
|
||||||
"Please file a report at https://haveno.exchange/issues");
|
"Please file a report at https://github.com/haveno-dex/haveno/issues");
|
||||||
ex.printStackTrace(err);
|
ex.printStackTrace(err);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ configure(subprojects) {
|
|||||||
gsonVersion = '2.8.5'
|
gsonVersion = '2.8.5'
|
||||||
guavaVersion = '32.1.1-jre'
|
guavaVersion = '32.1.1-jre'
|
||||||
guiceVersion = '7.0.0'
|
guiceVersion = '7.0.0'
|
||||||
moneroJavaVersion = '0.8.31'
|
moneroJavaVersion = '0.8.33'
|
||||||
httpclient5Version = '5.0'
|
httpclient5Version = '5.0'
|
||||||
hamcrestVersion = '2.2'
|
hamcrestVersion = '2.2'
|
||||||
httpclientVersion = '4.5.12'
|
httpclientVersion = '4.5.12'
|
||||||
@ -334,6 +334,7 @@ configure(project(':p2p')) {
|
|||||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||||
implementation "org.fxmisc.easybind:easybind:$easybindVersion"
|
implementation "org.fxmisc.easybind:easybind:$easybindVersion"
|
||||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||||
|
implementation "org.apache.commons:commons-lang3:$langVersion"
|
||||||
implementation("com.github.haveno-dex.netlayer:tor.external:$netlayerVersion") {
|
implementation("com.github.haveno-dex.netlayer:tor.external:$netlayerVersion") {
|
||||||
exclude(module: 'slf4j-api')
|
exclude(module: 'slf4j-api')
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import ch.qos.logback.classic.Level;
|
|||||||
import ch.qos.logback.classic.Logger;
|
import ch.qos.logback.classic.Logger;
|
||||||
import ch.qos.logback.classic.LoggerContext;
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
|
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
|
||||||
|
import ch.qos.logback.classic.filter.ThresholdFilter;
|
||||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
|
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
|
||||||
import ch.qos.logback.core.rolling.RollingFileAppender;
|
import ch.qos.logback.core.rolling.RollingFileAppender;
|
||||||
@ -52,11 +53,12 @@ public class Log {
|
|||||||
|
|
||||||
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
|
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
|
||||||
triggeringPolicy.setMaxFileSize(FileSize.valueOf("10MB"));
|
triggeringPolicy.setMaxFileSize(FileSize.valueOf("10MB"));
|
||||||
|
triggeringPolicy.setContext(loggerContext);
|
||||||
triggeringPolicy.start();
|
triggeringPolicy.start();
|
||||||
|
|
||||||
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
|
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
|
||||||
encoder.setContext(loggerContext);
|
encoder.setContext(loggerContext);
|
||||||
encoder.setPattern("%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{15}: %msg %xEx%n");
|
encoder.setPattern("%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{15}: %msg%n");
|
||||||
encoder.start();
|
encoder.start();
|
||||||
|
|
||||||
appender.setEncoder(encoder);
|
appender.setEncoder(encoder);
|
||||||
@ -64,25 +66,43 @@ public class Log {
|
|||||||
appender.setTriggeringPolicy(triggeringPolicy);
|
appender.setTriggeringPolicy(triggeringPolicy);
|
||||||
appender.start();
|
appender.start();
|
||||||
|
|
||||||
logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
|
|
||||||
logbackLogger.addAppender(appender);
|
|
||||||
logbackLogger.setLevel(Level.INFO);
|
|
||||||
|
|
||||||
// log errors in separate file
|
// log errors in separate file
|
||||||
// not working as expected still.... damn logback...
|
PatternLayoutEncoder errorEncoder = new PatternLayoutEncoder();
|
||||||
/* FileAppender errorAppender = new FileAppender();
|
errorEncoder.setContext(loggerContext);
|
||||||
errorAppender.setEncoder(encoder);
|
errorEncoder.setPattern("%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger: %msg%n%ex");
|
||||||
|
errorEncoder.start();
|
||||||
|
|
||||||
|
RollingFileAppender<ILoggingEvent> errorAppender = new RollingFileAppender<>();
|
||||||
|
errorAppender.setEncoder(errorEncoder);
|
||||||
errorAppender.setName("Error");
|
errorAppender.setName("Error");
|
||||||
errorAppender.setContext(loggerContext);
|
errorAppender.setContext(loggerContext);
|
||||||
errorAppender.setFile(fileName + "_error.log");
|
errorAppender.setFile(fileName + "_error.log");
|
||||||
LevelFilter levelFilter = new LevelFilter();
|
|
||||||
levelFilter.setLevel(Level.ERROR);
|
FixedWindowRollingPolicy errorRollingPolicy = new FixedWindowRollingPolicy();
|
||||||
levelFilter.setOnMatch(FilterReply.ACCEPT);
|
errorRollingPolicy.setContext(loggerContext);
|
||||||
levelFilter.setOnMismatch(FilterReply.DENY);
|
errorRollingPolicy.setParent(errorAppender);
|
||||||
levelFilter.start();
|
errorRollingPolicy.setFileNamePattern(fileName + "_error_%i.log");
|
||||||
errorAppender.addFilter(levelFilter);
|
errorRollingPolicy.setMinIndex(1);
|
||||||
|
errorRollingPolicy.setMaxIndex(20);
|
||||||
|
errorRollingPolicy.start();
|
||||||
|
|
||||||
|
SizeBasedTriggeringPolicy<ILoggingEvent> errorTriggeringPolicy = new SizeBasedTriggeringPolicy<>();
|
||||||
|
errorTriggeringPolicy.setMaxFileSize(FileSize.valueOf("10MB"));
|
||||||
|
errorTriggeringPolicy.start();
|
||||||
|
|
||||||
|
ThresholdFilter thresholdFilter = new ThresholdFilter();
|
||||||
|
thresholdFilter.setLevel("WARN");
|
||||||
|
thresholdFilter.start();
|
||||||
|
|
||||||
|
errorAppender.setRollingPolicy(errorRollingPolicy);
|
||||||
|
errorAppender.setTriggeringPolicy(errorTriggeringPolicy);
|
||||||
|
errorAppender.addFilter(thresholdFilter);
|
||||||
errorAppender.start();
|
errorAppender.start();
|
||||||
logbackLogger.addAppender(errorAppender);*/
|
|
||||||
|
logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
|
||||||
|
logbackLogger.addAppender(errorAppender);
|
||||||
|
logbackLogger.addAppender(appender);
|
||||||
|
logbackLogger.setLevel(Level.INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setCustomLogLevel(String pattern, Level logLevel) {
|
public static void setCustomLogLevel(String pattern, Level logLevel) {
|
||||||
|
@ -68,8 +68,7 @@ public class FileUtil {
|
|||||||
|
|
||||||
pruneBackup(backupFileDir, numMaxBackupFiles);
|
pruneBackup(backupFileDir, numMaxBackupFiles);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Backup key failed: " + e.getMessage());
|
log.error("Backup key failed: {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,7 +96,7 @@ public class FileUtil {
|
|||||||
try {
|
try {
|
||||||
FileUtils.deleteDirectory(backupFileDir);
|
FileUtils.deleteDirectory(backupFileDir);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
log.error("Delete backup key failed: {}\n", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,8 +172,7 @@ public class FileUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.error(t.toString());
|
log.error("Could not delete file, error={}\n", t.getMessage(), t);
|
||||||
t.printStackTrace();
|
|
||||||
throw new IOException(t);
|
throw new IOException(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,11 +69,7 @@ public class CommonSetup {
|
|||||||
"The system tray is not supported on the current platform.".equals(throwable.getMessage())) {
|
"The system tray is not supported on the current platform.".equals(throwable.getMessage())) {
|
||||||
log.warn(throwable.getMessage());
|
log.warn(throwable.getMessage());
|
||||||
} else {
|
} else {
|
||||||
log.error("Uncaught Exception from thread " + Thread.currentThread().getName());
|
log.error("Uncaught Exception from thread {}, error={}\n", Thread.currentThread().getName(), throwable.getMessage(), throwable);
|
||||||
log.error("throwableMessage= " + throwable.getMessage());
|
|
||||||
log.error("throwableClass= " + throwable.getClass());
|
|
||||||
log.error("Stack trace:\n" + ExceptionUtils.getStackTrace(throwable));
|
|
||||||
throwable.printStackTrace();
|
|
||||||
UserThread.execute(() -> uncaughtExceptionHandler.handleUncaughtException(throwable, false));
|
UserThread.execute(() -> uncaughtExceptionHandler.handleUncaughtException(throwable, false));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -113,8 +109,7 @@ public class CommonSetup {
|
|||||||
if (!pathOfCodeSource.endsWith("classes"))
|
if (!pathOfCodeSource.endsWith("classes"))
|
||||||
log.info("Path to Haveno jar file: " + pathOfCodeSource);
|
log.info("Path to Haveno jar file: " + pathOfCodeSource);
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
log.error(e.toString());
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ import java.util.Arrays;
|
|||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TaskRunner<T extends Model> {
|
public class TaskRunner<T extends Model> {
|
||||||
private final Queue<Class<? extends Task<T>>> tasks = new LinkedBlockingQueue<>();
|
private final Queue<Class<? extends Task<T>>> tasks = new LinkedBlockingQueue<>();
|
||||||
@ -67,8 +69,8 @@ public class TaskRunner<T extends Model> {
|
|||||||
log.info("Run task: " + currentTask.getSimpleName());
|
log.info("Run task: " + currentTask.getSimpleName());
|
||||||
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModelClass).newInstance(this, sharedModel).run();
|
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModelClass).newInstance(this, sharedModel).run();
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
throwable.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(throwable));
|
||||||
handleErrorMessage("Error at taskRunner: " + throwable.getMessage());
|
handleErrorMessage("Error at taskRunner, error=" + throwable.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
|
@ -331,8 +331,7 @@ public class Utilities {
|
|||||||
clipboard.setContent(clipboardContent);
|
clipboard.setContent(clipboardContent);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error("copyToClipboard failed " + e.getMessage());
|
log.error("copyToClipboard failed: {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
@ -204,7 +207,7 @@ public class CoreDisputesService {
|
|||||||
throw new IllegalStateException(errMessage, err);
|
throw new IllegalStateException(errMessage, err);
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
throw new IllegalStateException(e.getMessage() == null ? ("Error resolving dispute for trade " + trade.getId()) : e.getMessage());
|
throw new IllegalStateException(e.getMessage() == null ? ("Error resolving dispute for trade " + trade.getId()) : e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,8 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@ -161,7 +163,7 @@ class CoreTradesService {
|
|||||||
errorMessageHandler
|
errorMessageHandler
|
||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
errorMessageHandler.handleErrorMessage(e.getMessage());
|
errorMessageHandler.handleErrorMessage(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,9 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
import javafx.beans.property.IntegerProperty;
|
import javafx.beans.property.IntegerProperty;
|
||||||
import javafx.beans.property.LongProperty;
|
import javafx.beans.property.LongProperty;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
@ -464,7 +467,7 @@ public final class XmrConnectionService {
|
|||||||
log.info(getClass() + ".onAccountOpened() called");
|
log.info(getClass() + ".onAccountOpened() called");
|
||||||
initialize();
|
initialize();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Error initializing connection service after account opened, error={}\n", e.getMessage(), e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,8 +625,7 @@ public final class XmrConnectionService {
|
|||||||
log.info("Starting local node");
|
log.info("Starting local node");
|
||||||
xmrLocalNode.startMoneroNode();
|
xmrLocalNode.startMoneroNode();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Unable to start local monero node: " + e.getMessage());
|
log.error("Unable to start local monero node, error={}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -721,8 +723,8 @@ public final class XmrConnectionService {
|
|||||||
|
|
||||||
// log error message periodically
|
// log error message periodically
|
||||||
if (lastLogPollErrorTimestamp == null || System.currentTimeMillis() - lastLogPollErrorTimestamp > HavenoUtils.LOG_POLL_ERROR_PERIOD_MS) {
|
if (lastLogPollErrorTimestamp == null || System.currentTimeMillis() - lastLogPollErrorTimestamp > HavenoUtils.LOG_POLL_ERROR_PERIOD_MS) {
|
||||||
log.warn("Failed to fetch daemon info, trying to switch to best connection: " + e.getMessage());
|
log.warn("Failed to fetch daemon info, trying to switch to best connection, error={}", e.getMessage());
|
||||||
if (DevEnv.isDevMode()) e.printStackTrace();
|
if (DevEnv.isDevMode()) log.error(ExceptionUtils.getStackTrace(e));
|
||||||
lastLogPollErrorTimestamp = System.currentTimeMillis();
|
lastLogPollErrorTimestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ public abstract class HavenoExecutable implements GracefulShutDownHandler, Haven
|
|||||||
System.exit(EXIT_FAILURE);
|
System.exit(EXIT_FAILURE);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
System.err.println("fault: An unexpected error occurred. " +
|
System.err.println("fault: An unexpected error occurred. " +
|
||||||
"Please file a report at https://haveno.exchange/issues");
|
"Please file a report at https://github.com/haveno-dex/haveno/issues");
|
||||||
ex.printStackTrace(System.err);
|
ex.printStackTrace(System.err);
|
||||||
System.exit(EXIT_FAILURE);
|
System.exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@ -201,8 +201,7 @@ public abstract class HavenoExecutable implements GracefulShutDownHandler, Haven
|
|||||||
startApplication();
|
startApplication();
|
||||||
}
|
}
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
log.error("An error occurred: {}", e.getMessage());
|
log.error("An error occurred: {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -362,7 +361,7 @@ public abstract class HavenoExecutable implements GracefulShutDownHandler, Haven
|
|||||||
try {
|
try {
|
||||||
ThreadUtils.awaitTasks(tasks, tasks.size(), 90000l); // run in parallel with timeout
|
ThreadUtils.awaitTasks(tasks, tasks.size(), 90000l); // run in parallel with timeout
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Failed to notify all services to prepare for shutdown: {}\n", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
injector.getInstance(TradeManager.class).shutDown();
|
injector.getInstance(TradeManager.class).shutDown();
|
||||||
@ -397,8 +396,7 @@ public abstract class HavenoExecutable implements GracefulShutDownHandler, Haven
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.error("App shutdown failed with exception {}", t.toString());
|
log.error("App shutdown failed with exception: {}\n", t.getMessage(), t);
|
||||||
t.printStackTrace();
|
|
||||||
completeShutdown(resultHandler, EXIT_FAILURE, systemExit);
|
completeShutdown(resultHandler, EXIT_FAILURE, systemExit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -376,8 +376,7 @@ public class HavenoSetup {
|
|||||||
moneroWalletRpcFile.setExecutable(true);
|
moneroWalletRpcFile.setExecutable(true);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warn("Failed to install Monero binaries: {}\n", e.getMessage(), e);
|
||||||
log.warn("Failed to install Monero binaries: " + e.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,9 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -48,8 +51,7 @@ public class TorSetup {
|
|||||||
if (resultHandler != null)
|
if (resultHandler != null)
|
||||||
resultHandler.run();
|
resultHandler.run();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
log.error(e.toString());
|
|
||||||
if (errorMessageHandler != null)
|
if (errorMessageHandler != null)
|
||||||
errorMessageHandler.handleErrorMessage(e.toString());
|
errorMessageHandler.handleErrorMessage(e.toString());
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ public abstract class ExecutableForAppWithP2p extends HavenoExecutable {
|
|||||||
try {
|
try {
|
||||||
ThreadUtils.awaitTasks(tasks, tasks.size(), 120000l); // run in parallel with timeout
|
ThreadUtils.awaitTasks(tasks, tasks.size(), 120000l); // run in parallel with timeout
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Error awaiting tasks to complete: {}\n", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonFileManager.shutDownAllInstances();
|
JsonFileManager.shutDownAllInstances();
|
||||||
@ -177,8 +177,7 @@ public abstract class ExecutableForAppWithP2p extends HavenoExecutable {
|
|||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.debug("App shutdown failed with exception");
|
log.info("App shutdown failed with exception: {}\n", t.getMessage(), t);
|
||||||
t.printStackTrace();
|
|
||||||
PersistenceManager.flushAllDataToDiskAtShutdown(() -> {
|
PersistenceManager.flushAllDataToDiskAtShutdown(() -> {
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
log.info("Graceful shutdown resulted in an error. Exiting now.");
|
log.info("Graceful shutdown resulted in an error. Exiting now.");
|
||||||
|
@ -977,7 +977,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
// handle result
|
// handle result
|
||||||
resultHandler.handleResult(null);
|
resultHandler.handleResult(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (!openOffer.isCanceled()) e.printStackTrace();
|
if (!openOffer.isCanceled()) log.error("Error processing pending offer: {}\n", e.getMessage(), e);
|
||||||
errorMessageHandler.handleErrorMessage(e.getMessage());
|
errorMessageHandler.handleErrorMessage(e.getMessage());
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
@ -1365,9 +1365,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
});
|
});
|
||||||
result = true;
|
result = true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
|
||||||
errorMessage = "Exception at handleSignOfferRequest " + e.getMessage();
|
errorMessage = "Exception at handleSignOfferRequest " + e.getMessage();
|
||||||
log.error(errorMessage);
|
log.error(errorMessage + "\n", e);
|
||||||
} finally {
|
} finally {
|
||||||
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), result, errorMessage);
|
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), result, errorMessage);
|
||||||
}
|
}
|
||||||
@ -1519,8 +1518,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||||||
result = true;
|
result = true;
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
errorMessage = "Exception at handleRequestIsOfferAvailableMessage " + t.getMessage();
|
errorMessage = "Exception at handleRequestIsOfferAvailableMessage " + t.getMessage();
|
||||||
log.error(errorMessage);
|
log.error(errorMessage + "\n", t);
|
||||||
t.printStackTrace();
|
|
||||||
} finally {
|
} finally {
|
||||||
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), result, errorMessage);
|
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), result, errorMessage);
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,7 @@ public class FeeProvider extends HttpClientProvider {
|
|||||||
map.put(Config.BTC_TX_FEE, btcTxFee);
|
map.put(Config.BTC_TX_FEE, btcTxFee);
|
||||||
map.put(Config.BTC_MIN_TX_FEE, btcMinTxFee);
|
map.put(Config.BTC_MIN_TX_FEE, btcMinTxFee);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.error(t.toString());
|
log.error("Error getting fees: {}\n", t.getMessage(), t);
|
||||||
t.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return new Tuple2<>(tsMap, map);
|
return new Tuple2<>(tsMap, map);
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,7 @@ public class PriceProvider extends HttpClientProvider {
|
|||||||
long timestampSec = MathUtils.doubleToLong((Double) treeMap.get("timestampSec"));
|
long timestampSec = MathUtils.doubleToLong((Double) treeMap.get("timestampSec"));
|
||||||
marketPriceMap.put(currencyCode, new MarketPrice(currencyCode, price, timestampSec, true));
|
marketPriceMap.put(currencyCode, new MarketPrice(currencyCode, price, timestampSec, true));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.error(t.toString());
|
log.error("Error getting all prices: {}\n", t.getMessage(), t);
|
||||||
t.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -83,6 +83,9 @@ import monero.wallet.model.MoneroTxConfig;
|
|||||||
import monero.wallet.model.MoneroTxWallet;
|
import monero.wallet.model.MoneroTxWallet;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -523,7 +526,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||||||
DisputeValidation.validateSenderNodeAddress(dispute, message.getSenderNodeAddress(), config);
|
DisputeValidation.validateSenderNodeAddress(dispute, message.getSenderNodeAddress(), config);
|
||||||
//DisputeValidation.testIfDisputeTriesReplay(dispute, disputeList.getList());
|
//DisputeValidation.testIfDisputeTriesReplay(dispute, disputeList.getList());
|
||||||
} catch (DisputeValidation.ValidationException e) {
|
} catch (DisputeValidation.ValidationException e) {
|
||||||
e.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
validationExceptions.add(e);
|
validationExceptions.add(e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -532,9 +535,9 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||||||
try {
|
try {
|
||||||
DisputeValidation.validatePaymentAccountPayload(dispute); // TODO: add field to dispute details: valid, invalid, missing
|
DisputeValidation.validatePaymentAccountPayload(dispute); // TODO: add field to dispute details: valid, invalid, missing
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
log.warn(e.getMessage());
|
|
||||||
trade.prependErrorMessage(e.getMessage());
|
trade.prependErrorMessage(e.getMessage());
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get sender
|
// get sender
|
||||||
@ -606,9 +609,8 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
errorMessage = e.getMessage();
|
errorMessage = e.getMessage();
|
||||||
log.warn(errorMessage);
|
|
||||||
if (trade != null) trade.setErrorMessage(errorMessage);
|
if (trade != null) trade.setErrorMessage(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public class DisputeSummaryVerification {
|
|||||||
disputeAgent = arbitratorManager.getDisputeAgentByNodeAddress(nodeAddress).orElse(null);
|
disputeAgent = arbitratorManager.getDisputeAgentByNodeAddress(nodeAddress).orElse(null);
|
||||||
checkNotNull(disputeAgent, "Dispute agent is null");
|
checkNotNull(disputeAgent, "Dispute agent is null");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
log.error("Error verifying signature: {}\n", e.getMessage(), e);
|
||||||
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.invalidFormat"));
|
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.invalidFormat"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ public class DisputeSummaryVerification {
|
|||||||
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.failed"));
|
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.failed"));
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
log.error("Error verifying signature with agent pub key ring: {}\n", e.getMessage(), e);
|
||||||
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.invalidFormat"));
|
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.invalidFormat"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,8 @@ import java.util.Map;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -355,7 +357,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
|||||||
requestPersistence(trade);
|
requestPersistence(trade);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Error processing dispute closed message: {}", e.getMessage());
|
log.warn("Error processing dispute closed message: {}", e.getMessage());
|
||||||
e.printStackTrace();
|
log.warn(ExceptionUtils.getStackTrace(e));
|
||||||
requestPersistence(trade);
|
requestPersistence(trade);
|
||||||
|
|
||||||
// nack bad message and do not reprocess
|
// nack bad message and do not reprocess
|
||||||
@ -489,8 +491,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
|||||||
try {
|
try {
|
||||||
feeEstimateTx = createDisputePayoutTx(trade, dispute.getContract(), disputeResult, false);
|
feeEstimateTx = createDisputePayoutTx(trade, dispute.getContract(), disputeResult, false);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warn("Could not recreate dispute payout tx to verify fee: {}\n", e.getMessage(), e);
|
||||||
log.warn("Could not recreate dispute payout tx to verify fee: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
if (feeEstimateTx != null) {
|
if (feeEstimateTx != null) {
|
||||||
BigInteger feeEstimate = feeEstimateTx.getFee();
|
BigInteger feeEstimate = feeEstimateTx.getFee();
|
||||||
|
@ -999,8 +999,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
|||||||
xmrWalletService.deleteWallet(getWalletName());
|
xmrWalletService.deleteWallet(getWalletName());
|
||||||
xmrWalletService.deleteWalletBackups(getWalletName());
|
xmrWalletService.deleteWalletBackups(getWalletName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn(e.getMessage());
|
log.warn("Error deleting wallet for {} {}: {}\n", getClass().getSimpleName(), getId(), e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
setErrorMessage(e.getMessage());
|
setErrorMessage(e.getMessage());
|
||||||
processModel.getTradeManager().getNotificationService().sendErrorNotification("Error", e.getMessage());
|
processModel.getTradeManager().getNotificationService().sendErrorNotification("Error", e.getMessage());
|
||||||
}
|
}
|
||||||
@ -1051,7 +1050,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
|||||||
synchronized (HavenoUtils.getWalletFunctionLock()) {
|
synchronized (HavenoUtils.getWalletFunctionLock()) {
|
||||||
MoneroTxWallet tx = wallet.createTx(txConfig);
|
MoneroTxWallet tx = wallet.createTx(txConfig);
|
||||||
exportMultisigHex();
|
exportMultisigHex();
|
||||||
requestSaveWallet();
|
saveWallet();
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1152,7 +1151,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requestSaveWallet();
|
saveWallet();
|
||||||
}
|
}
|
||||||
log.info("Done importing multisig hexes for {} {} in {} ms, count={}", getClass().getSimpleName(), getShortId(), System.currentTimeMillis() - startTime, multisigHexes.size());
|
log.info("Done importing multisig hexes for {} {} in {} ms, count={}", getClass().getSimpleName(), getShortId(), System.currentTimeMillis() - startTime, multisigHexes.size());
|
||||||
}
|
}
|
||||||
@ -1365,6 +1364,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
|||||||
// verify fee is within tolerance by recreating payout tx
|
// verify fee is within tolerance by recreating payout tx
|
||||||
// TODO (monero-project): creating tx will require exchanging updated multisig hex if message needs reprocessed. provide weight with describe_transfer so fee can be estimated?
|
// TODO (monero-project): creating tx will require exchanging updated multisig hex if message needs reprocessed. provide weight with describe_transfer so fee can be estimated?
|
||||||
log.info("Creating fee estimate tx for {} {}", getClass().getSimpleName(), getId());
|
log.info("Creating fee estimate tx for {} {}", getClass().getSimpleName(), getId());
|
||||||
|
saveWallet(); // save wallet before creating fee estimate tx
|
||||||
MoneroTxWallet feeEstimateTx = createPayoutTx();
|
MoneroTxWallet feeEstimateTx = createPayoutTx();
|
||||||
BigInteger feeEstimate = feeEstimateTx.getFee();
|
BigInteger feeEstimate = feeEstimateTx.getFee();
|
||||||
double feeDiff = payoutTx.getFee().subtract(feeEstimate).abs().doubleValue() / feeEstimate.doubleValue(); // TODO: use BigDecimal?
|
double feeDiff = payoutTx.getFee().subtract(feeEstimate).abs().doubleValue() / feeEstimate.doubleValue(); // TODO: use BigDecimal?
|
||||||
@ -1373,6 +1373,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// save trade state
|
// save trade state
|
||||||
|
saveWallet();
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
|
|
||||||
// submit payout tx
|
// submit payout tx
|
||||||
@ -1536,8 +1537,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
|||||||
try {
|
try {
|
||||||
ThreadUtils.awaitTask(shutDownTask, SHUTDOWN_TIMEOUT_MS);
|
ThreadUtils.awaitTask(shutDownTask, SHUTDOWN_TIMEOUT_MS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Error shutting down {} {}: {}", getClass().getSimpleName(), getId(), e.getMessage());
|
log.warn("Error shutting down {} {}: {}\n", getClass().getSimpleName(), getId(), e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
// force close wallet
|
// force close wallet
|
||||||
forceCloseWallet();
|
forceCloseWallet();
|
||||||
@ -2817,8 +2817,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
|||||||
processing = false;
|
processing = false;
|
||||||
if (!isInitialized || isShutDownStarted) return;
|
if (!isInitialized || isShutDownStarted) return;
|
||||||
if (isWalletConnectedToDaemon()) {
|
if (isWalletConnectedToDaemon()) {
|
||||||
e.printStackTrace();
|
log.warn("Error polling idle trade for {} {}: {}. Monerod={}\n", getClass().getSimpleName(), getId(), e.getMessage(), getXmrWalletService().getXmrConnectionService().getConnection(), e);
|
||||||
log.warn("Error polling idle trade for {} {}: {}. Monerod={}", getClass().getSimpleName(), getId(), e.getMessage(), getXmrWalletService().getXmrConnectionService().getConnection());
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, getId());
|
}, getId());
|
||||||
|
@ -366,8 +366,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
trade.onShutDownStarted();
|
trade.onShutDownStarted();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e.getMessage() != null && e.getMessage().contains("Connection reset")) return; // expected if shut down with ctrl+c
|
if (e.getMessage() != null && e.getMessage().contains("Connection reset")) return; // expected if shut down with ctrl+c
|
||||||
log.warn("Error notifying {} {} that shut down started {}", trade.getClass().getSimpleName(), trade.getId());
|
log.warn("Error notifying {} {} that shut down started: {}\n", trade.getClass().getSimpleName(), trade.getId(), e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -396,15 +395,13 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
trade.shutDown();
|
trade.shutDown();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e.getMessage() != null && (e.getMessage().contains("Connection reset") || e.getMessage().contains("Connection refused"))) return; // expected if shut down with ctrl+c
|
if (e.getMessage() != null && (e.getMessage().contains("Connection reset") || e.getMessage().contains("Connection refused"))) return; // expected if shut down with ctrl+c
|
||||||
log.warn("Error closing {} {}", trade.getClass().getSimpleName(), trade.getId());
|
log.warn("Error closing {} {}: {}", trade.getClass().getSimpleName(), trade.getId(), e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
ThreadUtils.awaitTasks(tasks);
|
ThreadUtils.awaitTasks(tasks);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Error shutting down trades: {}", e.getMessage());
|
log.warn("Error shutting down trades: {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,8 +459,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (!isShutDownStarted) {
|
if (!isShutDownStarted) {
|
||||||
e.printStackTrace();
|
log.warn("Error initializing {} {}: {}\n", trade.getClass().getSimpleName(), trade.getId(), e.getMessage(), e);
|
||||||
log.warn("Error initializing {} {}: {}", trade.getClass().getSimpleName(), trade.getId(), e.getMessage());
|
|
||||||
trade.setInitError(e);
|
trade.setInitError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
|
|||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
this.error = t;
|
this.error = t;
|
||||||
t.printStackTrace();
|
log.error("Error processing deposit request for trade {}: {}\n", trade.getId(), t.getMessage(), t);
|
||||||
trade.setStateIfValidTransitionTo(Trade.State.PUBLISH_DEPOSIT_TX_REQUEST_FAILED);
|
trade.setStateIfValidTransitionTo(Trade.State.PUBLISH_DEPOSIT_TX_REQUEST_FAILED);
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
@ -155,15 +155,14 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
|
|||||||
log.info("Arbitrator published deposit txs for trade " + trade.getId());
|
log.info("Arbitrator published deposit txs for trade " + trade.getId());
|
||||||
trade.setStateIfValidTransitionTo(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
trade.setStateIfValidTransitionTo(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Arbitrator error publishing deposit txs for trade {} {}: {}", trade.getClass().getSimpleName(), trade.getShortId(), e.getMessage());
|
log.warn("Arbitrator error publishing deposit txs for trade {} {}: {}\n", trade.getClass().getSimpleName(), trade.getShortId(), e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
if (!depositTxsRelayed) {
|
if (!depositTxsRelayed) {
|
||||||
|
|
||||||
// flush txs from pool
|
// flush txs from pool
|
||||||
try {
|
try {
|
||||||
daemon.flushTxPool(processModel.getMaker().getDepositTxHash(), processModel.getTaker().getDepositTxHash());
|
daemon.flushTxPool(processModel.getMaker().getDepositTxHash(), processModel.getTaker().getDepositTxHash());
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
e2.printStackTrace();
|
log.warn("Error flushing deposit txs from pool for trade {}: {}\n", trade.getId(), e2.getMessage(), e2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -29,6 +29,8 @@ import monero.daemon.model.MoneroTx;
|
|||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arbitrator verifies reserve tx from maker or taker.
|
* Arbitrator verifies reserve tx from maker or taker.
|
||||||
*
|
*
|
||||||
@ -73,7 +75,7 @@ public class ArbitratorProcessReserveTx extends TradeTask {
|
|||||||
request.getReserveTxKey(),
|
request.getReserveTxKey(),
|
||||||
null);
|
null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
throw new RuntimeException("Error processing reserve tx from " + (isFromMaker ? "maker " : "taker ") + processModel.getTempTradePeerNodeAddress() + ", offerId=" + offer.getId() + ": " + e.getMessage());
|
throw new RuntimeException("Error processing reserve tx from " + (isFromMaker ? "maker " : "taker ") + processModel.getTempTradePeerNodeAddress() + ", offerId=" + offer.getId() + ": " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class MaybeResendDisputeClosedMessageWithPayout extends TradeTask {
|
|||||||
HavenoUtils.arbitrationManager.closeDisputeTicket(dispute.getDisputeResultProperty().get(), dispute, dispute.getDisputeResultProperty().get().summaryNotesProperty().get(), () -> {
|
HavenoUtils.arbitrationManager.closeDisputeTicket(dispute.getDisputeResultProperty().get(), dispute, dispute.getDisputeResultProperty().get().summaryNotesProperty().get(), () -> {
|
||||||
completeAux();
|
completeAux();
|
||||||
}, (errMessage, err) -> {
|
}, (errMessage, err) -> {
|
||||||
err.printStackTrace();
|
log.error("Failed to close dispute ticket for trade {}: {}\n", trade.getId(), errMessage, err);
|
||||||
failed(err);
|
failed(err);
|
||||||
});
|
});
|
||||||
ticketClosed = true;
|
ticketClosed = true;
|
||||||
|
@ -70,7 +70,7 @@ public class ProcessDepositsConfirmedMessage extends TradeTask {
|
|||||||
try {
|
try {
|
||||||
trade.importMultisigHex();
|
trade.importMultisigHex();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warn("Error importing multisig hex on deposits confirmed for trade " + trade.getId() + ": " + e.getMessage() + "\n", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import haveno.network.p2p.NodeAddress;
|
|||||||
import haveno.network.p2p.SendDirectMessageListener;
|
import haveno.network.p2p.SendDirectMessageListener;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import monero.wallet.MoneroWallet;
|
import monero.wallet.MoneroWallet;
|
||||||
|
import monero.wallet.model.MoneroMultisigInfo;
|
||||||
import monero.wallet.model.MoneroMultisigInitResult;
|
import monero.wallet.model.MoneroMultisigInitResult;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -118,8 +119,17 @@ public class ProcessInitMultisigRequest extends TradeTask {
|
|||||||
if (processModel.getMultisigAddress() == null && peers[0].getExchangedMultisigHex() != null && peers[1].getExchangedMultisigHex() != null) {
|
if (processModel.getMultisigAddress() == null && peers[0].getExchangedMultisigHex() != null && peers[1].getExchangedMultisigHex() != null) {
|
||||||
log.info("Importing exchanged multisig hex for trade {}", trade.getId());
|
log.info("Importing exchanged multisig hex for trade {}", trade.getId());
|
||||||
MoneroMultisigInitResult result = multisigWallet.exchangeMultisigKeys(Arrays.asList(peers[0].getExchangedMultisigHex(), peers[1].getExchangedMultisigHex()), xmrWalletService.getWalletPassword());
|
MoneroMultisigInitResult result = multisigWallet.exchangeMultisigKeys(Arrays.asList(peers[0].getExchangedMultisigHex(), peers[1].getExchangedMultisigHex()), xmrWalletService.getWalletPassword());
|
||||||
|
|
||||||
|
// check multisig state
|
||||||
|
MoneroMultisigInfo multisigInfo = multisigWallet.getMultisigInfo();
|
||||||
|
if (!multisigInfo.isMultisig()) throw new RuntimeException("Multisig wallet is not multisig on completion");
|
||||||
|
if (!multisigInfo.isReady()) throw new RuntimeException("Multisig wallet is not ready on completion");
|
||||||
|
if (multisigInfo.getThreshold() != 2) throw new RuntimeException("Multisig wallet has unexpected threshold: " + multisigInfo.getThreshold());
|
||||||
|
if (multisigInfo.getNumParticipants() != 3) throw new RuntimeException("Multisig wallet has unexpected number of participants: " + multisigInfo.getNumParticipants());
|
||||||
|
|
||||||
|
// set final address and save
|
||||||
processModel.setMultisigAddress(result.getAddress());
|
processModel.setMultisigAddress(result.getAddress());
|
||||||
new Thread(() -> trade.saveWallet()).start(); // save multisig wallet off thread on completion
|
trade.saveWallet();
|
||||||
trade.setStateIfValidTransitionTo(Trade.State.MULTISIG_COMPLETED);
|
trade.setStateIfValidTransitionTo(Trade.State.MULTISIG_COMPLETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public abstract class TradeTask extends Task<Trade> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void failed(Throwable t) {
|
protected void failed(Throwable t) {
|
||||||
t.printStackTrace();
|
log.error("Trade task failed, error={}\n", t.getMessage(), t);
|
||||||
appendExceptionToErrorMessage(t);
|
appendExceptionToErrorMessage(t);
|
||||||
trade.setErrorMessage(errorMessage);
|
trade.setErrorMessage(errorMessage);
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
|
@ -6,6 +6,8 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
import haveno.common.Timer;
|
import haveno.common.Timer;
|
||||||
import haveno.common.UserThread;
|
import haveno.common.UserThread;
|
||||||
import haveno.core.api.XmrConnectionService;
|
import haveno.core.api.XmrConnectionService;
|
||||||
@ -106,7 +108,7 @@ public class XmrWalletBase {
|
|||||||
height = wallet.getHeight(); // can get read timeout while syncing
|
height = wallet.getHeight(); // can get read timeout while syncing
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Error getting wallet height while syncing with progress: " + e.getMessage());
|
log.warn("Error getting wallet height while syncing with progress: " + e.getMessage());
|
||||||
if (wallet != null && !isShutDownStarted) e.printStackTrace();
|
if (wallet != null && !isShutDownStarted) log.warn(ExceptionUtils.getStackTrace(e));
|
||||||
|
|
||||||
// stop polling and release latch
|
// stop polling and release latch
|
||||||
syncProgressError = e;
|
syncProgressError = e;
|
||||||
|
@ -818,7 +818,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
MoneroFeeEstimate feeEstimates = getDaemon().getFeeEstimate();
|
MoneroFeeEstimate feeEstimates = getDaemon().getFeeEstimate();
|
||||||
BigInteger baseFeeEstimate = feeEstimates.getFees().get(2); // get elevated fee per kB
|
BigInteger baseFeeEstimate = feeEstimates.getFees().get(2); // get elevated fee per kB
|
||||||
BigInteger qmask = feeEstimates.getQuantizationMask();
|
BigInteger qmask = feeEstimates.getQuantizationMask();
|
||||||
log.info("Monero base fee estimate={}, qmask={}: " + baseFeeEstimate, qmask);
|
log.info("Monero base fee estimate={}, qmask={}", baseFeeEstimate, qmask);
|
||||||
|
|
||||||
// get tx base fee
|
// get tx base fee
|
||||||
BigInteger baseFee = baseFeeEstimate.multiply(BigInteger.valueOf(txWeight));
|
BigInteger baseFee = baseFeeEstimate.multiply(BigInteger.valueOf(txWeight));
|
||||||
@ -922,8 +922,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
try {
|
try {
|
||||||
ThreadUtils.awaitTask(shutDownTask, SHUTDOWN_TIMEOUT_MS);
|
ThreadUtils.awaitTask(shutDownTask, SHUTDOWN_TIMEOUT_MS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Error shutting down {}: {}", getClass().getSimpleName(), e.getMessage());
|
log.warn("Error shutting down {}: {}\n", getClass().getSimpleName(), e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
// force close wallet
|
// force close wallet
|
||||||
forceCloseMainWallet();
|
forceCloseMainWallet();
|
||||||
@ -945,8 +944,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
List<XmrAddressEntry> unusedAddressEntries = getUnusedAddressEntries();
|
List<XmrAddressEntry> unusedAddressEntries = getUnusedAddressEntries();
|
||||||
if (!unusedAddressEntries.isEmpty()) return xmrAddressEntryList.swapAvailableToAddressEntryWithOfferId(unusedAddressEntries.get(0), context, offerId);
|
if (!unusedAddressEntries.isEmpty()) return xmrAddressEntryList.swapAvailableToAddressEntryWithOfferId(unusedAddressEntries.get(0), context, offerId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Error getting new address entry based on incoming transactions");
|
log.warn("Error getting new address entry based on incoming transactions: {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create new entry
|
// create new entry
|
||||||
@ -1172,8 +1170,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
try {
|
try {
|
||||||
balanceListener.onBalanceChanged(balance);
|
balanceListener.onBalanceChanged(balance);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Failed to notify balance listener of change");
|
log.warn("Failed to notify balance listener of change: {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1309,8 +1306,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
try {
|
try {
|
||||||
doMaybeInitMainWallet(sync, MAX_SYNC_ATTEMPTS);
|
doMaybeInitMainWallet(sync, MAX_SYNC_ATTEMPTS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Error initializing main wallet: " + e.getMessage());
|
log.warn("Error initializing main wallet: {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
HavenoUtils.setTopError(e.getMessage());
|
HavenoUtils.setTopError(e.getMessage());
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -1459,9 +1455,10 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
log.info("Done creating full wallet " + config.getPath() + " in " + (System.currentTimeMillis() - time) + " ms");
|
log.info("Done creating full wallet " + config.getPath() + " in " + (System.currentTimeMillis() - time) + " ms");
|
||||||
return walletFull;
|
return walletFull;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
String errorMsg = "Could not create wallet '" + config.getPath() + "': " + e.getMessage();
|
||||||
|
log.warn(errorMsg + "\n", e);
|
||||||
if (walletFull != null) forceCloseWallet(walletFull, config.getPath());
|
if (walletFull != null) forceCloseWallet(walletFull, config.getPath());
|
||||||
throw new IllegalStateException("Could not create wallet '" + config.getPath() + "'");
|
throw new IllegalStateException(errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1503,15 +1500,15 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle success or failure
|
// handle success or failure
|
||||||
|
File originalCacheBackup = new File(cachePath + ".backup");
|
||||||
if (retrySuccessful) {
|
if (retrySuccessful) {
|
||||||
originalCacheFile.delete(); // delete original wallet cache backup
|
if (originalCacheBackup.exists()) originalCacheBackup.delete(); // delete original wallet cache backup
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// restore original wallet cache
|
// restore original wallet cache
|
||||||
log.warn("Failed to open full wallet using backup cache, restoring original cache");
|
log.warn("Failed to open full wallet using backup cache, restoring original cache");
|
||||||
File cacheFile = new File(cachePath);
|
File cacheFile = new File(cachePath);
|
||||||
if (cacheFile.exists()) cacheFile.delete();
|
if (cacheFile.exists()) cacheFile.delete();
|
||||||
File originalCacheBackup = new File(cachePath + ".backup");
|
|
||||||
if (originalCacheBackup.exists()) originalCacheBackup.renameTo(new File(cachePath));
|
if (originalCacheBackup.exists()) originalCacheBackup.renameTo(new File(cachePath));
|
||||||
|
|
||||||
// throw exception
|
// throw exception
|
||||||
@ -1525,9 +1522,10 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
log.info("Done opening full wallet " + config.getPath());
|
log.info("Done opening full wallet " + config.getPath());
|
||||||
return walletFull;
|
return walletFull;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
String errorMsg = "Could not open full wallet '" + config.getPath() + "': " + e.getMessage();
|
||||||
|
log.warn(errorMsg + "\n", e);
|
||||||
if (walletFull != null) forceCloseWallet(walletFull, config.getPath());
|
if (walletFull != null) forceCloseWallet(walletFull, config.getPath());
|
||||||
throw new IllegalStateException("Could not open full wallet '" + config.getPath() + "'");
|
throw new IllegalStateException(errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1557,7 +1555,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
log.info("Done creating RPC wallet " + config.getPath() + " in " + (System.currentTimeMillis() - time) + " ms");
|
log.info("Done creating RPC wallet " + config.getPath() + " in " + (System.currentTimeMillis() - time) + " ms");
|
||||||
return walletRpc;
|
return walletRpc;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warn("Could not create wallet '" + config.getPath() + "': " + e.getMessage() + "\n", e);
|
||||||
if (walletRpc != null) forceCloseWallet(walletRpc, config.getPath());
|
if (walletRpc != null) forceCloseWallet(walletRpc, config.getPath());
|
||||||
throw new IllegalStateException("Could not create wallet '" + config.getPath() + "'. Please close Haveno, stop all monero-wallet-rpc processes in your task manager, and restart Haveno.");
|
throw new IllegalStateException("Could not create wallet '" + config.getPath() + "'. Please close Haveno, stop all monero-wallet-rpc processes in your task manager, and restart Haveno.");
|
||||||
}
|
}
|
||||||
@ -1607,15 +1605,15 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle success or failure
|
// handle success or failure
|
||||||
|
File originalCacheBackup = new File(cachePath + ".backup");
|
||||||
if (retrySuccessful) {
|
if (retrySuccessful) {
|
||||||
originalCacheFile.delete(); // delete original wallet cache backup
|
if (originalCacheBackup.exists()) originalCacheBackup.delete(); // delete original wallet cache backup
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// restore original wallet cache
|
// restore original wallet cache
|
||||||
log.warn("Failed to open RPC wallet using backup cache, restoring original cache");
|
log.warn("Failed to open RPC wallet using backup cache, restoring original cache");
|
||||||
File cacheFile = new File(cachePath);
|
File cacheFile = new File(cachePath);
|
||||||
if (cacheFile.exists()) cacheFile.delete();
|
if (cacheFile.exists()) cacheFile.delete();
|
||||||
File originalCacheBackup = new File(cachePath + ".backup");
|
|
||||||
if (originalCacheBackup.exists()) originalCacheBackup.renameTo(new File(cachePath));
|
if (originalCacheBackup.exists()) originalCacheBackup.renameTo(new File(cachePath));
|
||||||
|
|
||||||
// throw exception
|
// throw exception
|
||||||
@ -1629,7 +1627,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
log.info("Done opening RPC wallet " + config.getPath());
|
log.info("Done opening RPC wallet " + config.getPath());
|
||||||
return walletRpc;
|
return walletRpc;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warn("Could not open wallet '" + config.getPath() + "': " + e.getMessage() + "\n", e);
|
||||||
if (walletRpc != null) forceCloseWallet(walletRpc, config.getPath());
|
if (walletRpc != null) forceCloseWallet(walletRpc, config.getPath());
|
||||||
throw new IllegalStateException("Could not open wallet '" + config.getPath() + "'. Please close Haveno, stop all monero-wallet-rpc processes in your task manager, and restart Haveno.\n\nError message: " + e.getMessage());
|
throw new IllegalStateException("Could not open wallet '" + config.getPath() + "'. Please close Haveno, stop all monero-wallet-rpc processes in your task manager, and restart Haveno.\n\nError message: " + e.getMessage());
|
||||||
}
|
}
|
||||||
@ -1733,7 +1731,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
wallet.changePassword(oldPassword, newPassword);
|
wallet.changePassword(oldPassword, newPassword);
|
||||||
saveMainWallet();
|
saveMainWallet();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warn("Error changing main wallet password: " + e.getMessage() + "\n", e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1916,7 +1914,7 @@ public class XmrWalletService extends XmrWalletBase {
|
|||||||
cacheWalletInfo();
|
cacheWalletInfo();
|
||||||
requestSaveMainWallet();
|
requestSaveMainWallet();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.warn("Error caching wallet info: " + e.getMessage() + "\n", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ class TransactionsListItem {
|
|||||||
private boolean received;
|
private boolean received;
|
||||||
private boolean detailsAvailable;
|
private boolean detailsAvailable;
|
||||||
private BigInteger amount = BigInteger.ZERO;
|
private BigInteger amount = BigInteger.ZERO;
|
||||||
|
private BigInteger txFee = BigInteger.ZERO;
|
||||||
private String memo = "";
|
private String memo = "";
|
||||||
private long confirmations = 0;
|
private long confirmations = 0;
|
||||||
@Getter
|
@Getter
|
||||||
@ -107,6 +108,7 @@ class TransactionsListItem {
|
|||||||
amount = valueSentFromMe.multiply(BigInteger.valueOf(-1));
|
amount = valueSentFromMe.multiply(BigInteger.valueOf(-1));
|
||||||
received = false;
|
received = false;
|
||||||
direction = Res.get("funds.tx.direction.sentTo");
|
direction = Res.get("funds.tx.direction.sentTo");
|
||||||
|
txFee = tx.getFee().multiply(BigInteger.valueOf(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optionalTradable.isPresent()) {
|
if (optionalTradable.isPresent()) {
|
||||||
@ -201,6 +203,14 @@ class TransactionsListItem {
|
|||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigInteger getTxFee() {
|
||||||
|
return txFee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTxFeeStr() {
|
||||||
|
return txFee.equals(BigInteger.ZERO) ? "" : HavenoUtils.formatXmr(txFee);
|
||||||
|
}
|
||||||
|
|
||||||
public String getAddressString() {
|
public String getAddressString() {
|
||||||
return addressString;
|
return addressString;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,8 @@
|
|||||||
<TableColumn fx:id="detailsColumn" minWidth="220" maxWidth="220"/>
|
<TableColumn fx:id="detailsColumn" minWidth="220" maxWidth="220"/>
|
||||||
<TableColumn fx:id="addressColumn" minWidth="260"/>
|
<TableColumn fx:id="addressColumn" minWidth="260"/>
|
||||||
<TableColumn fx:id="transactionColumn" minWidth="180"/>
|
<TableColumn fx:id="transactionColumn" minWidth="180"/>
|
||||||
<TableColumn fx:id="amountColumn" minWidth="130" maxWidth="130"/>
|
<TableColumn fx:id="amountColumn" minWidth="110" maxWidth="110"/>
|
||||||
|
<TableColumn fx:id="txFeeColumn" minWidth="110" maxWidth="110"/>
|
||||||
<TableColumn fx:id="memoColumn" minWidth="40"/>
|
<TableColumn fx:id="memoColumn" minWidth="40"/>
|
||||||
<TableColumn fx:id="confidenceColumn" minWidth="120" maxWidth="130"/>
|
<TableColumn fx:id="confidenceColumn" minWidth="120" maxWidth="130"/>
|
||||||
<TableColumn fx:id="revertTxColumn" sortable="false" minWidth="110" maxWidth="110" visible="false"/>
|
<TableColumn fx:id="revertTxColumn" sortable="false" minWidth="110" maxWidth="110" visible="false"/>
|
||||||
|
@ -70,7 +70,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
@FXML
|
@FXML
|
||||||
TableView<TransactionsListItem> tableView;
|
TableView<TransactionsListItem> tableView;
|
||||||
@FXML
|
@FXML
|
||||||
TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, detailsColumn, addressColumn, transactionColumn, amountColumn, memoColumn, confidenceColumn, revertTxColumn;
|
TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, detailsColumn, addressColumn, transactionColumn, amountColumn, txFeeColumn, memoColumn, confidenceColumn, revertTxColumn;
|
||||||
@FXML
|
@FXML
|
||||||
Label numItems;
|
Label numItems;
|
||||||
@FXML
|
@FXML
|
||||||
@ -89,7 +89,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
private EventHandler<KeyEvent> keyEventEventHandler;
|
private EventHandler<KeyEvent> keyEventEventHandler;
|
||||||
private Scene scene;
|
private Scene scene;
|
||||||
|
|
||||||
private TransactionsUpdater transactionsUpdater = new TransactionsUpdater();
|
private final TransactionsUpdater transactionsUpdater = new TransactionsUpdater();
|
||||||
|
|
||||||
private class TransactionsUpdater extends MoneroWalletListener {
|
private class TransactionsUpdater extends MoneroWalletListener {
|
||||||
@Override
|
@Override
|
||||||
@ -129,11 +129,12 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
|
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
|
||||||
transactionColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.txId", Res.getBaseCurrencyCode())));
|
transactionColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.txId", Res.getBaseCurrencyCode())));
|
||||||
amountColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.amountWithCur", Res.getBaseCurrencyCode())));
|
amountColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.amountWithCur", Res.getBaseCurrencyCode())));
|
||||||
|
txFeeColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.txFee", Res.getBaseCurrencyCode())));
|
||||||
memoColumn.setGraphic(new AutoTooltipLabel(Res.get("funds.tx.memo")));
|
memoColumn.setGraphic(new AutoTooltipLabel(Res.get("funds.tx.memo")));
|
||||||
confidenceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.confirmations", Res.getBaseCurrencyCode())));
|
confidenceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.confirmations", Res.getBaseCurrencyCode())));
|
||||||
revertTxColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.revert", Res.getBaseCurrencyCode())));
|
revertTxColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.revert", Res.getBaseCurrencyCode())));
|
||||||
|
|
||||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_FLEX_LAST_COLUMN);
|
||||||
tableView.setPlaceholder(new AutoTooltipLabel(Res.get("funds.tx.noTxAvailable")));
|
tableView.setPlaceholder(new AutoTooltipLabel(Res.get("funds.tx.noTxAvailable")));
|
||||||
|
|
||||||
setDateColumnCellFactory();
|
setDateColumnCellFactory();
|
||||||
@ -141,6 +142,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
setAddressColumnCellFactory();
|
setAddressColumnCellFactory();
|
||||||
setTransactionColumnCellFactory();
|
setTransactionColumnCellFactory();
|
||||||
setAmountColumnCellFactory();
|
setAmountColumnCellFactory();
|
||||||
|
setTxFeeColumnCellFactory();
|
||||||
setMemoColumnCellFactory();
|
setMemoColumnCellFactory();
|
||||||
setConfidenceColumnCellFactory();
|
setConfidenceColumnCellFactory();
|
||||||
setRevertTxColumnCellFactory();
|
setRevertTxColumnCellFactory();
|
||||||
@ -156,7 +158,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
addressColumn.setComparator(Comparator.comparing(item -> item.getDirection() + item.getAddressString()));
|
addressColumn.setComparator(Comparator.comparing(item -> item.getDirection() + item.getAddressString()));
|
||||||
transactionColumn.setComparator(Comparator.comparing(TransactionsListItem::getTxId));
|
transactionColumn.setComparator(Comparator.comparing(TransactionsListItem::getTxId));
|
||||||
amountColumn.setComparator(Comparator.comparing(TransactionsListItem::getAmount));
|
amountColumn.setComparator(Comparator.comparing(TransactionsListItem::getAmount));
|
||||||
confidenceColumn.setComparator(Comparator.comparingLong(item -> item.getNumConfirmations()));
|
confidenceColumn.setComparator(Comparator.comparingLong(TransactionsListItem::getNumConfirmations));
|
||||||
memoColumn.setComparator(Comparator.comparing(TransactionsListItem::getMemo));
|
memoColumn.setComparator(Comparator.comparing(TransactionsListItem::getMemo));
|
||||||
|
|
||||||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||||
@ -216,8 +218,9 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
columns[2] = item.getDirection() + " " + item.getAddressString();
|
columns[2] = item.getDirection() + " " + item.getAddressString();
|
||||||
columns[3] = item.getTxId();
|
columns[3] = item.getTxId();
|
||||||
columns[4] = item.getAmountStr();
|
columns[4] = item.getAmountStr();
|
||||||
columns[5] = item.getMemo() == null ? "" : item.getMemo();
|
columns[5] = item.getTxFeeStr();
|
||||||
columns[6] = String.valueOf(item.getNumConfirmations());
|
columns[6] = item.getMemo() == null ? "" : item.getMemo();
|
||||||
|
columns[7] = String.valueOf(item.getNumConfirmations());
|
||||||
return columns;
|
return columns;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -414,6 +417,33 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void setTxFeeColumnCellFactory() {
|
||||||
|
txFeeColumn.setCellValueFactory((addressListItem) ->
|
||||||
|
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||||
|
txFeeColumn.setCellFactory(
|
||||||
|
new Callback<>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableCell<TransactionsListItem, TransactionsListItem> call(TableColumn<TransactionsListItem,
|
||||||
|
TransactionsListItem> column) {
|
||||||
|
return new TableCell<>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateItem(final TransactionsListItem item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
|
||||||
|
if (item != null && !empty) {
|
||||||
|
setGraphic(new AutoTooltipLabel(item.getTxFeeStr()));
|
||||||
|
} else {
|
||||||
|
setGraphic(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void setMemoColumnCellFactory() {
|
private void setMemoColumnCellFactory() {
|
||||||
memoColumn.setCellValueFactory((addressListItem) ->
|
memoColumn.setCellValueFactory((addressListItem) ->
|
||||||
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||||
|
@ -678,7 +678,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
|||||||
closeTicketButton.disableProperty().unbind();
|
closeTicketButton.disableProperty().unbind();
|
||||||
hide();
|
hide();
|
||||||
}, (errMessage, err) -> {
|
}, (errMessage, err) -> {
|
||||||
log.error(errMessage);
|
log.error("Error closing dispute ticket: " + errMessage + "\n", err);
|
||||||
new Popup().error(err.toString()).show();
|
new Popup().error(err.toString()).show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -153,8 +153,7 @@ public abstract class TradeSubView extends HBox {
|
|||||||
tradeStepView.setChatCallback(chatCallback);
|
tradeStepView.setChatCallback(chatCallback);
|
||||||
tradeStepView.activate();
|
tradeStepView.activate();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Creating viewClass {} caused an error {}", viewClass, e.getMessage());
|
log.error("Creating viewClass {} caused an error {}\n", viewClass, e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ import javafx.scene.text.TextAlignment;
|
|||||||
|
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.fxmisc.easybind.EasyBind;
|
import org.fxmisc.easybind.EasyBind;
|
||||||
import org.fxmisc.easybind.Subscription;
|
import org.fxmisc.easybind.Subscription;
|
||||||
|
|
||||||
@ -565,12 +566,10 @@ public class ChatView extends AnchorPane {
|
|||||||
inputTextArea.setText(inputTextArea.getText() + "\n[" + Res.get("support.attachment") + " " + result.getName() + "]");
|
inputTextArea.setText(inputTextArea.getText() + "\n[" + Res.get("support.attachment") + " " + result.getName() + "]");
|
||||||
}
|
}
|
||||||
} catch (java.io.IOException e) {
|
} catch (java.io.IOException e) {
|
||||||
e.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
log.error(e.getMessage());
|
|
||||||
}
|
}
|
||||||
} catch (MalformedURLException e2) {
|
} catch (MalformedURLException e2) {
|
||||||
e2.printStackTrace();
|
log.error(ExceptionUtils.getStackTrace(e2));
|
||||||
log.error(e2.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -593,8 +592,7 @@ public class ChatView extends AnchorPane {
|
|||||||
inputTextArea.setText(inputTextArea.getText() + "\n[" + Res.get("support.attachment") + " " + name + "]");
|
inputTextArea.setText(inputTextArea.getText() + "\n[" + Res.get("support.attachment") + " " + name + "]");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.toString());
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,8 +627,7 @@ public class ChatView extends AnchorPane {
|
|||||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file.getAbsolutePath())) {
|
try (FileOutputStream fileOutputStream = new FileOutputStream(file.getAbsolutePath())) {
|
||||||
fileOutputStream.write(attachment.getBytes());
|
fileOutputStream.write(attachment.getBytes());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
log.error("Error opening attachment: {}\n", e.getMessage(), e);
|
||||||
System.out.println(e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -878,9 +878,9 @@
|
|||||||
<sha256 value="c92e2ca40a3f2474d61e56831aeb379cf8ae3dddeea61b4a828cee2d99f71f38" origin="Generated by Gradle"/>
|
<sha256 value="c92e2ca40a3f2474d61e56831aeb379cf8ae3dddeea61b4a828cee2d99f71f38" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
<component group="io.github.woodser" name="monero-java" version="0.8.31">
|
<component group="io.github.woodser" name="monero-java" version="0.8.33">
|
||||||
<artifact name="monero-java-0.8.31.jar">
|
<artifact name="monero-java-0.8.33.jar">
|
||||||
<sha256 value="46b81b98bc76f60a965bc7de429ff72cf6c443858987cbd51b9cacd2f8a8d28b" origin="Generated by Gradle"/>
|
<sha256 value="f9a02386ec0870b13a512bf5f72da464c9507e1a1ed6982716bff87641f94e81" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
<component group="io.grpc" name="grpc-api" version="1.42.1">
|
<component group="io.grpc" name="grpc-api" version="1.42.1">
|
||||||
|
@ -24,6 +24,7 @@ import haveno.common.config.Config;
|
|||||||
import haveno.network.p2p.network.NetworkNode;
|
import haveno.network.p2p.network.NetworkNode;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -96,8 +97,7 @@ public class Socks5ProxyProvider {
|
|||||||
try {
|
try {
|
||||||
return new Socks5Proxy(tokens[0], Integer.valueOf(tokens[1]));
|
return new Socks5Proxy(tokens[0], Integer.valueOf(tokens[1]));
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
log.error(e.getMessage());
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("Incorrect format for socks5ProxyAddress. Should be: host:port.\n" +
|
log.error("Incorrect format for socks5ProxyAddress. Should be: host:port.\n" +
|
||||||
|
@ -57,6 +57,8 @@ import javafx.beans.property.ReadOnlyIntegerProperty;
|
|||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.beans.property.SimpleIntegerProperty;
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.fxmisc.easybind.EasyBind;
|
import org.fxmisc.easybind.EasyBind;
|
||||||
import org.fxmisc.easybind.Subscription;
|
import org.fxmisc.easybind.Subscription;
|
||||||
import org.fxmisc.easybind.monadic.MonadicBinding;
|
import org.fxmisc.easybind.monadic.MonadicBinding;
|
||||||
@ -433,15 +435,12 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NotNull Throwable throwable) {
|
public void onFailure(@NotNull Throwable throwable) {
|
||||||
log.error(throwable.toString());
|
log.error(ExceptionUtils.getStackTrace(throwable));
|
||||||
throwable.printStackTrace();
|
|
||||||
sendDirectMessageListener.onFault(throwable.toString());
|
sendDirectMessageListener.onFault(throwable.toString());
|
||||||
}
|
}
|
||||||
}, MoreExecutors.directExecutor());
|
}, MoreExecutors.directExecutor());
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
e.printStackTrace();
|
log.error("Error sending encrypted direct message, message={}, error={}\n", message.toString(), e.getMessage(), e);
|
||||||
log.error(message.toString());
|
|
||||||
log.error(e.toString());
|
|
||||||
sendDirectMessageListener.onFault(e.toString());
|
sendDirectMessageListener.onFault(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,7 @@ public class MailboxMessageList extends PersistableList<MailboxItem> {
|
|||||||
try {
|
try {
|
||||||
return MailboxItem.fromProto(e, networkProtoResolver);
|
return MailboxItem.fromProto(e, networkProtoResolver);
|
||||||
} catch (ProtobufferException protobufferException) {
|
} catch (ProtobufferException protobufferException) {
|
||||||
protobufferException.printStackTrace();
|
log.error("Error at MailboxItem.fromProto: {}", protobufferException.toString(), protobufferException);
|
||||||
log.error("Error at MailboxItem.fromProto: {}", protobufferException.toString());
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -335,8 +335,7 @@ public class MailboxMessageService implements HashMapChangedListener, PersistedD
|
|||||||
}
|
}
|
||||||
}, MoreExecutors.directExecutor());
|
}, MoreExecutors.directExecutor());
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
log.error("sendEncryptedMessage failed");
|
log.error("sendEncryptedMessage failed: {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
sendMailboxMessageListener.onFault("sendEncryptedMailboxMessage failed " + e);
|
sendMailboxMessageListener.onFault("sendEncryptedMailboxMessage failed " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -644,8 +643,7 @@ public class MailboxMessageService implements HashMapChangedListener, PersistedD
|
|||||||
log.info("The mailboxEntry was already removed earlier.");
|
log.info("The mailboxEntry was already removed earlier.");
|
||||||
}
|
}
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
e.printStackTrace();
|
log.error("Could not remove ProtectedMailboxStorageEntry from network. Error: {}\n", e.toString(), e);
|
||||||
log.error("Could not remove ProtectedMailboxStorageEntry from network. Error: {}", e.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,8 @@ import javafx.beans.property.ObjectProperty;
|
|||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -511,8 +513,7 @@ public class Connection implements HasCapabilities, Runnable, MessageListener {
|
|||||||
|
|
||||||
Uninterruptibles.sleepUninterruptibly(200, TimeUnit.MILLISECONDS);
|
Uninterruptibles.sleepUninterruptibly(200, TimeUnit.MILLISECONDS);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.error(t.getMessage());
|
log.error(ExceptionUtils.getStackTrace(t));
|
||||||
t.printStackTrace();
|
|
||||||
} finally {
|
} finally {
|
||||||
stopped = true;
|
stopped = true;
|
||||||
ThreadUtils.execute(() -> doShutDown(closeConnectionReason, shutDownCompleteHandler), THREAD_ID);
|
ThreadUtils.execute(() -> doShutDown(closeConnectionReason, shutDownCompleteHandler), THREAD_ID);
|
||||||
@ -537,16 +538,14 @@ public class Connection implements HasCapabilities, Runnable, MessageListener {
|
|||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
log.trace("SocketException at shutdown might be expected {}", e.getMessage());
|
log.trace("SocketException at shutdown might be expected {}", e.getMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Exception at shutdown. " + e.getMessage());
|
log.error("Exception at shutdown. {}\n", e.getMessage(), e);
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
} finally {
|
||||||
capabilitiesListeners.clear();
|
capabilitiesListeners.clear();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
protoInputStream.close();
|
protoInputStream.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(e.getMessage());
|
log.error(ExceptionUtils.getStackTrace(e));
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Utilities.shutdownAndAwaitTermination(executorService, SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
|
Utilities.shutdownAndAwaitTermination(executorService, SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||||
|
@ -76,8 +76,7 @@ public class LocalhostNetworkNode extends NetworkNode {
|
|||||||
try {
|
try {
|
||||||
startServer(new ServerSocket(servicePort));
|
startServer(new ServerSocket(servicePort));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
log.error("Exception at startServer: {}\n", e.getMessage(), e);
|
||||||
log.error("Exception at startServer: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
setupListeners.stream().forEach(SetupListener::onHiddenServicePublished);
|
setupListeners.stream().forEach(SetupListener::onHiddenServicePublished);
|
||||||
}, simulateTorDelayTorNode, TimeUnit.MILLISECONDS);
|
}, simulateTorDelayTorNode, TimeUnit.MILLISECONDS);
|
||||||
|
@ -97,11 +97,10 @@ class Server implements Runnable {
|
|||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (isServerActive())
|
if (isServerActive())
|
||||||
e.printStackTrace();
|
log.error("Error executing server loop: {}\n", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.error("Executing task failed. " + t.getMessage());
|
log.error("Executing task failed: {}\n", t.getMessage(), t);
|
||||||
t.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,8 +974,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener, Pers
|
|||||||
broadcaster.broadcast(refreshTTLMessage, sender);
|
broadcaster.broadcast(refreshTTLMessage, sender);
|
||||||
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
log.error("refreshTTL failed, missing data: {}", e.toString());
|
log.error("refreshTTL failed, missing data: {}\n", e.toString(), e);
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -116,8 +116,7 @@ public abstract class StoreService<T extends PersistableEnvelope> {
|
|||||||
log.debug("Could not find resourceFile " + resourceFileName + ". That is expected if none is provided yet.");
|
log.debug("Could not find resourceFile " + resourceFileName + ". That is expected if none is provided yet.");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error("Could not copy resourceFile " + resourceFileName + " to " +
|
log.error("Could not copy resourceFile " + resourceFileName + " to " +
|
||||||
destinationFile.getAbsolutePath() + ".\n" + e.getMessage());
|
destinationFile.getAbsolutePath() + ".\n", e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug("No resource file was copied. {} exists already.", fileName);
|
log.debug("No resource file was copied. {} exists already.", fileName);
|
||||||
|
@ -2,8 +2,13 @@
|
|||||||
|
|
||||||
Install Haveno on Tails by following these steps:
|
Install Haveno on Tails by following these steps:
|
||||||
|
|
||||||
1. Enable persistent storage dotfiles and admin password before starting tails.
|
1. Enable persistent storage dotfiles and admin password before starting Tails.
|
||||||
2. Download [haveno-install.sh](haveno-install.sh).
|
2. Download [haveno-install.sh](haveno-install.sh):
|
||||||
|
|
||||||
|
```
|
||||||
|
curl -fsSLO https://github.com/haveno-dex/haveno/raw/master/scripts/install_tails/haveno-install.sh
|
||||||
|
```
|
||||||
|
|
||||||
3. Execute installation script:
|
3. Execute installation script:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -17,3 +22,9 @@ Install Haveno on Tails by following these steps:
|
|||||||
```
|
```
|
||||||
|
|
||||||
4. Upon successful execution of the script (no errors), the Haveno release will be installed to persistent storage and can be launched via the desktop shortcut in the 'Other' section of the start menu.
|
4. Upon successful execution of the script (no errors), the Haveno release will be installed to persistent storage and can be launched via the desktop shortcut in the 'Other' section of the start menu.
|
||||||
|
|
||||||
|
> [!note]
|
||||||
|
> If you have already installed Haveno on Tails, we recommend moving your data directory (/home/amnesia/Persistent/Haveno-example) to the new default location (/home/amnesia/Persistent/haveno/Data/Haveno-example), to retain your history and for future support.
|
||||||
|
|
||||||
|
> [!note]
|
||||||
|
> Modern versions of Tails will invoke `curl` over Tor, but if your installation does not, then you can add `--socks5-hostname 127.0.0.1:9050` when invoking the install script.
|
11
scripts/install_tails/deprecated/README.md
Normal file
11
scripts/install_tails/deprecated/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Steps to use (This has serious security concerns to tails threat model only run when you need to access haveno)
|
||||||
|
|
||||||
|
## 1. Enable persistent storage and admin password before starting tails
|
||||||
|
|
||||||
|
## 2. Get your haveno deb file in persistent storage (amd64 version for tails)
|
||||||
|
|
||||||
|
## 3. Edit the path to the haveno deb file if necessary then run ```sudo ./haveno-install.sh```
|
||||||
|
## 4. As amnesia run ```source ~/.bashrc```
|
||||||
|
## 5. Start haveno using ```haveno-tails```
|
||||||
|
|
||||||
|
## You will need to run this script after each reset, but your data will be saved persistently in /home/amnesia/Persistence/Haveno
|
77
scripts/install_tails/deprecated/haveno-install.sh
Normal file
77
scripts/install_tails/deprecated/haveno-install.sh
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Written by BrandyJson, with heavy inspiration from bisq.wiki tails script #
|
||||||
|
#############################################################################
|
||||||
|
echo "Installing dpkg from persistent, (1.07-1, if this is out of date change the deb path in the script or manually install after running"
|
||||||
|
dpkg -i "/home/amnesia/Persistent/haveno_1.0.7-1_amd64.deb"
|
||||||
|
echo -e "Allowing amnesia to read tor control port cookie, only run this script when you actually want to use haveno\n\n!!! not secure !!!\n"
|
||||||
|
chmod o+r /var/run/tor/control.authcookie
|
||||||
|
echo "Updating apparmor-profile"
|
||||||
|
echo "---
|
||||||
|
- apparmor-profiles:
|
||||||
|
- '/opt/haveno/bin/Haveno'
|
||||||
|
users:
|
||||||
|
- 'amnesia'
|
||||||
|
commands:
|
||||||
|
AUTHCHALLENGE:
|
||||||
|
- 'SAFECOOKIE .*'
|
||||||
|
SETEVENTS:
|
||||||
|
- 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'
|
||||||
|
GETINFO:
|
||||||
|
- pattern: 'status/bootstrap-phase'
|
||||||
|
response:
|
||||||
|
- pattern: '250-status/bootstrap-phase=*'
|
||||||
|
replacement: '250-status/bootstrap-phase=NOTICE BOOTSTRAP PROGRESS=100 TAG=done SUMMARY="Done"'
|
||||||
|
- 'net/listeners/socks'
|
||||||
|
ADD_ONION:
|
||||||
|
- pattern: 'NEW:(\S+) Port=9999,(\S+)'
|
||||||
|
replacement: 'NEW:{} Port=9999,{client-address}:{}'
|
||||||
|
- pattern: '(\S+):(\S+) Port=9999,(\S+)'
|
||||||
|
replacement: '{}:{} Port=9999,{client-address}:{}'
|
||||||
|
DEL_ONION:
|
||||||
|
- '.+'
|
||||||
|
HSFETCH:
|
||||||
|
- '.+'
|
||||||
|
events:
|
||||||
|
CIRC:
|
||||||
|
suppress: true
|
||||||
|
ORCONN:
|
||||||
|
suppress: true
|
||||||
|
INFO:
|
||||||
|
suppress: true
|
||||||
|
NOTICE:
|
||||||
|
suppress: true
|
||||||
|
WARN:
|
||||||
|
suppress: true
|
||||||
|
ERR:
|
||||||
|
suppress: true
|
||||||
|
HS_DESC:
|
||||||
|
response:
|
||||||
|
- pattern: '650 HS_DESC CREATED (\S+) (\S+) (\S+) \S+ (.+)'
|
||||||
|
replacement: '650 HS_DESC CREATED {} {} {} redacted {}'
|
||||||
|
- pattern: '650 HS_DESC UPLOAD (\S+) (\S+) .*'
|
||||||
|
replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'
|
||||||
|
- pattern: '650 HS_DESC UPLOADED (\S+) (\S+) .+'
|
||||||
|
replacement: '650 HS_DESC UPLOADED {} {} redacted'
|
||||||
|
- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH'
|
||||||
|
replacement: '650 HS_DESC REQUESTED {} NO_AUTH'
|
||||||
|
- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH \S+ \S+'
|
||||||
|
replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'
|
||||||
|
- pattern: '650 HS_DESC RECEIVED (\S+) NO_AUTH \S+ \S+'
|
||||||
|
replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'
|
||||||
|
- pattern: '.*'
|
||||||
|
replacement: ''
|
||||||
|
HS_DESC_CONTENT:
|
||||||
|
suppress: true" > /etc/onion-grater.d/haveno.yml
|
||||||
|
echo "Adding rule to iptables to allow for monero-wallet-rpc to work"
|
||||||
|
iptables -I OUTPUT 2 -p tcp -d 127.0.0.1 -m tcp --dport 18081 -m owner --uid-owner 1855 -j ACCEPT
|
||||||
|
echo "Updating torsocks to allow for inbound connection"
|
||||||
|
sed -i 's/#AllowInbound/AllowInbound/g' /etc/tor/torsocks.conf
|
||||||
|
|
||||||
|
echo "Restarting onion-grater service"
|
||||||
|
|
||||||
|
systemctl restart onion-grater.service
|
||||||
|
|
||||||
|
echo "alias haveno-tails='torsocks /opt/haveno/bin/Haveno --torControlPort 951 --torControlCookieFile=/var/run/tor/control.authcookie --torControlUseSafeCookieAuth --useTorForXmr=ON --userDataDir=/home/amnesia/Persistent/'" >> /home/amnesia/.bashrc
|
||||||
|
echo -e "Everything is set up just run\n\nsource ~/.bashrc\n\nThen you can start haveno using haveno-tails"
|
@ -75,7 +75,7 @@ public class SeedNodeMain extends ExecutableForAppWithP2p {
|
|||||||
seedNode = new SeedNode();
|
seedNode = new SeedNode();
|
||||||
UserThread.execute(this::onApplicationLaunched);
|
UserThread.execute(this::onApplicationLaunched);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Error launching seed node: {}\n", e.toString(), e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user