Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce gRPC API proof of concept #3888

Merged
merged 14 commits into from
Jan 20, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 70 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ configure(subprojects) {
bitcoinjVersion = 'a88d36d'
btcdCli4jVersion = '975ff5d4'
codecVersion = '1.9'
commonProtosVersion = '1.17.0'
easybindVersion = '1.0.3'
easyVersion = '4.0.1'
findbugsVersion = '3.0.2'
firebaseVersion = '6.2.0'
fontawesomefxVersion = '8.0.0'
fontawesomefxCommonsVersion = '9.1.2'
fontawesomefxMaterialdesignfontVersion = '2.0.26-9.1.2'
grpcVersion = '1.25.0'
guavaVersion = '20.0'
guiceVersion = '4.2.2'
hamcrestVersion = '1.3'
Expand All @@ -58,6 +60,7 @@ configure(subprojects) {
logbackVersion = '1.1.10'
lombokVersion = '1.18.2'
mockitoVersion = '3.0.0'
nettyTcNativeVersion = '2.0.27.Final'
netlayerVersion = '0.6.5.2'
protobufVersion = '3.9.1'
pushyVersion = '0.13.2'
Expand Down Expand Up @@ -91,7 +94,8 @@ configure([project(':desktop'),
project(':relay'),
project(':seednode'),
project(':statsnode'),
project(':pricenode')]) {
project(':pricenode'),
project(':grpc')]) {

apply plugin: 'application'

Expand Down Expand Up @@ -267,7 +271,6 @@ configure(project(':core')) {
}
}


configure(project(':desktop')) {
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'witness'
Expand All @@ -286,6 +289,7 @@ configure(project(':desktop')) {

dependencies {
compile project(':core')
compile project(':grpc')
compile "net.glxn:qrgen:$qrgenVersion"
compile "de.jensd:fontawesomefx:$fontawesomefxVersion"
compile "de.jensd:fontawesomefx-commons:$fontawesomefxCommonsVersion"
Expand Down Expand Up @@ -402,3 +406,67 @@ configure(project(':statsnode')) {
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
}
}

configure(project(':grpc')) {
apply plugin: 'com.google.protobuf'

mainClassName = 'bisq.grpc.BisqGrpcServerMain'

// FIXME we dont want to have one src dir inside the other....
sourceSets.main.java.srcDir "$buildDir/generated/source/proto/main"
sourceSets.main.java.srcDir "$buildDir/generated/source/proto/main/java"

protobuf {
protoc {
artifact = "com.google.protobuf:protoc:$protobufVersion"
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:$grpcVersion"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}

dependencies {
compile project(':core')
compile "com.google.protobuf:protobuf-java:$protobufVersion"
compile "com.google.api.grpc:proto-google-common-protos:$commonProtosVersion"

// FIXME Not clear which of the following libs have a newer version of guava which is not compatible with ours
compile ("io.grpc:grpc-alts:$grpcVersion") {
exclude(module: 'guava')
}

compile ("io.grpc:grpc-netty:$grpcVersion") {
exclude(module: 'guava')
}


compile ("io.grpc:grpc-protobuf:$grpcVersion") {
exclude(module: 'guava')
}

compile ("io.grpc:grpc-stub:$grpcVersion") {
exclude(module: 'guava')
}

// Used for TLS in HelloWorldServerTls
compile "io.netty:netty-tcnative-boringssl-static:${nettyTcNativeVersion}"

compileOnly "org.projectlombok:lombok:$lombokVersion"
compileOnly "javax.annotation:javax.annotation-api:1.2"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"

testCompile "io.grpc:grpc-testing:${grpcVersion}"
testCompile "org.mockito:mockito-core:$mockitoVersion"
testCompile "org.springframework:spring-test:$springVersion"
testCompile "com.natpryce:make-it-easy:$easyVersion"
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
}
}
163 changes: 163 additions & 0 deletions core/src/main/java/bisq/core/CoreApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* 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.core;

import bisq.core.btc.Balances;
import bisq.core.monetary.Price;
import bisq.core.offer.CreateOfferService;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferBookService;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.PaymentAccount;
import bisq.core.presentation.BalancePresentation;
import bisq.core.trade.handlers.TransactionResultHandler;
import bisq.core.trade.statistics.TradeStatistics2;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.user.User;

import bisq.common.app.Version;

import org.bitcoinj.core.Coin;

import javax.inject.Inject;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import lombok.extern.slf4j.Slf4j;

/**
* Provides high level interface to functionality of core Bisq features.
* E.g. useful for different APIs to access data of different domains of Bisq.
*/
@Slf4j
public class CoreApi {
private final Balances balances;
private final BalancePresentation balancePresentation;
private final OfferBookService offerBookService;
private final TradeStatisticsManager tradeStatisticsManager;
private final CreateOfferService createOfferService;
private final OpenOfferManager openOfferManager;
private final User user;

@Inject
public CoreApi(Balances balances,
BalancePresentation balancePresentation,
OfferBookService offerBookService,
TradeStatisticsManager tradeStatisticsManager,
CreateOfferService createOfferService,
OpenOfferManager openOfferManager,
User user) {
this.balances = balances;
this.balancePresentation = balancePresentation;
this.offerBookService = offerBookService;
this.tradeStatisticsManager = tradeStatisticsManager;
this.createOfferService = createOfferService;
this.openOfferManager = openOfferManager;
this.user = user;
}

public String getVersion() {
return Version.VERSION;
}

public long getAvailableBalance() {
return balances.getAvailableBalance().get().getValue();
}

public String getAvailableBalanceAsString() {
return balancePresentation.getAvailableBalance().get();
}

public List<TradeStatistics2> getTradeStatistics() {
return new ArrayList<>(tradeStatisticsManager.getObservableTradeStatisticsSet());
}

public List<Offer> getOffers() {
return offerBookService.getOffers();
}

public Set<PaymentAccount> getPaymentAccounts() {
return user.getPaymentAccounts();
}

public void placeOffer(String currencyCode,
String directionAsString,
long priceAsLong,
boolean useMarketBasedPrice,
double marketPriceMargin,
long amountAsLong,
long minAmountAsLong,
double buyerSecurityDeposit,
String paymentAccountId,
TransactionResultHandler resultHandler) {
String offerId = createOfferService.getRandomOfferId();
OfferPayload.Direction direction = OfferPayload.Direction.valueOf(directionAsString);
Price price = Price.valueOf(currencyCode, priceAsLong);
Coin amount = Coin.valueOf(amountAsLong);
Coin minAmount = Coin.valueOf(minAmountAsLong);
PaymentAccount paymentAccount = user.getPaymentAccount(paymentAccountId);
// We don't support atm funding from external wallet to keep it simple
boolean useSavingsWallet = true;

placeOffer(offerId,
currencyCode,
direction,
price,
useMarketBasedPrice,
marketPriceMargin,
amount,
minAmount,
buyerSecurityDeposit,
paymentAccount,
useSavingsWallet,
resultHandler);
}

public void placeOffer(String offerId,
String currencyCode,
OfferPayload.Direction direction,
Price price,
boolean useMarketBasedPrice,
double marketPriceMargin,
Coin amount,
Coin minAmount,
double buyerSecurityDeposit,
PaymentAccount paymentAccount,
boolean useSavingsWallet,
TransactionResultHandler resultHandler) {
Offer offer = createOfferService.createAndGetOffer(offerId,
direction,
currencyCode,
amount,
minAmount,
price,
useMarketBasedPrice,
marketPriceMargin,
buyerSecurityDeposit,
paymentAccount);

openOfferManager.placeOffer(offer,
buyerSecurityDeposit,
useSavingsWallet,
resultHandler,
log::error);
}
}
2 changes: 0 additions & 2 deletions core/src/main/java/bisq/core/app/AppOptionKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
package bisq.core.app;

public class AppOptionKeys {
public static final String DESKTOP_WITH_HTTP_API = "desktopWithHttpApi";
public static final String DESKTOP_WITH_GRPC_API = "desktopWithGrpcApi";
public static final String APP_NAME_KEY = "appName";
public static final String USER_DATA_DIR_KEY = "userDataDir";
public static final String APP_DATA_DIR_KEY = "appDataDir";
Expand Down
6 changes: 0 additions & 6 deletions core/src/main/java/bisq/core/app/BisqEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,6 @@ public static boolean isDaoActivated(Environment environment) {
@Setter
protected boolean isBitcoinLocalhostNodeRunning;
@Getter
protected String desktopWithHttpApi, desktopWithGrpcApi;
@Getter
protected List<String> bannedSeedNodes, bannedBtcNodes, bannedPriceRelayNodes;

protected final String btcNodes, seedNodes, ignoreDevMsg, useDevPrivilegeKeys, useDevMode, useTorForBtc, rpcUser, rpcPassword,
Expand Down Expand Up @@ -219,8 +217,6 @@ public BisqEnvironment(PropertySource commandLineProperties) {
appDataDir = getProperty(commandLineProperties, AppOptionKeys.APP_DATA_DIR_KEY, appDataDir(userDataDir, appName));
staticAppDataDir = appDataDir;

desktopWithHttpApi = getProperty(commandLineProperties, AppOptionKeys.DESKTOP_WITH_HTTP_API, "false");
desktopWithGrpcApi = getProperty(commandLineProperties, AppOptionKeys.DESKTOP_WITH_GRPC_API, "false");
ignoreDevMsg = getProperty(commandLineProperties, AppOptionKeys.IGNORE_DEV_MSG_KEY, "");
useDevPrivilegeKeys = getProperty(commandLineProperties, AppOptionKeys.USE_DEV_PRIVILEGE_KEYS, "");
referralId = getProperty(commandLineProperties, AppOptionKeys.REFERRAL_ID, "");
Expand Down Expand Up @@ -398,8 +394,6 @@ private PropertySource<?> defaultProperties() {
setProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_SLEEP, sendMsgThrottleSleep);

setProperty(AppOptionKeys.APP_DATA_DIR_KEY, appDataDir);
setProperty(AppOptionKeys.DESKTOP_WITH_HTTP_API, desktopWithHttpApi);
setProperty(AppOptionKeys.DESKTOP_WITH_GRPC_API, desktopWithGrpcApi);
setProperty(AppOptionKeys.IGNORE_DEV_MSG_KEY, ignoreDevMsg);
setProperty(AppOptionKeys.USE_DEV_PRIVILEGE_KEYS, useDevPrivilegeKeys);
setProperty(AppOptionKeys.REFERRAL_ID, referralId);
Expand Down
10 changes: 0 additions & 10 deletions core/src/main/java/bisq/core/app/BisqExecutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -446,16 +446,6 @@ protected void customizeOptionParsing(OptionParser parser) {
.withRequiredArg()
.ofType(boolean.class);

parser.accepts(AppOptionKeys.DESKTOP_WITH_HTTP_API,
format("If set to true Bisq Desktop starts with Http API (default: %s)", "false"))
.withRequiredArg()
.ofType(boolean.class);

parser.accepts(AppOptionKeys.DESKTOP_WITH_GRPC_API,
format("If set to true Bisq Desktop starts with gRPC API (default: %s)", "false"))
.withRequiredArg()
.ofType(boolean.class);

parser.accepts(AppOptionKeys.USE_DEV_PRIVILEGE_KEYS,
format("If that is true all the privileged features which requires a private key " +
"to enable it are overridden by a dev key pair (This is for developers only!) (default: %s)", "false"))
Expand Down
22 changes: 4 additions & 18 deletions desktop/src/main/java/bisq/desktop/app/BisqAppMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@ public BisqAppMain() {
super("Bisq Desktop", "bisq-desktop", Version.VERSION);
}

/* @Nullable
private BisqHttpApiServer bisqHttpApiServer;*/
/* @Nullable
private BisqGrpcServer bisqGrpcServer;
*/
public static void main(String[] args) throws Exception {
if (BisqExecutable.setupInitialOptionParser(args)) {
// For some reason the JavaFX launch process results in us losing the thread context class loader: reset it.
Expand Down Expand Up @@ -135,20 +130,11 @@ protected void startApplication() {
protected void onApplicationStarted() {
super.onApplicationStarted();

/* if (runWithHttpApi()) {
bisqHttpApiServer = new BisqHttpApiServer();
}*/
/*
if (runWithGrpcApi()) {
bisqGrpcServer = new BisqGrpcServer();
}*/
}

private boolean runWithHttpApi() {
return bisqEnvironment.getDesktopWithHttpApi().toLowerCase().equals("true");
}

private boolean runWithGrpcApi() {
return bisqEnvironment.getDesktopWithGrpcApi().toLowerCase().equals("true");
CoreApi coreApi = injector.getInstance(CoreApi.class);
bisqGrpcServer = new BisqGrpcServer(coreApi);
}
*/
}
}
Loading