Merge branch 'master_upstream' into refactor-filter

This commit is contained in:
chimp1984 2020-08-31 10:15:42 -05:00
commit 5555c43ea9
No known key found for this signature in database
GPG key ID: 9801B4EC591F90E3
17 changed files with 166 additions and 230 deletions

View file

@ -1,11 +1,11 @@
#!/usr/bin/env bats #!/usr/bin/env bats
# #
# Integration tests for bisq-cli running against a live bisq-daemon # Smoke tests for bisq-cli running against a live bisq-daemon (on mainnet)
# #
# Prerequisites: # Prerequisites:
# #
# - bats v0.4.0 must be installed (brew install bats on macOS) # - bats-core 1.2.0+ must be installed (brew install bats-core on macOS)
# see https://github.com/sstephenson/bats/tree/v0.4.0 # see https://github.com/bats-core/bats-core
# #
# - Run `./bisq-daemon --apiPassword=xyz --appDataDir=$TESTDIR` where $TESTDIR # - Run `./bisq-daemon --apiPassword=xyz --appDataDir=$TESTDIR` where $TESTDIR
# is empty or otherwise contains an unencrypted wallet with a 0 BTC balance # is empty or otherwise contains an unencrypted wallet with a 0 BTC balance
@ -48,14 +48,14 @@
run ./bisq-cli --password="xyz" getversion run ./bisq-cli --password="xyz" getversion
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
echo "actual output: $output" >&2 echo "actual output: $output" >&2
[ "$output" = "1.3.5" ] [ "$output" = "1.3.7" ]
} }
@test "test getversion" { @test "test getversion" {
run ./bisq-cli --password=xyz getversion run ./bisq-cli --password=xyz getversion
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
echo "actual output: $output" >&2 echo "actual output: $output" >&2
[ "$output" = "1.3.5" ] [ "$output" = "1.3.7" ]
} }
@test "test setwalletpassword \"a b c\"" { @test "test setwalletpassword \"a b c\"" {
@ -190,8 +190,8 @@
[ "$output" = "Error: incorrect parameter count, expecting direction (buy|sell), currency code" ] [ "$output" = "Error: incorrect parameter count, expecting direction (buy|sell), currency code" ]
} }
@test "test getoffers buy eur check return status" { @test "test getoffers sell eur check return status" {
run ./bisq-cli --password=xyz getoffers buy eur run ./bisq-cli --password=xyz getoffers sell eur
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
} }

View file

