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

Define gRPC api call rate constraints #5103

Merged
merged 2 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@
import bisq.proto.grpc.RegisterDisputeAgentReply;
import bisq.proto.grpc.RegisterDisputeAgentRequest;

import io.grpc.ServerInterceptor;
import io.grpc.stub.StreamObserver;

import javax.inject.Inject;

import java.util.HashMap;
import java.util.Optional;

import lombok.extern.slf4j.Slf4j;

import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
import static java.util.concurrent.TimeUnit.SECONDS;



import bisq.daemon.grpc.interceptor.CallRateMeteringInterceptor;
import bisq.daemon.grpc.interceptor.GrpcCallRateMeter;

@Slf4j
class GrpcDisputeAgentsService extends DisputeAgentsGrpc.DisputeAgentsImplBase {

Expand All @@ -36,4 +48,22 @@ public void registerDisputeAgent(RegisterDisputeAgentRequest req,
exceptionHandler.handleException(cause, responseObserver);
}
}

final ServerInterceptor[] interceptors() {
Optional<ServerInterceptor> rateMeteringInterceptor = rateMeteringInterceptor();
return rateMeteringInterceptor.map(serverInterceptor ->
new ServerInterceptor[]{serverInterceptor}).orElseGet(() -> new ServerInterceptor[0]);
}

final Optional<ServerInterceptor> rateMeteringInterceptor() {
CallRateMeteringInterceptor defaultCallRateMeteringInterceptor =
new CallRateMeteringInterceptor(new HashMap<>() {{
// You can only register mainnet dispute agents in the UI.
// Do not limit devs' ability to register test agents.
put("registerDisputeAgent", new GrpcCallRateMeter(1, SECONDS));
}});

return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
.or(() -> Optional.of(defaultCallRateMeteringInterceptor));
}
ghubstan marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,23 @@
import bisq.proto.grpc.GetTradeStatisticsReply;
import bisq.proto.grpc.GetTradeStatisticsRequest;

import io.grpc.ServerInterceptor;
import io.grpc.stub.StreamObserver;

import javax.inject.Inject;

import java.util.HashMap;
import java.util.Optional;
import java.util.stream.Collectors;

import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
import static java.util.concurrent.TimeUnit.SECONDS;



import bisq.daemon.grpc.interceptor.CallRateMeteringInterceptor;
import bisq.daemon.grpc.interceptor.GrpcCallRateMeter;

class GrpcGetTradeStatisticsService extends GetTradeStatisticsGrpc.GetTradeStatisticsImplBase {

private final CoreApi coreApi;
Expand All @@ -39,4 +50,20 @@ public void getTradeStatistics(GetTradeStatisticsRequest req,
exceptionHandler.handleException(cause, responseObserver);
}
}

final ServerInterceptor[] interceptors() {
Optional<ServerInterceptor> rateMeteringInterceptor = rateMeteringInterceptor();
return rateMeteringInterceptor.map(serverInterceptor ->
new ServerInterceptor[]{serverInterceptor}).orElseGet(() -> new ServerInterceptor[0]);
}

final Optional<ServerInterceptor> rateMeteringInterceptor() {
CallRateMeteringInterceptor defaultCallRateMeteringInterceptor =
new CallRateMeteringInterceptor(new HashMap<>() {{
put("getTradeStatistics", new GrpcCallRateMeter(1, SECONDS));
}});

return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
.or(() -> Optional.of(defaultCallRateMeteringInterceptor));
}
}
28 changes: 28 additions & 0 deletions daemon/src/main/java/bisq/daemon/grpc/GrpcHelpService.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@
import bisq.proto.grpc.GetMethodHelpRequest;
import bisq.proto.grpc.HelpGrpc;

import io.grpc.ServerInterceptor;
import io.grpc.stub.StreamObserver;

import javax.inject.Inject;

import java.util.HashMap;
import java.util.Optional;

import lombok.extern.slf4j.Slf4j;

import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
import static java.util.concurrent.TimeUnit.SECONDS;



import bisq.daemon.grpc.interceptor.CallRateMeteringInterceptor;
import bisq.daemon.grpc.interceptor.GrpcCallRateMeter;

@Slf4j
class GrpcHelpService extends HelpGrpc.HelpImplBase {

Expand All @@ -53,4 +65,20 @@ public void getMethodHelp(GetMethodHelpRequest req,
exceptionHandler.handleException(cause, responseObserver);
}
}

final ServerInterceptor[] interceptors() {
Optional<ServerInterceptor> rateMeteringInterceptor = rateMeteringInterceptor();
return rateMeteringInterceptor.map(serverInterceptor ->
new ServerInterceptor[]{serverInterceptor}).orElseGet(() -> new ServerInterceptor[0]);
}

