mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Merge branch 'master' into 1-basic-api-bsqswap-support
This commit is contained in:
commit
b65cc9c1f4
@ -32,7 +32,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static bisq.core.locale.CountryUtil.findCountryByCode;
|
||||
import static bisq.core.payment.payload.PaymentMethod.CLEAR_X_CHANGE_ID;
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethodById;
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethod;
|
||||
import static java.lang.String.format;
|
||||
import static java.lang.System.getProperty;
|
||||
import static java.nio.file.Files.readAllBytes;
|
||||
@ -74,7 +74,7 @@ public abstract class AbstractBotTest extends MethodTest {
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
format("This test harness bot does not work with %s payment accounts yet.",
|
||||
getPaymentMethodById(paymentMethodId).getDisplayString()));
|
||||
getPaymentMethod(paymentMethodId).getDisplayString()));
|
||||
}
|
||||
} else {
|
||||
String countryCode = botScript.getCountryCode();
|
||||
|
@ -8,7 +8,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static bisq.core.locale.CountryUtil.findCountryByCode;
|
||||
import static bisq.core.payment.payload.PaymentMethod.CLEAR_X_CHANGE_ID;
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethodById;
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethod;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||
|
||||
@ -62,7 +62,7 @@ class Bot {
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
format("This bot test does not work with %s payment accounts yet.",
|
||||
getPaymentMethodById(paymentMethodId).getDisplayString()));
|
||||
getPaymentMethod(paymentMethodId).getDisplayString()));
|
||||
}
|
||||
} else {
|
||||
Country country = findCountry(botScript.getCountryCode());
|
||||
|
548
build.gradle
548
build.gradle
@ -5,12 +5,11 @@ buildscript {
|
||||
maven { url "https://plugins.gradle.org/m2/" }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.10'
|
||||
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.17'
|
||||
classpath 'com.google.gradle:osdetector-gradle-plugin:1.6.0'
|
||||
classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
|
||||
classpath 'org.openjfx:javafx-plugin:0.0.10'
|
||||
classpath files('gradle/witness/gradle-witness.jar')
|
||||
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.10.RELEASE'
|
||||
classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.5.6'
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,9 +41,9 @@ configure(subprojects) {
|
||||
fontawesomefxVersion = '8.0.0'
|
||||
fontawesomefxCommonsVersion = '9.1.2'
|
||||
fontawesomefxMaterialdesignfontVersion = '2.0.26-9.1.2'
|
||||
grpcVersion = '1.25.0'
|
||||
grpcVersion = '1.42.1'
|
||||
gsonVersion = '2.8.5'
|
||||
guavaVersion = '28.2-jre'
|
||||
guavaVersion = '30.1.1-jre'
|
||||
guiceVersion = '5.0.1'
|
||||
hamcrestVersion = '1.3'
|
||||
httpclientVersion = '4.5.12'
|
||||
@ -66,16 +65,16 @@ configure(subprojects) {
|
||||
langVersion = '3.11'
|
||||
logbackVersion = '1.1.11'
|
||||
loggingVersion = '1.2'
|
||||
lombokVersion = '1.18.12'
|
||||
mockitoVersion = '3.5.15'
|
||||
lombokVersion = '1.18.22'
|
||||
mockitoVersion = '4.0.0'
|
||||
netlayerVersion = '0.7.2' // Tag from https://github.com/bisq-network/netlayer/tags based on externaltor branch
|
||||
protobufVersion = '3.10.0'
|
||||
protobufVersion = '3.19.1'
|
||||
protocVersion = protobufVersion
|
||||
pushyVersion = '0.13.2'
|
||||
qrgenVersion = '1.3'
|
||||
slf4jVersion = '1.7.30'
|
||||
sparkVersion = '2.5.2'
|
||||
springBootVersion = '1.5.10.RELEASE'
|
||||
springBootVersion = '2.5.6'
|
||||
|
||||
os = osdetector.os == 'osx' ? 'mac' : osdetector.os == 'windows' ? 'win' : osdetector.os
|
||||
}
|
||||
@ -86,7 +85,7 @@ configure(subprojects) {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile "junit:junit:$junitVersion"
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
@ -141,7 +140,7 @@ configure([project(':cli'),
|
||||
|
||||
def unixScriptFile = file("${rootProject.projectDir}/bisq-$applicationName")
|
||||
unixScriptFile.text = unixScriptFile.text.replace(
|
||||
'cd "`dirname \\"$PRG\\"`/.." >/dev/null', 'cd "`dirname \\"$PRG\\"`" >/dev/null')
|
||||
'APP_HOME=$( cd "${APP_HOME:-./}.." && pwd -P ) || exit', 'APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit')
|
||||
|
||||
if (applicationName == 'desktop') {
|
||||
def script = file("${rootProject.projectDir}/bisq-$applicationName")
|
||||
@ -178,22 +177,22 @@ configure(project(':proto')) {
|
||||
apply plugin: 'com.google.protobuf'
|
||||
|
||||
dependencies {
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("io.grpc:grpc-protobuf:$grpcVersion") {
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation("io.grpc:grpc-stub:$grpcVersion") {
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
}
|
||||
|
||||
sourceSets.main.java.srcDirs += [
|
||||
@ -218,18 +217,18 @@ configure(project(':proto')) {
|
||||
|
||||
configure(project(':assets')) {
|
||||
dependencies {
|
||||
compile("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'slf4j-api')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'protobuf-java')
|
||||
implementation("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'bcprov-jdk15on')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'okhttp')
|
||||
exclude(module: 'okio')
|
||||
exclude(module: 'protobuf-java')
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
compile "com.google.guava:guava:$guavaVersion"
|
||||
compile "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
compile "org.apache.commons:commons-lang3:$langVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "org.apache.commons:commons-lang3:$langVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,39 +242,40 @@ configure(project(':common')) {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':proto')
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
||||
compile "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
compile "com.google.code.gson:gson:$gsonVersion"
|
||||
compile "net.sf.jopt-simple:jopt-simple:$joptVersion"
|
||||
compile "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
compile "ch.qos.logback:logback-core:$logbackVersion"
|
||||
compile "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
compile "com.google.code.findbugs:jsr305:$findbugsVersion"
|
||||
compile "com.google.guava:guava:$guavaVersion"
|
||||
compile("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
compile("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'slf4j-api')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'protobuf-java')
|
||||
implementation project(':proto')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'bcprov-jdk15on')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'okhttp')
|
||||
exclude(module: 'okio')
|
||||
exclude(module: 'protobuf-java')
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion") {
|
||||
implementation "com.google.code.findbugs:jsr305:$findbugsVersion"
|
||||
implementation "com.google.code.gson:gson:$gsonVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation "commons-io:commons-io:$ioVersion"
|
||||
implementation "net.sf.jopt-simple:jopt-simple:$joptVersion"
|
||||
implementation "org.apache.commons:commons-lang3:$langVersion"
|
||||
implementation "org.bouncycastle:bcpg-jdk15on:$bcVersion"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
||||
implementation "org.jetbrains:annotations:$jetbrainsAnnotationsVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-all:$hamcrestVersion"
|
||||
runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion") {
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
}
|
||||
compile "org.jetbrains:annotations:$jetbrainsAnnotationsVersion"
|
||||
compile "org.bouncycastle:bcpg-jdk15on:$bcVersion"
|
||||
compile "commons-io:commons-io:$ioVersion"
|
||||
compile "org.apache.commons:commons-lang3:$langVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompile "org.hamcrest:hamcrest-all:$hamcrestVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,22 +289,41 @@ configure(project(':p2p')) {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':common')
|
||||
compile("com.github.bisq-network.netlayer:tor.native:$netlayerVersion") {
|
||||
implementation project(':proto')
|
||||
implementation project(':common')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation "org.fxmisc.easybind:easybind:$easybindVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("com.github.bisq-network.netlayer:tor.external:$netlayerVersion") {
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
compile("com.github.bisq-network.netlayer:tor.external:$netlayerVersion") {
|
||||
implementation("com.github.bisq-network.netlayer:tor.native:$netlayerVersion") {
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'bcprov-jdk15on')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'okhttp')
|
||||
exclude(module: 'okio')
|
||||
exclude(module: 'protobuf-java')
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation("org.apache.httpcomponents:httpclient:$httpclientVersion") {
|
||||
exclude(module: 'commons-codec')
|
||||
}
|
||||
compile "org.fxmisc.easybind:easybind:$easybindVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompile("org.mockito:mockito-core:$mockitoVersion")
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testImplementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
testImplementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
testImplementation "org.apache.commons:commons-lang3:$langVersion"
|
||||
testImplementation("org.mockito:mockito-core:$mockitoVersion")
|
||||
}
|
||||
|
||||
processResources.doFirst {
|
||||
@ -329,34 +348,62 @@ configure(project(':core')) {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':proto')
|
||||
compile project(':assets')
|
||||
compile project(':p2p')
|
||||
implementation "commons-codec:commons-codec:$codecVersion"
|
||||
implementation project(':proto')
|
||||
implementation project(':assets')
|
||||
implementation project(':common')
|
||||
implementation project(':p2p')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion"
|
||||
implementation "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
|
||||
implementation "com.google.code.findbugs:jsr305:$findbugsVersion"
|
||||
implementation "com.google.code.gson:gson:$gsonVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation "commons-codec:commons-codec:$codecVersion"
|
||||
implementation "commons-io:commons-io:$ioVersion"
|
||||
implementation "net.sf.jopt-simple:jopt-simple:$joptVersion"
|
||||
implementation "org.apache.commons:commons-lang3:$langVersion"
|
||||
implementation "org.apache.httpcomponents:httpcore:$httpcoreVersion"
|
||||
implementation("org.apache.httpcomponents:httpclient:$httpclientVersion") {
|
||||
exclude(module: 'commons-codec')
|
||||
implementation "org.fxmisc.easybind:easybind:$easybindVersion"
|
||||
implementation "org.jetbrains:annotations:$jetbrainsAnnotationsVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion") {
|
||||
exclude(module: 'jackson-annotations')
|
||||
}
|
||||
compile "com.google.guava:guava:$guavaVersion"
|
||||
compile("com.github.bisq-network:jsonrpc4j:$jsonrpc4jVersion") {
|
||||
implementation("com.github.bisq-network.netlayer:tor.external:$netlayerVersion") {
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.github.bisq-network.netlayer:tor.native:$netlayerVersion") {
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'bcprov-jdk15on')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'okhttp')
|
||||
exclude(module: 'okio')
|
||||
exclude(module: 'protobuf-java')
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.github.bisq-network:jsonrpc4j:$jsonrpc4jVersion") {
|
||||
exclude(module: 'base64')
|
||||
exclude(module: 'httpcore-nio')
|
||||
}
|
||||
compile "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
|
||||
compile "com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion"
|
||||
compile("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion") {
|
||||
exclude(module: 'jackson-annotations')
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation("org.apache.httpcomponents:httpclient:$httpclientVersion") {
|
||||
exclude(module: 'commons-codec')
|
||||
}
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
|
||||
testCompile "org.hamcrest:hamcrest-all:$hamcrestVersion"
|
||||
testCompile "org.mockito:mockito-core:$mockitoVersion"
|
||||
testCompile "com.natpryce:make-it-easy:$easyVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testImplementation "com.natpryce:make-it-easy:$easyVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-all:$hamcrestVersion"
|
||||
testImplementation "org.mockito:mockito-core:$mockitoVersion"
|
||||
}
|
||||
|
||||
test {
|
||||
@ -368,35 +415,34 @@ configure(project(':cli')) {
|
||||
mainClassName = 'bisq.cli.CliMain'
|
||||
|
||||
dependencies {
|
||||
compile project(':proto')
|
||||
implementation "net.sf.jopt-simple:jopt-simple:$joptVersion"
|
||||
implementation project(':proto')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation "net.sf.jopt-simple:jopt-simple:$joptVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("io.grpc:grpc-core:$grpcVersion") {
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation("io.grpc:grpc-stub:$grpcVersion") {
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion") {
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testRuntime "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
testImplementation "org.bitbucket.cowwoc:diff-match-patch:$cowwocVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testRuntimeOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
}
|
||||
|
||||
test {
|
||||
@ -407,8 +453,6 @@ configure(project(':cli')) {
|
||||
configure(project(':desktop')) {
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
apply plugin: 'org.openjfx.javafxplugin'
|
||||
apply plugin: 'witness'
|
||||
apply from: '../gradle/witness/gradle-witness.gradle'
|
||||
apply from: 'package/package.gradle'
|
||||
|
||||
javafx {
|
||||
@ -424,7 +468,7 @@ configure(project(':desktop')) {
|
||||
|
||||
mainClassName = 'bisq.desktop.app.BisqAppMain'
|
||||
|
||||
tasks.withType(AbstractArchiveTask) {
|
||||
jar {
|
||||
preserveFileTimestamps = false
|
||||
reproducibleFileOrder = true
|
||||
}
|
||||
@ -432,22 +476,46 @@ configure(project(':desktop')) {
|
||||
sourceSets.main.resources.srcDirs += ['src/main/java'] // to copy fxml and css files
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile "net.glxn:qrgen:$qrgenVersion"
|
||||
compile "de.jensd:fontawesomefx:$fontawesomefxVersion"
|
||||
compile "de.jensd:fontawesomefx-commons:$fontawesomefxCommonsVersion"
|
||||
compile "de.jensd:fontawesomefx-materialdesignfont:$fontawesomefxMaterialdesignfontVersion"
|
||||
compile "com.google.guava:guava:$guavaVersion"
|
||||
compile "com.googlecode.jcsv:jcsv:$jcsvVersion"
|
||||
compile "com.jfoenix:jfoenix:$jfoenixVersion"
|
||||
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation project(':assets')
|
||||
implementation project(':common')
|
||||
implementation project(':proto')
|
||||
implementation project(':p2p')
|
||||
implementation project(':core')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
|
||||
testCompile "org.mockito:mockito-core:$mockitoVersion"
|
||||
testCompile "com.natpryce:make-it-easy:$easyVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "com.google.code.gson:gson:$gsonVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation "com.googlecode.jcsv:jcsv:$jcsvVersion"
|
||||
implementation "com.jfoenix:jfoenix:$jfoenixVersion"
|
||||
implementation "commons-io:commons-io:$ioVersion"
|
||||
implementation "de.jensd:fontawesomefx-commons:$fontawesomefxCommonsVersion"
|
||||
implementation "de.jensd:fontawesomefx-materialdesignfont:$fontawesomefxMaterialdesignfontVersion"
|
||||
implementation "de.jensd:fontawesomefx:$fontawesomefxVersion"
|
||||
implementation "net.glxn:qrgen:$qrgenVersion"
|
||||
implementation "org.apache.commons:commons-lang3:$langVersion"
|
||||
implementation "org.bouncycastle:bcpg-jdk15on:$bcVersion"
|
||||
implementation "org.fxmisc.easybind:easybind:$easybindVersion"
|
||||
implementation "org.jetbrains:annotations:$jetbrainsAnnotationsVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'bcprov-jdk15on')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'okhttp')
|
||||
exclude(module: 'okio')
|
||||
exclude(module: 'protobuf-java')
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testImplementation "com.natpryce:make-it-easy:$easyVersion"
|
||||
testImplementation "org.mockito:mockito-core:$mockitoVersion"
|
||||
}
|
||||
|
||||
test {
|
||||
@ -474,20 +542,30 @@ configure(project(':monitor')) {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
compile "ch.qos.logback:logback-core:$logbackVersion"
|
||||
compile "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
compile "com.google.guava:guava:$guavaVersion"
|
||||
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation project(':assets')
|
||||
implementation project(':common')
|
||||
implementation project(':core')
|
||||
implementation project(':p2p')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
|
||||
testCompile "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testCompile "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("com.github.bisq-network.netlayer:tor.external:$netlayerVersion") {
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.github.bisq-network.netlayer:tor.native:$netlayerVersion") {
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testRuntime("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,6 +573,8 @@ configure(project(':monitor')) {
|
||||
configure(project(':pricenode')) {
|
||||
apply plugin: "org.springframework.boot"
|
||||
|
||||
mainClassName = 'bisq.price.Main'
|
||||
|
||||
version = file("src/main/resources/version.txt").text.trim()
|
||||
|
||||
jar.manifest.attributes(
|
||||
@ -502,45 +582,44 @@ configure(project(':pricenode')) {
|
||||
"Implementation-Version": version)
|
||||
|
||||
dependencies {
|
||||
compile project(":core")
|
||||
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation project(":common")
|
||||
implementation project(":core")
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "com.google.code.gson:gson:$gsonVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "commons-codec:commons-codec:$codecVersion"
|
||||
implementation "org.apache.httpcomponents:httpcore:$httpcoreVersion"
|
||||
implementation("org.apache.httpcomponents:httpclient:$httpclientVersion") {
|
||||
exclude(module: 'commons-codec')
|
||||
}
|
||||
compile("org.knowm.xchange:xchange-bitbay:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-btcmarkets:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-binance:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-bitfinex:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-bitflyer:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-bitstamp:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-cexio:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-coinmate:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-coinmarketcap:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-coinone:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-exmo:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-hitbtc:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-huobi:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-independentreserve:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-kraken:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-luno:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-mercadobitcoin:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-paribu:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-poloniex:$knowmXchangeVersion")
|
||||
compile("org.knowm.xchange:xchange-quoine:$knowmXchangeVersion")
|
||||
compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
|
||||
compile("org.springframework.boot:spring-boot-starter-actuator")
|
||||
testCompile "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testCompile "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testRuntime("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation("org.knowm.xchange:xchange-binance:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-bitbay:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-bitfinex:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-bitflyer:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-bitstamp:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-btcmarkets:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-cexio:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-coinmarketcap:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-coinmate:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-coinone:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-exmo:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-hitbtc:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-huobi:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-independentreserve:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-kraken:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-luno:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-mercadobitcoin:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-paribu:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-poloniex:$knowmXchangeVersion")
|
||||
implementation("org.knowm.xchange:xchange-quoine:$knowmXchangeVersion")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
|
||||
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompile "org.mockito:mockito-core:$mockitoVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testImplementation "org.mockito:mockito-core:$mockitoVersion"
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
}
|
||||
|
||||
test {
|
||||
@ -565,17 +644,19 @@ configure(project(':relay')) {
|
||||
mainClassName = 'bisq.relay.RelayMain'
|
||||
|
||||
dependencies {
|
||||
compile project(':common')
|
||||
implementation "io.grpc:grpc-auth:$grpcVersion"
|
||||
compile "com.sparkjava:spark-core:$sparkVersion"
|
||||
compile "com.turo:pushy:$pushyVersion"
|
||||
implementation project(':common')
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation("com.google.firebase:firebase-admin:$firebaseVersion") {
|
||||
exclude(module: 'commons-logging')
|
||||
exclude(module: 'grpc-auth')
|
||||
exclude(module: 'httpclient')
|
||||
exclude(module: 'httpcore')
|
||||
exclude(module: 'grpc-auth')
|
||||
}
|
||||
compile "commons-codec:commons-codec:$codecVersion"
|
||||
implementation "com.sparkjava:spark-core:$sparkVersion"
|
||||
implementation "com.turo:pushy:$pushyVersion"
|
||||
implementation "commons-codec:commons-codec:$codecVersion"
|
||||
implementation "io.grpc:grpc-auth:$grpcVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,11 +667,17 @@ configure(project(':seednode')) {
|
||||
mainClassName = 'bisq.seednode.SeedNodeMain'
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
implementation project(':common')
|
||||
implementation project(':p2p')
|
||||
implementation project(':core')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompile "org.mockito:mockito-core:$mockitoVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
testImplementation "org.mockito:mockito-core:$mockitoVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,9 +686,15 @@ configure(project(':statsnode')) {
|
||||
mainClassName = 'bisq.statistics.StatisticsMain'
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation project(':common')
|
||||
implementation project(':p2p')
|
||||
implementation project(':core')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -609,33 +702,50 @@ configure(project(':daemon')) {
|
||||
mainClassName = 'bisq.daemon.app.BisqDaemonMain'
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
implementation project(':proto')
|
||||
implementation project(':common')
|
||||
implementation project(':p2p')
|
||||
implementation project(':core')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "com.google.code.gson:gson:$gsonVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation("io.grpc:grpc-protobuf:$grpcVersion") {
|
||||
implementation "org.apache.commons:commons-lang3:$langVersion"
|
||||
implementation "org.jetbrains:annotations:$jetbrainsAnnotationsVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'bcprov-jdk15on')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'okhttp')
|
||||
exclude(module: 'okio')
|
||||
exclude(module: 'protobuf-java')
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation("io.grpc:grpc-protobuf:$grpcVersion") {
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation("io.grpc:grpc-stub:$grpcVersion") {
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion") {
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
|
||||
testCompile "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testCompile "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testRuntime("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,12 +755,19 @@ configure(project(':inventory')) {
|
||||
mainClassName = 'bisq.inventory.InventoryMonitorMain'
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile "com.google.guava:guava:$guavaVersion"
|
||||
compile "com.sparkjava:spark-core:$sparkVersion"
|
||||
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation project(':common')
|
||||
implementation project(':p2p')
|
||||
implementation project(':core')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "com.sparkjava:spark-core:$sparkVersion"
|
||||
implementation "org.jetbrains:annotations:$jetbrainsAnnotationsVersion"
|
||||
implementation("com.google.inject:guice:$guiceVersion") {
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -716,37 +833,46 @@ configure(project(':apitest')) {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':proto')
|
||||
compile project(':common')
|
||||
compile project(':seednode')
|
||||
compile project(':desktop')
|
||||
compile project(':daemon')
|
||||
compile project(':cli')
|
||||
implementation "net.sf.jopt-simple:jopt-simple:$joptVersion"
|
||||
implementation project(':proto')
|
||||
implementation project(':common')
|
||||
implementation project(':core')
|
||||
implementation project(':seednode')
|
||||
implementation project(':desktop')
|
||||
implementation project(':daemon')
|
||||
implementation project(':cli')
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "com.google.code.gson:gson:$gsonVersion"
|
||||
implementation "com.google.guava:guava:$guavaVersion"
|
||||
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
implementation("io.grpc:grpc-protobuf:$grpcVersion") {
|
||||
implementation "net.sf.jopt-simple:jopt-simple:$joptVersion"
|
||||
implementation "org.apache.commons:commons-lang3:$langVersion"
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
|
||||
exclude(module: 'bcprov-jdk15on')
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'jsr305')
|
||||
exclude(module: 'okhttp')
|
||||
exclude(module: 'okio')
|
||||
exclude(module: 'protobuf-java')
|
||||
exclude(module: 'slf4j-api')
|
||||
}
|
||||
implementation("io.grpc:grpc-protobuf:$grpcVersion") {
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation("io.grpc:grpc-stub:$grpcVersion") {
|
||||
exclude(module: 'guava')
|
||||
exclude(module: 'animal-sniffer-annotations')
|
||||
exclude(module: 'guava')
|
||||
}
|
||||
implementation "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
implementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||
implementation "ch.qos.logback:logback-classic:$logbackVersion"
|
||||
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
testRuntime "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||
testRuntimeOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,7 +773,7 @@ public class AccountAgeWitnessService {
|
||||
filterManager.isNodeAddressBanned(dispute.getContract().getSellerNodeAddress()) ||
|
||||
filterManager.isCurrencyBanned(dispute.getContract().getOfferPayload().getCurrencyCode()) ||
|
||||
filterManager.isPaymentMethodBanned(
|
||||
PaymentMethod.getPaymentMethodById(dispute.getContract().getPaymentMethodId())) ||
|
||||
PaymentMethod.getPaymentMethod(dispute.getContract().getPaymentMethodId())) ||
|
||||
filterManager.arePeersPaymentAccountDataBanned(dispute.getContract().getBuyerPaymentAccountPayload()) ||
|
||||
filterManager.arePeersPaymentAccountDataBanned(
|
||||
dispute.getContract().getSellerPaymentAccountPayload()) ||
|
||||
|
@ -47,7 +47,7 @@ import java.lang.reflect.Type;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethodById;
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethod;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.lang.String.format;
|
||||
import static java.lang.System.getProperty;
|
||||
@ -148,7 +148,7 @@ public class PaymentAccountForm {
|
||||
* @return A uniquely named tmp file used to define new payment account details.
|
||||
*/
|
||||
public File getPaymentAccountForm(String paymentMethodId) {
|
||||
PaymentMethod paymentMethod = getPaymentMethodById(paymentMethodId);
|
||||
PaymentMethod paymentMethod = getPaymentMethod(paymentMethodId);
|
||||
File file = getTmpJsonFile(paymentMethodId);
|
||||
try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(checkNotNull(file), false), UTF_8)) {
|
||||
PaymentAccount paymentAccount = PaymentAccountFactory.getPaymentAccount(paymentMethod);
|
||||
@ -244,7 +244,7 @@ public class PaymentAccountForm {
|
||||
}
|
||||
|
||||
private Class<? extends PaymentAccount> getPaymentAccountClass(String paymentMethodId) {
|
||||
PaymentMethod paymentMethod = getPaymentMethodById(paymentMethodId);
|
||||
PaymentMethod paymentMethod = getPaymentMethod(paymentMethodId);
|
||||
return PaymentAccountFactory.getPaymentAccount(paymentMethod).getClass();
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ public class DtoNetworkInfo {
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum NetworkType {
|
||||
IPV4("ipv4"), IPV6("ipv6"), ONION("onion");
|
||||
IPV4("ipv4"), IPV6("ipv6"), ONION("onion"), I2P("i2p");
|
||||
|
||||
@Getter(onMethod_ = @JsonValue)
|
||||
private final String name;
|
||||
|
@ -109,6 +109,13 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
// See ProofOfWorkTest for more info.
|
||||
private final int powDifficulty;
|
||||
|
||||
// Added at v 1.8.0
|
||||
// BSQ fee gets updated in proposals repo (e.g. https://github.com/bisq-network/proposals/issues/345)
|
||||
private final long makerFeeBtc;
|
||||
private final long takerFeeBtc;
|
||||
private final long makerFeeBsq;
|
||||
private final long takerFeeBsq;
|
||||
|
||||
// After we have created the signature from the filter data we clone it and apply the signature
|
||||
static Filter cloneWithSig(Filter filter, String signatureAsBase64) {
|
||||
return new Filter(filter.getBannedOfferIds(),
|
||||
@ -140,7 +147,11 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
filter.isDisableMempoolValidation(),
|
||||
filter.isDisableApi(),
|
||||
filter.isDisablePowMessage(),
|
||||
filter.getPowDifficulty());
|
||||
filter.getPowDifficulty(),
|
||||
filter.getMakerFeeBtc(),
|
||||
filter.getTakerFeeBtc(),
|
||||
filter.getMakerFeeBsq(),
|
||||
filter.getTakerFeeBsq());
|
||||
}
|
||||
|
||||
// Used for signature verification as we created the sig without the signatureAsBase64 field we set it to null again
|
||||
@ -174,7 +185,11 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
filter.isDisableMempoolValidation(),
|
||||
filter.isDisableApi(),
|
||||
filter.isDisablePowMessage(),
|
||||
filter.getPowDifficulty());
|
||||
filter.getPowDifficulty(),
|
||||
filter.getMakerFeeBtc(),
|
||||
filter.getTakerFeeBtc(),
|
||||
filter.getMakerFeeBsq(),
|
||||
filter.getTakerFeeBsq());
|
||||
}
|
||||
|
||||
public Filter(List<String> bannedOfferIds,
|
||||
@ -203,7 +218,11 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
boolean disableMempoolValidation,
|
||||
boolean disableApi,
|
||||
boolean disablePowMessage,
|
||||
int powDifficulty) {
|
||||
int powDifficulty,
|
||||
long makerFeeBtc,
|
||||
long takerFeeBtc,
|
||||
long makerFeeBsq,
|
||||
long takerFeeBsq) {
|
||||
this(bannedOfferIds,
|
||||
nodeAddressesBannedFromTrading,
|
||||
bannedPaymentAccounts,
|
||||
@ -233,7 +252,11 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
disableMempoolValidation,
|
||||
disableApi,
|
||||
disablePowMessage,
|
||||
powDifficulty);
|
||||
powDifficulty,
|
||||
makerFeeBtc,
|
||||
takerFeeBtc,
|
||||
makerFeeBsq,
|
||||
takerFeeBsq);
|
||||
}
|
||||
|
||||
|
||||
@ -271,7 +294,11 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
boolean disableMempoolValidation,
|
||||
boolean disableApi,
|
||||
boolean disablePowMessage,
|
||||
int powDifficulty) {
|
||||
int powDifficulty,
|
||||
long makerFeeBtc,
|
||||
long takerFeeBtc,
|
||||
long makerFeeBsq,
|
||||
long takerFeeBsq) {
|
||||
this.bannedOfferIds = bannedOfferIds;
|
||||
this.nodeAddressesBannedFromTrading = nodeAddressesBannedFromTrading;
|
||||
this.bannedPaymentAccounts = bannedPaymentAccounts;
|
||||
@ -302,6 +329,10 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
this.disableApi = disableApi;
|
||||
this.disablePowMessage = disablePowMessage;
|
||||
this.powDifficulty = powDifficulty;
|
||||
this.makerFeeBtc = makerFeeBtc;
|
||||
this.takerFeeBtc = takerFeeBtc;
|
||||
this.makerFeeBsq = makerFeeBsq;
|
||||
this.takerFeeBsq = takerFeeBsq;
|
||||
|
||||
// ownerPubKeyBytes can be null when called from tests
|
||||
if (ownerPubKeyBytes != null) {
|
||||
@ -344,7 +375,11 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
.setDisableMempoolValidation(disableMempoolValidation)
|
||||
.setDisableApi(disableApi)
|
||||
.setDisablePowMessage(disablePowMessage)
|
||||
.setPowDifficulty(powDifficulty);
|
||||
.setPowDifficulty(powDifficulty)
|
||||
.setMakerFeeBtc(makerFeeBtc)
|
||||
.setTakerFeeBtc(takerFeeBtc)
|
||||
.setMakerFeeBsq(makerFeeBsq)
|
||||
.setTakerFeeBsq(takerFeeBsq);
|
||||
|
||||
Optional.ofNullable(signatureAsBase64).ifPresent(builder::setSignatureAsBase64);
|
||||
Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraData);
|
||||
@ -357,7 +392,6 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
.map(PaymentAccountFilter::fromProto)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
return new Filter(ProtoUtil.protocolStringListToList(proto.getBannedOfferIdsList()),
|
||||
ProtoUtil.protocolStringListToList(proto.getNodeAddressesBannedFromTradingList()),
|
||||
bannedPaymentAccountsList,
|
||||
@ -387,7 +421,11 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
proto.getDisableMempoolValidation(),
|
||||
proto.getDisableApi(),
|
||||
proto.getDisablePowMessage(),
|
||||
proto.getPowDifficulty()
|
||||
proto.getPowDifficulty(),
|
||||
proto.getMakerFeeBtc(),
|
||||
proto.getTakerFeeBtc(),
|
||||
proto.getMakerFeeBsq(),
|
||||
proto.getTakerFeeBsq()
|
||||
);
|
||||
}
|
||||
|
||||
@ -435,6 +473,10 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
|
||||
",\n disableApi=" + disableApi +
|
||||
",\n disablePowMessage=" + disablePowMessage +
|
||||
",\n powDifficulty=" + powDifficulty +
|
||||
",\n makerFeeBtc=" + makerFeeBtc +
|
||||
",\n takerFeeBtc=" + takerFeeBtc +
|
||||
",\n makerFeeBsq=" + makerFeeBsq +
|
||||
",\n takerFeeBsq=" + takerFeeBsq +
|
||||
"\n}";
|
||||
}
|
||||
}
|
||||
|
@ -314,13 +314,18 @@ public class FilterManager {
|
||||
}
|
||||
|
||||
public void removeInvalidFilters(Filter filter, String privKeyString) {
|
||||
log.info("Remove invalid filter {}", filter);
|
||||
setFilterSigningKey(privKeyString);
|
||||
String signatureAsBase64 = getSignature(Filter.cloneWithoutSig(filter));
|
||||
Filter filterWithSig = Filter.cloneWithSig(filter, signatureAsBase64);
|
||||
boolean result = p2PService.removeData(filterWithSig);
|
||||
if (!result) {
|
||||
log.warn("Could not remove filter {}", filter);
|
||||
// We can only remove the filter if it's our own filter
|
||||
if (Arrays.equals(filter.getOwnerPubKey().getEncoded(), keyRing.getSignatureKeyPair().getPublic().getEncoded())) {
|
||||
log.info("Remove invalid filter {}", filter);
|
||||
setFilterSigningKey(privKeyString);
|
||||
String signatureAsBase64 = getSignature(Filter.cloneWithoutSig(filter));
|
||||
Filter filterWithSig = Filter.cloneWithSig(filter, signatureAsBase64);
|
||||
boolean result = p2PService.removeData(filterWithSig);
|
||||
if (!result) {
|
||||
log.warn("Could not remove filter {}", filter);
|
||||
}
|
||||
} else {
|
||||
log.info("The invalid filter is not our own, so we cannot remove it from the network");
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,13 +528,13 @@ public class FilterManager {
|
||||
|
||||
if (currentFilter != null) {
|
||||
if (currentFilter.getCreationDate() > newFilter.getCreationDate()) {
|
||||
log.debug("We received a new filter from the network but the creation date is older than the " +
|
||||
log.info("We received a new filter from the network but the creation date is older than the " +
|
||||
"filter we have already. We ignore the new filter.");
|
||||
|
||||
addToInvalidFilters(newFilter);
|
||||
return;
|
||||
} else {
|
||||
log.debug("We received a new filter from the network and the creation date is newer than the " +
|
||||
log.info("We received a new filter from the network and the creation date is newer than the " +
|
||||
"filter we have already. We ignore the old filter.");
|
||||
addToInvalidFilters(currentFilter);
|
||||
}
|
||||
@ -580,7 +585,7 @@ public class FilterManager {
|
||||
|
||||
// We don't check for banned filter as we want to remove a banned filter anyway.
|
||||
|
||||
if (!filterProperty.get().equals(filter)) {
|
||||
if (filterProperty.get() != null && !filterProperty.get().equals(filter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -225,8 +225,15 @@ public class Offer implements NetworkPayload, PersistablePayload {
|
||||
return offerPayloadBase.getPrice();
|
||||
}
|
||||
|
||||
public void checkTradePriceTolerance(long takersTradePrice) throws TradePriceOutOfToleranceException,
|
||||
public void verifyTakersTradePrice(long takersTradePrice) throws TradePriceOutOfToleranceException,
|
||||
MarketPriceNotAvailableException, IllegalArgumentException {
|
||||
if (!isUseMarketBasedPrice()) {
|
||||
checkArgument(takersTradePrice == getFixedPrice(),
|
||||
"Takers price does not match offer price. " +
|
||||
"Takers price=" + takersTradePrice + "; offer price=" + getFixedPrice());
|
||||
return;
|
||||
}
|
||||
|
||||
Price tradePrice = Price.valueOf(getCurrencyCode(), takersTradePrice);
|
||||
Price offerPrice = getPrice();
|
||||
if (offerPrice == null)
|
||||
@ -340,7 +347,7 @@ public class Offer implements NetworkPayload, PersistablePayload {
|
||||
}
|
||||
|
||||
public PaymentMethod getPaymentMethod() {
|
||||
return PaymentMethod.getPaymentMethodById(offerPayloadBase.getPaymentMethodId());
|
||||
return PaymentMethod.getPaymentMethod(offerPayloadBase.getPaymentMethodId());
|
||||
}
|
||||
|
||||
// utils
|
||||
|
@ -685,7 +685,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
// Check also tradePrice to avoid failures after taker fee is paid caused by a too big difference
|
||||
// in trade price between the peers. Also here poor connectivity might cause market price API connection
|
||||
// losses and therefore an outdated market price.
|
||||
offer.checkTradePriceTolerance(request.getTakersTradePrice());
|
||||
offer.verifyTakersTradePrice(request.getTakersTradePrice());
|
||||
availabilityResult = AvailabilityResult.AVAILABLE;
|
||||
} catch (TradePriceOutOfToleranceException e) {
|
||||
log.warn("Trade price check failed because takers price is outside out tolerance.");
|
||||
|
@ -42,7 +42,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static bisq.core.payment.payload.PaymentMethod.TRANSFERWISE_ID;
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethodById;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@EqualsAndHashCode
|
||||
@ -113,7 +112,7 @@ public abstract class PaymentAccount implements PersistablePayload {
|
||||
ngnTwOptional.ifPresent(tradeCurrencies::remove);
|
||||
|
||||
try {
|
||||
PaymentAccount account = PaymentAccountFactory.getPaymentAccount(getPaymentMethodById(paymentMethodId));
|
||||
PaymentAccount account = PaymentAccountFactory.getPaymentAccount(PaymentMethod.getPaymentMethod(paymentMethodId));
|
||||
account.getTradeCurrencies().clear();
|
||||
account.setId(proto.getId());
|
||||
account.setCreationDate(proto.getCreationDate());
|
||||
|
@ -29,6 +29,7 @@ import org.bitcoinj.core.Coin;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -363,11 +364,16 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
||||
// API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static PaymentMethod getPaymentMethodById(String id) {
|
||||
public static PaymentMethod getPaymentMethod(String id) {
|
||||
return getActivePaymentMethod(id)
|
||||
.orElseGet(() -> new PaymentMethod(Res.get("shared.na")));
|
||||
}
|
||||
|
||||
// We look up only our active payment methods not retired ones.
|
||||
public static Optional<PaymentMethod> getActivePaymentMethod(String id) {
|
||||
return paymentMethods.stream()
|
||||
.filter(e -> e.getId().equals(id))
|
||||
.findFirst()
|
||||
.orElseGet(() -> new PaymentMethod(Res.get("shared.na")));
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public Coin getMaxTradeLimitAsCoin(String currencyCode) {
|
||||
@ -391,7 +397,9 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
||||
riskFactor = 8;
|
||||
else {
|
||||
riskFactor = 8;
|
||||
log.error("maxTradeLimit is not matching one of our default values. maxTradeLimit=" + Coin.valueOf(maxTradeLimit).toFriendlyString());
|
||||
log.warn("maxTradeLimit is not matching one of our default values. We use highest risk factor. " +
|
||||
"maxTradeLimit={}. PaymentMethod={}",
|
||||
Coin.valueOf(maxTradeLimit).toFriendlyString(), this);
|
||||
}
|
||||
|
||||
TradeLimits tradeLimits = TradeLimits.getINSTANCE();
|
||||
|
@ -93,7 +93,7 @@ public class MempoolService {
|
||||
|
||||
public void validateOfferMakerTx(OfferPayload offerPayload, Consumer<TxValidator> resultHandler) {
|
||||
validateOfferMakerTx(new TxValidator(daoStateService, offerPayload.getOfferFeePaymentTxId(), Coin.valueOf(offerPayload.getAmount()),
|
||||
offerPayload.isCurrencyForMakerFeeBtc()), resultHandler);
|
||||
offerPayload.isCurrencyForMakerFeeBtc(), offerPayload.getBlockHeightAtOfferCreation(), filterManager), resultHandler);
|
||||
}
|
||||
|
||||
public void validateOfferMakerTx(TxValidator txValidator, Consumer<TxValidator> resultHandler) {
|
||||
@ -107,7 +107,7 @@ public class MempoolService {
|
||||
|
||||
public void validateOfferTakerTx(Trade trade, Consumer<TxValidator> resultHandler) {
|
||||
validateOfferTakerTx(new TxValidator(daoStateService, trade.getTakerFeeTxId(), trade.getAmount(),
|
||||
trade.isCurrencyForTakerFeeBtc()), resultHandler);
|
||||
trade.isCurrencyForTakerFeeBtc(), filterManager), resultHandler);
|
||||
}
|
||||
|
||||
public void validateOfferTakerTx(TxValidator txValidator, Consumer<TxValidator> resultHandler) {
|
||||
@ -120,7 +120,7 @@ public class MempoolService {
|
||||
}
|
||||
|
||||
public void checkTxIsConfirmed(String txId, Consumer<TxValidator> resultHandler) {
|
||||
TxValidator txValidator = new TxValidator(daoStateService, txId);
|
||||
TxValidator txValidator = new TxValidator(daoStateService, txId, filterManager);
|
||||
if (!isServiceSupported()) {
|
||||
UserThread.runAfter(() -> resultHandler.accept(txValidator.endResult("mempool request not supported, bypassing", true)), 1);
|
||||
return;
|
||||
|
@ -19,8 +19,10 @@ package bisq.core.provider.mempool;
|
||||
|
||||
import bisq.core.dao.governance.param.Param;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.filter.FilterManager;
|
||||
|
||||
import bisq.common.util.Tuple2;
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
@ -31,7 +33,10 @@ import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@ -45,10 +50,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@Slf4j
|
||||
@Getter
|
||||
public class TxValidator {
|
||||
private static final Date USE_FEE_FROM_FILTER_ACTIVATION_DATE = Utilities.getUTCDate(2022, GregorianCalendar.JANUARY, 1);
|
||||
private final static double FEE_TOLERANCE = 0.95; // we expect fees to be at least 95% of target
|
||||
private final static long BLOCK_TOLERANCE = 599999L; // allow really old offers with weird fee addresses
|
||||
private final static long BLOCK_TOLERANCE = 599999; // allow really old offers with weird fee addresses
|
||||
|
||||
private final DaoStateService daoStateService;
|
||||
private final FilterManager filterManager;
|
||||
private long blockHeightAtOfferCreation; // Only set for maker.
|
||||
private final List<String> errorList;
|
||||
private final String txId;
|
||||
private Coin amount;
|
||||
@ -59,20 +67,41 @@ public class TxValidator {
|
||||
@Setter
|
||||
private String jsonTxt;
|
||||
|
||||
|
||||
public TxValidator(DaoStateService daoStateService, String txId, Coin amount, @Nullable Boolean isFeeCurrencyBtc) {
|
||||
public TxValidator(DaoStateService daoStateService,
|
||||
String txId,
|
||||
Coin amount,
|
||||
@Nullable Boolean isFeeCurrencyBtc,
|
||||
FilterManager filterManager) {
|
||||
this.daoStateService = daoStateService;
|
||||
this.txId = txId;
|
||||
this.amount = amount;
|
||||
this.isFeeCurrencyBtc = isFeeCurrencyBtc;
|
||||
this.filterManager = filterManager;
|
||||
this.errorList = new ArrayList<>();
|
||||
this.jsonTxt = "";
|
||||
}
|
||||
|
||||
public TxValidator(DaoStateService daoStateService, String txId) {
|
||||
public TxValidator(DaoStateService daoStateService,
|
||||
String txId,
|
||||
Coin amount,
|
||||
@Nullable Boolean isFeeCurrencyBtc,
|
||||
long blockHeightAtOfferCreation,
|
||||
FilterManager filterManager) {
|
||||
this.daoStateService = daoStateService;
|
||||
this.txId = txId;
|
||||
this.amount = amount;
|
||||
this.isFeeCurrencyBtc = isFeeCurrencyBtc;
|
||||
this.blockHeightAtOfferCreation = blockHeightAtOfferCreation;
|
||||
this.filterManager = filterManager;
|
||||
this.errorList = new ArrayList<>();
|
||||
this.jsonTxt = "";
|
||||
}
|
||||
|
||||
public TxValidator(DaoStateService daoStateService, String txId, FilterManager filterManager) {
|
||||
this.daoStateService = daoStateService;
|
||||
this.txId = txId;
|
||||
this.chainHeight = (long) daoStateService.getChainHeight();
|
||||
this.filterManager = filterManager;
|
||||
this.errorList = new ArrayList<>();
|
||||
this.jsonTxt = "";
|
||||
}
|
||||
@ -171,30 +200,52 @@ public class TxValidator {
|
||||
}
|
||||
long feeValue = jsonFeeValue.getAsLong();
|
||||
log.debug("BTC fee: {}", feeValue);
|
||||
Coin expectedFee = getFeeHistorical(tradeAmount,
|
||||
|
||||
Param minFeeParam = isMaker ? Param.MIN_MAKER_FEE_BTC : Param.MIN_TAKER_FEE_BTC;
|
||||
Coin expectedFee = calculateFee(tradeAmount,
|
||||
isMaker ? getMakerFeeRateBtc(blockHeight) : getTakerFeeRateBtc(blockHeight),
|
||||
isMaker ? Param.MIN_MAKER_FEE_BTC : Param.MIN_TAKER_FEE_BTC);
|
||||
double leniencyCalc = feeValue / (double) expectedFee.getValue();
|
||||
String description = "Expected BTC fee: " + expectedFee.toString() + " sats , actual fee paid: " + Coin.valueOf(feeValue).toString() + " sats";
|
||||
if (expectedFee.getValue() == feeValue) {
|
||||
minFeeParam);
|
||||
|
||||
Coin feeValueAsCoin = Coin.valueOf(feeValue);
|
||||
long expectedFeeAsLong = expectedFee.getValue();
|
||||
String description = "Expected BTC fee: " + expectedFee + " sats , actual fee paid: " +
|
||||
feeValueAsCoin + " sats";
|
||||
if (expectedFeeAsLong == feeValue) {
|
||||
log.debug("The fee matched what we expected");
|
||||
return true;
|
||||
} else if (expectedFee.getValue() < feeValue) {
|
||||
}
|
||||
|
||||
if (expectedFeeAsLong < feeValue) {
|
||||
log.info("The fee was more than what we expected: " + description);
|
||||
return true;
|
||||
} else if (leniencyCalc > FEE_TOLERANCE) {
|
||||
log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", FEE_TOLERANCE, leniencyCalc, description);
|
||||
}
|
||||
|
||||
double leniencyCalc = feeValue / (double) expectedFeeAsLong;
|
||||
if (leniencyCalc > FEE_TOLERANCE) {
|
||||
log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}",
|
||||
FEE_TOLERANCE, leniencyCalc, description);
|
||||
return true;
|
||||
} else if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue),
|
||||
isMaker ? Param.DEFAULT_MAKER_FEE_BTC : Param.DEFAULT_TAKER_FEE_BTC,
|
||||
isMaker ? Param.MIN_MAKER_FEE_BTC : Param.MIN_TAKER_FEE_BTC)) {
|
||||
}
|
||||
|
||||
Optional<Boolean> result = maybeCheckAgainstFeeFromFilter(tradeAmount,
|
||||
isMaker,
|
||||
feeValueAsCoin,
|
||||
minFeeParam,
|
||||
true,
|
||||
description);
|
||||
if (result.isPresent()) {
|
||||
return result.get();
|
||||
}
|
||||
|
||||
Param defaultFeeParam = isMaker ? Param.DEFAULT_MAKER_FEE_BTC : Param.DEFAULT_TAKER_FEE_BTC;
|
||||
if (feeExistsUsingDifferentDaoParam(tradeAmount, feeValueAsCoin, defaultFeeParam, minFeeParam)) {
|
||||
log.info("Leniency rule: the fee matches a different DAO parameter {}", description);
|
||||
return true;
|
||||
} else {
|
||||
String feeUnderpaidMessage = "UNDERPAID. " + description;
|
||||
errorList.add(feeUnderpaidMessage);
|
||||
log.info(feeUnderpaidMessage);
|
||||
}
|
||||
|
||||
String feeUnderpaidMessage = "UNDERPAID. " + description;
|
||||
errorList.add(feeUnderpaidMessage);
|
||||
log.info(feeUnderpaidMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -212,9 +263,10 @@ public class TxValidator {
|
||||
if (jsonVIn0Value == null || jsonFeeValue == null) {
|
||||
throw new JsonSyntaxException("vin/vout missing data");
|
||||
}
|
||||
Coin expectedFee = getFeeHistorical(tradeAmount,
|
||||
Param minFeeParam = isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ;
|
||||
Coin expectedFee = calculateFee(tradeAmount,
|
||||
isMaker ? getMakerFeeRateBsq(blockHeight) : getTakerFeeRateBsq(blockHeight),
|
||||
isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ);
|
||||
minFeeParam);
|
||||
long feeValue = jsonVIn0Value.getAsLong() - jsonFeeValue.getAsLong();
|
||||
// if the first output (BSQ) is greater than the first input (BSQ) include the second input (presumably BSQ)
|
||||
if (jsonFeeValue.getAsLong() > jsonVIn0Value.getAsLong()) {
|
||||
@ -225,27 +277,45 @@ public class TxValidator {
|
||||
feeValue += jsonVIn1Value.getAsLong();
|
||||
}
|
||||
log.debug("BURNT BSQ maker fee: {} BSQ ({} sats)", (double) feeValue / 100.0, feeValue);
|
||||
double leniencyCalc = feeValue / (double) expectedFee.getValue();
|
||||
long expectedFeeAsLong = expectedFee.getValue();
|
||||
String description = String.format("Expected fee: %.2f BSQ, actual fee paid: %.2f BSQ",
|
||||
(double) expectedFee.getValue() / 100.0, (double) feeValue / 100.0);
|
||||
if (expectedFee.getValue() == feeValue) {
|
||||
(double) expectedFeeAsLong / 100.0, (double) feeValue / 100.0);
|
||||
|
||||
if (expectedFeeAsLong == feeValue) {
|
||||
log.debug("The fee matched what we expected");
|
||||
return true;
|
||||
} else if (expectedFee.getValue() < feeValue) {
|
||||
}
|
||||
|
||||
if (expectedFeeAsLong < feeValue) {
|
||||
log.info("The fee was more than what we expected. " + description);
|
||||
return true;
|
||||
} else if (leniencyCalc > FEE_TOLERANCE) {
|
||||
}
|
||||
|
||||
double leniencyCalc = feeValue / (double) expectedFeeAsLong;
|
||||
if (leniencyCalc > FEE_TOLERANCE) {
|
||||
log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", FEE_TOLERANCE, leniencyCalc, description);
|
||||
return true;
|
||||
} else if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue),
|
||||
isMaker ? Param.DEFAULT_MAKER_FEE_BSQ : Param.DEFAULT_TAKER_FEE_BSQ,
|
||||
isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ)) {
|
||||
}
|
||||
Coin feeValueAsCoin = Coin.valueOf(feeValue);
|
||||
|
||||
Optional<Boolean> maybeTestFeeFromFilter = maybeCheckAgainstFeeFromFilter(tradeAmount,
|
||||
isMaker,
|
||||
feeValueAsCoin,
|
||||
minFeeParam,
|
||||
false,
|
||||
description);
|
||||
if (maybeTestFeeFromFilter.isPresent()) {
|
||||
return maybeTestFeeFromFilter.get();
|
||||
}
|
||||
|
||||
Param defaultFeeParam = isMaker ? Param.DEFAULT_MAKER_FEE_BSQ : Param.DEFAULT_TAKER_FEE_BSQ;
|
||||
if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), defaultFeeParam, minFeeParam)) {
|
||||
log.info("Leniency rule: the fee matches a different DAO parameter {}", description);
|
||||
return true;
|
||||
} else {
|
||||
errorList.add(description);
|
||||
log.info(description);
|
||||
}
|
||||
|
||||
errorList.add(description);
|
||||
log.info(description);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -299,10 +369,16 @@ public class TxValidator {
|
||||
// we want the block height applicable for calculating the appropriate expected trading fees
|
||||
// if the tx is not yet confirmed, use current block tip, if tx is confirmed use the block it was confirmed at.
|
||||
private long getBlockHeightForFeeCalculation(String jsonTxt) {
|
||||
// For the maker we set the blockHeightAtOfferCreation from the offer
|
||||
if (blockHeightAtOfferCreation > 0) {
|
||||
return blockHeightAtOfferCreation;
|
||||
}
|
||||
|
||||
long txBlockHeight = getTxBlockHeight(jsonTxt);
|
||||
if (txBlockHeight > 0) {
|
||||
return txBlockHeight;
|
||||
}
|
||||
|
||||
return daoStateService.getChainHeight();
|
||||
}
|
||||
|
||||
@ -329,7 +405,7 @@ public class TxValidator {
|
||||
return 0L; // in mempool, not confirmed yet
|
||||
}
|
||||
|
||||
private Coin getFeeHistorical(Coin amount, Coin feeRatePerBtc, Param minFeeParam) {
|
||||
private Coin calculateFee(Coin amount, Coin feeRatePerBtc, Param minFeeParam) {
|
||||
double feePerBtcAsDouble = (double) feeRatePerBtc.value;
|
||||
double amountAsDouble = amount != null ? (double) amount.value : 0;
|
||||
double btcAsDouble = (double) Coin.COIN.value;
|
||||
@ -355,17 +431,69 @@ public class TxValidator {
|
||||
return daoStateService.getParamValueAsCoin(Param.DEFAULT_TAKER_FEE_BTC, (int) blockHeight);
|
||||
}
|
||||
|
||||
private Optional<Boolean> maybeCheckAgainstFeeFromFilter(Coin tradeAmount,
|
||||
boolean isMaker,
|
||||
Coin feeValueAsCoin,
|
||||
Param minFeeParam,
|
||||
boolean isBtcFee,
|
||||
String description) {
|
||||
if (new Date().before(USE_FEE_FROM_FILTER_ACTIVATION_DATE)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return getFeeFromFilter(isMaker, isBtcFee)
|
||||
.map(feeFromFilter -> {
|
||||
boolean isValid = testWithFeeFromFilter(tradeAmount, feeValueAsCoin, feeFromFilter, minFeeParam);
|
||||
if (!isValid) {
|
||||
log.warn("Fee does not match fee from filter. Fee from filter={}. {}", feeFromFilter, description);
|
||||
}
|
||||
return isValid;
|
||||
});
|
||||
}
|
||||
|
||||
private Optional<Coin> getFeeFromFilter(boolean isMaker, boolean isBtcFee) {
|
||||
return Optional.ofNullable(filterManager.getFilter())
|
||||
.map(filter -> {
|
||||
Coin value;
|
||||
if (isMaker) {
|
||||
value = isBtcFee ?
|
||||
Coin.valueOf(filter.getMakerFeeBtc()) :
|
||||
Coin.valueOf(filter.getMakerFeeBsq());
|
||||
} else {
|
||||
value = isBtcFee ?
|
||||
Coin.valueOf(filter.getTakerFeeBtc()) :
|
||||
Coin.valueOf(filter.getTakerFeeBsq());
|
||||
}
|
||||
return value;
|
||||
})
|
||||
.filter(Coin::isPositive);
|
||||
}
|
||||
|
||||
private boolean testWithFeeFromFilter(Coin tradeAmount,
|
||||
Coin actualFeeValue,
|
||||
Coin feeFromFilter,
|
||||
Param minFeeParam) {
|
||||
long actualFeeAsLong = actualFeeValue.value;
|
||||
long feeFromFilterAsLong = calculateFee(tradeAmount, feeFromFilter, minFeeParam).value;
|
||||
double deviation = actualFeeAsLong / (double) feeFromFilterAsLong;
|
||||
// It can be that the filter has not been updated immediately after DAO param change, so we need a tolerance
|
||||
// Common change rate is 15-20%
|
||||
return deviation > 0.7;
|
||||
}
|
||||
|
||||
// implements leniency rule of accepting old DAO rate parameters: https://github.com/bisq-network/bisq/issues/5329#issuecomment-803223859
|
||||
// We iterate over all past dao param values and if one of those matches we consider it valid. That covers the non-in-sync cases.
|
||||
private boolean feeExistsUsingDifferentDaoParam(Coin tradeAmount, Coin actualFeeValue, Param defaultFeeParam, Param minFeeParam) {
|
||||
private boolean feeExistsUsingDifferentDaoParam(Coin tradeAmount,
|
||||
Coin actualFeeValue,
|
||||
Param defaultFeeParam,
|
||||
Param minFeeParam) {
|
||||
for (Coin daoHistoricalRate : daoStateService.getParamChangeList(defaultFeeParam)) {
|
||||
if (actualFeeValue.equals(getFeeHistorical(tradeAmount, daoHistoricalRate, minFeeParam))) {
|
||||
if (actualFeeValue.equals(calculateFee(tradeAmount, daoHistoricalRate, minFeeParam))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// finally check the default rate used when we ask for the fee rate at block height 0 (it is hard coded in the Param enum)
|
||||
Coin defaultRate = daoStateService.getParamValueAsCoin(defaultFeeParam, 0);
|
||||
return actualFeeValue.equals(getFeeHistorical(tradeAmount, defaultRate, minFeeParam));
|
||||
// Finally, check the default rate used when we ask for the fee rate at genesis block height (it is hard coded in the Param enum)
|
||||
Coin defaultRate = daoStateService.getParamValueAsCoin(defaultFeeParam, daoStateService.getGenesisBlockHeight());
|
||||
return actualFeeValue.equals(calculateFee(tradeAmount, defaultRate, minFeeParam));
|
||||
}
|
||||
|
||||
public TxValidator endResult(String title, boolean status) {
|
||||
|
@ -67,6 +67,17 @@ public final class DisputeResult implements NetworkPayload {
|
||||
PEER_WAS_LATE
|
||||
}
|
||||
|
||||
public enum PayoutSuggestion {
|
||||
UNKNOWN,
|
||||
BUYER_GETS_TRADE_AMOUNT,
|
||||
BUYER_GETS_TRADE_AMOUNT_PLUS_COMPENSATION,
|
||||
BUYER_GETS_TRADE_AMOUNT_MINUS_PENALTY,
|
||||
SELLER_GETS_TRADE_AMOUNT,
|
||||
SELLER_GETS_TRADE_AMOUNT_PLUS_COMPENSATION,
|
||||
SELLER_GETS_TRADE_AMOUNT_MINUS_PENALTY,
|
||||
CUSTOM_PAYOUT
|
||||
}
|
||||
|
||||
private final String tradeId;
|
||||
private final int traderId;
|
||||
@Setter
|
||||
@ -91,6 +102,10 @@ public final class DisputeResult implements NetworkPayload {
|
||||
private long closeDate;
|
||||
@Setter
|
||||
private boolean isLoserPublisher;
|
||||
@Setter
|
||||
private String payoutAdjustmentPercent = "";
|
||||
@Setter
|
||||
private PayoutSuggestion payoutSuggestion;
|
||||
|
||||
public DisputeResult(String tradeId, int traderId) {
|
||||
this.tradeId = tradeId;
|
||||
@ -111,7 +126,9 @@ public final class DisputeResult implements NetworkPayload {
|
||||
long sellerPayoutAmount,
|
||||
@Nullable byte[] arbitratorPubKey,
|
||||
long closeDate,
|
||||
boolean isLoserPublisher) {
|
||||
boolean isLoserPublisher,
|
||||
String payoutAdjustmentPercent,
|
||||
PayoutSuggestion payoutSuggestion) {
|
||||
this.tradeId = tradeId;
|
||||
this.traderId = traderId;
|
||||
this.winner = winner;
|
||||
@ -127,6 +144,8 @@ public final class DisputeResult implements NetworkPayload {
|
||||
this.arbitratorPubKey = arbitratorPubKey;
|
||||
this.closeDate = closeDate;
|
||||
this.isLoserPublisher = isLoserPublisher;
|
||||
this.payoutAdjustmentPercent = payoutAdjustmentPercent;
|
||||
this.payoutSuggestion = payoutSuggestion;
|
||||
}
|
||||
|
||||
|
||||
@ -149,7 +168,9 @@ public final class DisputeResult implements NetworkPayload {
|
||||
proto.getSellerPayoutAmount(),
|
||||
proto.getArbitratorPubKey().toByteArray(),
|
||||
proto.getCloseDate(),
|
||||
proto.getIsLoserPublisher());
|
||||
proto.getIsLoserPublisher(),
|
||||
proto.getPayoutAdjustmentPercent(),
|
||||
ProtoUtil.enumFromProto(DisputeResult.PayoutSuggestion.class, proto.getPayoutSuggestion().name()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -165,13 +186,15 @@ public final class DisputeResult implements NetworkPayload {
|
||||
.setBuyerPayoutAmount(buyerPayoutAmount)
|
||||
.setSellerPayoutAmount(sellerPayoutAmount)
|
||||
.setCloseDate(closeDate)
|
||||
.setIsLoserPublisher(isLoserPublisher);
|
||||
.setIsLoserPublisher(isLoserPublisher)
|
||||
.setPayoutAdjustmentPercent(payoutAdjustmentPercent);
|
||||
|
||||
Optional.ofNullable(arbitratorSignature).ifPresent(arbitratorSignature -> builder.setArbitratorSignature(ByteString.copyFrom(arbitratorSignature)));
|
||||
Optional.ofNullable(arbitratorPubKey).ifPresent(arbitratorPubKey -> builder.setArbitratorPubKey(ByteString.copyFrom(arbitratorPubKey)));
|
||||
Optional.ofNullable(winner).ifPresent(result -> builder.setWinner(protobuf.DisputeResult.Winner.valueOf(winner.name())));
|
||||
Optional.ofNullable(chatMessage).ifPresent(chatMessage ->
|
||||
builder.setChatMessage(chatMessage.toProtoNetworkEnvelope().getChatMessage()));
|
||||
Optional.ofNullable(payoutSuggestion).ifPresent(result -> builder.setPayoutSuggestion(protobuf.DisputeResult.PayoutSuggestion.valueOf(payoutSuggestion.name())));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@ -254,6 +277,8 @@ public final class DisputeResult implements NetworkPayload {
|
||||
",\n arbitratorPubKey=" + Utilities.bytesAsHexString(arbitratorPubKey) +
|
||||
",\n closeDate=" + closeDate +
|
||||
",\n isLoserPublisher=" + isLoserPublisher +
|
||||
",\n payoutAdjustmentPercent=" + payoutAdjustmentPercent +
|
||||
",\n payoutSuggestion=" + payoutSuggestion +
|
||||
"\n}";
|
||||
}
|
||||
}
|
||||
|
@ -919,8 +919,8 @@ public abstract class Trade extends TradeModel {
|
||||
}
|
||||
|
||||
public boolean isFundsLockedIn() {
|
||||
// If no deposit tx was published we have no funds locked in
|
||||
if (!isDepositPublished()) {
|
||||
// If no deposit tx was confirmed we have no funds locked in
|
||||
if (!isDepositConfirmed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ public class MakerProcessesInputsForDepositTxRequest extends TradeTask {
|
||||
Offer offer = checkNotNull(trade.getOffer(), "Offer must not be null");
|
||||
try {
|
||||
long takersTradePrice = request.getTradePrice();
|
||||
offer.checkTradePriceTolerance(takersTradePrice);
|
||||
offer.verifyTakersTradePrice(takersTradePrice);
|
||||
trade.setPriceAsLong(takersTradePrice);
|
||||
} catch (TradePriceOutOfToleranceException e) {
|
||||
failed(e.getMessage());
|
||||
|
@ -17,12 +17,14 @@
|
||||
|
||||
package bisq.core.trade.statistics;
|
||||
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.monetary.Altcoin;
|
||||
import bisq.core.monetary.AltcoinExchangeRate;
|
||||
import bisq.core.monetary.Price;
|
||||
import bisq.core.monetary.Volume;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.offer.bisq_v1.OfferPayload;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
import bisq.core.trade.model.bisq_v1.Trade;
|
||||
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
|
||||
import bisq.core.util.JsonUtil;
|
||||
@ -396,7 +398,7 @@ public final class TradeStatistics3 implements ProcessOncePersistableNetworkPayl
|
||||
refundAgent = null;
|
||||
}
|
||||
|
||||
public String getPaymentMethod() {
|
||||
public String getPaymentMethodId() {
|
||||
try {
|
||||
return PaymentMethodMapper.values()[Integer.parseInt(paymentMethod)].name();
|
||||
} catch (Throwable ignore) {
|
||||
@ -430,13 +432,29 @@ public final class TradeStatistics3 implements ProcessOncePersistableNetworkPayl
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
if (currency == null) {
|
||||
return false;
|
||||
}
|
||||
long maxTradeLimit = Coin.COIN.multiply(2).value;
|
||||
try {
|
||||
// We cover only active payment methods. Retired ones will not be found by getActivePaymentMethodById.
|
||||
String paymentMethodId = getPaymentMethodId();
|
||||
Optional<PaymentMethod> optionalPaymentMethod = PaymentMethod.getActivePaymentMethod(paymentMethodId);
|
||||
if (optionalPaymentMethod.isPresent()) {
|
||||
maxTradeLimit = optionalPaymentMethod.get().getMaxTradeLimitAsCoin(currency).value;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Error at isValid().", e);
|
||||
}
|
||||
return amount > 0 &&
|
||||
amount <= maxTradeLimit &&
|
||||
price > 0 &&
|
||||
date > 0 &&
|
||||
paymentMethod != null &&
|
||||
!paymentMethod.isEmpty() &&
|
||||
currency != null &&
|
||||
!currency.isEmpty();
|
||||
!currency.isEmpty() &&
|
||||
(CurrencyUtil.getCryptoCurrency(currency).isPresent() ||
|
||||
CurrencyUtil.getFiatCurrency(currency).isPresent());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,7 +52,7 @@ public final class TradeStatisticsForJson {
|
||||
|
||||
public TradeStatisticsForJson(TradeStatistics3 tradeStatistics) {
|
||||
this.currency = tradeStatistics.getCurrency();
|
||||
this.paymentMethod = tradeStatistics.getPaymentMethod();
|
||||
this.paymentMethod = tradeStatistics.getPaymentMethodId();
|
||||
this.tradePrice = tradeStatistics.getPrice();
|
||||
this.tradeAmount = tradeStatistics.getAmount();
|
||||
this.tradeDate = tradeStatistics.getDateAsLong();
|
||||
|
@ -2656,6 +2656,8 @@ disputeSummaryWindow.title=Summary
|
||||
disputeSummaryWindow.openDate=Ticket opening date
|
||||
disputeSummaryWindow.role=Trader's role
|
||||
disputeSummaryWindow.payout=Trade amount payout
|
||||
disputeSummaryWindow.payout.getsCompensation=BTC {0} gets trade amount plus compensation
|
||||
disputeSummaryWindow.payout.getsPenalty=BTC {0} gets trade amount minus penalty
|
||||
disputeSummaryWindow.payout.getsTradeAmount=BTC {0} gets trade amount payout
|
||||
disputeSummaryWindow.payout.getsAll=Max. payout to BTC {0}
|
||||
disputeSummaryWindow.payout.custom=Custom payout
|
||||
@ -2780,6 +2782,10 @@ filterWindow.disableApi=Disable API
|
||||
filterWindow.disableMempoolValidation=Disable Mempool Validation
|
||||
filterWindow.disablePowMessage=Disable messages requiring Proof of Work
|
||||
filterWindow.powDifficulty=Proof of work difficulty (BSQ swap offers)
|
||||
filterWindow.makerFeeBtc=Min. BTC maker fee (e.g. 0.001)
|
||||
filterWindow.takerFeeBtc=Min. BTC taker fee (e.g. 0.007)
|
||||
filterWindow.makerFeeBsq=Min. BSQ maker fee (e.g. 15.14)
|
||||
filterWindow.takerFeeBsq=Min. BSQ taker fee (e.g. 105.97)
|
||||
|
||||
offerDetailsWindow.minBtcAmount=Min. BTC amount
|
||||
offerDetailsWindow.min=(min. {0})
|
||||
@ -3417,7 +3423,7 @@ payment.swift.account=Account No. (or IBAN)
|
||||
payment.swift.use.intermediary=Use Intermediary Bank
|
||||
payment.swift.showPaymentInfo=Show Payment Information...
|
||||
payment.account.owner.address=Account owner address
|
||||
payment.transferwiseUsd.address= (must be US-based, consider using bank address)
|
||||
payment.transferwiseUsd.address=(must be US-based, consider using bank address)
|
||||
|
||||
payment.amazon.site=Buy giftcard at
|
||||
payment.ask=Ask in Trader Chat
|
||||
|
@ -65,7 +65,8 @@ import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethodById;
|
||||
import static bisq.core.payment.payload.PaymentMethod.getPaymentMethod;
|
||||
import static bisq.core.support.dispute.DisputeResult.PayoutSuggestion.UNKNOWN;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@ -213,7 +214,7 @@ public class AccountAgeWitnessServiceTest {
|
||||
0,
|
||||
null,
|
||||
now - 1,
|
||||
false));
|
||||
false, "", UNKNOWN));
|
||||
|
||||
// Filtermanager says nothing is filtered
|
||||
when(filterManager.isNodeAddressBanned(any())).thenReturn(false);
|
||||
@ -231,7 +232,7 @@ public class AccountAgeWitnessServiceTest {
|
||||
when(contract.getBuyerPaymentAccountPayload()).thenReturn(buyerPaymentAccountPayload);
|
||||
when(contract.getSellerPaymentAccountPayload()).thenReturn(sellerPaymentAccountPayload);
|
||||
when(contract.getOfferPayload()).thenReturn(mock(OfferPayload.class));
|
||||
List<TraderDataItem> items = service.getTraderPaymentAccounts(now, getPaymentMethodById(PaymentMethod.SEPA_ID), disputes);
|
||||
List<TraderDataItem> items = service.getTraderPaymentAccounts(now, getPaymentMethod(PaymentMethod.SEPA_ID), disputes);
|
||||
assertEquals(2, items.size());
|
||||
|
||||
// Setup a mocked arbitrator key
|
||||
|
@ -46,7 +46,7 @@ public class ReceiptValidatorTest {
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
verifyZeroInteractions(offer);
|
||||
verifyNoMoreInteractions(offer);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -19,6 +19,7 @@ package bisq.core.provider.mempool;
|
||||
|
||||
import bisq.core.dao.governance.param.Param;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.filter.FilterManager;
|
||||
import bisq.core.trade.DelayedPayoutAddressProvider;
|
||||
import bisq.core.util.FeeReceiverSelector;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
@ -204,7 +205,8 @@ public class TxValidatorTest {
|
||||
when(mockedDaoStateService.getParamValueAsCoin(Mockito.any(Param.class), Mockito.anyInt())).thenAnswer(mockGetFeeRate);
|
||||
when(mockedDaoStateService.getParamValueAsCoin(Mockito.any(Param.class), Mockito.anyString())).thenAnswer(mockGetParamValueAsCoin);
|
||||
when(mockedDaoStateService.getParamChangeList(Mockito.any())).thenAnswer(mockGetParamChangeList);
|
||||
TxValidator txValidator = new TxValidator(mockedDaoStateService, txId, Coin.valueOf(amount), isCurrencyForMakerFeeBtc);
|
||||
FilterManager filterManager = mock(FilterManager.class);
|
||||
TxValidator txValidator = new TxValidator(mockedDaoStateService, txId, Coin.valueOf(amount), isCurrencyForMakerFeeBtc, filterManager);
|
||||
return txValidator;
|
||||
} catch (RuntimeException ignore) {
|
||||
// If input format is not as expected we ignore entry
|
||||
|
@ -71,6 +71,10 @@ public class UserPayloadModelVOTest {
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0));
|
||||
|
||||
vo.setRegisteredArbitrator(ArbitratorTest.getArbitratorMock());
|
||||
|
@ -132,6 +132,10 @@ public class FeeReceiverSelectorTest {
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,6 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
private EventHandler<MouseEvent> dividerMouseDraggedEventHandler;
|
||||
private final StringProperty fromProperty = new SimpleStringProperty();
|
||||
private final StringProperty toProperty = new SimpleStringProperty();
|
||||
private boolean dataApplied;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -569,6 +568,8 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
long ts2 = System.currentTimeMillis();
|
||||
updateChartAfterDataChange();
|
||||
log.debug("updateChartAfterDataChange took {}", System.currentTimeMillis() - ts2);
|
||||
|
||||
onDataApplied();
|
||||
});
|
||||
}
|
||||
|
||||
@ -776,21 +777,13 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
}
|
||||
|
||||
protected void mapToUserThread(Runnable command) {
|
||||
UserThread.execute(() -> {
|
||||
command.run();
|
||||
onDataApplied();
|
||||
});
|
||||
UserThread.execute(command);
|
||||
}
|
||||
|
||||
// For the async handling we need to wait until we get the data applied and then still delay a bit otherwise
|
||||
// the UI does not get rendered at first start
|
||||
protected void onDataApplied() {
|
||||
if (!dataApplied) {
|
||||
dataApplied = true;
|
||||
UserThread.execute(() -> {
|
||||
applyTimeLineNavigationLabels();
|
||||
updateTimeLinePositions();
|
||||
});
|
||||
// Once we have data applied we need to call initBoundsForTimelineNavigation again
|
||||
if (model.upperBound.longValue() == 0) {
|
||||
initBoundsForTimelineNavigation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,8 +247,9 @@ public abstract class ChartViewModel<T extends ChartDataModel> extends Activatab
|
||||
private Tuple2<Double, Double> getMinMax(List<XYChart.Data<Number, Number>> chartData) {
|
||||
long min = Long.MAX_VALUE, max = 0;
|
||||
for (XYChart.Data<Number, ?> data : chartData) {
|
||||
min = Math.min(data.getXValue().longValue(), min);
|
||||
max = Math.max(data.getXValue().longValue(), max);
|
||||
long value = data.getXValue().longValue();
|
||||
min = Math.min(value, min);
|
||||
max = Math.max(value, max);
|
||||
}
|
||||
return new Tuple2<>((double) min, (double) max);
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ public class MarketView extends ActivatableView<TabPane, Void> {
|
||||
.append("Price: ").append(FormattingUtils.formatPrice(tradeStatistics3.getTradePrice())).append("\n")
|
||||
.append("Amount: ").append(formatter.formatCoin(tradeStatistics3.getTradeAmount())).append("\n")
|
||||
.append("Volume: ").append(VolumeUtil.formatVolume(tradeStatistics3.getTradeVolume())).append("\n")
|
||||
.append("Payment method: ").append(Res.get(tradeStatistics3.getPaymentMethod())).append("\n")
|
||||
.append("Payment method: ").append(Res.get(tradeStatistics3.getPaymentMethodId())).append("\n")
|
||||
.append("ReferralID: ").append(tradeStatistics3.getExtraDataMap().get(OfferPayload.REFERRAL_ID));
|
||||
return sb.toString();
|
||||
})
|
||||
|
@ -83,7 +83,7 @@ public class TradeStatistics3ListItem {
|
||||
|
||||
public String getPaymentMethodString() {
|
||||
if (paymentMethodString == null) {
|
||||
paymentMethodString = tradeStatistics3 != null ? Res.get(tradeStatistics3.getPaymentMethod()) : "";
|
||||
paymentMethodString = tradeStatistics3 != null ? Res.get(tradeStatistics3.getPaymentMethodId()) : "";
|
||||
}
|
||||
return paymentMethodString;
|
||||
}
|
||||
|
@ -113,7 +113,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
private ToggleGroup tradeAmountToggleGroup, reasonToggleGroup;
|
||||
private DisputeResult disputeResult;
|
||||
private RadioButton buyerGetsTradeAmountRadioButton, sellerGetsTradeAmountRadioButton,
|
||||
buyerGetsAllRadioButton, sellerGetsAllRadioButton, customRadioButton;
|
||||
buyerGetsCompensationRadioButton, sellerGetsCompensationRadioButton,
|
||||
buyerGetsTradeAmountMinusPenaltyRadioButton, sellerGetsTradeAmountMinusPenaltyRadioButton, customRadioButton;
|
||||
private RadioButton reasonWasBugRadioButton, reasonWasUsabilityIssueRadioButton,
|
||||
reasonProtocolViolationRadioButton, reasonNoReplyRadioButton, reasonWasScamRadioButton,
|
||||
reasonWasOtherRadioButton, reasonWasBankRadioButton, reasonWasOptionTradeRadioButton,
|
||||
@ -126,13 +127,13 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
private Label delayedPayoutTxStatus;
|
||||
private TextArea summaryNotesTextArea;
|
||||
|
||||
private ChangeListener<Boolean> customRadioButtonSelectedListener;
|
||||
private ChangeListener<Boolean> customRadioButtonSelectedListener, buyerGetsTradeAmountSelectedListener, sellerGetsTradeAmountSelectedListener;
|
||||
private ChangeListener<Toggle> reasonToggleSelectionListener;
|
||||
private InputTextField buyerPayoutAmountInputTextField, sellerPayoutAmountInputTextField;
|
||||
private InputTextField buyerPayoutAmountInputTextField, sellerPayoutAmountInputTextField, compensationOrPenalty;
|
||||
private ChangeListener<Boolean> buyerPayoutAmountListener, sellerPayoutAmountListener;
|
||||
private CheckBox isLoserPublisherCheckBox;
|
||||
private ChangeListener<Toggle> tradeAmountToggleGroupListener;
|
||||
|
||||
private ChangeListener<String> compensationOrPenaltyListener;
|
||||
private boolean updatingUi = false;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public API
|
||||
@ -189,6 +190,12 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
if (customRadioButton != null)
|
||||
customRadioButton.selectedProperty().removeListener(customRadioButtonSelectedListener);
|
||||
|
||||
if (buyerGetsTradeAmountRadioButton != null)
|
||||
buyerGetsTradeAmountRadioButton.selectedProperty().removeListener(buyerGetsTradeAmountSelectedListener);
|
||||
|
||||
if (sellerGetsTradeAmountRadioButton != null)
|
||||
sellerGetsTradeAmountRadioButton.selectedProperty().removeListener(sellerGetsTradeAmountSelectedListener);
|
||||
|
||||
if (tradeAmountToggleGroup != null)
|
||||
tradeAmountToggleGroup.selectedToggleProperty().removeListener(tradeAmountToggleGroupListener);
|
||||
|
||||
@ -210,7 +217,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
@Override
|
||||
protected void createGridPane() {
|
||||
super.createGridPane();
|
||||
gridPane.setPadding(new Insets(35, 40, 30, 40));
|
||||
gridPane.setPadding(new Insets(35, 40, 0, 40));
|
||||
gridPane.getStyleClass().add("grid-pane");
|
||||
gridPane.getColumnConstraints().get(0).setHalignment(HPos.LEFT);
|
||||
gridPane.setPrefWidth(width);
|
||||
@ -232,6 +239,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
addTradeAmountPayoutControls();
|
||||
addPayoutAmountTextFields();
|
||||
addReasonControls();
|
||||
applyDisputeResultToUiControls();
|
||||
|
||||
boolean applyPeersDisputeResult = peersDisputeOptional.isPresent() && peersDisputeOptional.get().isClosed();
|
||||
if (applyPeersDisputeResult) {
|
||||
@ -239,21 +247,26 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
DisputeResult peersDisputeResult = peersDisputeOptional.get().getDisputeResultProperty().get();
|
||||
disputeResult.setBuyerPayoutAmount(peersDisputeResult.getBuyerPayoutAmount());
|
||||
disputeResult.setSellerPayoutAmount(peersDisputeResult.getSellerPayoutAmount());
|
||||
disputeResult.setPayoutAdjustmentPercent(peersDisputeResult.getPayoutAdjustmentPercent());
|
||||
disputeResult.setPayoutSuggestion(peersDisputeResult.getPayoutSuggestion());
|
||||
disputeResult.setWinner(peersDisputeResult.getWinner());
|
||||
disputeResult.setLoserPublisher(peersDisputeResult.isLoserPublisher());
|
||||
disputeResult.setReason(peersDisputeResult.getReason());
|
||||
disputeResult.setSummaryNotes(peersDisputeResult.summaryNotesProperty().get());
|
||||
|
||||
buyerGetsTradeAmountRadioButton.setDisable(true);
|
||||
buyerGetsAllRadioButton.setDisable(true);
|
||||
buyerGetsCompensationRadioButton.setDisable(true);
|
||||
buyerGetsTradeAmountMinusPenaltyRadioButton.setDisable(true);
|
||||
sellerGetsTradeAmountRadioButton.setDisable(true);
|
||||
sellerGetsAllRadioButton.setDisable(true);
|
||||
sellerGetsCompensationRadioButton.setDisable(true);
|
||||
sellerGetsTradeAmountMinusPenaltyRadioButton.setDisable(true);
|
||||
customRadioButton.setDisable(true);
|
||||
|
||||
buyerPayoutAmountInputTextField.setDisable(true);
|
||||
sellerPayoutAmountInputTextField.setDisable(true);
|
||||
compensationOrPenalty.setDisable(true);
|
||||
buyerPayoutAmountInputTextField.setEditable(false);
|
||||
sellerPayoutAmountInputTextField.setEditable(false);
|
||||
compensationOrPenalty.setEditable(false);
|
||||
|
||||
reasonWasBugRadioButton.setDisable(true);
|
||||
reasonWasUsabilityIssueRadioButton.setDisable(true);
|
||||
@ -267,14 +280,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
reasonWasWrongSenderAccountRadioButton.setDisable(true);
|
||||
reasonWasPeerWasLateRadioButton.setDisable(true);
|
||||
reasonWasTradeAlreadySettledRadioButton.setDisable(true);
|
||||
|
||||
isLoserPublisherCheckBox.setDisable(true);
|
||||
isLoserPublisherCheckBox.setSelected(peersDisputeResult.isLoserPublisher());
|
||||
|
||||
applyPayoutAmounts(tradeAmountToggleGroup.selectedToggleProperty().get());
|
||||
applyTradeAmountRadioButtonStates();
|
||||
} else {
|
||||
isLoserPublisherCheckBox.setSelected(false);
|
||||
applyDisputeResultToUiControls();
|
||||
}
|
||||
|
||||
setReasonRadioButtonState();
|
||||
@ -328,41 +334,51 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
}
|
||||
|
||||
private void addTradeAmountPayoutControls() {
|
||||
buyerGetsTradeAmountRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsTradeAmount",
|
||||
Res.get("shared.buyer")));
|
||||
buyerGetsAllRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsAll",
|
||||
Res.get("shared.buyer")));
|
||||
sellerGetsTradeAmountRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsTradeAmount",
|
||||
Res.get("shared.seller")));
|
||||
sellerGetsAllRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsAll",
|
||||
Res.get("shared.seller")));
|
||||
buyerGetsTradeAmountRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsTradeAmount", Res.get("shared.buyer")));
|
||||
buyerGetsCompensationRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsCompensation", Res.get("shared.buyer")));
|
||||
buyerGetsTradeAmountMinusPenaltyRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsPenalty", Res.get("shared.buyer")));
|
||||
sellerGetsTradeAmountRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsTradeAmount", Res.get("shared.seller")));
|
||||
sellerGetsCompensationRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsCompensation", Res.get("shared.seller")));
|
||||
sellerGetsTradeAmountMinusPenaltyRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.getsPenalty", Res.get("shared.seller")));
|
||||
customRadioButton = new AutoTooltipRadioButton(Res.get("disputeSummaryWindow.payout.custom"));
|
||||
|
||||
VBox radioButtonPane = new VBox();
|
||||
radioButtonPane.setSpacing(10);
|
||||
radioButtonPane.getChildren().addAll(buyerGetsTradeAmountRadioButton, buyerGetsAllRadioButton,
|
||||
sellerGetsTradeAmountRadioButton, sellerGetsAllRadioButton,
|
||||
radioButtonPane.getChildren().addAll(buyerGetsTradeAmountRadioButton, buyerGetsCompensationRadioButton,
|
||||
buyerGetsTradeAmountMinusPenaltyRadioButton, sellerGetsTradeAmountRadioButton, sellerGetsCompensationRadioButton, sellerGetsTradeAmountMinusPenaltyRadioButton,
|
||||
customRadioButton);
|
||||
|
||||
addTopLabelWithVBox(gridPane, ++rowIndex, Res.get("disputeSummaryWindow.payout"), radioButtonPane, 0);
|
||||
|
||||
tradeAmountToggleGroup = new ToggleGroup();
|
||||
buyerGetsTradeAmountRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
buyerGetsAllRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
buyerGetsCompensationRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
buyerGetsTradeAmountMinusPenaltyRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
sellerGetsTradeAmountRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
sellerGetsAllRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
sellerGetsCompensationRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
sellerGetsTradeAmountMinusPenaltyRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
customRadioButton.setToggleGroup(tradeAmountToggleGroup);
|
||||
|
||||
tradeAmountToggleGroupListener = (observable, oldValue, newValue) -> applyPayoutAmounts(newValue);
|
||||
tradeAmountToggleGroupListener = (observable, oldValue, newValue) -> applyUpdateFromUi(newValue);
|
||||
tradeAmountToggleGroup.selectedToggleProperty().addListener(tradeAmountToggleGroupListener);
|
||||
|
||||
buyerPayoutAmountListener = (observable, oldValue, newValue) -> applyCustomAmounts(buyerPayoutAmountInputTextField, oldValue, newValue);
|
||||
sellerPayoutAmountListener = (observable, oldValue, newValue) -> applyCustomAmounts(sellerPayoutAmountInputTextField, oldValue, newValue);
|
||||
|
||||
buyerGetsTradeAmountSelectedListener = (observable, oldValue, newValue) -> {
|
||||
compensationOrPenalty.setEditable(!newValue);
|
||||
};
|
||||
buyerGetsTradeAmountRadioButton.selectedProperty().addListener(buyerGetsTradeAmountSelectedListener);
|
||||
|
||||
sellerGetsTradeAmountSelectedListener = (observable, oldValue, newValue) -> {
|
||||
compensationOrPenalty.setEditable(!newValue);
|
||||
};
|
||||
sellerGetsTradeAmountRadioButton.selectedProperty().addListener(sellerGetsTradeAmountSelectedListener);
|
||||
|
||||
customRadioButtonSelectedListener = (observable, oldValue, newValue) -> {
|
||||
buyerPayoutAmountInputTextField.setEditable(newValue);
|
||||
sellerPayoutAmountInputTextField.setEditable(newValue);
|
||||
|
||||
compensationOrPenalty.setEditable(!newValue);
|
||||
if (newValue) {
|
||||
buyerPayoutAmountInputTextField.focusedProperty().addListener(buyerPayoutAmountListener);
|
||||
sellerPayoutAmountInputTextField.focusedProperty().addListener(sellerPayoutAmountListener);
|
||||
@ -379,7 +395,6 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
|
||||
if (sellerPayoutAmountInputTextField != null && sellerPayoutAmountListener != null)
|
||||
sellerPayoutAmountInputTextField.focusedProperty().removeListener(sellerPayoutAmountListener);
|
||||
|
||||
}
|
||||
|
||||
private boolean isPayoutAmountValid() {
|
||||
@ -486,15 +501,26 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
sellerPayoutAmountInputTextField.setPromptText(Res.get("disputeSummaryWindow.payoutAmount.seller"));
|
||||
sellerPayoutAmountInputTextField.setEditable(false);
|
||||
|
||||
isLoserPublisherCheckBox = new AutoTooltipCheckBox(Res.get("disputeSummaryWindow.payoutAmount.invert"));
|
||||
compensationOrPenalty = new InputTextField();
|
||||
compensationOrPenalty.setPromptText("Comp|Penalty percent");
|
||||
compensationOrPenalty.setLabelFloat(true);
|
||||
HBox hBoxPenalty = new HBox(compensationOrPenalty);
|
||||
HBox hBoxPayouts = new HBox(buyerPayoutAmountInputTextField, sellerPayoutAmountInputTextField);
|
||||
hBoxPayouts.setSpacing(15);
|
||||
|
||||
VBox vBox = new VBox();
|
||||
vBox.setSpacing(15);
|
||||
vBox.getChildren().addAll(buyerPayoutAmountInputTextField, sellerPayoutAmountInputTextField, isLoserPublisherCheckBox);
|
||||
GridPane.setMargin(vBox, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
|
||||
vBox.setSpacing(25);
|
||||
vBox.getChildren().addAll(hBoxPenalty, hBoxPayouts);
|
||||
GridPane.setMargin(vBox, new Insets(80, 50, 50, 50));
|
||||
GridPane.setRowIndex(vBox, rowIndex);
|
||||
GridPane.setColumnIndex(vBox, 1);
|
||||
gridPane.getChildren().add(vBox);
|
||||
|
||||
compensationOrPenaltyListener = (observable, oldValue, newValue) -> {
|
||||
applyUpdateFromUi(tradeAmountToggleGroup.selectedToggleProperty().get());
|
||||
};
|
||||
|
||||
compensationOrPenalty.textProperty().addListener(compensationOrPenaltyListener);
|
||||
}
|
||||
|
||||
private void addReasonControls() {
|
||||
@ -628,7 +654,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
Res.get("disputeSummaryWindow.summaryNotes"), summaryNotesTextArea, 0);
|
||||
GridPane.setColumnSpan(topLabelWithVBox.second, 2);
|
||||
|
||||
summaryNotesTextArea.setPrefHeight(50);
|
||||
summaryNotesTextArea.setPrefHeight(160);
|
||||
summaryNotesTextArea.textProperty().bindBidirectional(disputeResult.summaryNotesProperty());
|
||||
}
|
||||
|
||||
@ -833,7 +859,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
}
|
||||
|
||||
boolean isRefundAgent = disputeManager instanceof RefundManager;
|
||||
disputeResult.setLoserPublisher(isLoserPublisherCheckBox.isSelected());
|
||||
disputeResult.setLoserPublisher(false); // field no longer used per pazza / leo816
|
||||
disputeResult.setCloseDate(new Date());
|
||||
dispute.setDisputeResult(disputeResult);
|
||||
dispute.setIsClosed();
|
||||
@ -911,88 +937,136 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
// Controller
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void applyPayoutAmounts(Toggle selectedTradeAmountToggle) {
|
||||
if (selectedTradeAmountToggle != customRadioButton && selectedTradeAmountToggle != null) {
|
||||
applyPayoutAmountsToDisputeResult(selectedTradeAmountToggle);
|
||||
applyTradeAmountRadioButtonStates();
|
||||
}
|
||||
private boolean isMediationDispute() {
|
||||
return getDisputeManager(dispute) instanceof MediationManager;
|
||||
}
|
||||
|
||||
private void applyPayoutAmountsToDisputeResult(Toggle selectedTradeAmountToggle) {
|
||||
// called when a radio button or amount box ui control is changed
|
||||
private void applyUpdateFromUi(Toggle selectedTradeAmountToggle) {
|
||||
if (updatingUi || selectedTradeAmountToggle == null) {
|
||||
return;
|
||||
}
|
||||
applyUiControlsToDisputeResult(selectedTradeAmountToggle);
|
||||
applyDisputeResultToUiControls();
|
||||
}
|
||||
|
||||
private void applyUiControlsToDisputeResult(Toggle selectedTradeAmountToggle) {
|
||||
Contract contract = dispute.getContract();
|
||||
Offer offer = new Offer(contract.getOfferPayload());
|
||||
Coin buyerSecurityDeposit = offer.getBuyerSecurityDeposit();
|
||||
Coin sellerSecurityDeposit = offer.getSellerSecurityDeposit();
|
||||
Coin tradeAmount = contract.getTradeAmount();
|
||||
|
||||
boolean isMediationDispute = getDisputeManager(dispute) instanceof MediationManager;
|
||||
Coin totalPot = tradeAmount.add(buyerSecurityDeposit).add(sellerSecurityDeposit);
|
||||
// At mediation we require a min. payout to the losing party to keep incentive for the trader to accept the
|
||||
// mediated payout. For Refund agent cases we do not have that restriction.
|
||||
Coin minRefundAtDispute = isMediationDispute ? Restrictions.getMinRefundAtMediatedDispute() : Coin.ZERO;
|
||||
Coin maxPayoutAmount = tradeAmount
|
||||
.add(buyerSecurityDeposit)
|
||||
.add(sellerSecurityDeposit)
|
||||
.subtract(minRefundAtDispute);
|
||||
Coin minRefundAtDispute = isMediationDispute() ? Restrictions.getMinRefundAtMediatedDispute() : Coin.ZERO;
|
||||
|
||||
Coin penalizedPortionOfTradeAmount = Coin.ZERO;
|
||||
try {
|
||||
disputeResult.setPayoutAdjustmentPercent(compensationOrPenalty.getText().replaceAll("[^0-9]", ""));
|
||||
double percentPenalty = ParsingUtils.parsePercentStringToDouble(disputeResult.getPayoutAdjustmentPercent());
|
||||
penalizedPortionOfTradeAmount = Coin.valueOf((long) (contract.getTradeAmount().getValue() * percentPenalty));
|
||||
} catch (NumberFormatException | NullPointerException e) {
|
||||
log.warn(e.toString());
|
||||
}
|
||||
|
||||
if (selectedTradeAmountToggle == buyerGetsTradeAmountRadioButton) {
|
||||
disputeResult.setPayoutSuggestion(DisputeResult.PayoutSuggestion.BUYER_GETS_TRADE_AMOUNT);
|
||||
disputeResult.setBuyerPayoutAmount(tradeAmount.add(buyerSecurityDeposit));
|
||||
disputeResult.setSellerPayoutAmount(sellerSecurityDeposit);
|
||||
disputeResult.setWinner(DisputeResult.Winner.BUYER);
|
||||
} else if (selectedTradeAmountToggle == buyerGetsAllRadioButton) {
|
||||
disputeResult.setBuyerPayoutAmount(maxPayoutAmount);
|
||||
disputeResult.setSellerPayoutAmount(minRefundAtDispute);
|
||||
disputeResult.setWinner(DisputeResult.Winner.BUYER);
|
||||
disputeResult.setPayoutAdjustmentPercent("");
|
||||
} else if (selectedTradeAmountToggle == sellerGetsTradeAmountRadioButton) {
|
||||
disputeResult.setPayoutSuggestion(DisputeResult.PayoutSuggestion.SELLER_GETS_TRADE_AMOUNT);
|
||||
disputeResult.setBuyerPayoutAmount(buyerSecurityDeposit);
|
||||
disputeResult.setSellerPayoutAmount(tradeAmount.add(sellerSecurityDeposit));
|
||||
disputeResult.setWinner(DisputeResult.Winner.SELLER);
|
||||
} else if (selectedTradeAmountToggle == sellerGetsAllRadioButton) {
|
||||
disputeResult.setBuyerPayoutAmount(minRefundAtDispute);
|
||||
disputeResult.setSellerPayoutAmount(maxPayoutAmount);
|
||||
disputeResult.setWinner(DisputeResult.Winner.SELLER);
|
||||
disputeResult.setPayoutAdjustmentPercent("");
|
||||
} else if (selectedTradeAmountToggle == buyerGetsTradeAmountMinusPenaltyRadioButton) {
|
||||
disputeResult.setPayoutSuggestion(DisputeResult.PayoutSuggestion.BUYER_GETS_TRADE_AMOUNT_MINUS_PENALTY);
|
||||
Coin buyerPayout = tradeAmount.add(offer.getBuyerSecurityDeposit()).subtract(penalizedPortionOfTradeAmount);
|
||||
disputeResult.setBuyerPayoutAmount(buyerPayout);
|
||||
disputeResult.setSellerPayoutAmount(totalPot.subtract(buyerPayout));
|
||||
} else if (selectedTradeAmountToggle == sellerGetsTradeAmountMinusPenaltyRadioButton) {
|
||||
disputeResult.setPayoutSuggestion(DisputeResult.PayoutSuggestion.SELLER_GETS_TRADE_AMOUNT_MINUS_PENALTY);
|
||||
Coin sellerPayout = tradeAmount.add(offer.getBuyerSecurityDeposit()).subtract(penalizedPortionOfTradeAmount);
|
||||
disputeResult.setSellerPayoutAmount(sellerPayout);
|
||||
disputeResult.setBuyerPayoutAmount(totalPot.subtract(sellerPayout));
|
||||
} else if (selectedTradeAmountToggle == buyerGetsCompensationRadioButton) {
|
||||
disputeResult.setPayoutSuggestion(DisputeResult.PayoutSuggestion.BUYER_GETS_TRADE_AMOUNT_PLUS_COMPENSATION);
|
||||
Coin buyerPayout = tradeAmount.add(offer.getBuyerSecurityDeposit()).add(penalizedPortionOfTradeAmount);
|
||||
disputeResult.setBuyerPayoutAmount(buyerPayout);
|
||||
disputeResult.setSellerPayoutAmount(totalPot.subtract(buyerPayout));
|
||||
} else if (selectedTradeAmountToggle == sellerGetsCompensationRadioButton) {
|
||||
disputeResult.setPayoutSuggestion(DisputeResult.PayoutSuggestion.SELLER_GETS_TRADE_AMOUNT_PLUS_COMPENSATION);
|
||||
Coin sellerPayout = tradeAmount.add(offer.getSellerSecurityDeposit()).add(penalizedPortionOfTradeAmount);
|
||||
disputeResult.setSellerPayoutAmount(sellerPayout);
|
||||
disputeResult.setBuyerPayoutAmount(totalPot.subtract(sellerPayout));
|
||||
} else {
|
||||
disputeResult.setPayoutSuggestion(DisputeResult.PayoutSuggestion.CUSTOM_PAYOUT);
|
||||
disputeResult.setPayoutAdjustmentPercent("");
|
||||
}
|
||||
|
||||
buyerPayoutAmountInputTextField.setText(formatter.formatCoin(disputeResult.getBuyerPayoutAmount()));
|
||||
sellerPayoutAmountInputTextField.setText(formatter.formatCoin(disputeResult.getSellerPayoutAmount()));
|
||||
// enforce rule that we cannot pay out less than minRefundAtDispute
|
||||
if (disputeResult.getBuyerPayoutAmount().isLessThan(minRefundAtDispute)) {
|
||||
disputeResult.setBuyerPayoutAmount(minRefundAtDispute);
|
||||
disputeResult.setSellerPayoutAmount(totalPot.subtract(minRefundAtDispute));
|
||||
} else if (disputeResult.getSellerPayoutAmount().isLessThan(minRefundAtDispute)) {
|
||||
disputeResult.setSellerPayoutAmount(minRefundAtDispute);
|
||||
disputeResult.setBuyerPayoutAmount(totalPot.subtract(minRefundAtDispute));
|
||||
}
|
||||
|
||||
// winner is the one who receives most from the multisig, or if equal, the buyer.
|
||||
// (winner is used to decide who publishes the tx)
|
||||
disputeResult.setWinner(disputeResult.getSellerPayoutAmount().isLessThan(disputeResult.getBuyerPayoutAmount()) ?
|
||||
DisputeResult.Winner.BUYER : DisputeResult.Winner.BUYER);
|
||||
}
|
||||
|
||||
private void applyTradeAmountRadioButtonStates() {
|
||||
Contract contract = dispute.getContract();
|
||||
Offer offer = new Offer(contract.getOfferPayload());
|
||||
Coin buyerSecurityDeposit = offer.getBuyerSecurityDeposit();
|
||||
Coin sellerSecurityDeposit = offer.getSellerSecurityDeposit();
|
||||
Coin tradeAmount = contract.getTradeAmount();
|
||||
|
||||
Coin buyerPayoutAmount = disputeResult.getBuyerPayoutAmount();
|
||||
Coin sellerPayoutAmount = disputeResult.getSellerPayoutAmount();
|
||||
|
||||
buyerPayoutAmountInputTextField.setText(formatter.formatCoin(buyerPayoutAmount));
|
||||
sellerPayoutAmountInputTextField.setText(formatter.formatCoin(sellerPayoutAmount));
|
||||
|
||||
boolean isMediationDispute = getDisputeManager(dispute) instanceof MediationManager;
|
||||
// At mediation we require a min. payout to the losing party to keep incentive for the trader to accept the
|
||||
// mediated payout. For Refund agent cases we do not have that restriction.
|
||||
Coin minRefundAtDispute = isMediationDispute ? Restrictions.getMinRefundAtMediatedDispute() : Coin.ZERO;
|
||||
Coin maxPayoutAmount = tradeAmount
|
||||
.add(buyerSecurityDeposit)
|
||||
.add(sellerSecurityDeposit)
|
||||
.subtract(minRefundAtDispute);
|
||||
|
||||
if (buyerPayoutAmount.equals(tradeAmount.add(buyerSecurityDeposit)) &&
|
||||
sellerPayoutAmount.equals(sellerSecurityDeposit)) {
|
||||
private void applyDisputeResultToUiControls() {
|
||||
updatingUi = true;
|
||||
buyerPayoutAmountInputTextField.setText(formatter.formatCoin(disputeResult.getBuyerPayoutAmount()));
|
||||
sellerPayoutAmountInputTextField.setText(formatter.formatCoin(disputeResult.getSellerPayoutAmount()));
|
||||
compensationOrPenalty.setText(disputeResult.getPayoutAdjustmentPercent());
|
||||
if (disputeResult.getPayoutSuggestion() == DisputeResult.PayoutSuggestion.BUYER_GETS_TRADE_AMOUNT) {
|
||||
buyerGetsTradeAmountRadioButton.setSelected(true);
|
||||
} else if (buyerPayoutAmount.equals(maxPayoutAmount) &&
|
||||
sellerPayoutAmount.equals(minRefundAtDispute)) {
|
||||
buyerGetsAllRadioButton.setSelected(true);
|
||||
} else if (sellerPayoutAmount.equals(tradeAmount.add(sellerSecurityDeposit))
|
||||
&& buyerPayoutAmount.equals(buyerSecurityDeposit)) {
|
||||
} else if (disputeResult.getPayoutSuggestion() == DisputeResult.PayoutSuggestion.SELLER_GETS_TRADE_AMOUNT) {
|
||||
sellerGetsTradeAmountRadioButton.setSelected(true);
|
||||
} else if (sellerPayoutAmount.equals(maxPayoutAmount)
|
||||
&& buyerPayoutAmount.equals(minRefundAtDispute)) {
|
||||
sellerGetsAllRadioButton.setSelected(true);
|
||||
} else {
|
||||
} else if (disputeResult.getPayoutSuggestion() == DisputeResult.PayoutSuggestion.BUYER_GETS_TRADE_AMOUNT_PLUS_COMPENSATION) {
|
||||
buyerGetsCompensationRadioButton.setSelected(true);
|
||||
} else if (disputeResult.getPayoutSuggestion() == DisputeResult.PayoutSuggestion.SELLER_GETS_TRADE_AMOUNT_PLUS_COMPENSATION) {
|
||||
sellerGetsCompensationRadioButton.setSelected(true);
|
||||
} else if (disputeResult.getPayoutSuggestion() == DisputeResult.PayoutSuggestion.BUYER_GETS_TRADE_AMOUNT_MINUS_PENALTY) {
|
||||
buyerGetsTradeAmountMinusPenaltyRadioButton.setSelected(true);
|
||||
} else if (disputeResult.getPayoutSuggestion() == DisputeResult.PayoutSuggestion.SELLER_GETS_TRADE_AMOUNT_MINUS_PENALTY) {
|
||||
sellerGetsTradeAmountMinusPenaltyRadioButton.setSelected(true);
|
||||
} else if (disputeResult.getPayoutSuggestion() == DisputeResult.PayoutSuggestion.CUSTOM_PAYOUT) {
|
||||
customRadioButton.setSelected(true);
|
||||
} else {
|
||||
// the option was not set, this will apply to older records before PayoutSuggestion was persisted
|
||||
// what it used to do was infer the option based on the payout amounts
|
||||
Contract contract = dispute.getContract();
|
||||
Offer offer = new Offer(contract.getOfferPayload());
|
||||
Coin buyerSecurityDeposit = offer.getBuyerSecurityDeposit();
|
||||
Coin sellerSecurityDeposit = offer.getSellerSecurityDeposit();
|
||||
Coin tradeAmount = contract.getTradeAmount();
|
||||
Coin totalPot = tradeAmount.add(buyerSecurityDeposit).add(sellerSecurityDeposit);
|
||||
Coin minRefundAtDispute = isMediationDispute() ? Restrictions.getMinRefundAtMediatedDispute() : Coin.ZERO;
|
||||
Coin maxPayoutAmount = totalPot.subtract(minRefundAtDispute);
|
||||
if (disputeResult.getBuyerPayoutAmount().equals(tradeAmount.add(buyerSecurityDeposit)) &&
|
||||
disputeResult.getSellerPayoutAmount().equals(sellerSecurityDeposit)) {
|
||||
buyerGetsTradeAmountRadioButton.setSelected(true);
|
||||
} else if (disputeResult.getBuyerPayoutAmount().equals(maxPayoutAmount) &&
|
||||
disputeResult.getSellerPayoutAmount().equals(minRefundAtDispute)) {
|
||||
buyerGetsCompensationRadioButton.setSelected(true);
|
||||
} else if (disputeResult.getSellerPayoutAmount().equals(tradeAmount.add(sellerSecurityDeposit))
|
||||
&& disputeResult.getBuyerPayoutAmount().equals(buyerSecurityDeposit)) {
|
||||
sellerGetsTradeAmountRadioButton.setSelected(true);
|
||||
} else if (disputeResult.getSellerPayoutAmount().equals(maxPayoutAmount)
|
||||
&& disputeResult.getBuyerPayoutAmount().equals(minRefundAtDispute)) {
|
||||
sellerGetsCompensationRadioButton.setSelected(true);
|
||||
} else {
|
||||
customRadioButton.setSelected(true);
|
||||
}
|
||||
}
|
||||
updatingUi = false;
|
||||
}
|
||||
|
||||
private void checkDelayedPayoutTransaction() {
|
||||
@ -1016,3 +1090,4 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,17 @@ import bisq.core.filter.Filter;
|
||||
import bisq.core.filter.FilterManager;
|
||||
import bisq.core.filter.PaymentAccountFilter;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.util.FormattingUtils;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
import bisq.core.util.coin.BsqFormatter;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.app.DevEnv;
|
||||
import bisq.common.config.Config;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import javax.inject.Named;
|
||||
@ -63,13 +69,19 @@ import static bisq.desktop.util.FormBuilder.addTopLabelInputTextField;
|
||||
|
||||
public class FilterWindow extends Overlay<FilterWindow> {
|
||||
private final FilterManager filterManager;
|
||||
private final BsqFormatter bsqFormatter;
|
||||
private final CoinFormatter btcFormatter;
|
||||
private final boolean useDevPrivilegeKeys;
|
||||
private ScrollPane scrollPane;
|
||||
|
||||
@Inject
|
||||
public FilterWindow(FilterManager filterManager,
|
||||
BsqFormatter bsqFormatter,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
|
||||
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
|
||||
this.filterManager = filterManager;
|
||||
this.bsqFormatter = bsqFormatter;
|
||||
this.btcFormatter = btcFormatter;
|
||||
this.useDevPrivilegeKeys = useDevPrivilegeKeys;
|
||||
type = Type.Attention;
|
||||
}
|
||||
@ -178,6 +190,14 @@ public class FilterWindow extends Overlay<FilterWindow> {
|
||||
InputTextField powDifficultyTF = addInputTextField(gridPane, ++rowIndex,
|
||||
Res.get("filterWindow.powDifficulty"));
|
||||
powDifficultyTF.setText("0");
|
||||
InputTextField makerFeeBtcTF = addInputTextField(gridPane, ++rowIndex,
|
||||
Res.get("filterWindow.makerFeeBtc"));
|
||||
InputTextField takerFeeBtcTF = addInputTextField(gridPane, ++rowIndex,
|
||||
Res.get("filterWindow.takerFeeBtc"));
|
||||
InputTextField makerFeeBsqTF = addInputTextField(gridPane, ++rowIndex,
|
||||
Res.get("filterWindow.makerFeeBsq"));
|
||||
InputTextField takerFeeBsqTF = addInputTextField(gridPane, ++rowIndex,
|
||||
Res.get("filterWindow.takerFeeBsq"));
|
||||
|
||||
Filter filter = filterManager.getDevFilter();
|
||||
if (filter != null) {
|
||||
@ -207,6 +227,11 @@ public class FilterWindow extends Overlay<FilterWindow> {
|
||||
disableApiCheckBox.setSelected(filter.isDisableApi());
|
||||
disablePowMessage.setSelected(filter.isDisablePowMessage());
|
||||
powDifficultyTF.setText(String.valueOf(filter.getPowDifficulty()));
|
||||
|
||||
makerFeeBtcTF.setText(btcFormatter.formatCoin(Coin.valueOf(filter.getMakerFeeBtc())));
|
||||
takerFeeBtcTF.setText(btcFormatter.formatCoin(Coin.valueOf(filter.getTakerFeeBtc())));
|
||||
makerFeeBsqTF.setText(bsqFormatter.formatBSQSatoshis(filter.getMakerFeeBsq()));
|
||||
takerFeeBsqTF.setText(bsqFormatter.formatBSQSatoshis(filter.getTakerFeeBsq()));
|
||||
}
|
||||
|
||||
Button removeFilterMessageButton = new AutoTooltipButton(Res.get("filterWindow.remove"));
|
||||
@ -244,7 +269,11 @@ public class FilterWindow extends Overlay<FilterWindow> {
|
||||
disableMempoolValidationCheckBox.isSelected(),
|
||||
disableApiCheckBox.isSelected(),
|
||||
disablePowMessage.isSelected(),
|
||||
Integer.parseInt(powDifficultyTF.getText())
|
||||
Integer.parseInt(powDifficultyTF.getText()),
|
||||
ParsingUtils.parseToCoin(makerFeeBtcTF.getText(), btcFormatter).value,
|
||||
ParsingUtils.parseToCoin(takerFeeBtcTF.getText(), btcFormatter).value,
|
||||
ParsingUtils.parseToCoin(makerFeeBsqTF.getText(), bsqFormatter).value,
|
||||
ParsingUtils.parseToCoin(takerFeeBsqTF.getText(), bsqFormatter).value
|
||||
);
|
||||
|
||||
// We remove first the old filter
|
||||
|
@ -72,6 +72,7 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
||||
private boolean editOpenOfferViewOpen;
|
||||
private OpenOffer openOffer;
|
||||
private OpenOffersView openOffersView;
|
||||
private int initialTabCount = 0;
|
||||
|
||||
@Inject
|
||||
public PortfolioView(CachingViewLoader viewLoader, Navigation navigation, FailedTradesManager failedTradesManager) {
|
||||
@ -82,6 +83,7 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
initialTabCount = root.getTabs().size();
|
||||
root.setTabClosingPolicy(TabPane.TabClosingPolicy.ALL_TABS);
|
||||
failedTradesTab.setClosable(false);
|
||||
|
||||
@ -151,10 +153,10 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
||||
@Override
|
||||
protected void activate() {
|
||||
failedTradesManager.getObservableList().addListener((ListChangeListener<Trade>) c -> {
|
||||
if (failedTradesManager.getObservableList().size() > 0 && root.getTabs().size() == 3)
|
||||
if (failedTradesManager.getObservableList().size() > 0 && root.getTabs().size() == initialTabCount)
|
||||
root.getTabs().add(failedTradesTab);
|
||||
});
|
||||
if (failedTradesManager.getObservableList().size() > 0 && root.getTabs().size() == 3)
|
||||
if (failedTradesManager.getObservableList().size() > 0 && root.getTabs().size() == initialTabCount)
|
||||
root.getTabs().add(failedTradesTab);
|
||||
|
||||
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package bisq.desktop.util;
|
||||
|
||||
import bisq.core.locale.GlobalSettings;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.monetary.Volume;
|
||||
import bisq.core.offer.Offer;
|
||||
@ -32,7 +33,8 @@ public class DisplayUtilsTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Locale.setDefault(new Locale("en", "US"));
|
||||
Locale.setDefault(Locale.US);
|
||||
GlobalSettings.setLocale(Locale.US);
|
||||
Res.setBaseCurrencyCode("BTC");
|
||||
Res.setBaseCurrencyName("Bitcoin");
|
||||
}
|
||||
|
2814
gradle/verification-metadata.xml
Normal file
2814
gradle/verification-metadata.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,89 +0,0 @@
|
||||
// To update the `dependencyVerification` block below (we don't add local bisq modules and org.openjfx libraries as
|
||||
// those cause problems):
|
||||
//
|
||||
// 1. Remove the block entirely
|
||||
// 2. Replace the block with the following command:
|
||||
//
|
||||
// ./gradlew -q calculateChecksums | grep -v 'bisq:\|org.openjfx:' >> gradle/witness/gradle-witness.gradle
|
||||
//
|
||||
// 3. Run `git diff` to verify that expected hashes have changed
|
||||
// 4. Commit the changes
|
||||
//
|
||||
// Note: The checksums are SHA-256.
|
||||
//
|
||||
// See https://github.com/signalapp/gradle-witness#using-witness for further details.
|
||||
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'aopalliance:aopalliance:0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08',
|
||||
'ch.qos.logback:logback-classic:86a0268c3c96888d4e49d8a754b5b2173286aee100559e803efcbb0df676c66e',
|
||||
'ch.qos.logback:logback-core:58738067842476feeae5768e832cd36a0e40ce41576ba5739c3632d376bd8c86',
|
||||
'com.fasterxml.jackson.core:jackson-annotations:203cefdfa6c81e6aa84e11f292f29ca97344a3c3bc0293abea065cd837592873',
|
||||
'com.fasterxml.jackson.core:jackson-core:cc899cb6eae0c80b87d590eea86528797369cc4feb7b79463207d6bb18f0c257',
|
||||
'com.fasterxml.jackson.core:jackson-databind:f2ca3c28ebded59c98447d51afe945323df961540af66a063c015597af936aa0',
|
||||
'com.github.JesusMcCloud:jtorctl:389d61b1b5a85eb2f23c582c3913ede49f80c9f2b553e4762382c836270e57e5',
|
||||
'com.github.bisq-network.netlayer:tor.external:45daf9b30f753c49b62cf56226539e824886ce1ff430e03dbef1bddff919cbfc',
|
||||
'com.github.bisq-network.netlayer:tor.native:ebb37e76fa14461be1ab2750daa3f8e5b78c8ff0d2adb72832ca0d38a1fb8f0d',
|
||||
'com.github.bisq-network.netlayer:tor:48b097d756bf1221a2fe7f9bfd4ec6c505719502997d87cc18d912d4323e59d3',
|
||||
'com.github.bisq-network.tor-binary:tor-binary-geoip:5a55df3a5bed0aa57165e9bae9ecda8b14d5e85b97dd1a266fa77602fbdaec54',
|
||||
'com.github.bisq-network.tor-binary:tor-binary-linux32:fe8b0ddb1c109b453adf9b055e067be04b6ca4cda9d2b33c875b99d2092f0eae',
|
||||
'com.github.bisq-network.tor-binary:tor-binary-linux64:7f58d31dd684b2e361e2980ba23922cadd5d9d8f8dbab9b3a2c6737741b21f7e',
|
||||
'com.github.bisq-network.tor-binary:tor-binary-macos:a23802ff66d4ac01366ebe712879e2f51df960572dc34db269588da87453a70d',
|
||||
'com.github.bisq-network.tor-binary:tor-binary-windows:8e0dee7429228aa0c9f7a36f40f303a016ed8dfb40fea77382f7076c13fc27f1',
|
||||
'com.github.bisq-network:bitcoinj:eccd3b5250d40ac3147d0e087e856ebaa8665720351b802d30ac53cf17b559c5',
|
||||
'com.github.bisq-network:jsonrpc4j:842b4a660440ef53cd436da2e21c3e1fed939b620a3fc7542307deb3e77fdeb6',
|
||||
'com.github.ravn:jsocks:3c71600af027b2b6d4244e4ad14d98ff2352a379410daebefff5d8cd48d742a4',
|
||||
'com.google.android:annotations:ba734e1e84c09d615af6a09d33034b4f0442f8772dec120efb376d86a565ae15',
|
||||
'com.google.api.grpc:proto-google-common-protos:bd60cd7a423b00fb824c27bdd0293aaf4781be1daba6ed256311103fb4b84108',
|
||||
'com.google.code.findbugs:jsr305:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.code.gson:gson:233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81',
|
||||
'com.google.errorprone:error_prone_annotations:baf7d6ea97ce606c53e11b6854ba5f2ce7ef5c24dddf0afa18d1260bd25b002c',
|
||||
'com.google.guava:failureaccess:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
|
||||
'com.google.guava:guava:fc3aa363ad87223d1fbea584eee015a862150f6d34c71f24dc74088a635f08ef',
|
||||
'com.google.guava:listenablefuture:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
|
||||
'com.google.inject:guice:3bae18be3e0f0940375d1ebdd2f3b84d87ae16026ae663b2f5d4667fe5b04036',
|
||||
'com.google.j2objc:j2objc-annotations:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||
'com.google.protobuf:protobuf-java:161d7d61a8cb3970891c299578702fd079646e032329d6c2cabf998d191437c9',
|
||||
'com.google.zxing:core:11aae8fd974ab25faa8208be50468eb12349cd239e93e7c797377fa13e381729',
|
||||
'com.google.zxing:javase:0ec23e2ec12664ddd6347c8920ad647bb3b9da290f897a88516014b56cc77eb9',
|
||||
'com.googlecode.jcsv:jcsv:73ca7d715e90c8d2c2635cc284543b038245a34f70790660ed590e157b8714a2',
|
||||
'com.jfoenix:jfoenix:8060235fec5eb49617ec8d81d379e8c945f6cc722d0645e97190045100de2084',
|
||||
'commons-codec:commons-codec:61f7a3079e92b9fdd605238d0295af5fd11ac411a0a0af48deace1f6c5ffa072',
|
||||
'commons-io:commons-io:f877d304660ac2a142f3865badfc971dec7ed73c747c7f8d5d2f5139ca736513',
|
||||
'commons-logging:commons-logging:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636',
|
||||
'de.jensd:fontawesomefx-commons:5539bb3335ecb822dbf928546f57766eeb9f1516cc1417a064b5709629612149',
|
||||
'de.jensd:fontawesomefx-materialdesignfont:dbad8dfdd1c85e298d5bbae25b2399aec9e85064db57b2427d10f3815aa98752',
|
||||
'de.jensd:fontawesomefx:73bacc991a0a6f5cf0f911767c8db161e0949dbca61e8371eb4342e3da96887b',
|
||||
'io.github.microutils:kotlin-logging:4992504fd3c6ecdf9ed10874b9508e758bb908af9e9d7af19a61e9afb6b7e27a',
|
||||
'io.grpc:grpc-api:a269094009588213ab5386a6fb92426b8056a130b2653d3b4e59e971f2f1ef08',
|
||||
'io.grpc:grpc-context:f4c8f878c320f6fb56c1c14692618f6df8253314b556176e32727afbc5921a73',
|
||||
'io.grpc:grpc-core:d67fa113fd9cc45a02710f9c41dda9c15191448c14e9e96fcc21839a41345d4c',
|
||||
'io.grpc:grpc-netty-shaded:9edfd45da473d2efbb5683fc3eaf1857e82d2148033d82dd558a7ac38731ea33',
|
||||
'io.grpc:grpc-protobuf-lite:9ba9aaa3e6997a04c707793c25e3ec88c6bad86f8d6f6b8b7a1a0c33ea2429d8',
|
||||
'io.grpc:grpc-protobuf:454dae7e246dac25526ed5b795d97a5dafedd3cc2042cfc810f02051d7d3e3cb',
|
||||
'io.grpc:grpc-stub:1532e291c0e9fd8230a6416c8ebbd902d99c7e2760241ae638ea761aa3dd5f43',
|
||||
'io.opencensus:opencensus-api:8e2cb0f6391d8eb0a1bcd01e7748883f0033b1941754f4ed3f19d2c3e4276fc8',
|
||||
'io.opencensus:opencensus-contrib-grpc-metrics:29fc79401082301542cab89d7054d2f0825f184492654c950020553ef4ff0ef8',
|
||||
'io.perfmark:perfmark-api:b734ba2149712409a44eabdb799f64768578fee0defe1418bb108fe32ea43e1a',
|
||||
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'net.glxn:qrgen:c85d9d8512d91e8ad11fe56259a7825bd50ce0245447e236cf168d1b17591882',
|
||||
'net.jcip:jcip-annotations:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||
'net.sf.jopt-simple:jopt-simple:df26cc58f235f477db07f753ba5a3ab243ebe5789d9f89ecf68dd62ea9a66c28',
|
||||
'org.apache.commons:commons-compress:5f2df1e467825e4cac5996d44890c4201c000b43c0b23cffc0782d28a0beb9b0',
|
||||
'org.apache.commons:commons-lang3:4ee380259c068d1dbe9e84ab52186f2acd65de067ec09beff731fca1697fdb16',
|
||||
'org.apache.httpcomponents:httpclient:bc5f065aba5dd815ee559dd24d9bcb797fb102ff9cfa036f5091ebc529bd3b93',
|
||||
'org.apache.httpcomponents:httpcore:e06e89d40943245fcfa39ec537cdbfce3762aecde8f9c597780d2b00c2b43424',
|
||||
'org.bouncycastle:bcpg-jdk15on:dc4f51adfc46583c2543489c82708fef5660202bf264c7cd453f081a117ea536',
|
||||
'org.bouncycastle:bcprov-jdk15on:28155c8695934f666fabc235f992096e40d97ecb044d5b6b0902db6e15a0b72f',
|
||||
'org.bouncycastle:bcprov-jdk15to18:82c28318b178da751d174b1adf6c43e0199f0fcf80a7bf6483caa226ae0d30b3',
|
||||
'org.checkerframework:checker-qual:d261fde25d590f6b69db7721d469ac1b0a19a17ccaaaa751c31f0d8b8260b894',
|
||||
'org.fxmisc.easybind:easybind:666af296dda6de68751668a62661571b5238ac6f1c07c8a204fc6f902b222aaf',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:6c91dea17d7dce5f0b550c3de3305767e5fb46247b6d1eb7eca0ca1fe18458de',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:25e2409aba0ec37d2fd7c77727d7835b511879de8d9bf4862af0b493aabbe39e',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:f7dbbaee3e0841758187a213c052388a4e619e11c87ab16f4bc229cfe7ce5fed',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:6ea3d0921b26919b286f05cbdb906266666a36f9a7c096197114f7495708ffbc',
|
||||
'org.jetbrains:annotations:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
||||
'org.slf4j:slf4j-api:cdba07964d1bb40a0761485c6b1e8c2f8fd9eb1d19c53928ac0d7f9510105c57',
|
||||
'org.tukaani:xz:a594643d73cc01928cf6ca5ce100e094ea9d73af760a5d4fb6b75fa673ecec96',
|
||||
]
|
||||
}
|
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=11657af6356b7587bfb37287b5992e94a9686d5c8a0a1b60b87b9928a2decde5
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -47,7 +47,6 @@ To manually test endpoints, run each of the following:
|
||||
curl http://localhost:8080/getAllMarketPrices
|
||||
curl http://localhost:8080/getFees
|
||||
curl http://localhost:8080/getParams
|
||||
curl http://localhost:8080/getVersion
|
||||
curl http://localhost:8080/info
|
||||
```
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.price.util;
|
||||
|
||||
import bisq.price.PriceController;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.actuate.info.Info;
|
||||
import org.springframework.boot.actuate.info.InfoContributor;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
@RestController
|
||||
class VersionController extends PriceController implements InfoContributor {
|
||||
|
||||
private final String version;
|
||||
|
||||
public VersionController(@Value("classpath:version.txt") Resource versionTxt) throws IOException {
|
||||
this.version = FileCopyUtils.copyToString(
|
||||
new InputStreamReader(
|
||||
versionTxt.getInputStream()
|
||||
)
|
||||
).trim();
|
||||
}
|
||||
|
||||
@GetMapping(path = "/getVersion")
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contribute(Info.Builder builder) {
|
||||
builder.withDetail("version", version);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package bisq.price.util;
|
||||
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class VersionControllerTest {
|
||||
|
||||
@Test
|
||||
public void getVersion() throws IOException {
|
||||
VersionController controller = new VersionController(
|
||||
new FileSystemResource("src/main/resources/version.txt"));
|
||||
|
||||
String version = controller.getVersion();
|
||||
assertTrue(version.length() > 0);
|
||||
}
|
||||
}
|
@ -770,6 +770,10 @@ message Filter {
|
||||
bool disable_mempool_validation = 28;
|
||||
bool disable_pow_message = 29;
|
||||
int32 pow_difficulty = 30;
|
||||
int64 maker_fee_btc = 31;
|
||||
int64 taker_fee_btc = 32;
|
||||
int64 maker_fee_bsq = 33;
|
||||
int64 taker_fee_bsq = 34;
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
@ -975,6 +979,16 @@ message DisputeResult {
|
||||
PEER_WAS_LATE = 12;
|
||||
}
|
||||
|
||||
enum PayoutSuggestion {
|
||||
CUSTOM_PAYOUT = 0;
|
||||
BUYER_GETS_TRADE_AMOUNT = 1;
|
||||
BUYER_GETS_TRADE_AMOUNT_PLUS_COMPENSATION = 2;
|
||||
BUYER_GETS_TRADE_AMOUNT_MINUS_PENALTY = 3;
|
||||
SELLER_GETS_TRADE_AMOUNT = 4;
|
||||
SELLER_GETS_TRADE_AMOUNT_PLUS_COMPENSATION = 5;
|
||||
SELLER_GETS_TRADE_AMOUNT_MINUS_PENALTY = 6;
|
||||
}
|
||||
|
||||
string trade_id = 1;
|
||||
int32 trader_id = 2;
|
||||
Winner winner = 3;
|
||||
@ -990,6 +1004,8 @@ message DisputeResult {
|
||||
bytes arbitrator_pub_key = 13;
|
||||
int64 close_date = 14;
|
||||
bool is_loser_publisher = 15;
|
||||
string payout_adjustment_percent = 16;
|
||||
PayoutSuggestion payout_suggestion = 17;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user