@ -311,17 +311,25 @@ public class Scaffold {
bitcoinDaemon.verifyBitcoindRunning(); bitcoinDaemon.verifyBitcoindRunning();
} }
// Start Bisq apps defined by the supportingApps option, in the in proper order.
if (config.hasSupportingApp(seednode.name())) if (config.hasSupportingApp(seednode.name()))
startBisqApp(seednode, executor, countdownLatch); startBisqApp(seednode, executor, countdownLatch);
if (config.hasSupportingApp(arbdaemon.name(), arbdesktop.name())) if (config.hasSupportingApp(arbdaemon.name()))
startBisqApp(config.runArbNodeAsDesktop ? arbdesktop : arbdaemon, executor, countdownLatch); startBisqApp(arbdaemon, executor, countdownLatch);
else if (config.hasSupportingApp(arbdesktop.name()))
startBisqApp(arbdesktop, executor, countdownLatch);
if (config.hasSupportingApp(alicedaemon.name(), alicedesktop.name())) if (config.hasSupportingApp(alicedaemon.name()))
startBisqApp(config.runAliceNodeAsDesktop ? alicedesktop : alicedaemon, executor, countdownLatch); startBisqApp(alicedaemon, executor, countdownLatch);
else if (config.hasSupportingApp(alicedesktop.name()))
startBisqApp(alicedesktop, executor, countdownLatch);
if (config.hasSupportingApp(bobdaemon.name(), bobdesktop.name())) if (config.hasSupportingApp(bobdaemon.name()))
startBisqApp(config.runBobNodeAsDesktop ? bobdesktop : bobdaemon, executor, countdownLatch); startBisqApp(bobdaemon, executor, countdownLatch);
else if (config.hasSupportingApp(bobdesktop.name()))
startBisqApp(bobdesktop, executor, countdownLatch);
} }
private void startBisqApp(BisqAppConfig bisqAppConfig, private void startBisqApp(BisqAppConfig bisqAppConfig,
@ -329,28 +337,24 @@ public class Scaffold {
CountDownLatch countdownLatch) CountDownLatch countdownLatch)
throws IOException, InterruptedException { throws IOException, InterruptedException {
BisqApp bisqApp; BisqApp bisqApp = createBisqApp(bisqAppConfig);
switch (bisqAppConfig) { switch (bisqAppConfig) {
case seednode: case seednode:
bisqApp = createBisqApp(seednode);
seedNodeTask = new SetupTask(bisqApp, countdownLatch); seedNodeTask = new SetupTask(bisqApp, countdownLatch);
seedNodeTaskFuture = executor.submit(seedNodeTask); seedNodeTaskFuture = executor.submit(seedNodeTask);
break; break;
case arbdaemon: case arbdaemon:
case arbdesktop: case arbdesktop:
bisqApp = createBisqApp(config.runArbNodeAsDesktop ? arbdesktop : arbdaemon);
arbNodeTask = new SetupTask(bisqApp, countdownLatch); arbNodeTask = new SetupTask(bisqApp, countdownLatch);
arbNodeTaskFuture = executor.submit(arbNodeTask); arbNodeTaskFuture = executor.submit(arbNodeTask);
break; break;
case alicedaemon: case alicedaemon:
case alicedesktop: case alicedesktop:
bisqApp = createBisqApp(config.runAliceNodeAsDesktop ? alicedesktop : alicedaemon);
aliceNodeTask = new SetupTask(bisqApp, countdownLatch); aliceNodeTask = new SetupTask(bisqApp, countdownLatch);
aliceNodeTaskFuture = executor.submit(aliceNodeTask); aliceNodeTaskFuture = executor.submit(aliceNodeTask);
break; break;
case bobdaemon: case bobdaemon:
case bobdesktop: case bobdesktop:
bisqApp = createBisqApp(config.runBobNodeAsDesktop ? bobdesktop : bobdaemon);
bobNodeTask = new SetupTask(bisqApp, countdownLatch); bobNodeTask = new SetupTask(bisqApp, countdownLatch);
bobNodeTaskFuture = executor.submit(bobNodeTask); bobNodeTaskFuture = executor.submit(bobNodeTask);
break; break;

View file

@ -65,13 +65,11 @@ public class ApiTestConfig {
static final String ROOT_APP_DATA_DIR = "rootAppDataDir"; static final String ROOT_APP_DATA_DIR = "rootAppDataDir";
static final String API_PASSWORD = "apiPassword"; static final String API_PASSWORD = "apiPassword";
static final String RUN_SUBPROJECT_JARS = "runSubprojectJars"; static final String RUN_SUBPROJECT_JARS = "runSubprojectJars";
static final String RUN_ARB_NODE_AS_DESKTOP = "runArbNodeAsDesktop";
static final String RUN_ALICE_NODE_AS_DESKTOP = "runAliceNodeAsDesktop";
static final String RUN_BOB_NODE_AS_DESKTOP = "runBobNodeAsDesktop";
static final String BISQ_APP_INIT_TIME = "bisqAppInitTime"; static final String BISQ_APP_INIT_TIME = "bisqAppInitTime";
static final String SKIP_TESTS = "skipTests"; static final String SKIP_TESTS = "skipTests";
static final String SHUTDOWN_AFTER_TESTS = "shutdownAfterTests"; static final String SHUTDOWN_AFTER_TESTS = "shutdownAfterTests";
static final String SUPPORTING_APPS = "supportingApps"; static final String SUPPORTING_APPS = "supportingApps";
static final String ENABLE_BISQ_DEBUGGING = "enableBisqDebugging";
// Default values for certain options // Default values for certain options
static final String DEFAULT_CONFIG_FILE_NAME = "apitest.properties"; static final String DEFAULT_CONFIG_FILE_NAME = "apitest.properties";
@ -98,13 +96,11 @@ public class ApiTestConfig {
// Daemon instances can use same gRPC password, but each needs a different apiPort. // Daemon instances can use same gRPC password, but each needs a different apiPort.
public final String apiPassword; public final String apiPassword;
public final boolean runSubprojectJars; public final boolean runSubprojectJars;
public final boolean runArbNodeAsDesktop;
public final boolean runAliceNodeAsDesktop;
public final boolean runBobNodeAsDesktop;
public final long bisqAppInitTime; public final long bisqAppInitTime;
public final boolean skipTests; public final boolean skipTests;
public final boolean shutdownAfterTests; public final boolean shutdownAfterTests;
public final List<String> supportingApps; public final List<String> supportingApps;
public final boolean enableBisqDebugging;
// Immutable system configurations set in the constructor. // Immutable system configurations set in the constructor.
public final String bitcoinDatadir; public final String bitcoinDatadir;
@ -202,27 +198,6 @@ public class ApiTestConfig {
.ofType(Boolean.class) .ofType(Boolean.class)
.defaultsTo(false); .defaultsTo(false);
ArgumentAcceptingOptionSpec<Boolean> runArbNodeAsDesktopOpt =
parser.accepts(RUN_ARB_NODE_AS_DESKTOP,
"Run Arbitration node as desktop")
.withRequiredArg()
.ofType(Boolean.class)
.defaultsTo(false); // TODO how do I register mediator?
ArgumentAcceptingOptionSpec<Boolean> runAliceNodeAsDesktopOpt =
parser.accepts(RUN_ALICE_NODE_AS_DESKTOP,
"Run Alice node as desktop")
.withRequiredArg()
.ofType(Boolean.class)
.defaultsTo(false);
ArgumentAcceptingOptionSpec<Boolean> runBobNodeAsDesktopOpt =
parser.accepts(RUN_BOB_NODE_AS_DESKTOP,
"Run Bob node as desktop")
.withRequiredArg()
.ofType(Boolean.class)
.defaultsTo(false);
ArgumentAcceptingOptionSpec<Long> bisqAppInitTimeOpt = ArgumentAcceptingOptionSpec<Long> bisqAppInitTimeOpt =
parser.accepts(BISQ_APP_INIT_TIME, parser.accepts(BISQ_APP_INIT_TIME,
"Amount of time (ms) to wait on a Bisq instance's initialization") "Amount of time (ms) to wait on a Bisq instance's initialization")
@ -251,6 +226,12 @@ public class ApiTestConfig {
.ofType(String.class) .ofType(String.class)
.defaultsTo("bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon"); .defaultsTo("bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon");
ArgumentAcceptingOptionSpec<Boolean> enableBisqDebuggingOpt =
parser.accepts(ENABLE_BISQ_DEBUGGING,
"Start Bisq apps with remote debug options")
.withRequiredArg()
.ofType(Boolean.class)
.defaultsTo(false);
try { try {
CompositeOptionSet options = new CompositeOptionSet(); CompositeOptionSet options = new CompositeOptionSet();
@ -302,13 +283,11 @@ public class ApiTestConfig {
this.bitcoinRpcPassword = options.valueOf(bitcoinRpcPasswordOpt); this.bitcoinRpcPassword = options.valueOf(bitcoinRpcPasswordOpt);
this.apiPassword = options.valueOf(apiPasswordOpt); this.apiPassword = options.valueOf(apiPasswordOpt);
this.runSubprojectJars = options.valueOf(runSubprojectJarsOpt); this.runSubprojectJars = options.valueOf(runSubprojectJarsOpt);
this.runArbNodeAsDesktop = options.valueOf(runArbNodeAsDesktopOpt);
this.runAliceNodeAsDesktop = options.valueOf(runAliceNodeAsDesktopOpt);
this.runBobNodeAsDesktop = options.valueOf(runBobNodeAsDesktopOpt);
this.bisqAppInitTime = options.valueOf(bisqAppInitTimeOpt); this.bisqAppInitTime = options.valueOf(bisqAppInitTimeOpt);
this.skipTests = options.valueOf(skipTestsOpt); this.skipTests = options.valueOf(skipTestsOpt);
this.shutdownAfterTests = options.valueOf(shutdownAfterTestsOpt); this.shutdownAfterTests = options.valueOf(shutdownAfterTestsOpt);
this.supportingApps = asList(options.valueOf(supportingAppsOpt).split(",")); this.supportingApps = asList(options.valueOf(supportingAppsOpt).split(","));
this.enableBisqDebugging = options.valueOf(enableBisqDebuggingOpt);
// Assign values to special-case static fields. // Assign values to special-case static fields.
BASH_PATH_VALUE = bashPath; BASH_PATH_VALUE = bashPath;

View file

@ -30,58 +30,64 @@ import bisq.daemon.app.BisqDaemonMain;
@see <a href="https://github.com/bisq-network/bisq/blob/master/docs/dev-setup.md">dev-setup.md</a> @see <a href="https://github.com/bisq-network/bisq/blob/master/docs/dev-setup.md">dev-setup.md</a>
@see <a href="https://github.com/bisq-network/bisq/blob/master/docs/dao-setup.md">dao-setup.md</a> @see <a href="https://github.com/bisq-network/bisq/blob/master/docs/dao-setup.md">dao-setup.md</a>
*/ */
@SuppressWarnings("unused")
public enum BisqAppConfig { public enum BisqAppConfig {
seednode("bisq-BTC_REGTEST_Seed_2002", seednode("bisq-BTC_REGTEST_Seed_2002",
"bisq-seednode", "bisq-seednode",
"\"-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", "-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml",
SeedNodeMain.class.getName(), SeedNodeMain.class.getName(),
2002, 2002,
5120, 5120,
-1), -1,
49996),
arbdaemon("bisq-BTC_REGTEST_Arb_dao", arbdaemon("bisq-BTC_REGTEST_Arb_dao",
"bisq-daemon", "bisq-daemon",
"\"-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", "-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml",
BisqDaemonMain.class.getName(), BisqDaemonMain.class.getName(),
4444, 4444,
5121, 5121,
9997), 9997,
49997),
arbdesktop("bisq-BTC_REGTEST_Arb_dao", arbdesktop("bisq-BTC_REGTEST_Arb_dao",
"bisq-desktop", "bisq-desktop",
"\"-XX:MaxRAM=3g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", "-XX:MaxRAM=3g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml",
BisqAppMain.class.getName(), BisqAppMain.class.getName(),
4444, 4444,
5121, 5121,
-1), -1,
49997),
alicedaemon("bisq-BTC_REGTEST_Alice_dao", alicedaemon("bisq-BTC_REGTEST_Alice_dao",
"bisq-daemon", "bisq-daemon",
"\"-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", "-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml",
BisqDaemonMain.class.getName(), BisqDaemonMain.class.getName(),
7777, 7777,
5122, 5122,
9998), 9998,
49998),
alicedesktop("bisq-BTC_REGTEST_Alice_dao", alicedesktop("bisq-BTC_REGTEST_Alice_dao",
"bisq-desktop", "bisq-desktop",
"\"-XX:MaxRAM=4g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", "-XX:MaxRAM=4g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml",
BisqAppMain.class.getName(), BisqAppMain.class.getName(),
7777, 7777,
5122, 5122,
-1), -1,
49998),
bobdaemon("bisq-BTC_REGTEST_Bob_dao", bobdaemon("bisq-BTC_REGTEST_Bob_dao",
"bisq-daemon", "bisq-daemon",
"\"-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", "-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml",
BisqDaemonMain.class.getName(), BisqDaemonMain.class.getName(),
8888, 8888,
5123, 5123,
9999), 9999,
49999),
bobdesktop("bisq-BTC_REGTEST_Bob_dao", bobdesktop("bisq-BTC_REGTEST_Bob_dao",
"bisq-desktop", "bisq-desktop",
"\"-XX:MaxRAM=4g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", "-XX:MaxRAM=4g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml",
BisqAppMain.class.getName(), BisqAppMain.class.getName(),
8888, 8888,
5123, 5123,
-1); -1,
49999);
public final String appName; public final String appName;
public final String startupScript; public final String startupScript;
@ -91,6 +97,7 @@ public enum BisqAppConfig {
public final int rpcBlockNotificationPort; public final int rpcBlockNotificationPort;
// Daemons can use a global gRPC password, but each needs a unique apiPort. // Daemons can use a global gRPC password, but each needs a unique apiPort.
public final int apiPort; public final int apiPort;
public final int remoteDebugPort;
BisqAppConfig(String appName, BisqAppConfig(String appName,
String startupScript, String startupScript,
@ -98,7 +105,8 @@ public enum BisqAppConfig {
String mainClassName, String mainClassName,
int nodePort, int nodePort,
int rpcBlockNotificationPort, int rpcBlockNotificationPort,
int apiPort) { int apiPort,
int remoteDebugPort) {
this.appName = appName; this.appName = appName;
this.startupScript = startupScript; this.startupScript = startupScript;
this.javaOpts = javaOpts; this.javaOpts = javaOpts;
@ -106,6 +114,7 @@ public enum BisqAppConfig {
this.nodePort = nodePort; this.nodePort = nodePort;
this.rpcBlockNotificationPort = rpcBlockNotificationPort; this.rpcBlockNotificationPort = rpcBlockNotificationPort;
this.apiPort = apiPort; this.apiPort = apiPort;
this.remoteDebugPort = remoteDebugPort;
} }
@Override @Override
@ -118,6 +127,7 @@ public enum BisqAppConfig {
", nodePort=" + nodePort + "\n" + ", nodePort=" + nodePort + "\n" +
", rpcBlockNotificationPort=" + rpcBlockNotificationPort + "\n" + ", rpcBlockNotificationPort=" + rpcBlockNotificationPort + "\n" +
", apiPort=" + apiPort + "\n" + ", apiPort=" + apiPort + "\n" +
", remoteDebugPort=" + remoteDebugPort + "\n" +
'}'; '}';
} }
} }

View file

@ -53,6 +53,7 @@ public class BisqApp extends AbstractLinuxProcess implements LinuxProcess {
private final boolean useLocalhostForP2P; private final boolean useLocalhostForP2P;
public final boolean useDevPrivilegeKeys; public final boolean useDevPrivilegeKeys;
private final String findBisqPidScript; private final String findBisqPidScript;
private final String debugOpts;
public BisqApp(BisqAppConfig bisqAppConfig, ApiTestConfig config) { public BisqApp(BisqAppConfig bisqAppConfig, ApiTestConfig config) {
super(bisqAppConfig.appName, config); super(bisqAppConfig.appName, config);
@ -67,6 +68,9 @@ public class BisqApp extends AbstractLinuxProcess implements LinuxProcess {
this.useDevPrivilegeKeys = true; this.useDevPrivilegeKeys = true;
this.findBisqPidScript = (config.isRunningTest ? "." : "./apitest") this.findBisqPidScript = (config.isRunningTest ? "." : "./apitest")
+ "/scripts/get-bisq-pid.sh"; + "/scripts/get-bisq-pid.sh";
this.debugOpts = config.enableBisqDebugging
? " -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:" + bisqAppConfig.remoteDebugPort
: "";
} }
@Override @Override
@ -112,7 +116,6 @@ public class BisqApp extends AbstractLinuxProcess implements LinuxProcess {
if (isAlive(pid)) { if (isAlive(pid)) {
this.shutdownExceptions.add(new IllegalStateException(format("%s shutdown did not work", bisqAppConfig.appName))); this.shutdownExceptions.add(new IllegalStateException(format("%s shutdown did not work", bisqAppConfig.appName)));
return;
} }
} catch (Exception e) { } catch (Exception e) {
@ -209,7 +212,7 @@ public class BisqApp extends AbstractLinuxProcess implements LinuxProcess {
} }
private String getJavaOptsSpec() { private String getJavaOptsSpec() {
return "export JAVA_OPTS=" + bisqAppConfig.javaOpts + "; "; return "export JAVA_OPTS=\"" + bisqAppConfig.javaOpts + debugOpts + "\"; ";
} }
private List<String> getOptsList() { private List<String> getOptsList() {

View file

@ -28,6 +28,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import bisq.apitest.config.ApiTestConfig; import bisq.apitest.config.ApiTestConfig;
import bisq.apitest.method.BitcoinCliHelper; import bisq.apitest.method.BitcoinCliHelper;
import bisq.cli.GrpcStubs;
/** /**
* Base class for all test types: 'method', 'scenario' and 'e2e'. * Base class for all test types: 'method', 'scenario' and 'e2e'.
@ -65,19 +66,19 @@ public class ApiTestCase {
public static void setUpScaffold(String supportingApps) public static void setUpScaffold(String supportingApps)
throws InterruptedException, ExecutionException, IOException { throws InterruptedException, ExecutionException, IOException {
// The supportingApps argument is a comma delimited string of supporting app
// names, e.g. "bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon"
scaffold = new Scaffold(supportingApps).setUp(); scaffold = new Scaffold(supportingApps).setUp();
config = scaffold.config; config = scaffold.config;
bitcoinCli = new BitcoinCliHelper((config)); bitcoinCli = new BitcoinCliHelper((config));
grpcStubs = new GrpcStubs(alicedaemon, config).init(); // For now, all grpc requests are sent to the alicedaemon, but this will need to
// be made configurable for new test cases that call arb or bob node daemons.
grpcStubs = new GrpcStubs("localhost", alicedaemon.apiPort, config.apiPassword);
} }
public static void setUpScaffold() public static void setUpScaffold(String[] params)
throws InterruptedException, ExecutionException, IOException { throws InterruptedException, ExecutionException, IOException {
scaffold = new Scaffold(new String[]{}).setUp(); scaffold = new Scaffold(params).setUp();
config = scaffold.config; config = scaffold.config;
grpcStubs = new GrpcStubs(alicedaemon, config).init(); grpcStubs = new GrpcStubs("localhost", alicedaemon.apiPort, config.apiPassword);
} }
public static void tearDownScaffold() { public static void tearDownScaffold() {

View file

@ -1,109 +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.apitest;
import bisq.proto.grpc.GetVersionGrpc;
import bisq.proto.grpc.OffersGrpc;
import bisq.proto.grpc.PaymentAccountsGrpc;
import bisq.proto.grpc.WalletsGrpc;
import io.grpc.CallCredentials;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Metadata;
import java.util.concurrent.Executor;
import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
import static io.grpc.Status.UNAUTHENTICATED;
import static java.lang.String.format;
import static java.util.concurrent.TimeUnit.SECONDS;
import bisq.apitest.config.ApiTestConfig;
import bisq.apitest.config.BisqAppConfig;
public class GrpcStubs {
public final CallCredentials credentials;
public final String host;
public final int port;
public GetVersionGrpc.GetVersionBlockingStub versionService;
public OffersGrpc.OffersBlockingStub offersService;
public PaymentAccountsGrpc.PaymentAccountsBlockingStub paymentAccountsService;
public WalletsGrpc.WalletsBlockingStub walletsService;
public GrpcStubs(BisqAppConfig bisqAppConfig, ApiTestConfig config) {
this.credentials = new PasswordCallCredentials(config.apiPassword);
this.host = "localhost";
this.port = bisqAppConfig.apiPort;
}
public GrpcStubs init() {
var channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
channel.shutdown().awaitTermination(1, SECONDS);
} catch (InterruptedException ex) {
throw new IllegalStateException(ex);
}
}));
this.versionService = GetVersionGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.offersService = OffersGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.paymentAccountsService = PaymentAccountsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.walletsService = WalletsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
return this;
}
static class PasswordCallCredentials extends CallCredentials {
public static final String PASSWORD_KEY = "password";
private final String passwordValue;
public PasswordCallCredentials(String passwordValue) {
if (passwordValue == null)
throw new IllegalArgumentException(format("'%s' value must not be null", PASSWORD_KEY));
this.passwordValue = passwordValue;
}
@Override
public void applyRequestMetadata(RequestInfo requestInfo,
Executor appExecutor,
MetadataApplier metadataApplier) {
appExecutor.execute(() -> {
try {
var headers = new Metadata();
var passwordKey = Metadata.Key.of(PASSWORD_KEY, ASCII_STRING_MARSHALLER);
headers.put(passwordKey, passwordValue);
metadataApplier.apply(headers);
} catch (Throwable ex) {
metadataApplier.fail(UNAUTHENTICATED.withCause(ex));
}
});
}
@Override
public void thisUsesUnstableApi() {
// An experimental api. A noop but never called; tries to make it clearer to
// implementors that they may break in the future.
}
}
}

View file

@ -51,7 +51,7 @@ configure(subprojects) {
javaxAnnotationVersion = '1.2' javaxAnnotationVersion = '1.2'
jcsvVersion = '1.4.0' jcsvVersion = '1.4.0'
jetbrainsAnnotationsVersion = '13.0' jetbrainsAnnotationsVersion = '13.0'
jfoenixVersion = '9.0.6' jfoenixVersion = '9.0.10'
joptVersion = '5.0.4' joptVersion = '5.0.4'
jsonsimpleVersion = '1.1.1' jsonsimpleVersion = '1.1.1'
junitVersion = '4.12' junitVersion = '4.12'

View file

@ -133,21 +133,11 @@ public class CliMain {
if (password == null) if (password == null)
throw new IllegalArgumentException("missing required 'password' option"); throw new IllegalArgumentException("missing required 'password' option");
var credentials = new PasswordCallCredentials(password); GrpcStubs grpcStubs = new GrpcStubs(host, port, password);
var versionService = grpcStubs.versionService;
var channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build(); var offersService = grpcStubs.offersService;
Runtime.getRuntime().addShutdownHook(new Thread(() -> { var paymentAccountsService = grpcStubs.paymentAccountsService;
try { var walletsService = grpcStubs.walletsService;
channel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}));
var versionService = GetVersionGrpc.newBlockingStub(channel).withCallCredentials(credentials);
var offersService = OffersGrpc.newBlockingStub(channel).withCallCredentials(credentials);
var paymentAccountsService = PaymentAccountsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
var walletsService = WalletsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
try { try {
switch (method) { switch (method) {

View file

@ -0,0 +1,54 @@
/*
* 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.cli;
import bisq.proto.grpc.GetVersionGrpc;
import bisq.proto.grpc.OffersGrpc;
import bisq.proto.grpc.PaymentAccountsGrpc;
import bisq.proto.grpc.WalletsGrpc;
import io.grpc.CallCredentials;
import io.grpc.ManagedChannelBuilder;
import static java.util.concurrent.TimeUnit.SECONDS;
public class GrpcStubs {
public final GetVersionGrpc.GetVersionBlockingStub versionService;
public final OffersGrpc.OffersBlockingStub offersService;
public final PaymentAccountsGrpc.PaymentAccountsBlockingStub paymentAccountsService;
public final WalletsGrpc.WalletsBlockingStub walletsService;
public GrpcStubs(String apiHost, int apiPort, String apiPassword) {
CallCredentials credentials = new PasswordCallCredentials(apiPassword);
var channel = ManagedChannelBuilder.forAddress(apiHost, apiPort).usePlaintext().build();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
channel.shutdown().awaitTermination(1, SECONDS);
} catch (InterruptedException ex) {
throw new IllegalStateException(ex);
}
}));
this.versionService = GetVersionGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.offersService = OffersGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.paymentAccountsService = PaymentAccountsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
this.walletsService = WalletsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
}
}

View file

@ -84,7 +84,7 @@ public class Restrictions {
return SELLER_SECURITY_DEPOSIT; return SELLER_SECURITY_DEPOSIT;
} }
// This value must not be lower than MIN_BUYER_SECURITY_DEPOSIT or SELLER_SECURITY_DEPOSIT // This value must be lower than MIN_BUYER_SECURITY_DEPOSIT and SELLER_SECURITY_DEPOSIT
public static Coin getMinRefundAtMediatedDispute() { public static Coin getMinRefundAtMediatedDispute() {
if (MIN_REFUND_AT_MEDIATED_DISPUTE == null) if (MIN_REFUND_AT_MEDIATED_DISPUTE == null)
MIN_REFUND_AT_MEDIATED_DISPUTE = Coin.parseCoin("0.003"); // 0.003 BTC about 21 USD @ 7000 USD/BTC MIN_REFUND_AT_MEDIATED_DISPUTE = Coin.parseCoin("0.003"); // 0.003 BTC about 21 USD @ 7000 USD/BTC

View file

@ -2627,9 +2627,10 @@ popup.warning.btcChangeBelowDustException=This transaction creates a change outp
You need to add the dust amount to your sending amount to avoid to generate a dust output.\n\n\ You need to add the dust amount to your sending amount to avoid to generate a dust output.\n\n\
The dust output is {0}. The dust output is {0}.
popup.warning.insufficientBsqFundsForBtcFeePayment=You don''t have sufficient BSQ funds for paying the trade fee in BSQ. \ popup.warning.insufficientBsqFundsForBtcFeePayment=You''ll need more BSQ to do this transaction—the last \
You can pay the fee in BTC or you need to fund your BSQ wallet. You can buy BSQ in Bisq.\n\n\ 5.46 BSQ in your wallet cannot be used to pay trade fees because of dust limits in the Bitcoin protocol.\n\n\
Missing BSQ funds: {0} You can either buy more BSQ or pay trade fees with BTC.\n\n\
Missing funds: {0}
popup.warning.noBsqFundsForBtcFeePayment=Your BSQ wallet does not have sufficient funds for paying the trade fee in BSQ. popup.warning.noBsqFundsForBtcFeePayment=Your BSQ wallet does not have sufficient funds for paying the trade fee in BSQ.
popup.warning.messageTooLong=Your message exceeds the max. allowed size. Please send it in several parts or upload it to a service like https://pastebin.com. popup.warning.messageTooLong=Your message exceeds the max. allowed size. Please send it in several parts or upload it to a service like https://pastebin.com.
popup.warning.lockedUpFunds=You have locked up funds from a failed trade.\n\ popup.warning.lockedUpFunds=You have locked up funds from a failed trade.\n\

View file

@ -642,8 +642,8 @@ tree-table-view:focused {
} }
.top-navigation .separator:vertical .line { .top-navigation .separator:vertical .line {
-fx-border-color: transparent transparent transparent transparent; -fx-border-color: transparent transparent transparent -bs-rd-nav-border-color;
-fx-border-width: 3; -fx-border-width: 1;
-fx-border-insets: 0 0 0 1; -fx-border-insets: 0 0 0 1;
} }
@ -661,6 +661,7 @@ tree-table-view:focused {
.nav-price-balance { .nav-price-balance {
-fx-background-color: -bs-color-gray-background; -fx-background-color: -bs-color-gray-background;
-fx-background-radius: 3; -fx-background-radius: 3;
-fx-effect: innershadow(gaussian, -bs-text-color-transparent, 3, 0, 0, 1);
-fx-pref-height: 41; -fx-pref-height: 41;
-fx-padding: 0 10 0 0; -fx-padding: 0 10 0 0;
} }
@ -2119,3 +2120,4 @@ textfield */
-fx-stroke: linear-gradient(to bottom, -bs-text-color-transparent, -bs-text-color-transparent-dark) !important; -fx-stroke: linear-gradient(to bottom, -bs-text-color-transparent, -bs-text-color-transparent-dark) !important;
-fx-fill: -bs-background-color !important; -fx-fill: -bs-background-color !important;
} }

View file

@ -43,12 +43,12 @@ import bisq.desktop.util.DisplayUtils;
import bisq.desktop.util.Transitions; import bisq.desktop.util.Transitions;
import bisq.core.dao.monitoring.DaoStateMonitoringService; import bisq.core.dao.monitoring.DaoStateMonitoringService;
import bisq.common.BisqException;
import bisq.core.locale.GlobalSettings; import bisq.core.locale.GlobalSettings;
import bisq.core.locale.LanguageUtil; import bisq.core.locale.LanguageUtil;
import bisq.core.locale.Res; import bisq.core.locale.Res;
import bisq.core.provider.price.MarketPrice; import bisq.core.provider.price.MarketPrice;
import bisq.common.BisqException;
import bisq.common.Timer; import bisq.common.Timer;
import bisq.common.UserThread; import bisq.common.UserThread;
import bisq.common.app.Version; import bisq.common.app.Version;
@ -318,17 +318,15 @@ public class MainView extends InitializableView<StackPane, MainViewModel>
} }
}); });
HBox primaryNav = new HBox(marketButton, getNavigationSeparator(), buyButton, HBox primaryNav = new HBox(marketButton, getNavigationSeparator(), buyButton, getNavigationSeparator(),
getNavigationSeparator(), sellButton, getNavigationSeparator(), sellButton, getNavigationSeparator(), portfolioButtonWithBadge, getNavigationSeparator(), fundsButton);
portfolioButtonWithBadge, getNavigationSeparator(), fundsButton);
primaryNav.setAlignment(Pos.CENTER); primaryNav.setAlignment(Pos.CENTER_LEFT);
primaryNav.getStyleClass().add("nav-primary"); primaryNav.getStyleClass().add("nav-primary");
HBox.setHgrow(primaryNav, Priority.SOMETIMES); HBox.setHgrow(primaryNav, Priority.SOMETIMES);
HBox secondaryNav = new HBox(supportButtonWithBadge, getNavigationSeparator(), HBox secondaryNav = new HBox(supportButtonWithBadge, getNavigationSpacer(), settingsButton,
settingsButton, getNavigationSeparator(), accountButtonWithBadge, getNavigationSpacer(), accountButtonWithBadge, getNavigationSpacer(), daoButtonWithBadge);
getNavigationSeparator(), daoButtonWithBadge);
secondaryNav.getStyleClass().add("nav-secondary"); secondaryNav.getStyleClass().add("nav-secondary");
HBox.setHgrow(secondaryNav, Priority.SOMETIMES); HBox.setHgrow(secondaryNav, Priority.SOMETIMES);
@ -343,14 +341,14 @@ public class MainView extends InitializableView<StackPane, MainViewModel>
priceAndBalance.getStyleClass().add("nav-price-balance"); priceAndBalance.getStyleClass().add("nav-price-balance");
HBox navPane = new HBox(primaryNav, secondaryNav, HBox navPane = new HBox(primaryNav, secondaryNav,
getNavigationSpacer(), priceAndBalance) {{ priceAndBalance) {{
setLeftAnchor(this, 0d); setLeftAnchor(this, 0d);
setRightAnchor(this, 0d); setRightAnchor(this, 0d);
setTopAnchor(this, 0d); setTopAnchor(this, 0d);
setPadding(new Insets(0, 0, 0, 0)); setPadding(new Insets(0, 0, 0, 0));
getStyleClass().add("top-navigation"); getStyleClass().add("top-navigation");
}}; }};
navPane.setAlignment(Pos.CENTER_LEFT); navPane.setAlignment(Pos.CENTER);
AnchorPane contentContainer = new AnchorPane() {{ AnchorPane contentContainer = new AnchorPane() {{
getStyleClass().add("content-pane"); getStyleClass().add("content-pane");
@ -383,15 +381,15 @@ public class MainView extends InitializableView<StackPane, MainViewModel>
contentContainer.getChildren().setAll(view.getRoot()); contentContainer.getChildren().setAll(view.getRoot());
try { try {
navButtons.getToggles().stream() navButtons.getToggles().stream()
.filter(toggle -> toggle instanceof NavButton) .filter(toggle -> toggle instanceof NavButton)
.filter(button -> viewClass == ((NavButton) button).viewClass) .filter(button -> viewClass == ((NavButton) button).viewClass)
.findFirst() .findFirst()
.orElseThrow(() -> new BisqException("No button matching %s found", viewClass)) .orElseThrow(() -> new BisqException("No button matching %s found", viewClass))
.setSelected(true); .setSelected(true);
} catch (BisqException e) { } catch (BisqException e) {
navigation.navigateTo(MainView.class, MarketView.class, OfferBookChartView.class); navigation.navigateTo(MainView.class, MarketView.class, OfferBookChartView.class);
} }
}); });
VBox splashScreen = createSplashScreen(); VBox splashScreen = createSplashScreen();
@ -538,7 +536,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel>
return Res.get("mainView.marketPrice.tooltip", return Res.get("mainView.marketPrice.tooltip",
"Bisq Price Index for " + selectedCurrencyCode, "Bisq Price Index for " + selectedCurrencyCode,
"", "",
DisplayUtils.formatTime(new Date(selectedMarketPrice.getTimestampSec())), selectedMarketPrice != null ? DisplayUtils.formatTime(new Date(selectedMarketPrice.getTimestampSec())) : Res.get("shared.na"),
model.getPriceFeedService().getProviderNodeAddress()); model.getPriceFeedService().getProviderNodeAddress());
} }

View file

@ -524,8 +524,3 @@
.jfx-date-picker .left-button, .jfx-date-picker .right-button{ .jfx-date-picker .left-button, .jfx-date-picker .right-button{
-fx-background-color: derive(-bs-color-gray-0, -10%); -fx-background-color: derive(-bs-color-gray-0, -10%);
} }
.popup-bg, .notification-popup-bg, .peer-info-popup-bg {
-fx-effect: dropshadow(gaussian, -bs-color-gray-fafa, 44, 0, 0, 0);
}

View file

@ -42,7 +42,7 @@ dependencyVerification {
'com.google.zxing:core:11aae8fd974ab25faa8208be50468eb12349cd239e93e7c797377fa13e381729', 'com.google.zxing:core:11aae8fd974ab25faa8208be50468eb12349cd239e93e7c797377fa13e381729',
'com.google.zxing:javase:0ec23e2ec12664ddd6347c8920ad647bb3b9da290f897a88516014b56cc77eb9', 'com.google.zxing:javase:0ec23e2ec12664ddd6347c8920ad647bb3b9da290f897a88516014b56cc77eb9',
'com.googlecode.jcsv:jcsv:73ca7d715e90c8d2c2635cc284543b038245a34f70790660ed590e157b8714a2', 'com.googlecode.jcsv:jcsv:73ca7d715e90c8d2c2635cc284543b038245a34f70790660ed590e157b8714a2',
'com.jfoenix:jfoenix:4739e37a05e67c3bc9d5b391a1b93717b5a48fa872992616b0964d3f827f8fe6', 'com.jfoenix:jfoenix:8060235fec5eb49617ec8d81d379e8c945f6cc722d0645e97190045100de2084',
'com.lambdaworks:scrypt:9a82d218099fb14c10c0e86e7eefeebd8c104de920acdc47b8b4b7a686fb73b4', 'com.lambdaworks:scrypt:9a82d218099fb14c10c0e86e7eefeebd8c104de920acdc47b8b4b7a686fb73b4',
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f', 'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
'com.nativelibs4java:bridj:101bcd9b6637e6bc16e56deb3daefba62b1f5e8e9e37e1b3e56e3b5860d659cf', 'com.nativelibs4java:bridj:101bcd9b6637e6bc16e56deb3daefba62b1f5e8e9e37e1b3e56e3b5860d659cf',

View file

@ -1,13 +1,21 @@
server=1 server=1
daemon=1
listen=1
discover=1
txindex=1 txindex=1
dbcache=1337 dbcache=1337
maxconnections=1337 maxconnections=1337
timeout=30000
listen=1
discover=1
peerbloomfilters=1 peerbloomfilters=1
onion=127.0.0.1:9050 onion=127.0.0.1:9050
rpcallowip=127.0.0.1 rpcallowip=127.0.0.1
rpcuser=__BITCOIN_RPC_USER__ rpcuser=__BITCOIN_RPC_USER__
rpcpassword=__BITCOIN_RPC_PASS__ rpcpassword=__BITCOIN_RPC_PASS__
blocknotify=/bitcoin/blocknotify.sh %s blocknotify=/bitcoin/blocknotify.sh %s
[main]
bind=127.0.0.1:8333
rpcbind=127.0.0.1:8332
[test]
bind=127.0.0.1:18333
rpcbind=127.0.0.1:18332