final Optional<ServerInterceptor> rateMeteringInterceptor() {
CallRateMeteringInterceptor defaultCallRateMeteringInterceptor =
new CallRateMeteringInterceptor(new HashMap<>() {{
put("getMethodHelp", new GrpcCallRateMeter(1, SECONDS));
}});

return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
.or(() -> Optional.of(defaultCallRateMeteringInterceptor));
}
}
32 changes: 32 additions & 0 deletions daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,27 @@
import bisq.proto.grpc.GetOffersRequest;
import bisq.proto.grpc.OffersGrpc;

import io.grpc.ServerInterceptor;
import io.grpc.stub.StreamObserver;

import javax.inject.Inject;

import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

import static bisq.core.api.model.OfferInfo.toOfferInfo;
import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;



import bisq.daemon.grpc.interceptor.CallRateMeteringInterceptor;
import bisq.daemon.grpc.interceptor.GrpcCallRateMeter;

@Slf4j
class GrpcOffersService extends OffersGrpc.OffersImplBase {
Expand Down Expand Up @@ -171,4 +182,25 @@ public void cancelOffer(CancelOfferRequest req,
exceptionHandler.handleException(cause, responseObserver);
}
}

final ServerInterceptor[] interceptors() {
Optional<ServerInterceptor> rateMeteringInterceptor = rateMeteringInterceptor();
return rateMeteringInterceptor.map(serverInterceptor ->
new ServerInterceptor[]{serverInterceptor}).orElseGet(() -> new ServerInterceptor[0]);
}

final Optional<ServerInterceptor> rateMeteringInterceptor() {
CallRateMeteringInterceptor defaultCallRateMeteringInterceptor =
new CallRateMeteringInterceptor(new HashMap<>() {{
put("getOffer", new GrpcCallRateMeter(1, SECONDS));
put("getMyOffer", new GrpcCallRateMeter(1, SECONDS));
put("getOffers", new GrpcCallRateMeter(1, SECONDS));
put("getMyOffers", new GrpcCallRateMeter(1, SECONDS));
put("createOffer", new GrpcCallRateMeter(1, MINUTES));
put("cancelOffer", new GrpcCallRateMeter(1, MINUTES));
}});

return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
.or(() -> Optional.of(defaultCallRateMeteringInterceptor));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,24 @@
import bisq.proto.grpc.GetPaymentMethodsRequest;
import bisq.proto.grpc.PaymentAccountsGrpc;

import io.grpc.ServerInterceptor;
import io.grpc.stub.StreamObserver;

import javax.inject.Inject;

import java.util.HashMap;
import java.util.Optional;
import java.util.stream.Collectors;

import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;



import bisq.daemon.grpc.interceptor.CallRateMeteringInterceptor;
import bisq.daemon.grpc.interceptor.GrpcCallRateMeter;


class GrpcPaymentAccountsService extends PaymentAccountsGrpc.PaymentAccountsImplBase {

Expand Down Expand Up @@ -110,4 +122,23 @@ public void getPaymentAccountForm(GetPaymentAccountFormRequest req,
exceptionHandler.handleException(cause, responseObserver);
}
}

final ServerInterceptor[] interceptors() {
Optional<ServerInterceptor> rateMeteringInterceptor = rateMeteringInterceptor();
return rateMeteringInterceptor.map(serverInterceptor ->
new ServerInterceptor[]{serverInterceptor}).orElseGet(() -> new ServerInterceptor[0]);
}

final Optional<ServerInterceptor> rateMeteringInterceptor() {
CallRateMeteringInterceptor defaultCallRateMeteringInterceptor =
new CallRateMeteringInterceptor(new HashMap<>() {{
put("createPaymentAccount", new GrpcCallRateMeter(1, MINUTES));
put("getPaymentAccounts", new GrpcCallRateMeter(1, SECONDS));
put("getPaymentMethods", new GrpcCallRateMeter(1, SECONDS));
put("getPaymentAccountForm", new GrpcCallRateMeter(1, SECONDS));
}});

return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
.or(() -> Optional.of(defaultCallRateMeteringInterceptor));
}
}
28 changes: 28 additions & 0 deletions daemon/src/main/java/bisq/daemon/grpc/GrpcPriceService.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@
import bisq.proto.grpc.MarketPriceRequest;
import bisq.proto.grpc.PriceGrpc;

import io.grpc.ServerInterceptor;
import io.grpc.stub.StreamObserver;

import javax.inject.Inject;

import java.util.HashMap;
import java.util.Optional;

import lombok.extern.slf4j.Slf4j;

import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
import static java.util.concurrent.TimeUnit.SECONDS;



import bisq.daemon.grpc.interceptor.CallRateMeteringInterceptor;
import bisq.daemon.grpc.interceptor.GrpcCallRateMeter;

@Slf4j
class GrpcPriceService extends PriceGrpc.PriceImplBase {

Expand All @@ -55,4 +67,20 @@ public void getMarketPrice(MarketPriceRequest req,
exceptionHandler.handleException(cause, responseObserver);
}
}

