Merge branch 'master' into 1-basic-api-bsqswap-support

This commit is contained in:
ghubstan 2021-11-23 17:02:49 -03:00
commit b65cc9c1f4
No known key found for this signature in database
GPG Key ID: E35592D6800A861E
41 changed files with 3729 additions and 589 deletions

View File

@ -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();

View File

@ -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());

View File

@ -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")
}
}

View File

@ -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()) ||

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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}";
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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.");

View File

@ -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());

View File

@ -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();

View File

@ -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;

View File

@ -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) {

View File

@ -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}";
}
}

View File

@ -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;
}

View File

@ -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());

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -46,7 +46,7 @@ public class ReceiptValidatorTest {
@After
public void tearDown() {
verifyZeroInteractions(offer);
verifyNoMoreInteractions(offer);
}
@Test

View File

@ -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

View File

@ -71,6 +71,10 @@ public class UserPayloadModelVOTest {
false,
false,
false,
0,
0,
0,
0,
0));
vo.setRegisteredArbitrator(ArbitratorTest.getArbitratorMock());

View File

@ -132,6 +132,10 @@ public class FeeReceiverSelectorTest {
false,
false,
false,
0,
0,
0,
0,
0);
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}

View File

@ -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();
})

View File

@ -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;
}

View File

@ -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> {
}
}
}

View File

@ -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

View File

@ -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);

View File

@ -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");
}

File diff suppressed because it is too large Load Diff

View File

@ -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.

View File

@ -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

View File

@ -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
```

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
///////////////////////////////////////////////////////////////////////////////////////////