final ServerInterceptor[] interceptors() {
Optional<ServerInterceptor> rateMeteringInterceptor = rateMeteringInterceptor();
return rateMeteringInterceptor.map(serverInterceptor ->
new ServerInterceptor[]{serverInterceptor}).orElseGet(() -> new ServerInterceptor[0]);
}

final Optional<ServerInterceptor> rateMeteringInterceptor() {
CallRateMeteringInterceptor defaultCallRateMeteringInterceptor =
new CallRateMeteringInterceptor(new HashMap<>() {{
put("getMarketPrice", new GrpcCallRateMeter(1, SECONDS));
}});

return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
.or(() -> Optional.of(defaultCallRateMeteringInterceptor));
}
}
16 changes: 8 additions & 8 deletions daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ public GrpcServer(CoreContext coreContext,
GrpcWalletsService walletsService) {
this.server = ServerBuilder.forPort(config.apiPort)
.executor(UserThread.getExecutor())
.addService(disputeAgentsService)
.addService(helpService)
.addService(offersService)
.addService(paymentAccountsService)
.addService(priceService)
.addService(tradeStatisticsService)
.addService(tradesService)
.addService(interceptForward(disputeAgentsService, disputeAgentsService.interceptors()))
.addService(interceptForward(helpService, helpService.interceptors()))
.addService(interceptForward(offersService, offersService.interceptors()))
.addService(interceptForward(paymentAccountsService, paymentAccountsService.interceptors()))
.addService(interceptForward(priceService, priceService.interceptors()))
.addService(interceptForward(tradeStatisticsService, tradeStatisticsService.interceptors()))
.addService(interceptForward(tradesService, tradesService.interceptors()))
.addService(interceptForward(versionService, versionService.interceptors()))
.addService(walletsService)
.addService(interceptForward(walletsService, walletsService.interceptors()))
.intercept(passwordAuthInterceptor)
.build();
coreContext.setApiUser(true);
Expand Down
33 changes: 33 additions & 0 deletions daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,25 @@
import bisq.proto.grpc.WithdrawFundsReply;
import bisq.proto.grpc.WithdrawFundsRequest;

import io.grpc.ServerInterceptor;
import io.grpc.stub.StreamObserver;

import javax.inject.Inject;

import java.util.HashMap;
import java.util.Optional;

import lombok.extern.slf4j.Slf4j;

import static bisq.core.api.model.TradeInfo.toTradeInfo;
import static bisq.daemon.grpc.interceptor.GrpcServiceRateMeteringConfig.getCustomRateMeteringInterceptor;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;



import bisq.daemon.grpc.interceptor.CallRateMeteringInterceptor;
import bisq.daemon.grpc.interceptor.GrpcCallRateMeter;

@Slf4j
class GrpcTradesService extends TradesGrpc.TradesImplBase {
Expand Down Expand Up @@ -142,4 +154,25 @@ public void withdrawFunds(WithdrawFundsRequest req,
exceptionHandler.handleException(cause, responseObserver);
}
}

final ServerInterceptor[] interceptors() {
Optional<ServerInterceptor> rateMeteringInterceptor = rateMeteringInterceptor();
return rateMeteringInterceptor.map(serverInterceptor ->
new ServerInterceptor[]{serverInterceptor}).orElseGet(() -> new ServerInterceptor[0]);
}

final Optional<ServerInterceptor> rateMeteringInterceptor() {
CallRateMeteringInterceptor defaultCallRateMeteringInterceptor =
new CallRateMeteringInterceptor(new HashMap<>() {{
put("getTrade", new GrpcCallRateMeter(1, SECONDS));
put("takeOffer", new GrpcCallRateMeter(1, MINUTES));
put("confirmPaymentStarted", new GrpcCallRateMeter(1, MINUTES));
put("confirmPaymentReceived", new GrpcCallRateMeter(1, MINUTES));
put("keepFunds", new GrpcCallRateMeter(1, MINUTES));
put("withdrawFunds", new GrpcCallRateMeter(1, MINUTES));
}});

return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
.or(() -> Optional.of(defaultCallRateMeteringInterceptor));
}
}
5 changes: 2 additions & 3 deletions daemon/src/main/java/bisq/daemon/grpc/GrpcVersionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,12 @@ final ServerInterceptor[] interceptors() {
}

final Optional<ServerInterceptor> rateMeteringInterceptor() {
@SuppressWarnings("unused") // Defined as a usage example.
CallRateMeteringInterceptor defaultCallRateMeteringInterceptor =
new CallRateMeteringInterceptor(new HashMap<>() {{
put("getVersion", new GrpcCallRateMeter(100, SECONDS));
put("getVersion", new GrpcCallRateMeter(1, SECONDS));
}});

return getCustomRateMeteringInterceptor(coreApi.getConfig().appDataDir, this.getClass())
.or(Optional::empty /* Optional.of(defaultCallRateMeteringInterceptor) */);
.or(() -> Optional.of(defaultCallRateMeteringInterceptor));
}
}
Loading