From 02965e286c99e7dcd53162a634c932f41260e2e6 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 26 Jan 2024 11:55:16 +0000 Subject: [PATCH] Build .adoc Files for GitHub Pages from 1f841da1d2b28b82c1e4a281b3b91d3395959ad8 --- .github/workflows/publish.yaml | 54 - .github/workflows/static.yml | 40 - .github/workflows/test.yaml | 45 - README.adoc | 212 --- README.html | 808 ++++++++++++ docs/00-intro.adoc | 28 - docs/00-intro.html | 511 ++++++++ docs/01-architecture-intro.adoc | 73 -- docs/01-architecture-intro.html | 595 +++++++++ docs/02-quick-start.adoc | 151 --- docs/02-quick-start.html | 656 ++++++++++ docs/03-server-config.adoc | 203 --- docs/03-server-config.html | 798 ++++++++++++ docs/04-upstream-config.adoc | 408 ------ docs/04-upstream-config.html | 1342 +++++++++++++++++++ docs/05-start.adoc | 20 - docs/05-start.html | 485 +++++++ docs/06-monitoring.adoc | 191 --- docs/06-monitoring.html | 777 +++++++++++ docs/07-methods.adoc | 260 ---- docs/07-methods.html | 875 +++++++++++++ docs/08-authentication.adoc | 196 --- docs/08-authentication.html | 707 ++++++++++ docs/09-quorum-and-selectors.adoc | 7 - docs/09-quorum-and-selectors.html | 463 +++++++ docs/10-caching.adoc | 67 - docs/10-caching.html | 540 ++++++++ docs/99-ending.adoc | 12 - docs/99-ending.html | 476 +++++++ docs/README.adoc | 57 - docs/README.html | 585 +++++++++ docs/index.html | 1 + docs/reference-configuration.adoc | 947 -------------- docs/reference-configuration.html | 2009 +++++++++++++++++++++++++++++ index.html | 1 + 35 files changed, 11629 insertions(+), 2971 deletions(-) delete mode 100644 .github/workflows/publish.yaml delete mode 100644 .github/workflows/static.yml delete mode 100644 .github/workflows/test.yaml delete mode 100644 README.adoc create mode 100644 README.html delete mode 100644 docs/00-intro.adoc create mode 100644 docs/00-intro.html delete mode 100644 docs/01-architecture-intro.adoc create mode 100644 docs/01-architecture-intro.html delete mode 100644 docs/02-quick-start.adoc create mode 100644 docs/02-quick-start.html delete mode 100644 docs/03-server-config.adoc create mode 100644 docs/03-server-config.html delete mode 100644 docs/04-upstream-config.adoc create mode 100644 docs/04-upstream-config.html delete mode 100644 docs/05-start.adoc create mode 100644 docs/05-start.html delete mode 100644 docs/06-monitoring.adoc create mode 100644 docs/06-monitoring.html delete mode 100644 docs/07-methods.adoc create mode 100644 docs/07-methods.html delete mode 100644 docs/08-authentication.adoc create mode 100644 docs/08-authentication.html delete mode 100644 docs/09-quorum-and-selectors.adoc create mode 100644 docs/09-quorum-and-selectors.html delete mode 100644 docs/10-caching.adoc create mode 100644 docs/10-caching.html delete mode 100644 docs/99-ending.adoc create mode 100644 docs/99-ending.html delete mode 100644 docs/README.adoc create mode 100644 docs/README.html create mode 120000 docs/index.html delete mode 100644 docs/reference-configuration.adoc create mode 100644 docs/reference-configuration.html create mode 120000 index.html diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml deleted file mode 100644 index dc65f5184..000000000 --- a/.github/workflows/publish.yaml +++ /dev/null @@ -1,54 +0,0 @@ -name: Publish -on: - release: - types: [created] - push: - tags: - - '*' - workflow_dispatch: - -jobs: - publish-docker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.ref }} - submodules: recursive - - name: Set up JDK - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: 20 - - name: Setup gradle - uses: gradle/gradle-build-action@v2 - - name: Upload to Docker - run: make jib - env: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - - publish-github: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.ref }} - submodules: recursive - - name: Set up JDK - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: 20 - - name: Setup gradle - uses: gradle/gradle-build-action@v2 - - name: Build zip - run: make distZip - - name: Upload Release - id: upload-release-asset - uses: svenstaro/upload-release-action@v1-release - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ github.ref }} - file: ./build/distributions/*.zip - file_glob: true diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml deleted file mode 100644 index be4ee76e6..000000000 --- a/.github/workflows/static.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Simple workflow for deploying static content to GitHub Pages -name: Deploy static content to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ["master"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Single deploy job since we're just deploying - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: asciidoctor-ghpages - uses: manoelcampos/asciidoctor-ghpages-action@v2 - - name: Setup Pages - uses: actions/configure-pages@v4 - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - # Upload entire repository - path: '.' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml deleted file mode 100644 index d38b06ac9..000000000 --- a/.github/workflows/test.yaml +++ /dev/null @@ -1,45 +0,0 @@ -name: Tests - -on: - # if pushed directly - push: - branches: - - master - - release/* - - ci/* - # on a pull request - pull_request: - branches: - - master - - release/* - - ci/* - -jobs: - unit-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: recursive - - name: Set up JDK - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: 20 - - - name: Install System Libs - run: sudo apt-get install -y openssl libapr1 - - name: Setup gradle - uses: gradle/gradle-build-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - - name: Check - run: make test - env: - CI: true - - - name: Upload Coverage Report - uses: codecov/codecov-action@v1 - with: - file: ./build/reports/jacoco/test/jacocoTestReport.xml diff --git a/README.adoc b/README.adoc deleted file mode 100644 index 98f7466ea..000000000 --- a/README.adoc +++ /dev/null @@ -1,212 +0,0 @@ -= Dshackle -:imagesdir: docs/assets -ifdef::env-github[] -:imagesdir: https://raw.githubusercontent.com/emeraldpay/dshackle/master/docs/assets -endif::[] -:version: 0.12.0 -:version-short: 0.12 - -image:https://github.com/p2p-org/dshackle/workflows/Tests/badge.svg["Unit Tests"] -image:https://img.shields.io/github/license/p2p-org/dshackle.svg?style=flat-square&maxAge=2592000["License",link="https://github.com/emeraldpay/dshackle/blob/master/LICENSE"] - -[.lead] -_Dshackle is a Fault Tolerant Load Balancer for Blockchain API used at https://drpc.org/[DRPC]_ - -Is is a fork of the https://github.com/emeraldpay/dshackle[EmeraldPay's dshackle], adapted to work as a provider side adapter for the DRPC network. This project is specifically designed to integrate providers into the https://drpc.org/[DRPC] network, which is distinguished by its focus on low latency and high availability. Our service facilitates providers in easily connecting to the DRPC, enabling them to be part of a network that prioritizes robust, consistent, and responsive operations. Joining this network through our adapted service allows providers to contribute towards creating a highly available and resilient decentralized system. - -The goal of the Dshackle is to provide a stable routing to multiple nodes, and ensure that each request is executed on an appropriate provider. -It considers nodes locations, state, current height, RPC methods it can provide and other characteristics. - -It tries to recover from connection errors, faulty nodes, invalid responses, etc. -If upstream lags behind others, lost peers below required, started to resync or went down, then Dshackle temporarily excludes it from requests and returns it when the upstream problem is fixed. - -The upstreams may be blockchain nodes such as Bitcoind, Geth, Parity, or public providers like DRPC. -It automatically verifies their availability and the current status of the network, executes commands making sure that the response is consistent and/or data successfully broadcast to the network. - -Provides: - -- Standard Bitcoin and Ethereum JSON RPC API over HTTP and WebSocket -- Enhanced gRPC-based API, with upstream selection, async execution, etc -- **Secure** TLS with optional client authentication -- Blockchain-aware edge **caching**, in memory and Redis -- Routing based on **data availability** (peers, height, sync status) -- **Data consistency**, it always gives a most actual state -- Automatic **failover** and retry -- Separate public blockchain nodes from your internal servers - -Blockchains support: - -* Ethereum like -** Mainnet and testnets -** Arbitrum -** Optimism -** BSC -* Starknet -* Solana -* Varanet -* Bitcoin - -...and more - -Full list of supported blockchains - link:foundation/src/main/resources/chains.yaml[here]. Feel free to contribute new chains. - -Architecture: - -image::dshackle-intro.png[alt="",width=80%,align="center"] - -WARNING: The project is still under development, please use with caution. - -== Quick Start - -=== Configuration - -Create file `dshackle.yaml` with the following content: - -[source,yaml] ----- -version: v1 -port: 2449 -tls: - enabled: false - -proxy: - host: 0.0.0.0 - port: 8545 - routes: - - id: eth - blockchain: ethereum - - id: btc - blockchain: bitcoin - -cluster: - upstreams: - - id: drpc-eth - chain: ethereum - connection: - generic: - rpc: - url: "https://lb.drpc.org/ogrpc?network=ethereum&dkey=${DRPC_KEY}" - ws: - url: "wss://lb.drpc.org/ogws?network=ethereum&dkey=${DRPC_KEY}" - - id: solana - chain: solana - connection: - generic: - rpc: - url: "https://localhost:8899" - ws: - url: "wss://localhost:8900" - - id: bitcoin-main - chain: bitcoin - connection: - bitcoin: - rpc: - url: "http://localhost:8332" - basic-auth: - username: bitcoin - password: mypassword ----- - -Which sets the following: - -- gRPC access through 0.0.0.0:2449 -** TLS security is disabled (_please don't use in production!_) -** compression is disabled for gRPC server (enabled by default) -- JSON RPC access through 0.0.0.0:8545 (both HTTP and WebsScket) -** proxy requests to Ethereum and Bitcoin upstreams -** request path for Ethereum Mainnet is `/eth` and `/btc` for bitcoin -** i.e. call Ethereum Mainnet by `POST http://127.0.0.0:8545/eth` with JSON RPC payload -- three upstreams - ethereum, solana and bitcoin -- for Ethereum Mainnet it connects using JSON RPC and WebSocket connections, -- for Bitcoin Mainnet only JSON RPC is used -- `${DRPC_KEY}` will be provided through environment variable - -Please note that you can configure many upstreams for a single blockchains. -If there is more than one upstream, then Dshackle routes requests to them as Round Robin. -If one of them becomes unavailable, Dshackle continues to use only active nodes. - -I.e., you can set up a node in the local network, plus Infura with `role: fallback`. -If anything happened to your local node, you still have access to a consistent state of the Ethereum blockchain via Infura. - -link:docs[See full documentations]. - -==== Run docker image - -Official Docker image you can find at: https://hub.docker.com/r/p2p-org/dshackle[p2p-org/dshackle] - -.Setup DRPC key -[source,bash] ----- -export DRPC_KEY=... ----- - -.Run Dshackle -[source,bash,subs="attributes"] ----- -docker run -p 2449:2449 -p 8545:8545 -v $(pwd):/etc/dshackle -e "DRPC_KEY=$INFURA_USER" emeraldpay/dshackle:{version-short} ----- - -Now it listens on port 2449 at the localhost and can be connected from any gRPC compatible client. -Tools such as https://github.com/fullstorydev/grpcurl[gRPCurl] can use protobuf definitions from proto reflection and connect to it - -Alternatively you can connect to port 8545 with traditional JSON RPC requests - -== Documentation - -For detailed documentation see link:docs/[] directory. - -== Development - -WARNING: The code in `master` branch is considered a development version, which may lack proper testing and should not be used in production. - -=== Setting up environment - -Dshackle is JVM based project written in Kotlin. -To build and run it from sources you'll need to install https://openjdk.org/projects/jdk/20/[Java JDK] and https://gradle.org/[Gradle] - -=== Build Dshackle - -==== Build everything - -[source,bash] ----- -gradle build ----- - -==== Make a Zip distribution - -[source,bash] ----- -gradle distZip ----- - -You can find a redistributable zip in `build/distributions` - -==== Make a Docker distribution - -[source, bash] ----- -gradle jib -Pdocker=gcr.io/myproject ----- - -Gradle will prepare a Docker image and upload it to your custom Docker Registry at `gcr.io/myproject` (please change to address of your actual registry) - -== Community - -Join our https://drpc.org/discord[Discord] - -== License - -Copyright 2021 EmeraldPay, Inc - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and limitations under the License. - -=== Modifications Copyright: - -Modifications made by p2p.org in 2022 are licensed under the same Apache License, Version 2.0. These modifications are copyrighted by p2p.org. diff --git a/README.html b/README.html new file mode 100644 index 000000000..3d60f843a --- /dev/null +++ b/README.html @@ -0,0 +1,808 @@ + + + + + + + +Dshackle + + + + + +
+
+
+
+

Unit Tests +License

+
+
+

Dshackle is a Fault Tolerant Load Balancer for Blockchain API used at DRPC

+
+
+

Is is a fork of the EmeraldPay’s dshackle, adapted to work as a provider side adapter for the DRPC network. This project is specifically designed to integrate providers into the DRPC network, which is distinguished by its focus on low latency and high availability. Our service facilitates providers in easily connecting to the DRPC, enabling them to be part of a network that prioritizes robust, consistent, and responsive operations. Joining this network through our adapted service allows providers to contribute towards creating a highly available and resilient decentralized system.

+
+
+

The goal of the Dshackle is to provide a stable routing to multiple nodes, and ensure that each request is executed on an appropriate provider. +It considers nodes locations, state, current height, RPC methods it can provide and other characteristics.

+
+
+

It tries to recover from connection errors, faulty nodes, invalid responses, etc. +If upstream lags behind others, lost peers below required, started to resync or went down, then Dshackle temporarily excludes it from requests and returns it when the upstream problem is fixed.

+
+
+

The upstreams may be blockchain nodes such as Bitcoind, Geth, Parity, or public providers like DRPC. +It automatically verifies their availability and the current status of the network, executes commands making sure that the response is consistent and/or data successfully broadcast to the network.

+
+
+

Provides:

+
+
+
    +
  • +

    Standard Bitcoin and Ethereum JSON RPC API over HTTP and WebSocket

    +
  • +
  • +

    Enhanced gRPC-based API, with upstream selection, async execution, etc

    +
  • +
  • +

    Secure TLS with optional client authentication

    +
  • +
  • +

    Blockchain-aware edge caching, in memory and Redis

    +
  • +
  • +

    Routing based on data availability (peers, height, sync status)

    +
  • +
  • +

    Data consistency, it always gives a most actual state

    +
  • +
  • +

    Automatic failover and retry

    +
  • +
  • +

    Separate public blockchain nodes from your internal servers

    +
  • +
+
+
+

Blockchains support:

+
+
+
    +
  • +

    Ethereum like

    +
    +
      +
    • +

      Mainnet and testnets

      +
    • +
    • +

      Arbitrum

      +
    • +
    • +

      Optimism

      +
    • +
    • +

      BSC

      +
    • +
    +
    +
  • +
  • +

    Starknet

    +
  • +
  • +

    Solana

    +
  • +
  • +

    Varanet

    +
  • +
  • +

    Bitcoin

    +
  • +
+
+
+

…​and more

+
+
+

Full list of supported blockchains - here. Feel free to contribute new chains.

+
+
+

Architecture:

+
+
+
+ +
+
+
+ + + + + +
+
Warning
+
+The project is still under development, please use with caution. +
+
+
+
+
+

Quick Start

+
+
+

Configuration

+
+

Create file dshackle.yaml with the following content:

+
+
+
+
version: v1
+port: 2449
+tls:
+  enabled: false
+
+proxy:
+  host: 0.0.0.0
+  port: 8545
+  routes:
+    - id: eth
+      blockchain: ethereum
+    - id: btc
+      blockchain: bitcoin
+
+cluster:
+  upstreams:
+    - id: drpc-eth
+      chain: ethereum
+      connection:
+        generic:
+          rpc:
+            url: "https://lb.drpc.org/ogrpc?network=ethereum&dkey=${DRPC_KEY}"
+          ws:
+            url: "wss://lb.drpc.org/ogws?network=ethereum&dkey=${DRPC_KEY}"
+    - id: solana
+      chain: solana
+      connection:
+        generic:
+          rpc:
+            url: "https://localhost:8899"
+          ws:
+            url: "wss://localhost:8900"
+    - id: bitcoin-main
+      chain: bitcoin
+      connection:
+        bitcoin:
+          rpc:
+            url: "http://localhost:8332"
+            basic-auth:
+              username: bitcoin
+              password: mypassword
+
+
+
+

Which sets the following:

+
+
+
    +
  • +

    gRPC access through 0.0.0.0:2449

    +
    +
      +
    • +

      TLS security is disabled (please don’t use in production!)

      +
    • +
    • +

      compression is disabled for gRPC server (enabled by default)

      +
    • +
    +
    +
  • +
  • +

    JSON RPC access through 0.0.0.0:8545 (both HTTP and WebsScket)

    +
    +
      +
    • +

      proxy requests to Ethereum and Bitcoin upstreams

      +
    • +
    • +

      request path for Ethereum Mainnet is /eth and /btc for bitcoin

      +
    • +
    • +

      i.e. call Ethereum Mainnet by POST http://127.0.0.0:8545/eth with JSON RPC payload

      +
    • +
    +
    +
  • +
  • +

    three upstreams - ethereum, solana and bitcoin

    +
  • +
  • +

    for Ethereum Mainnet it connects using JSON RPC and WebSocket connections,

    +
  • +
  • +

    for Bitcoin Mainnet only JSON RPC is used

    +
  • +
  • +

    ${DRPC_KEY} will be provided through environment variable

    +
  • +
+
+
+

Please note that you can configure many upstreams for a single blockchains. +If there is more than one upstream, then Dshackle routes requests to them as Round Robin. +If one of them becomes unavailable, Dshackle continues to use only active nodes.

+
+
+

I.e., you can set up a node in the local network, plus Infura with role: fallback. +If anything happened to your local node, you still have access to a consistent state of the Ethereum blockchain via Infura.

+
+ +
+

Run docker image

+
+

Official Docker image you can find at: p2p-org/dshackle

+
+
+
Setup DRPC key
+
+
export DRPC_KEY=...
+
+
+
+
Run Dshackle
+
+
docker run -p 2449:2449 -p 8545:8545 -v $(pwd):/etc/dshackle -e "DRPC_KEY=$INFURA_USER" emeraldpay/dshackle:0.12
+
+
+
+

Now it listens on port 2449 at the localhost and can be connected from any gRPC compatible client. +Tools such as gRPCurl can use protobuf definitions from proto reflection and connect to it

+
+
+

Alternatively you can connect to port 8545 with traditional JSON RPC requests

+
+
+
+
+
+
+

Documentation

+
+
+

For detailed documentation see docs/ directory.

+
+
+
+
+

Development

+
+
+ + + + + +
+
Warning
+
+The code in master branch is considered a development version, which may lack proper testing and should not be used in production. +
+
+
+

Setting up environment

+
+

Dshackle is JVM based project written in Kotlin. +To build and run it from sources you’ll need to install Java JDK and Gradle

+
+
+
+

Build Dshackle

+
+

Build everything

+
+
+
gradle build
+
+
+
+
+

Make a Zip distribution

+
+
+
gradle distZip
+
+
+
+

You can find a redistributable zip in build/distributions

+
+
+
+

Make a Docker distribution

+
+
+
gradle jib -Pdocker=gcr.io/myproject
+
+
+
+

Gradle will prepare a Docker image and upload it to your custom Docker Registry at gcr.io/myproject (please change to address of your actual registry)

+
+
+
+
+
+
+

Community

+
+
+

Join our Discord

+
+
+
+
+

License

+
+
+

Copyright 2021 EmeraldPay, Inc

+
+
+

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at

+
+ +
+

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and limitations under the License.

+
+
+ +
+

Modifications made by p2p.org in 2022 are licensed under the same Apache License, Version 2.0. These modifications are copyrighted by p2p.org.

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/00-intro.adoc b/docs/00-intro.adoc deleted file mode 100644 index 49bdec1d1..000000000 --- a/docs/00-intro.adoc +++ /dev/null @@ -1,28 +0,0 @@ -== What is Dshackle - -Dshackle is an L7 Blockchain API Load Balancer with automatic discovery and health checking, authentication, and TLS termination. -It is designed to work as an edge proxy, middle proxy, or API gateway. - -Dshackle provides a high level aggregated API on top of several underlying upstreams. -I.e. to blockchain nodes such as Bitcoind, Geth, Parity, or providers like DRPC, and so on. -It automatically verifies their availability and the current status of the network, executes commands making sure that the response is consistent and/or data successfully broadcasted to the network. - -Example use cases: - -- Read a _transaction_ - Dshackle tries to find it on different nodes and retries until it's found or there is a consistent answer from upstreams that the transaction doesn't exist -- Get _nonce_ to send a transaction - Dshackle makes sure it finds the highest value across several nodes -- Send _transaction_ - Dshackle distributes it to several nodes in parallel - -Availability and fault tolerance: - -- Dshackle connects to several upstreams via JSON RPC, Websockets or gRPC protocol -- It verifies if a node ("upstream") is fully synchronized (not in initial sync mode), has enough peers and its height - is not behind other nodes -- If upstream lags behind, lost peers, started to resync, or goes down then Dshackle temporarily excludes it from - routing and returns back when the upstream's problem is fixed - -Main goals: - -- separate application services and blockchain nodes -- make blockchain access compatible with modern microservice oriented architecture -- provide secure access to a blockchain, on both protocol and data level \ No newline at end of file diff --git a/docs/00-intro.html b/docs/00-intro.html new file mode 100644 index 000000000..04c9ad902 --- /dev/null +++ b/docs/00-intro.html @@ -0,0 +1,511 @@ + + + + + + + +What is Dshackle + + + + + +
+
+

What is Dshackle

+
+
+

Dshackle is an L7 Blockchain API Load Balancer with automatic discovery and health checking, authentication, and TLS termination. +It is designed to work as an edge proxy, middle proxy, or API gateway.

+
+
+

Dshackle provides a high level aggregated API on top of several underlying upstreams. +I.e. to blockchain nodes such as Bitcoind, Geth, Parity, or providers like DRPC, and so on. +It automatically verifies their availability and the current status of the network, executes commands making sure that the response is consistent and/or data successfully broadcasted to the network.

+
+
+

Example use cases:

+
+
+
    +
  • +

    Read a transaction - Dshackle tries to find it on different nodes and retries until it’s found or there is a consistent answer from upstreams that the transaction doesn’t exist

    +
  • +
  • +

    Get nonce to send a transaction - Dshackle makes sure it finds the highest value across several nodes

    +
  • +
  • +

    Send transaction - Dshackle distributes it to several nodes in parallel

    +
  • +
+
+
+

Availability and fault tolerance:

+
+
+
    +
  • +

    Dshackle connects to several upstreams via JSON RPC, Websockets or gRPC protocol

    +
  • +
  • +

    It verifies if a node ("upstream") is fully synchronized (not in initial sync mode), has enough peers and its height +is not behind other nodes

    +
  • +
  • +

    If upstream lags behind, lost peers, started to resync, or goes down then Dshackle temporarily excludes it from +routing and returns back when the upstream’s problem is fixed

    +
  • +
+
+
+

Main goals:

+
+
+
    +
  • +

    separate application services and blockchain nodes

    +
  • +
  • +

    make blockchain access compatible with modern microservice oriented architecture

    +
  • +
  • +

    provide secure access to a blockchain, on both protocol and data level

    +
  • +
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/01-architecture-intro.adoc b/docs/01-architecture-intro.adoc deleted file mode 100644 index 02ca1dcf1..000000000 --- a/docs/01-architecture-intro.adoc +++ /dev/null @@ -1,73 +0,0 @@ -== Architecture Overview - -Dshackle is built using/based on: - -- Java Virtual Machine, Java 20+ -- Kotlin -- Spring Framework, Boot and Reactor - -Its own communication protocol is based on Protobuf and gRPC, though it connects to other nodes using different protocols, -such as JSON RPC or Websockets. - -Dshackle connects to actual blockchain nodes and provides an aggregated API, automatically directing requests to -currently healthy nodes. It's built using _reactive_ and non-blocking code and provides low latency and high efficient -API. - -Dshackle servers can be connected to each other as well, or work in parallel, to provide scalable and fault tolerant -connection to blockchains. All connections can be secured and authenticated with client/server certificates. - -=== Upstream selection - -Dshackle tries to find an optimal upstream for each particular request, to do so it consider following factors of a node: - -- Current height -- Is it fully synchronized, missing few (less than 6) blocks, or in the process of initial sync? -- How many peers it has? - -And for a request: - -- Is it for concrete data (_block #100_) or the latest (_get balance_)? -- Is result a static value (_just block_) or may vary depending on network and node (_latest nonce_)? -- Does it need to be repeated over multiple nodes (_broadcast transaction_)? -- Request can also specify which subset of nodes should be able to execute the request by selecting node _Labels_ (see "link:09-quorum-and-selectors.adoc[Quorum and Selectors]") - -Based on these factors, Dshackle executes the request on a most optimal node. -For most of the simple requests, it just gets a node that is synchronized to the point that must have a response for that particular request. -If node failed, returned an invalid response, returned an empty response when shouldn't then Dshackle tries again on another node, or on the same node after awhile (default is 200ms between failover repeats) - -=== Proxy - -Dshackle provides access with standard JSON RPC protocol, functioning as a proxy to upstreams. -It provides: - -- Routes only realy/alive upstreams, i.e., synchronized and with enough peers -- Load Balancing -- Request Retry on upstream errors -- Local Caching (memory and Redis, see link:10-caching.adoc[Caching]) -- Broadcasting and Quorum for requests - -=== gRPC protocol - -Dshackle native protocol is based on gRPC, which provides many additional features: - -- provides additional parameters on top of upstreams JSON RPC requests -- based on HTTP/2 with low latency, compression, server push, pipelining and multiplexing -- gRPC has binding and code generators for most of the languages and frameworks -- easy to support TLS encryption and authentication - -gRPC protocol is more flexible, and many of the Dshackle features are accessible mostly through that native protocol. - -Dshackle has extra methods and functionality on top of standard APIs of upstreams, and it's more flexible to wrap original APIs, such as JSON, into gRPC, and Protobuf + has additional data provided by Dshackle. -It also allowed to push new data from the server or send responses asynchronously, immediately after it gets executed on an upstream. - -=== Distributed Load Balancing - -Dshackle servers can connect to each other through a secure encrypted and authenticated connection. -It allows to build a network of nodes deployed to different regions or run blockchain nodes outside of the main network. - -Later is especially important for blockchain nodes, as they require an open firewall with incoming connections for P2P, and -to execute untrusted code ("smart contracts") at the same time. With Dshackle, it's possible to separate insecure nodes from -the business application. - -But in general, Dshackle allows running a fault tolerant load balancing to build scalable and fail safe systems on -blockchain. \ No newline at end of file diff --git a/docs/01-architecture-intro.html b/docs/01-architecture-intro.html new file mode 100644 index 000000000..a5a73f2fa --- /dev/null +++ b/docs/01-architecture-intro.html @@ -0,0 +1,595 @@ + + + + + + + +Architecture Overview + + + + + +
+
+

Architecture Overview

+
+
+

Dshackle is built using/based on:

+
+
+
    +
  • +

    Java Virtual Machine, Java 20+

    +
  • +
  • +

    Kotlin

    +
  • +
  • +

    Spring Framework, Boot and Reactor

    +
  • +
+
+
+

Its own communication protocol is based on Protobuf and gRPC, though it connects to other nodes using different protocols, +such as JSON RPC or Websockets.

+
+
+

Dshackle connects to actual blockchain nodes and provides an aggregated API, automatically directing requests to +currently healthy nodes. It’s built using reactive and non-blocking code and provides low latency and high efficient +API.

+
+
+

Dshackle servers can be connected to each other as well, or work in parallel, to provide scalable and fault tolerant +connection to blockchains. All connections can be secured and authenticated with client/server certificates.

+
+
+

Upstream selection

+
+

Dshackle tries to find an optimal upstream for each particular request, to do so it consider following factors of a node:

+
+
+
    +
  • +

    Current height

    +
  • +
  • +

    Is it fully synchronized, missing few (less than 6) blocks, or in the process of initial sync?

    +
  • +
  • +

    How many peers it has?

    +
  • +
+
+
+

And for a request:

+
+
+
    +
  • +

    Is it for concrete data (block #100) or the latest (get balance)?

    +
  • +
  • +

    Is result a static value (just block) or may vary depending on network and node (latest nonce)?

    +
  • +
  • +

    Does it need to be repeated over multiple nodes (broadcast transaction)?

    +
  • +
  • +

    Request can also specify which subset of nodes should be able to execute the request by selecting node Labels (see "Quorum and Selectors")

    +
  • +
+
+
+

Based on these factors, Dshackle executes the request on a most optimal node. +For most of the simple requests, it just gets a node that is synchronized to the point that must have a response for that particular request. +If node failed, returned an invalid response, returned an empty response when shouldn’t then Dshackle tries again on another node, or on the same node after awhile (default is 200ms between failover repeats)

+
+
+
+

Proxy

+
+

Dshackle provides access with standard JSON RPC protocol, functioning as a proxy to upstreams. +It provides:

+
+
+
    +
  • +

    Routes only realy/alive upstreams, i.e., synchronized and with enough peers

    +
  • +
  • +

    Load Balancing

    +
  • +
  • +

    Request Retry on upstream errors

    +
  • +
  • +

    Local Caching (memory and Redis, see Caching)

    +
  • +
  • +

    Broadcasting and Quorum for requests

    +
  • +
+
+
+
+

gRPC protocol

+
+

Dshackle native protocol is based on gRPC, which provides many additional features:

+
+
+
    +
  • +

    provides additional parameters on top of upstreams JSON RPC requests

    +
  • +
  • +

    based on HTTP/2 with low latency, compression, server push, pipelining and multiplexing

    +
  • +
  • +

    gRPC has binding and code generators for most of the languages and frameworks

    +
  • +
  • +

    easy to support TLS encryption and authentication

    +
  • +
+
+
+

gRPC protocol is more flexible, and many of the Dshackle features are accessible mostly through that native protocol.

+
+
+

Dshackle has extra methods and functionality on top of standard APIs of upstreams, and it’s more flexible to wrap original APIs, such as JSON, into gRPC, and Protobuf + has additional data provided by Dshackle. +It also allowed to push new data from the server or send responses asynchronously, immediately after it gets executed on an upstream.

+
+
+
+

Distributed Load Balancing

+
+

Dshackle servers can connect to each other through a secure encrypted and authenticated connection. +It allows to build a network of nodes deployed to different regions or run blockchain nodes outside of the main network.

+
+
+

Later is especially important for blockchain nodes, as they require an open firewall with incoming connections for P2P, and +to execute untrusted code ("smart contracts") at the same time. With Dshackle, it’s possible to separate insecure nodes from +the business application.

+
+
+

But in general, Dshackle allows running a fault tolerant load balancing to build scalable and fail safe systems on +blockchain.

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/02-quick-start.adoc b/docs/02-quick-start.adoc deleted file mode 100644 index bef4a019a..000000000 --- a/docs/02-quick-start.adoc +++ /dev/null @@ -1,151 +0,0 @@ -== Quick Start -:version: 0.12.0 -:version-short: 0.12 - -=== Prerequisites - -Dshackle is designed for the cloud environment and supposed to be used withing Docker and/or Kubernetes. -However, it's a JVM based application and, therefore, can be used in most of the standard environments where Java Virtual Machine can be installed. - -We're going to use Docker image for this quick start. - -For demo access, we use gRPCurl tool, which can be installed from https://github.com/fullstorydev/grpcurl - -=== Configuration - -NOTE: you can find following example configuration in demo/quick-start directory of the project - -Create file `dshackle.yaml` with following content: -[source,yaml] ----- -version: v1 -host: 0.0.0.0 # <1> -port: 2449 -tls: # <2> - enabled: false -proxy: - host: 0.0.0.0 # <3> - port: 8545 - routes: - - id: eth - blockchain: ethereum - - id: kovan - blockchain: kovan -cluster: - upstreams: # <4> - - id: drpc-eth - chain: ethereum # <5> - method-groups: - enabled: - - trace - connection: - ethereum: - rpc: # <6> - url: "https://lb.drpc.org/ogrpc?network=ethereum&dkey=${DRPC_KEY}" # <7> - ws: # <8> - url: "wss://lb.drpc.org/ogws?network=ethereum&dkey=${DRPC_KEY}" - - id: local-eth # <9> - chain: ethereum - connection: - ethereum: - rpc: - url: "http://192.168.1.100:8545/" # <10> - ws: - url: "ws://192.168.1.100:8546" - - id: bitcoin-main - chain: bitcoin # <11> - connection: - bitcoin: - rpc: - url: "http://localhost:8332" - basic-auth: # <12> - username: bitcoin - password: test ----- -<1> application listen for gRPC connections on 0.0.0.0:2449 -<2> with TLS security for gRPC disabled (_never use in production!_) -<3> listen for HTTP JSON RPC connections on 0.0.0.0:8545, without TLS security too (again, _don't use in production, it's insecure_) -<4> sets up 2 upstreams -<5> one for Ethereum Mainnet, using -<6> HTTP and -<7> `${DRPC_KEY}` value is provided through environment variable -<8> in addition to HTTPS is uses Websocket protocol to connect to DRPC, used to subscribe to updates -<9> setup another upstream for Ethereum Mainnet -<10> which connects to a node in the internal networks, without any authentication at this case -<11> and another for Bitcoin -<12> with Basic Auth for bitcoin node connection - -The configuration above sets up the Dshackle to provide a fault-tolerant access to Bitcoin and Ethereum blockchain. -And for Ethereum, at this particular example, it uses a Round Robin Load Balancing over the DRPC and the local node. - -See detailed link:reference-configuration.adoc[Configuration Reference] - -==== Run as docker - -Official Docker image you can find at: https://hub.docker.com/r/p2p-org/dshackle[p2p-org/dshackle] - -.Setup DRPC key -[source,bash] ----- -export DRPC_KEY=... ----- - -.Run Dshackle -[source,bash,subs="attributes"] ----- -docker run -p 2449:2449 -p 8545:8545 -v $(pwd):/etc/dshackle -e "DRPC_KEY=$DRPC_KEY" p2p-org/dshackle:{version-short} ----- - -==== Access using JSON RPC - -Dshackle implements standard JSON RPC interface, providing additional caching layer, upstream readiness/liveness checks, retry and other features for building Fault Tolerant services. - -.Request using Curl -[source,bash] ----- -curl --request POST \ - --url http://localhost:8545/eth \ - --header 'content-type: application/json' \ - --data '{"jsonrpc":"2.0", "method":"eth_getBalance", "id":1, "params":["0x690b2bdf41f33f9f251ae0459e5898b856ed96be", "latest"]}' ----- - -.Output -[source,bash] ----- -{"jsonrpc":"2.0","id":1,"result":"0x72fa5e0181"} ----- - -==== Access using gRPC - -.Connect and listen for new blocks on Ethereum Mainnet -[source,bash] ----- -grpcurl -d "{\"type\": 100}" -plaintext 127.0.0.1:2449 emerald.Blockchain/SubscribeHead ----- - -`type: 100` specifies the blockchain id, and 100 means Ethereum Mainnet. - -.Output would be like ----- -{ - "chain": "CHAIN_ETHEREUM", - "height": 8396159, - "blockId": "fc58a258adccc94466ae967b1178eea721349b0667f59d5fe1b0b436460bce75", - "timestamp": 1566423564000, - "weight": "AnMcf2VJB5kOSQ==" -} -{ - "chain": "CHAIN_ETHEREUM", - "height": 8396160, - "blockId": "787899711b862b77df8d2faa69de664048598265a9f96abf178d341076e200e0", - "timestamp": 1566423574000, - "weight": "AnMch35tO6hSGg==" -} -... -... ----- - -The output above is for a _streaming subscription_ to all new blocks on Ethereum Mainnet. -It's one of the services provided by Dshackle, in addition to standard methods provided by RPC JSON of underlying nodes. - -See other enhanced methods in the link:07-methods.adoc[Documentation for Enhanced Methods] diff --git a/docs/02-quick-start.html b/docs/02-quick-start.html new file mode 100644 index 000000000..55c5781bc --- /dev/null +++ b/docs/02-quick-start.html @@ -0,0 +1,656 @@ + + + + + + + +Quick Start + + + + + +
+
+

Quick Start

+
+
+

Prerequisites

+
+

Dshackle is designed for the cloud environment and supposed to be used withing Docker and/or Kubernetes. +However, it’s a JVM based application and, therefore, can be used in most of the standard environments where Java Virtual Machine can be installed.

+
+
+

We’re going to use Docker image for this quick start.

+
+
+

For demo access, we use gRPCurl tool, which can be installed from https://github.com/fullstorydev/grpcurl

+
+
+
+

Configuration

+
+ + + + + +
+
Note
+
+you can find following example configuration in demo/quick-start directory of the project +
+
+
+

Create file dshackle.yaml with following content:

+
+
+
+
version: v1
+host: 0.0.0.0 # (1)
+port: 2449
+tls: # (2)
+  enabled: false
+proxy:
+  host: 0.0.0.0 # (3)
+  port: 8545
+  routes:
+    - id: eth
+      blockchain: ethereum
+    - id: kovan
+      blockchain: kovan
+cluster:
+  upstreams: # (4)
+    - id: drpc-eth
+      chain: ethereum # (5)
+      method-groups:
+       enabled:
+         - trace
+      connection:
+        ethereum:
+          rpc: # (6)
+            url: "https://lb.drpc.org/ogrpc?network=ethereum&dkey=${DRPC_KEY}" # (7)
+          ws: # (8)
+            url: "wss://lb.drpc.org/ogws?network=ethereum&dkey=${DRPC_KEY}"
+    - id: local-eth # (9)
+      chain: ethereum
+      connection:
+        ethereum:
+          rpc:
+            url: "http://192.168.1.100:8545/" # (10)
+          ws:
+            url: "ws://192.168.1.100:8546"
+    - id: bitcoin-main
+      chain: bitcoin # (11)
+      connection:
+        bitcoin:
+          rpc:
+            url: "http://localhost:8332"
+            basic-auth: # (12)
+              username: bitcoin
+              password: test
+
+
+
+
    +
  1. +

    application listen for gRPC connections on 0.0.0.0:2449

    +
  2. +
  3. +

    with TLS security for gRPC disabled (never use in production!)

    +
  4. +
  5. +

    listen for HTTP JSON RPC connections on 0.0.0.0:8545, without TLS security too (again, don’t use in production, it’s insecure)

    +
  6. +
  7. +

    sets up 2 upstreams

    +
  8. +
  9. +

    one for Ethereum Mainnet, using

    +
  10. +
  11. +

    HTTP and

    +
  12. +
  13. +

    ${DRPC_KEY} value is provided through environment variable

    +
  14. +
  15. +

    in addition to HTTPS is uses Websocket protocol to connect to DRPC, used to subscribe to updates

    +
  16. +
  17. +

    setup another upstream for Ethereum Mainnet

    +
  18. +
  19. +

    which connects to a node in the internal networks, without any authentication at this case

    +
  20. +
  21. +

    and another for Bitcoin

    +
  22. +
  23. +

    with Basic Auth for bitcoin node connection

    +
  24. +
+
+
+

The configuration above sets up the Dshackle to provide a fault-tolerant access to Bitcoin and Ethereum blockchain. +And for Ethereum, at this particular example, it uses a Round Robin Load Balancing over the DRPC and the local node.

+
+
+

See detailed Configuration Reference

+
+
+

Run as docker

+
+

Official Docker image you can find at: p2p-org/dshackle

+
+
+
Setup DRPC key
+
+
export DRPC_KEY=...
+
+
+
+
Run Dshackle
+
+
docker run -p 2449:2449 -p 8545:8545 -v $(pwd):/etc/dshackle -e "DRPC_KEY=$DRPC_KEY" p2p-org/dshackle:0.12
+
+
+
+
+

Access using JSON RPC

+
+

Dshackle implements standard JSON RPC interface, providing additional caching layer, upstream readiness/liveness checks, retry and other features for building Fault Tolerant services.

+
+
+
Request using Curl
+
+
curl --request POST \
+  --url http://localhost:8545/eth \
+  --header 'content-type: application/json' \
+  --data '{"jsonrpc":"2.0", "method":"eth_getBalance", "id":1, "params":["0x690b2bdf41f33f9f251ae0459e5898b856ed96be", "latest"]}'
+
+
+
+
Output
+
+
{"jsonrpc":"2.0","id":1,"result":"0x72fa5e0181"}
+
+
+
+
+

Access using gRPC

+
+
Connect and listen for new blocks on Ethereum Mainnet
+
+
grpcurl -d "{\"type\": 100}" -plaintext 127.0.0.1:2449 emerald.Blockchain/SubscribeHead
+
+
+
+

type: 100 specifies the blockchain id, and 100 means Ethereum Mainnet.

+
+
+
Output would be like
+
+
{
+  "chain": "CHAIN_ETHEREUM",
+  "height": 8396159,
+  "blockId": "fc58a258adccc94466ae967b1178eea721349b0667f59d5fe1b0b436460bce75",
+  "timestamp": 1566423564000,
+  "weight": "AnMcf2VJB5kOSQ=="
+}
+{
+  "chain": "CHAIN_ETHEREUM",
+  "height": 8396160,
+  "blockId": "787899711b862b77df8d2faa69de664048598265a9f96abf178d341076e200e0",
+  "timestamp": 1566423574000,
+  "weight": "AnMch35tO6hSGg=="
+}
+...
+...
+
+
+
+

The output above is for a streaming subscription to all new blocks on Ethereum Mainnet. +It’s one of the services provided by Dshackle, in addition to standard methods provided by RPC JSON of underlying nodes.

+
+
+

See other enhanced methods in the Documentation for Enhanced Methods

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/03-server-config.adoc b/docs/03-server-config.adoc deleted file mode 100644 index 9241b6f60..000000000 --- a/docs/03-server-config.adoc +++ /dev/null @@ -1,203 +0,0 @@ -== Server Configuration - -By default, the Dshackle looks for config in the following locations: - -1. Path specified by _optional_ `--configPath <...>` command line option -2. `/etc/dshackle/dshackle.yaml` -3. `./dshackle.yaml` (i.e. in the current working dir) - -If none found the application exists with an error. - -.Example dshackle.yaml configuration: -[source,yaml] ----- -version: v1 -port: 2449 -tls: - enabled: true - server: - certificate: "server.crt" - key: "server.p8.key" - client: - require: true - cas: - - "ca.crt" - -compression: - grpc: - server: - enabled: false - client: - enabled: false - -cluster: - include: "upstreams.yaml" ----- - -It configures following: - -- server is listening with gRCP API on `0.0.0.0:2449` -- TLS is enabled -- compression is disabled for gRPC-server (enabled by default) -- compression is disabled for upstream gRPC-client (enabled by default) -- server certificate is located at `server.crt` with the key for it at `server.p8.key` -- the server requires a client authentication by TLS client certificate signed by `ca.crt` certificate. -- no JSON RPC is configured -- upstreams configuration is configured in the file `upstreams.yaml` - -.Configuration -|=== -| Name | Example | Description - -a| `version` -| -| Version of the format of the config - -a| `port` -a| `port: 12449` -| Port to bind gRPC server. `2449` by default - -a| `tls` -| -| TLS configuration for gRPC. -See link:08-authentication.adoc[Authentication] for details - -a| `compression` -| -| Compression configuration - -a| `proxy` -| -| Proxy configuration - -a| `upstreams` -| -| Upstreams configuration -|=== - -=== Compression -Compression is enabled by default on the gRPC-server. -Responses will be compressed if a client supports compression -(sends relevant headers), otherwise, communication will be uncompressed. -But if for some reason you need to disable responses compression -forcibly (the server will still be able to accept compressed requests), -add following lines to the config: -[source,yaml] ----- -compression: - grpc: - server: - enabled: false ----- -Compression is enabled by default for gRPC-requests to upstreams. -If you want to disable it, -(gRPC-client will still be able to accept compressed responses), -add following lines to the config: -[source,yaml] ----- -compression: - grpc: - client: - enabled: false ----- -Thus, all possible combinations of compression configuration for -interacting dshackle grpc-client and grpc-server look like this: -|=== -| Client | Server | Requests | Responses - -| enabled -| enabled -| compressed -| compressed - -| enabled -| disabled -| compressed -| plain - -| disabled -| enabled -| plain -| compressed - -| disabled -| disabled -| plain -| plain -|=== - -=== Enabling JSON RPC proxy - -In addition to the gRPC protocol, Dshackle provides access compatible with Bitcoin and Ethereum JSON RPC. -The same server can be accessible as an HTTP JSON RPC and WebSocket JSON RPC. -For Ethereum, besides the standard RPC calls, it provides RPC subscriptions with `eth_subscribe` method. - -.Example proxy: -[source,yaml] ----- -version: v1 -port: 2449 - -proxy: - host: 0.0.0.0 - port: 8080 - routes: - - id: eth - blockchain: ethereum - -cluster: - include: "upstreams.yaml" ----- - -With that configuration Dshackle starts a JSON RPC proxy: - -- JSON RPC server is listening on `0.0.0.0:8080` -- `http://0.0.0.0:8080/eth` (and `ws://0.0.0.0:8080/eth`) provides access to Ethereum API routed to an available upstream - -NOTE: Same URL should be used to access both HTTP RPC and WebSocket RPC - -.Full configuration: -[source,yaml] ----- -proxy: - port: 8080 - tls: - enabled: true - server: - certificate: server.crt - key: server.p8.key - client: - require: true - ca: ca.crt - routes: - - id: eth - blockchain: ethereum - - id: etc - blockchain: ethereum_classic ----- - -.Proxy configuration -|=== -| Name | Example | Description - -a| `host` -a| `host: 0.0.0.0` -| Host to bind proxy server. `127.0.0.1` by default - -a| `port` -a| `port: 8545` -| Port to bind proxy server. `8080` by default - -a| `enabled` -a| `enabled: true` -| Enable/disable proxy server - -a| `tls` -| -| TLS configuration for proxy. -See link:08-authentication.adoc[Authentication] for details - -a| `routes` -| -| List of endpoints to proxy -|=== \ No newline at end of file diff --git a/docs/03-server-config.html b/docs/03-server-config.html new file mode 100644 index 000000000..0b7e8b22f --- /dev/null +++ b/docs/03-server-config.html @@ -0,0 +1,798 @@ + + + + + + + +Server Configuration + + + + + +
+
+

Server Configuration

+
+
+

By default, the Dshackle looks for config in the following locations:

+
+
+
    +
  1. +

    Path specified by optional --configPath <…​> command line option

    +
  2. +
  3. +

    /etc/dshackle/dshackle.yaml

    +
  4. +
  5. +

    ./dshackle.yaml (i.e. in the current working dir)

    +
  6. +
+
+
+

If none found the application exists with an error.

+
+
+
Example dshackle.yaml configuration:
+
+
version: v1
+port: 2449
+tls:
+  enabled: true
+  server:
+    certificate: "server.crt"
+    key: "server.p8.key"
+  client:
+    require: true
+    cas:
+      - "ca.crt"
+
+compression:
+  grpc:
+    server:
+      enabled: false
+    client:
+      enabled: false
+
+cluster:
+  include: "upstreams.yaml"
+
+
+
+

It configures following:

+
+
+
    +
  • +

    server is listening with gRCP API on 0.0.0.0:2449

    +
  • +
  • +

    TLS is enabled

    +
  • +
  • +

    compression is disabled for gRPC-server (enabled by default)

    +
  • +
  • +

    compression is disabled for upstream gRPC-client (enabled by default)

    +
  • +
  • +

    server certificate is located at server.crt with the key for it at server.p8.key

    +
  • +
  • +

    the server requires a client authentication by TLS client certificate signed by ca.crt certificate.

    +
  • +
  • +

    no JSON RPC is configured

    +
  • +
  • +

    upstreams configuration is configured in the file upstreams.yaml

    +
  • +
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Configuration
NameExampleDescription
+

version

+

Version of the format of the config

+

port

+
+

port: 12449

+

Port to bind gRPC server. 2449 by default

+

tls

+

TLS configuration for gRPC. +See Authentication for details

+

compression

+

Compression configuration

+

proxy

+

Proxy configuration

+

upstreams

+

Upstreams configuration

+
+

Compression

+
+

Compression is enabled by default on the gRPC-server. +Responses will be compressed if a client supports compression +(sends relevant headers), otherwise, communication will be uncompressed. +But if for some reason you need to disable responses compression +forcibly (the server will still be able to accept compressed requests), +add following lines to the config:

+
+
+
+
compression:
+  grpc:
+    server:
+      enabled: false
+
+
+
+

Compression is enabled by default for gRPC-requests to upstreams. +If you want to disable it, +(gRPC-client will still be able to accept compressed responses), +add following lines to the config:

+
+
+
+
compression:
+  grpc:
+    client:
+      enabled: false
+
+
+
+

Thus, all possible combinations of compression configuration for +interacting dshackle grpc-client and grpc-server look like this:

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ClientServerRequestsResponses

enabled

enabled

compressed

compressed

enabled

disabled

compressed

plain

disabled

enabled

plain

compressed

disabled

disabled

plain

plain

+
+
+

Enabling JSON RPC proxy

+
+

In addition to the gRPC protocol, Dshackle provides access compatible with Bitcoin and Ethereum JSON RPC. +The same server can be accessible as an HTTP JSON RPC and WebSocket JSON RPC. +For Ethereum, besides the standard RPC calls, it provides RPC subscriptions with eth_subscribe method.

+
+
+
Example proxy:
+
+
version: v1
+port: 2449
+
+proxy:
+  host: 0.0.0.0
+  port: 8080
+  routes:
+    - id: eth
+      blockchain: ethereum
+
+cluster:
+  include: "upstreams.yaml"
+
+
+
+

With that configuration Dshackle starts a JSON RPC proxy:

+
+
+
    +
  • +

    JSON RPC server is listening on 0.0.0.0:8080

    +
  • +
  • +

    http://0.0.0.0:8080/eth (and ws://0.0.0.0:8080/eth) provides access to Ethereum API routed to an available upstream

    +
  • +
+
+
+ + + + + +
+
Note
+
+Same URL should be used to access both HTTP RPC and WebSocket RPC +
+
+
+
Full configuration:
+
+
proxy:
+  port: 8080
+  tls:
+    enabled: true
+    server:
+      certificate: server.crt
+      key: server.p8.key
+    client:
+      require: true
+      ca: ca.crt
+  routes:
+    - id: eth
+      blockchain: ethereum
+    - id: etc
+      blockchain: ethereum_classic
+
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2. Proxy configuration
NameExampleDescription
+

host

+
+

host: 0.0.0.0

+

Host to bind proxy server. 127.0.0.1 by default

+

port

+
+

port: 8545

+

Port to bind proxy server. 8080 by default

+

enabled

+
+

enabled: true

+

Enable/disable proxy server

+

tls

+

TLS configuration for proxy. +See Authentication for details

+

routes

+

List of endpoints to proxy

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/04-upstream-config.adoc b/docs/04-upstream-config.adoc deleted file mode 100644 index 3feeee4cc..000000000 --- a/docs/04-upstream-config.adoc +++ /dev/null @@ -1,408 +0,0 @@ -== Upstreams Configuration - -Dshackle can connect to multiple independent APIs ("upstreams") and provides an unified API on top of it. - -Supported upstream protocols: - -- JSON RPC -- Websockets -- gRPC (i.e. can connect to another Dshackle) - -Those protocols can be configures with additional security, TLS and authentication. - -=== Notes on upstream configuration - -==== Generic - -- Most common way to connect upstream. Supported for Ethereum, Starknet, Solana and Varanet upstreams. It uses rpc and ws connection to provide access via jsonprc calls. - -==== Solana -In case of Solana nodes configuration with WS connection it is important to use `--rpc-pubsub-enable-block-subscription` on solana node to enable head subscription through ws - -==== Bitcoin - -- Bitcoind needs to be configured to index/track addresses that you're going to request. -Make sure you configure it to index your addresses with `importaddress`. -If you request balance for an address that is not indexed then it returns 0 balance. -- To track all transactions you need to setup index for transactions, which is disabled by default. -Run it with `-reindex` option, or set `txindex=1` in the config. - -=== Example Configuration - -.upstreams.yaml -[source,yaml] ----- -version: v1 - -cluster: - upstreams: - - id: us-nodes - node-id: 1 - chain: auto - method-groups: - enabled: - - trace - connection: - grpc: - host: 35.226.252.117 - port: 443 - tls: - ca: ca.crt - certificate: client.crt - key: client.p8.key - - id: drpc-eth - node-id: 2 - chain: ethereum - role: fallback - labels: - provider: infura - options: - disable-validation: true - connection: - ethereum-pos: - execution: - rpc: - url: "https://lb.drpc.org/ogrpc?network=ethereum&dkey=${DRPC_KEY}" - ws: - url: "wss://lb.drpc.org/ogws?network=ethereum&dkey=${DRPC_KEY}" - - id: solana - node-id: 3 - chain: solana - connection: - generic: - rpc: - url: ${SOLANA_NODE_RPC_URL} - ws: - url: ${SOLANA_NODE_WS_URL} ----- - -There are two main segments for upstreams configuration: - -- _upstreams_ - a list of API to connect to, with all configuration specific for upstream and chain -- and _default options_ as common configuration options applied to all nodes in that group - -In the example above we have: - -* as upstreams it has 2 configurations - for ethereum and solana -* balancer connects to another Dshackle/another machine by using gRPC protocol -** accepts (i.e. proxies) any blockchain available on that remote -** verifies TLS certificate of the server -** uses client certificate for authentication, i.e. remote server is accepting only clients authenticated by a certificate -* connects to DRPC provided _Ethereum Mainnet_ -** as a _fallback_ upstream, which means that it's used only if `us-nodes` fails -** configuration is using placeholders for `${DRPC_KEY}` which will be replaced with corresponding environment variables values -** label `[provider: drpc]` is set for that particular upstream, which can be selected during a request.For example for some requests you may want to use nodes with that label only, i.e. _"send that tx to drpc nodes only"_, or _"read only from archive node, with label [archive: true]"_ -** upstream validation (peers, sync status, etc) is disabled for that particular upstream - -=== Nodes -`[node-id: 1]` is numeric node identifier defined in a range [1..255] and used to forward -`eth_getFilterChanges` request to the node where one of `eth_newFilter`, `eth_newBlockFilter` or `eth_newPendingTransactionFilter` methods was executed (because filter is s stateful method). - -*It's kindly recommended* to strictly associate _node-id_ parameter with a physical node and keep it during any configuration changes - -=== Supported chains - -Currently, dshackle supports next chains (should be used as chain names in config): - -* ethereum -** ethereum (eth) -** ethereum-classic (etc) -** polygon (matic) -** polygon-mumbai -** arbitrum (arb) -** arbitrum-testnet -** arbitrum-nova -** optimism -** optimism-testnet -** optimism-sepolia -** binance (bsc, bnb-smart-chain) -** bsc-testnet -** zksync -** zksync-sepolia -** zksync-testnet -** polygon-zkevm -** polygon-zkevm-testnet -** morden -** kovan (kovan-testnet) -** goerli (goerli-testnet) -** rinkeby (rinkeby-testnet) -** ropsten (ropsten-testnet) -** ethereum-holesky -** bitcoin (bitcoin-testnet) -** base -** base-goerli -** linea -** linea-goerli -** fantom -** fantom-testnet -** gnosis -** gnosis-chiado -** avalanche -** avalanche-fuji -** aurora -** aurora-testnet -** scroll-alphanet -** scroll-sepolia -** mantle -** mantle-testnet -** klaytn -** klaytn-baobab -** celo -** celo-alfajores -** moonbeam -** moonriver -** moonbase-alpha -* starknet -* varanet -* solana - -All supported blockchains are listed link:/foundation/src/main/resources/chains.yaml[here]. Feel free to contribute new chains. - -=== Roles and Fallback upstream - -By default, the Dshackle connects to each upstream in a Round-Robin basis, i.e. sequentially one by one. -If you need more gradual control over the order of which upstream is used and when you can assign following roles: - -- `primary` (default role if nothing specified) -- `secondary` -- `fallback` - -Where `primary` and `secondary` are considered here a _standard_ upstreams, and `fallback` is used on failure of standard upstreams. -I.e. the Dshackle always starts with making requests to standard upstreams. -If all of them failed, if responses are inconsistent (ex. for `eth_getTransactionCount`), or when it needs to broadcast to a wider network (`sendrawtransaction`), then upstreams with role `fallback` cames to use. - -The internal request order is (goes to next only if all upstreams on current step a not available or failed): - -1. tries with primary upstreams -2. tries with secondary upstream -3. ... delay (100ms at first, increased each iteration) -4. tries with primary upstreams -5. tries with secondary upstream -6. tries with fallback upstreams -7. ... go to step 3 - -Steps 3-6 are repeated until a valid response received, or a timeout for the original request is reached. - -In general: -- you set role `secondary` for upstream in another cluster/datacenter - you set role `fallback` for an external upstream which may be provided by a third party, and you want to use it as a last resort - -=== Configuration options - -Options (default or as part of upstream config): - -[cols="2,1,5a"] -|=== -| Option | Default | Description - -| `disable-validation` | false | if `true` then Dshackle will not try to verify status of the upstream (could be useful for a trusted cloud -provider such as Infura, but disabling it is not recommended for a normal node) -| `min-peers` | 3 | specify minimum amount of connected peers, Dshackle will not use upstream with less than specified number -| `timeout` | 60 | timeout in seconds after which request to the upstream will be discarded (and may be retried on an another upstream) -| `balance` | `true` for ethereum, `false` for bitcoin | specify if this node should be used to fetch balance for an address -|=== - -=== Connection type - -Dshackle currently supports - -- `rpc` a standard Ethereum JSON RPC -- `ws` websocket connection (supposed to be used in addition to `rpc` connection) -- `grpc` connects to another Dshackle instance - -==== Connection mixture modes -In case of rpc and ws connection we can specify different modes of works together: - -|=== -|Type |Description - -|WS_ONLY -|Default mode in case WS endpoint specified. In this mode WS connection is used for all requests and subscriptions. - -|RPC_ONLY -|Default in case WS endpoint not specified. In this mode RPC connection is used for all requests, subscriptions doesn't work, head subscription works through scheduled RPC head request. - -|RPC_REQUESTS_WITH_MIXED_HEAD -|All requests are sent through RPC connection, eth_subscribe is sent through WS connection, head subscription works through scheduled RPC head request mixed with WS subscription. - -|RPC_REQUESTS_WITH_WS_HEAD -|All requests are sent through RPC connection, all subscriptions works through WS connection. -|=== - -You can specify this modes through `connector-mode` parameter in connection config. - -=== Bitcoin Methods - -.By default an ethereum upstream allows call to the following JSON RPC methods: -- `getbestblockhash` -- `getblock` -- `getblocknumber` -- `getblockcount` -- `gettransaction` -- `getrawtransaction` -- `gettxout` -- `getreceivedbyaddress` -- `listunspent` -- `sendrawtransaction` - -.Plus following methods are answered directly by Dshackle -- `getmemorypool` -- `getconnectioncount` -- `getnetworkinfo` - -=== Ethereum Methods - -.By default, an ethereum upstream allows calls to the following JSON RPC methods: -- `eth_gasPrice` -- `eth_call` -- `eth_estimateGas` -- `eth_getBlockTransactionCountByHash` -- `eth_getUncleCountByBlockHash` -- `eth_getBlockByHash` -- `eth_getTransactionByHash` -- `eth_getTransactionByBlockHashAndIndex` -- `eth_getStorageAt` -- `eth_getCode` -- `eth_getUncleByBlockHashAndIndex` -- `eth_getTransactionCount` -- `eth_blockNumber` -- `eth_getBalance` -- `eth_sendRawTransaction` -- `eth_getBlockTransactionCountByNumber` -- `eth_getUncleCountByBlockNumber` -- `eth_getBlockByNumber` -- `eth_getTransactionByBlockNumberAndIndex` -- `eth_getTransactionReceipt` -- `eth_getUncleByBlockNumberAndIndex` -- `eth_feeHistory` -- `eth_getLogs` -- `eth_getFilterChanges` -- `eth_newFilter` -- `eth_newBlockFilter` -- `eth_newPendingTransactionFilter` - -.Plus following methods are answered directly by Dshackle -- `net_version` -- `net_peerCount` -- `net_listening` -- `web3_clientVersion` -- `eth_protocolVersion` -- `eth_syncing` -- `eth_coinbase` -- `eth_mining` -- `eth_hashrate` -- `eth_accounts` - -It's possible to enable additional methods that are available on upstream, or disable an existing method. -For that purpose there is `methods` configuration: - -[source, yaml] ----- -upstreams: - - id: my-node - chain: ethereum - labels: - archive: true - methods: - enabled: - - name: trace_transaction - disabled: - - name: eth_getBlockByNumber ----- - -Such configuration option allows executing method `trace_transaction` and also disables `eth_getBlockByNumber` on that particular upstream. -If a client requests to execute method `trace_transaction` then it will be scheduled to that upstream (or any upstream with such method enabled). - -There are also method groups to more easily manage methods in batches, currently there are several groups: - -- https://github.com/p2p-org/dshackle/blob/master/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt#L53[trace] -- https://github.com/p2p-org/dshackle/blob/master/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt#L65[debug] -- https://github.com/p2p-org/dshackle/blob/master/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt#L41[filter] -- default, all methods that are enabled by default -[source, yaml] ----- -upstreams: - - id: my-node - chain: ethereum - labels: - archive: true - method-groups: - enabled: - - trace - disabled: - - default ----- -This config allows you to ONLY enable trace methods and disable everything else. - -NOTE: It's especially useful when used together with upstream labels.If an archive upstream has label `archive: true` it's possible to specify that the client wants to execute method `trace_transaction` only on an archive node(s), which has complete historical data for tracing. - -==== eth_subscribe ethereum methods -It is possible to control ethereum subscription types like regular methods. For now there are only one option - newPendingTransactions - you need to allow this method if you want to activate this type of subscription for Dshackle upstreams (disabled by default) - -=== Static Methods - -You can overwrite existing methods or add new ones using a static response: - -[source,yaml] ----- -upstreams: - - id: my-node - chain: ethereum - methods: - enabled: - - name: net_version - static: "\"100000\"" - - name: eth_chainId - static: "0x186a0" - - name: eth_custom_array - static: '["custom_array_response"]' - - name: eth_custom_bool - static: "false" ----- - -=== Authentication - -==== TLS - -All connection types can use TLS secured connection, with optional client certificate authentication: - -- `ca` path to certificate required from remote server -- optional `certificate` and `key` for client authentication. - -NOTE: Please note that `key` must be encoded with _PKCS 8_ - -==== Basic Authentication - -For JSON RPC and Websockets a Basic Authentication can be used: - -- `username` - username -- `password` - password - -=== Chains specific configuration -We can use chain settings to specify chain specific behavior, for example rules for dshackle to work with upstream statuses - -.chains.yaml -[source,yaml] ----- -chain-settings: - default: - lags: - syncing: 6 - lagging: 1 - chains: - - id: eth - lags: - syncing: 6 - lagging: 1 - - id: polygon - lags: - syncing: 20 - lagging: 10 ----- -Options -[cols="2,5a"] -|=== -| Option | Description - -| `lags.syncing` | the size of the lag after which the upstream is determined to be syncing -| `lags.lagging` | the size of the lag after which the upstream is determined to be lagging -|=== diff --git a/docs/04-upstream-config.html b/docs/04-upstream-config.html new file mode 100644 index 000000000..1b0830f4c --- /dev/null +++ b/docs/04-upstream-config.html @@ -0,0 +1,1342 @@ + + + + + + + +Upstreams Configuration + + + + + +
+
+

Upstreams Configuration

+
+
+

Dshackle can connect to multiple independent APIs ("upstreams") and provides an unified API on top of it.

+
+
+

Supported upstream protocols:

+
+
+
    +
  • +

    JSON RPC

    +
  • +
  • +

    Websockets

    +
  • +
  • +

    gRPC (i.e. can connect to another Dshackle)

    +
  • +
+
+
+

Those protocols can be configures with additional security, TLS and authentication.

+
+
+

Notes on upstream configuration

+
+

Generic

+
+
    +
  • +

    Most common way to connect upstream. Supported for Ethereum, Starknet, Solana and Varanet upstreams. It uses rpc and ws connection to provide access via jsonprc calls.

    +
  • +
+
+
+
+

Solana

+
+

In case of Solana nodes configuration with WS connection it is important to use --rpc-pubsub-enable-block-subscription on solana node to enable head subscription through ws

+
+
+
+

Bitcoin

+
+
    +
  • +

    Bitcoind needs to be configured to index/track addresses that you’re going to request. +Make sure you configure it to index your addresses with importaddress. +If you request balance for an address that is not indexed then it returns 0 balance.

    +
  • +
  • +

    To track all transactions you need to setup index for transactions, which is disabled by default. +Run it with -reindex option, or set txindex=1 in the config.

    +
  • +
+
+
+
+
+

Example Configuration

+
+
upstreams.yaml
+
+
version: v1
+
+cluster:
+  upstreams:
+    - id: us-nodes
+      node-id: 1
+      chain: auto
+      method-groups:
+       enabled:
+         - trace
+      connection:
+        grpc:
+          host: 35.226.252.117
+          port: 443
+          tls:
+            ca: ca.crt
+            certificate: client.crt
+            key: client.p8.key
+    - id: drpc-eth
+      node-id: 2
+      chain: ethereum
+      role: fallback
+      labels:
+        provider: infura
+      options:
+        disable-validation: true
+      connection:
+        ethereum-pos:
+            execution:
+              rpc:
+                url: "https://lb.drpc.org/ogrpc?network=ethereum&dkey=${DRPC_KEY}"
+              ws:
+                url: "wss://lb.drpc.org/ogws?network=ethereum&dkey=${DRPC_KEY}"
+    - id: solana
+      node-id: 3
+      chain: solana
+      connection:
+        generic:
+          rpc:
+            url: ${SOLANA_NODE_RPC_URL}
+          ws:
+            url: ${SOLANA_NODE_WS_URL}
+
+
+
+

There are two main segments for upstreams configuration:

+
+
+
    +
  • +

    upstreams - a list of API to connect to, with all configuration specific for upstream and chain

    +
  • +
  • +

    and default options as common configuration options applied to all nodes in that group

    +
  • +
+
+
+

In the example above we have:

+
+
+
    +
  • +

    as upstreams it has 2 configurations - for ethereum and solana

    +
  • +
  • +

    balancer connects to another Dshackle/another machine by using gRPC protocol

    +
    +
      +
    • +

      accepts (i.e. proxies) any blockchain available on that remote

      +
    • +
    • +

      verifies TLS certificate of the server

      +
    • +
    • +

      uses client certificate for authentication, i.e. remote server is accepting only clients authenticated by a certificate

      +
    • +
    +
    +
  • +
  • +

    connects to DRPC provided Ethereum Mainnet

    +
    +
      +
    • +

      as a fallback upstream, which means that it’s used only if us-nodes fails

      +
    • +
    • +

      configuration is using placeholders for ${DRPC_KEY} which will be replaced with corresponding environment variables values

      +
    • +
    • +

      label [provider: drpc] is set for that particular upstream, which can be selected during a request.For example for some requests you may want to use nodes with that label only, i.e. "send that tx to drpc nodes only", or "read only from archive node, with label [archive: true]"

      +
    • +
    • +

      upstream validation (peers, sync status, etc) is disabled for that particular upstream

      +
    • +
    +
    +
  • +
+
+
+
+

Nodes

+
+

[node-id: 1] is numeric node identifier defined in a range [1..255] and used to forward +eth_getFilterChanges request to the node where one of eth_newFilter, eth_newBlockFilter or eth_newPendingTransactionFilter methods was executed (because filter is s stateful method).

+
+
+

It’s kindly recommended to strictly associate node-id parameter with a physical node and keep it during any configuration changes

+
+
+
+

Supported chains

+
+

Currently, dshackle supports next chains (should be used as chain names in config):

+
+
+
    +
  • +

    ethereum

    +
    +
      +
    • +

      ethereum (eth)

      +
    • +
    • +

      ethereum-classic (etc)

      +
    • +
    • +

      polygon (matic)

      +
    • +
    • +

      polygon-mumbai

      +
    • +
    • +

      arbitrum (arb)

      +
    • +
    • +

      arbitrum-testnet

      +
    • +
    • +

      arbitrum-nova

      +
    • +
    • +

      optimism

      +
    • +
    • +

      optimism-testnet

      +
    • +
    • +

      optimism-sepolia

      +
    • +
    • +

      binance (bsc, bnb-smart-chain)

      +
    • +
    • +

      bsc-testnet

      +
    • +
    • +

      zksync

      +
    • +
    • +

      zksync-sepolia

      +
    • +
    • +

      zksync-testnet

      +
    • +
    • +

      polygon-zkevm

      +
    • +
    • +

      polygon-zkevm-testnet

      +
    • +
    • +

      morden

      +
    • +
    • +

      kovan (kovan-testnet)

      +
    • +
    • +

      goerli (goerli-testnet)

      +
    • +
    • +

      rinkeby (rinkeby-testnet)

      +
    • +
    • +

      ropsten (ropsten-testnet)

      +
    • +
    • +

      ethereum-holesky

      +
    • +
    • +

      bitcoin (bitcoin-testnet)

      +
    • +
    • +

      base

      +
    • +
    • +

      base-goerli

      +
    • +
    • +

      linea

      +
    • +
    • +

      linea-goerli

      +
    • +
    • +

      fantom

      +
    • +
    • +

      fantom-testnet

      +
    • +
    • +

      gnosis

      +
    • +
    • +

      gnosis-chiado

      +
    • +
    • +

      avalanche

      +
    • +
    • +

      avalanche-fuji

      +
    • +
    • +

      aurora

      +
    • +
    • +

      aurora-testnet

      +
    • +
    • +

      scroll-alphanet

      +
    • +
    • +

      scroll-sepolia

      +
    • +
    • +

      mantle

      +
    • +
    • +

      mantle-testnet

      +
    • +
    • +

      klaytn

      +
    • +
    • +

      klaytn-baobab

      +
    • +
    • +

      celo

      +
    • +
    • +

      celo-alfajores

      +
    • +
    • +

      moonbeam

      +
    • +
    • +

      moonriver

      +
    • +
    • +

      moonbase-alpha

      +
    • +
    +
    +
  • +
  • +

    starknet

    +
  • +
  • +

    varanet

    +
  • +
  • +

    solana

    +
  • +
+
+
+

All supported blockchains are listed here. Feel free to contribute new chains.

+
+
+
+

Roles and Fallback upstream

+
+

By default, the Dshackle connects to each upstream in a Round-Robin basis, i.e. sequentially one by one. +If you need more gradual control over the order of which upstream is used and when you can assign following roles:

+
+
+
    +
  • +

    primary (default role if nothing specified)

    +
  • +
  • +

    secondary

    +
  • +
  • +

    fallback

    +
  • +
+
+
+

Where primary and secondary are considered here a standard upstreams, and fallback is used on failure of standard upstreams. +I.e. the Dshackle always starts with making requests to standard upstreams. +If all of them failed, if responses are inconsistent (ex. for eth_getTransactionCount), or when it needs to broadcast to a wider network (sendrawtransaction), then upstreams with role fallback cames to use.

+
+
+

The internal request order is (goes to next only if all upstreams on current step a not available or failed):

+
+
+
    +
  1. +

    tries with primary upstreams

    +
  2. +
  3. +

    tries with secondary upstream

    +
  4. +
  5. +

    …​ delay (100ms at first, increased each iteration)

    +
  6. +
  7. +

    tries with primary upstreams

    +
  8. +
  9. +

    tries with secondary upstream

    +
  10. +
  11. +

    tries with fallback upstreams

    +
  12. +
  13. +

    …​ go to step 3

    +
  14. +
+
+
+

Steps 3-6 are repeated until a valid response received, or a timeout for the original request is reached.

+
+
+

In general: +- you set role secondary for upstream in another cluster/datacenter - you set role fallback for an external upstream which may be provided by a third party, and you want to use it as a last resort

+
+
+
+

Configuration options

+
+

Options (default or as part of upstream config):

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription

disable-validation

false

+

if true then Dshackle will not try to verify status of the upstream (could be useful for a trusted cloud +provider such as Infura, but disabling it is not recommended for a normal node)

+

min-peers

3

+

specify minimum amount of connected peers, Dshackle will not use upstream with less than specified number

+

timeout

60

+

timeout in seconds after which request to the upstream will be discarded (and may be retried on an another upstream)

+

balance

true for ethereum, false for bitcoin

+

specify if this node should be used to fetch balance for an address

+
+
+
+

Connection type

+
+

Dshackle currently supports

+
+
+
    +
  • +

    rpc a standard Ethereum JSON RPC

    +
  • +
  • +

    ws websocket connection (supposed to be used in addition to rpc connection)

    +
  • +
  • +

    grpc connects to another Dshackle instance

    +
  • +
+
+
+

Connection mixture modes

+
+

In case of rpc and ws connection we can specify different modes of works together:

+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDescription

WS_ONLY

Default mode in case WS endpoint specified. In this mode WS connection is used for all requests and subscriptions.

RPC_ONLY

Default in case WS endpoint not specified. In this mode RPC connection is used for all requests, subscriptions doesn’t work, head subscription works through scheduled RPC head request.

RPC_REQUESTS_WITH_MIXED_HEAD

All requests are sent through RPC connection, eth_subscribe is sent through WS connection, head subscription works through scheduled RPC head request mixed with WS subscription.

RPC_REQUESTS_WITH_WS_HEAD

All requests are sent through RPC connection, all subscriptions works through WS connection.

+
+

You can specify this modes through connector-mode parameter in connection config.

+
+
+
+
+

Bitcoin Methods

+
+
By default an ethereum upstream allows call to the following JSON RPC methods:
+
    +
  • +

    getbestblockhash

    +
  • +
  • +

    getblock

    +
  • +
  • +

    getblocknumber

    +
  • +
  • +

    getblockcount

    +
  • +
  • +

    gettransaction

    +
  • +
  • +

    getrawtransaction

    +
  • +
  • +

    gettxout

    +
  • +
  • +

    getreceivedbyaddress

    +
  • +
  • +

    listunspent

    +
  • +
  • +

    sendrawtransaction

    +
  • +
+
+
+
Plus following methods are answered directly by Dshackle
+
    +
  • +

    getmemorypool

    +
  • +
  • +

    getconnectioncount

    +
  • +
  • +

    getnetworkinfo

    +
  • +
+
+
+
+

Ethereum Methods

+
+
By default, an ethereum upstream allows calls to the following JSON RPC methods:
+
    +
  • +

    eth_gasPrice

    +
  • +
  • +

    eth_call

    +
  • +
  • +

    eth_estimateGas

    +
  • +
  • +

    eth_getBlockTransactionCountByHash

    +
  • +
  • +

    eth_getUncleCountByBlockHash

    +
  • +
  • +

    eth_getBlockByHash

    +
  • +
  • +

    eth_getTransactionByHash

    +
  • +
  • +

    eth_getTransactionByBlockHashAndIndex

    +
  • +
  • +

    eth_getStorageAt

    +
  • +
  • +

    eth_getCode

    +
  • +
  • +

    eth_getUncleByBlockHashAndIndex

    +
  • +
  • +

    eth_getTransactionCount

    +
  • +
  • +

    eth_blockNumber

    +
  • +
  • +

    eth_getBalance

    +
  • +
  • +

    eth_sendRawTransaction

    +
  • +
  • +

    eth_getBlockTransactionCountByNumber

    +
  • +
  • +

    eth_getUncleCountByBlockNumber

    +
  • +
  • +

    eth_getBlockByNumber

    +
  • +
  • +

    eth_getTransactionByBlockNumberAndIndex

    +
  • +
  • +

    eth_getTransactionReceipt

    +
  • +
  • +

    eth_getUncleByBlockNumberAndIndex

    +
  • +
  • +

    eth_feeHistory

    +
  • +
  • +

    eth_getLogs

    +
  • +
  • +

    eth_getFilterChanges

    +
  • +
  • +

    eth_newFilter

    +
  • +
  • +

    eth_newBlockFilter

    +
  • +
  • +

    eth_newPendingTransactionFilter

    +
  • +
+
+
+
Plus following methods are answered directly by Dshackle
+
    +
  • +

    net_version

    +
  • +
  • +

    net_peerCount

    +
  • +
  • +

    net_listening

    +
  • +
  • +

    web3_clientVersion

    +
  • +
  • +

    eth_protocolVersion

    +
  • +
  • +

    eth_syncing

    +
  • +
  • +

    eth_coinbase

    +
  • +
  • +

    eth_mining

    +
  • +
  • +

    eth_hashrate

    +
  • +
  • +

    eth_accounts

    +
  • +
+
+
+

It’s possible to enable additional methods that are available on upstream, or disable an existing method. +For that purpose there is methods configuration:

+
+
+
+
upstreams:
+  - id: my-node
+    chain: ethereum
+    labels:
+      archive: true
+    methods:
+      enabled:
+        - name: trace_transaction
+      disabled:
+        - name: eth_getBlockByNumber
+
+
+
+

Such configuration option allows executing method trace_transaction and also disables eth_getBlockByNumber on that particular upstream. +If a client requests to execute method trace_transaction then it will be scheduled to that upstream (or any upstream with such method enabled).

+
+
+

There are also method groups to more easily manage methods in batches, currently there are several groups:

+
+
+
    +
  • +

    trace

    +
  • +
  • +

    debug

    +
  • +
  • +

    filter

    +
  • +
  • +

    default, all methods that are enabled by default

    +
  • +
+
+
+
+
upstreams:
+  - id: my-node
+    chain: ethereum
+    labels:
+      archive: true
+    method-groups:
+      enabled:
+        - trace
+      disabled:
+        - default
+
+
+
+

This config allows you to ONLY enable trace methods and disable everything else.

+
+
+ + + + + +
+
Note
+
+It’s especially useful when used together with upstream labels.If an archive upstream has label archive: true it’s possible to specify that the client wants to execute method trace_transaction only on an archive node(s), which has complete historical data for tracing. +
+
+
+

eth_subscribe ethereum methods

+
+

It is possible to control ethereum subscription types like regular methods. For now there are only one option - newPendingTransactions - you need to allow this method if you want to activate this type of subscription for Dshackle upstreams (disabled by default)

+
+
+
+
+

Static Methods

+
+

You can overwrite existing methods or add new ones using a static response:

+
+
+
+
upstreams:
+  - id: my-node
+    chain: ethereum
+    methods:
+      enabled:
+        - name: net_version
+          static: "\"100000\""
+        - name: eth_chainId
+          static: "0x186a0"
+        - name: eth_custom_array
+          static: '["custom_array_response"]'
+        - name: eth_custom_bool
+          static: "false"
+
+
+
+
+

Authentication

+
+

TLS

+
+

All connection types can use TLS secured connection, with optional client certificate authentication:

+
+
+
    +
  • +

    ca path to certificate required from remote server

    +
  • +
  • +

    optional certificate and key for client authentication.

    +
  • +
+
+
+ + + + + +
+
Note
+
+Please note that key must be encoded with PKCS 8 +
+
+
+
+

Basic Authentication

+
+

For JSON RPC and Websockets a Basic Authentication can be used:

+
+
+
    +
  • +

    username - username

    +
  • +
  • +

    password - password

    +
  • +
+
+
+
+
+

Chains specific configuration

+
+

We can use chain settings to specify chain specific behavior, for example rules for dshackle to work with upstream statuses

+
+
+
chains.yaml
+
+
chain-settings:
+  default:
+    lags:
+      syncing: 6
+      lagging: 1
+  chains:
+    - id: eth
+      lags:
+        syncing: 6
+        lagging: 1
+    - id: polygon
+      lags:
+        syncing: 20
+        lagging: 10
+
+
+
+

Options

+
+ ++++ + + + + + + + + + + + + + + + + +
OptionDescription

lags.syncing

+

the size of the lag after which the upstream is determined to be syncing

+

lags.lagging

+

the size of the lag after which the upstream is determined to be lagging

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/05-start.adoc b/docs/05-start.adoc deleted file mode 100644 index 36b2fb6c7..000000000 --- a/docs/05-start.adoc +++ /dev/null @@ -1,20 +0,0 @@ -== Launch a server -:version: 0.12.0 -:version-short: 0.12 - -=== Docker - -Prepare configuration files `dshackle.yaml` and `upstreams.yaml` in the current directory, then launch docker as: - -[source,bash,subs="attributes"] ----- -docker run -p 2449:2449 -v $(pwd):/config -w /config p2p-org/dshackle:{version-short} ----- - -=== Install & Run manually - -1. Download latest release from https://github.com/p2p-org/dshackle/releases -2. Unpack `unzip dshackle-0.6.0.zip` -3. Copy to `/opt/dshackle` -4. Setup configuration in `/etc/dshackle` -5. Run as `cp /etc/dshackle && /opt/dshackle/bin/dshackle` \ No newline at end of file diff --git a/docs/05-start.html b/docs/05-start.html new file mode 100644 index 000000000..57955250a --- /dev/null +++ b/docs/05-start.html @@ -0,0 +1,485 @@ + + + + + + + +Launch a server + + + + + +
+
+

Launch a server

+
+
+

Docker

+
+

Prepare configuration files dshackle.yaml and upstreams.yaml in the current directory, then launch docker as:

+
+
+
+
docker run -p 2449:2449 -v $(pwd):/config -w /config p2p-org/dshackle:0.12
+
+
+
+
+

Install & Run manually

+
+
    +
  1. +

    Download latest release from https://github.com/p2p-org/dshackle/releases

    +
  2. +
  3. +

    Unpack unzip dshackle-0.6.0.zip

    +
  4. +
  5. +

    Copy to /opt/dshackle

    +
  6. +
  7. +

    Setup configuration in /etc/dshackle

    +
  8. +
  9. +

    Run as cp /etc/dshackle && /opt/dshackle/bin/dshackle

    +
  10. +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/06-monitoring.adoc b/docs/06-monitoring.adoc deleted file mode 100644 index cb63473d8..000000000 --- a/docs/06-monitoring.adoc +++ /dev/null @@ -1,191 +0,0 @@ -:imagesdir: assets - -= Logging & Monitoring - -== Access / Request Log - -Dshackle can log all requests to a file in JSON format. -Or https://jsonlines.org/[JSON Lines] to be more precise, i.e., a test file where each line is a JSON. - -NOTE: By default, the access log is disabled. - -To enable access log add following configuration: - -[source,yaml] ----- -accessLog: - enabled: true - filename: /var/log/dshackle/access_log.jsonl ----- - -`filename` is optional, and the default value is `access_log.jsonl` (i.e., in the current directory). - -Since a single request may contain multiple replies (ex., a batch call, or subscribe to the head blocks) the Dshackle logging is based on replies. -The access log file contains details per each response send from the server, and each of them refers to original request details. - -The access log contains the JSON lines similar to: - -[source,json] ----- -{ - "version":"accesslog/v1beta", - "ts":"2021-07-20T01:53:33.174645Z", - "id":"578d83db-cf53-4ef8-b73e-3f1cc0a67e96", - "method":"NativeCall", - "channel":"GRPC", - "blockchain":"ETHEREUM", - "total":2, - "index":0, - "succeed":true, - "request":{ - "id":"513b9b49-b472-4c83-b4b7-58dd2aabe9f6", - "start":"2021-07-20T01:53:33.086946Z", - "remote":{ - "ips":["127.0.0.1", "10.0.5.102", "172.217.8.78"], - "ip":"172.217.8.78", - "userAgent":"grpc-node-js/1.1.8" - } - }, - "nativeCall":{ - "method":"eth_blockNumber", - "id":2, - "payloadSizeBytes":2 - } -} ----- - -.Where: -- `ts` timestamp of the reply -- `id` uniq id of the reply -- `method` Dshackle method which was called (i.e., not a Blockchain API method, see `nativeCall` details) -- `blockchain` blockchain code -- `channel` access channel (`GRPC` for native Dshackle calls, `JSONRPC` for JSON RPC HTTP Proxy) -- `total` how many requests in the batch (available only for a `NativeCall` call) -- `index` current index (i.e. count) of the reply to the original request -- `succeed` if call succeeded, in terms of Blockchain API -- `request` original request details -** `id` uniq id of the request; all replied to the same request have same id -** `start` when request was received -** `remote` remote details -*** `ips` list of all recognized IPs (including headers such as `X-Real-IP` and `X-Forwarded-For`) -*** `ip` a single ip, that likely represent a real IP of the remote -*** `userAgent` user agent -- `nativeCall` details of the individual Native Call request -** `method` method name terms of Blockchain API -** `id` request id provided in the original request -** `payloadSizeBytes` size of the original _individual_ request (for JSON RPC it's size of the `params` value) - -== Prometheus Metrics - -By default, Dshackle provides Prometheus metrics on `http://127.0.0.1:8081/metrics`. - -To configure the metrics use: - -[source,yaml] ----- -monitoring: - enabled: true - jvm: false - extended: false - prometheus: - enabled: true - bind: 192.168.0.1 - port: 8000 - path: /status/prometheus ----- - -Where `jvm` options enabled monitoring of the JVM internals, such as memory, GC, threads, etc. -And `extended` enables additional metrics for query selectors, etc. - -== Grafana Dashboard - -Simple Grafana dashboard available link:../dashboard/dshackle.json[here] - -image::dshackle-dashboard.png[alt="",width=80%,align="center"] - -This dashboard contains: - -- Upstreams Availability - -- Upstreams Lag - -- JSON RPC total request / failed requests - -- GRPC total request / failed requests - -- JSON RPC Response time - -- Upstreams Errors - -- JSON RPC upstream conn seconds 50,75,90,99 percentiles - -== Health Checks - -Dshackle provides a http endpoint to check status of the servers. -This check is compatible with https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#http-probes[Kubernetes Liveness and Readiness Probes]. - -By default, it's disabled, and you have to set up which blockchain are required to be available to consider Dshackle alive. - -.Example config: -[source,yaml] ----- -health: - port: 8082 # <1> - host: 127.0.0.1 # <2> - path: /health # <3> - blockchains: # <4> - - chain: ethereum # <5> - min-available: 2 # <6> - - chain: bitcoin - min-available: 1 ----- - -<1> (optional) port to bind the Health server. -Default: `8082` -<2> (optional) host to bind the Health server. -Default: `127.0.0.1` -<3> (optional) path on the server. -Default: `/health`. -I.e., `http://127.0.0.1:8082/health` with default config -<4> list of blockchain to check availability -<5> a Blockchain to check -<6> minimum available (i.e., fully synced) Upstreams for that blockchain - -With the config above the server is considered healthy if: - -- Dshackle has connected to at least two valid Ethereum upstreams -- **and** at least one valid Bitcoin upstream. - -When the server is healthy is responds with `OK` and 200 as HTTP Status Code. -When any of the checks failed, it responds with a short description and 503 as HTTP Status Code. - -Example of a response for an unhealthy server that doesn't have enough upstreams for a Ethereum Classic Blockchain. - -.GET http://127.0.0.1:8082/health ----- -ETHEREUM_CLASSIC UNAVAILABLE ----- - -Optionally, the server can be called with `?detailed` query, which provides a more detailed response: - -.GET http://127.0.0.1:8082/health?detailed ----- -ETHEREUM_CLASSIC UNAVAILABLE -BITCOIN AVAILABLE - local-btc-1 OK with lag=0 -ETHEREUM AVAILABLE - local-eth-1 OK with lag=0 - local-eth-2 OK with lag=0 ----- - -== Tracing - -Dshackle provides an option to send spans to the DRPC tracing system to see the detailed path of a request and investigate some problems. - -By default, this feature is turned off. To turn it on set the env variable `ENABLE_COLLECT_SPANS` to `true`. - -Dshackle sends spans for a request: - -- which has completed with an error - -- which has at least one long span. Threshold to assume that a span is long is 1000 milliseconds by default, and you can control this value by passing the env variable `LONG_SPAN_THRESHOLD` in milliseconds. If you pass 0 it means that spans for all requests will be sent to the tracing system. diff --git a/docs/06-monitoring.html b/docs/06-monitoring.html new file mode 100644 index 000000000..d728b208f --- /dev/null +++ b/docs/06-monitoring.html @@ -0,0 +1,777 @@ + + + + + + + +Logging & Monitoring + + + + + +
+
+

Access / Request Log

+
+
+

Dshackle can log all requests to a file in JSON format. +Or JSON Lines to be more precise, i.e., a test file where each line is a JSON.

+
+
+ + + + + +
+
Note
+
+By default, the access log is disabled. +
+
+
+

To enable access log add following configuration:

+
+
+
+
accessLog:
+  enabled: true
+  filename: /var/log/dshackle/access_log.jsonl
+
+
+
+

filename is optional, and the default value is access_log.jsonl (i.e., in the current directory).

+
+
+

Since a single request may contain multiple replies (ex., a batch call, or subscribe to the head blocks) the Dshackle logging is based on replies. +The access log file contains details per each response send from the server, and each of them refers to original request details.

+
+
+

The access log contains the JSON lines similar to:

+
+
+
+
{
+  "version":"accesslog/v1beta",
+  "ts":"2021-07-20T01:53:33.174645Z",
+  "id":"578d83db-cf53-4ef8-b73e-3f1cc0a67e96",
+  "method":"NativeCall",
+  "channel":"GRPC",
+  "blockchain":"ETHEREUM",
+  "total":2,
+  "index":0,
+  "succeed":true,
+  "request":{
+    "id":"513b9b49-b472-4c83-b4b7-58dd2aabe9f6",
+    "start":"2021-07-20T01:53:33.086946Z",
+    "remote":{
+      "ips":["127.0.0.1", "10.0.5.102", "172.217.8.78"],
+      "ip":"172.217.8.78",
+      "userAgent":"grpc-node-js/1.1.8"
+    }
+  },
+  "nativeCall":{
+     "method":"eth_blockNumber",
+     "id":2,
+     "payloadSizeBytes":2
+  }
+}
+
+
+
+
Where:
+
    +
  • +

    ts timestamp of the reply

    +
  • +
  • +

    id uniq id of the reply

    +
  • +
  • +

    method Dshackle method which was called (i.e., not a Blockchain API method, see nativeCall details)

    +
  • +
  • +

    blockchain blockchain code

    +
  • +
  • +

    channel access channel (GRPC for native Dshackle calls, JSONRPC for JSON RPC HTTP Proxy)

    +
  • +
  • +

    total how many requests in the batch (available only for a NativeCall call)

    +
  • +
  • +

    index current index (i.e. count) of the reply to the original request

    +
  • +
  • +

    succeed if call succeeded, in terms of Blockchain API

    +
  • +
  • +

    request original request details

    +
    +
      +
    • +

      id uniq id of the request; all replied to the same request have same id

      +
    • +
    • +

      start when request was received

      +
    • +
    • +

      remote remote details

      +
      +
        +
      • +

        ips list of all recognized IPs (including headers such as X-Real-IP and X-Forwarded-For)

        +
      • +
      • +

        ip a single ip, that likely represent a real IP of the remote

        +
      • +
      • +

        userAgent user agent

        +
      • +
      +
      +
    • +
    +
    +
  • +
  • +

    nativeCall details of the individual Native Call request

    +
    +
      +
    • +

      method method name terms of Blockchain API

      +
    • +
    • +

      id request id provided in the original request

      +
    • +
    • +

      payloadSizeBytes size of the original individual request (for JSON RPC it’s size of the params value)

      +
    • +
    +
    +
  • +
+
+
+
+
+

Prometheus Metrics

+
+
+

By default, Dshackle provides Prometheus metrics on http://127.0.0.1:8081/metrics.

+
+
+

To configure the metrics use:

+
+
+
+
monitoring:
+  enabled: true
+  jvm: false
+  extended: false
+  prometheus:
+    enabled: true
+    bind: 192.168.0.1
+    port: 8000
+    path: /status/prometheus
+
+
+
+

Where jvm options enabled monitoring of the JVM internals, such as memory, GC, threads, etc. +And extended enables additional metrics for query selectors, etc.

+
+
+
+
+

Grafana Dashboard

+
+
+

Simple Grafana dashboard available here

+
+
+
+ +
+
+
+

This dashboard contains:

+
+
+
    +
  • +

    Upstreams Availability

    +
  • +
  • +

    Upstreams Lag

    +
  • +
  • +

    JSON RPC total request / failed requests

    +
  • +
  • +

    GRPC total request / failed requests

    +
  • +
  • +

    JSON RPC Response time

    +
  • +
  • +

    Upstreams Errors

    +
  • +
  • +

    JSON RPC upstream conn seconds 50,75,90,99 percentiles

    +
  • +
+
+
+
+
+

Health Checks

+
+
+

Dshackle provides a http endpoint to check status of the servers. +This check is compatible with Kubernetes Liveness and Readiness Probes.

+
+
+

By default, it’s disabled, and you have to set up which blockchain are required to be available to consider Dshackle alive.

+
+
+
Example config:
+
+
health:
+  port: 8082 # (1)
+  host: 127.0.0.1 # (2)
+  path: /health # (3)
+  blockchains: # (4)
+    - chain: ethereum # (5)
+      min-available: 2 # (6)
+    - chain: bitcoin
+      min-available: 1
+
+
+
+
    +
  1. +

    (optional) port to bind the Health server. +Default: 8082

    +
  2. +
  3. +

    (optional) host to bind the Health server. +Default: 127.0.0.1

    +
  4. +
  5. +

    (optional) path on the server. +Default: /health. +I.e., http://127.0.0.1:8082/health with default config

    +
  6. +
  7. +

    list of blockchain to check availability

    +
  8. +
  9. +

    a Blockchain to check

    +
  10. +
  11. +

    minimum available (i.e., fully synced) Upstreams for that blockchain

    +
  12. +
+
+
+

With the config above the server is considered healthy if:

+
+
+
    +
  • +

    Dshackle has connected to at least two valid Ethereum upstreams

    +
  • +
  • +

    and at least one valid Bitcoin upstream.

    +
  • +
+
+
+

When the server is healthy is responds with OK and 200 as HTTP Status Code. +When any of the checks failed, it responds with a short description and 503 as HTTP Status Code.

+
+
+

Example of a response for an unhealthy server that doesn’t have enough upstreams for a Ethereum Classic Blockchain.

+
+
+ +
+
ETHEREUM_CLASSIC UNAVAILABLE
+
+
+
+

Optionally, the server can be called with ?detailed query, which provides a more detailed response:

+
+
+ +
+
ETHEREUM_CLASSIC UNAVAILABLE
+BITCOIN AVAILABLE
+  local-btc-1 OK with lag=0
+ETHEREUM AVAILABLE
+  local-eth-1 OK with lag=0
+  local-eth-2 OK with lag=0
+
+
+
+
+
+

Tracing

+
+
+

Dshackle provides an option to send spans to the DRPC tracing system to see the detailed path of a request and investigate some problems.

+
+
+

By default, this feature is turned off. To turn it on set the env variable ENABLE_COLLECT_SPANS to true.

+
+
+

Dshackle sends spans for a request:

+
+
+
    +
  • +

    which has completed with an error

    +
  • +
  • +

    which has at least one long span. Threshold to assume that a span is long is 1000 milliseconds by default, and you can control this value by passing the env variable LONG_SPAN_THRESHOLD in milliseconds. If you pass 0 it means that spans for all requests will be sent to the tracing system.

    +
  • +
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/07-methods.adoc b/docs/07-methods.adoc deleted file mode 100644 index 735273692..000000000 --- a/docs/07-methods.adoc +++ /dev/null @@ -1,260 +0,0 @@ -== Enhanced Methods - -IMPORTANT: Dshackle provides an enhanced API based on gRPC and Protobuf, in addition to JSON RPC proxy - -Dshackle provides an enhanced and unified API based on HTTP2, gRPC and Protobuf. -It works in addition to JSON RPC proxy and can be used separately. -Clients can be generated for all major programming languages, and there're official libraries for Java and Javascript. - -NOTE: It's not necessary to use gRPC, as Dshackle can provide standard JSON RPC proxy, but Dshackle gRPC interface improves performance and provides additional features. - -=== gRPC definition - -The source code for the Protobuf definitions could be found in link:../proto/[/proto]. - -.Service API -[source,proto] ----- -service Blockchain { - rpc SubscribeHead (Chain) returns (stream ChainHead) {} - rpc SubscribeBalance (BalanceRequest) returns (stream AddressBalance) {} - rpc SubscribeTxStatus (TxStatusRequest) returns (stream TxStatus) {} - - rpc GetBalance (BalanceRequest) returns (stream AddressBalance) {} - - rpc NativeCall (NativeCallRequest) returns (stream NativeCallReplyItem) {} - rpc NativeSubscribe (NativeSubscribeRequest) returns (stream NativeSubscribeReplyItem) {} - - rpc Describe (DescribeRequest) returns (DescribeResponse) {} - rpc SubscribeStatus (StatusRequest) returns (stream ChainStatus) {} -} ----- - -=== Wrapped JSON RPC methods - -To call standard JSON RPC methods provided by Ethereum/Bitcoin you use `NativeCall` wrapping method, which provides additional flexibility and configuration for the calls. - -.NativeCallRequest -[source,proto] ----- -message NativeCallRequest { - ChainRef chain = 1; - repeated NativeCallItem items = 2; - Selector selector = 3; - int32 quorum = 4; - AvailabilityEnum min_availability = 5; -} - -message NativeCallItem { - uint32 id = 1; - string method = 3; - bytes payload = 4; - uint64 nonce = 5; -} ----- - -Where: - -- `chain` target chain (see reference for ids) -- `items` as a list of independent requests, which may be executed in different nodes in parallels or in different order, with: -* `method` - a JSON RPC standard name, ex: `eth_getBlockByHash` -* `payload` - list of parameters for the methods, encoded as JSON string, ex. `["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]` -- `Selector` and `AvailabilityEnum` are described in reference, in short they allow to specify which nodes must be selected -to execute the reques (i.e. "execute only on an archive node") - -.NativeCallReplyItem -[source,proto] ----- - -message NativeCallReplyItem { - uint32 id = 1; - bool succeed = 2; - bytes payload = 3; - bytes error = 4; - NativeCallReplySignature signature = 5; -} - -message NativeCallReplySignature { - uint64 nonce = 1; - bytes signature = 2; - uint64 key_id = 3; - string upstream_id = 4; -} ----- - -Where: - -- `payload` is JSON response for a particular call (`result` field), encoded into a string (`succeed` is true) -- or `error` if request failed (`succeed` is false) - -NOTE: Reply Items comes right after their execution on an upstream, therefore streaming response. -It allows building non-blocking queries - -[#signatures] -=== Signed JSON RPC Responses - -Dshackle can sign the responses it received from an upstream. -It can be enabled on server by configuring a path to a Secp256K1 Key used for signing. -And passing a `nonce` as part of the call request. -When both of them are set Dshackle adds a Signature to the response, which can travel through multiple levels of Dshackle-Dshackle connections. - -WARNING: Caching is disabled for signed requests, and you always touch an actual node even if there is a ready to use data in local cache. - -The signed message looks like: ----- -DSHACKLESIG/$nonce/$upstreamId/hex(sha256($response)) ----- - -.Where -- `nonce` is a 64-bit number provided with the request -- `upstreamId` id of an upstream which produced the result -- `response` is a part of the original JSON RPC message, i.e. it's what you have in `payload` field of `NativeCallReplyItem` - -.A signed response includes: -- `nonce` original nonce used for the call -- `signature` signature bytes (of the message above) -- `key_id` identifier of a key used for the signing -- `upstream_id` id of upstream which produce the response - -==== How to generate a key - -Here we generate a pair of Secret and Public keys using openssl. - -[source, bash] ----- -export KEYNAME=mykey - -openssl ecparam -name secp256k1 -out $KEYNAME_param.pem -openssl ecparam -in $KEYNAME_param.pem -genkey -noout -out $KEYNAME.pem - -openssl ec -in $KEYNAME.pem -text -openssl ec -in $KEYNAME.pem -out ${KEYNAME}_pub.pem -pubout - -rm $KEYNAME_param.pem -cat ${KEYNAME}_pub.pem ----- - -As a result you get `mykey.pem` with secret key to use on server, and `mykey_pub.pem` with public key to use on client to verify signatures. - -==== How to verify a signature - -Here is the example how to verify the signature with command line, and it can be easily adapted for your language of choice. - -.First, let's prepare all the values: -[source, bash] ----- -export PUBKEY=testing/dshackle/test_key.pub -export NONCE=10 - -export UPSTREAM=drpc -export PAYLOAD='["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]' - -export SIGNATURE=3045022100be1d730e0e381e25bff64f0fc598d19e31688a01db751098d0ed21847ca785b0022002f5651a0e8d447b0815aeb7b48738cb470cf46d60ee4e2f5bc9c0dc4e072dc3 ----- - -.Then rebuild the signed message: -[source, bash] ----- -echo -n "DSHACKLESIG/$NONCE/$UPSTREAM/" > msg.txt -echo -n $PAYLOAD | shasum -a 256 - | awk '{ printf $1 }' >> msg.txt ----- - -.And save signature as a binary file: -[source, bash] ----- -rm -f msg.sig && echo $SIGNATURE | xxd -r -p - msg.sig ----- - -.Now you can verify the payload with the following: -[source, bash] ----- -openssl dgst -sha256 -verify $PUBKEY -signature msg.sig msg.txt ----- - -.Which should print: ----- -Verified OK ----- - -==== What is the Key Identifier? - -Key Id is the first 64 bits of SHA-256 hash of the x509 encoded Public Key. -It's provided with the Signed Response for a reference. - -You can get it with: -[source, bash] ----- -cat $PUBKEY | sed -e '$ d' | awk '(NR>1)' | base64 -d | shasum -a 256 - | head -c 16 ----- - -=== Wrapped JSON RPC subscriptions - -Most of Ethereum APIs provides _subscription_ to events usually accessed through WebSocket connection. -Dshackle gives access to same events through gRPC protocol via the `NativeSubscribe` method. - -NOTE: Dshackle doesn't actually wrap existing subscription or dispatch request to an upstream. -It rather generates same events based on the available data, i.e., aggregates it from multiple upstreams. - -Supported subscriptions: - -- `newHeads` -- `logs` -- `syncing` - -Method data: - -[source,proto] ----- -message NativeSubscribeRequest { - ChainRef chain = 1; - string method = 2; - bytes payload = 3; -} - -message NativeSubscribeReplyItem { - bytes payload = 1; -} ----- - -Where: - -- `method` is a subscriptions method (one of `newHeads`, `logs` or `syncing`) -- `payload` in request is optional subscription params object, which exists only for `logs` methods. -In that case it may be `address` or `topics`. -Both address and topics can be a string or array of strings. -Empty payload for `logs` accepted as subscription to _all_ events. -- `payload` in reply item is as subscription response encoded as JSON - -For example to subscribe to USDC ERC-20 coin Approval events on Ethereum mainnet the request would be: - -- `chain=100` -- `method=logs` -- `payload={"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "topics": ["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]}` - -=== SubscribeHead - -This methods provides subscription to the new blocks on the specified chain. -Returns stream of blocks right after it was accepted (and verified by Dshackle) by any of the upstreams. - -.ChainHead -[source,proto] ----- -message ChainHead { - ChainRef chain = 1; - uint64 height = 2; - string block_id = 3; - uint64 timestamp = 4; - bytes weight = 5; - uint64 reorg = 6; -} ----- - -Where: - -- `chain` - chain id -- `height` - block number -- `block_id` - block hash, as a string (please note that it doesn't have `0x` prefix) -- `timestamp` - timestamp of that block -- `weight` - total network difficulty on that block, as raw bytes -- `reorg` - number of reorganized blocks, if reorg happened - diff --git a/docs/07-methods.html b/docs/07-methods.html new file mode 100644 index 000000000..b52f23530 --- /dev/null +++ b/docs/07-methods.html @@ -0,0 +1,875 @@ + + + + + + + +Enhanced Methods + + + + + +
+
+

Enhanced Methods

+
+
+ + + + + +
+
Important
+
+Dshackle provides an enhanced API based on gRPC and Protobuf, in addition to JSON RPC proxy +
+
+
+

Dshackle provides an enhanced and unified API based on HTTP2, gRPC and Protobuf. +It works in addition to JSON RPC proxy and can be used separately. +Clients can be generated for all major programming languages, and there’re official libraries for Java and Javascript.

+
+
+ + + + + +
+
Note
+
+It’s not necessary to use gRPC, as Dshackle can provide standard JSON RPC proxy, but Dshackle gRPC interface improves performance and provides additional features. +
+
+
+

gRPC definition

+
+

The source code for the Protobuf definitions could be found in /proto.

+
+
+
Service API
+
+
service Blockchain {
+    rpc SubscribeHead (Chain) returns (stream ChainHead) {}
+    rpc SubscribeBalance (BalanceRequest) returns (stream AddressBalance) {}
+    rpc SubscribeTxStatus (TxStatusRequest) returns (stream TxStatus) {}
+
+    rpc GetBalance (BalanceRequest) returns (stream AddressBalance) {}
+
+    rpc NativeCall (NativeCallRequest) returns (stream NativeCallReplyItem) {}
+    rpc NativeSubscribe (NativeSubscribeRequest) returns (stream NativeSubscribeReplyItem) {}
+
+    rpc Describe (DescribeRequest) returns (DescribeResponse) {}
+    rpc SubscribeStatus (StatusRequest) returns (stream ChainStatus) {}
+}
+
+
+
+
+

Wrapped JSON RPC methods

+
+

To call standard JSON RPC methods provided by Ethereum/Bitcoin you use NativeCall wrapping method, which provides additional flexibility and configuration for the calls.

+
+
+
NativeCallRequest
+
+
message NativeCallRequest {
+    ChainRef chain = 1;
+    repeated NativeCallItem items = 2;
+    Selector selector = 3;
+    int32 quorum = 4;
+    AvailabilityEnum min_availability = 5;
+}
+
+message NativeCallItem {
+    uint32 id = 1;
+    string method = 3;
+    bytes payload = 4;
+    uint64 nonce = 5;
+}
+
+
+
+

Where:

+
+
+
    +
  • +

    chain target chain (see reference for ids)

    +
  • +
  • +

    items as a list of independent requests, which may be executed in different nodes in parallels or in different order, with:

    +
    +
      +
    • +

      method - a JSON RPC standard name, ex: eth_getBlockByHash

      +
    • +
    • +

      payload - list of parameters for the methods, encoded as JSON string, ex. ["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]

      +
    • +
    +
    +
  • +
  • +

    Selector and AvailabilityEnum are described in reference, in short they allow to specify which nodes must be selected +to execute the reques (i.e. "execute only on an archive node")

    +
  • +
+
+
+
NativeCallReplyItem
+
+
message NativeCallReplyItem {
+    uint32 id = 1;
+    bool succeed = 2;
+    bytes payload = 3;
+    bytes error = 4;
+    NativeCallReplySignature signature = 5;
+}
+
+message NativeCallReplySignature {
+    uint64 nonce = 1;
+    bytes signature = 2;
+    uint64 key_id = 3;
+    string upstream_id = 4;
+}
+
+
+
+

Where:

+
+
+
    +
  • +

    payload is JSON response for a particular call (result field), encoded into a string (succeed is true)

    +
  • +
  • +

    or error if request failed (succeed is false)

    +
  • +
+
+
+ + + + + +
+
Note
+
+Reply Items comes right after their execution on an upstream, therefore streaming response. +It allows building non-blocking queries +
+
+
+
+

Signed JSON RPC Responses

+
+

Dshackle can sign the responses it received from an upstream. +It can be enabled on server by configuring a path to a Secp256K1 Key used for signing. +And passing a nonce as part of the call request. +When both of them are set Dshackle adds a Signature to the response, which can travel through multiple levels of Dshackle-Dshackle connections.

+
+
+ + + + + +
+
Warning
+
+Caching is disabled for signed requests, and you always touch an actual node even if there is a ready to use data in local cache. +
+
+
+

The signed message looks like:

+
+
+
+
DSHACKLESIG/$nonce/$upstreamId/hex(sha256($response))
+
+
+
+
Where
+
    +
  • +

    nonce is a 64-bit number provided with the request

    +
  • +
  • +

    upstreamId id of an upstream which produced the result

    +
  • +
  • +

    response is a part of the original JSON RPC message, i.e. it’s what you have in payload field of NativeCallReplyItem

    +
  • +
+
+
+
A signed response includes:
+
    +
  • +

    nonce original nonce used for the call

    +
  • +
  • +

    signature signature bytes (of the message above)

    +
  • +
  • +

    key_id identifier of a key used for the signing

    +
  • +
  • +

    upstream_id id of upstream which produce the response

    +
  • +
+
+
+

How to generate a key

+
+

Here we generate a pair of Secret and Public keys using openssl.

+
+
+
+
export KEYNAME=mykey
+
+openssl ecparam -name secp256k1 -out $KEYNAME_param.pem
+openssl ecparam -in $KEYNAME_param.pem -genkey -noout -out $KEYNAME.pem
+
+openssl ec -in $KEYNAME.pem -text
+openssl ec -in $KEYNAME.pem -out ${KEYNAME}_pub.pem -pubout
+
+rm $KEYNAME_param.pem
+cat ${KEYNAME}_pub.pem
+
+
+
+

As a result you get mykey.pem with secret key to use on server, and mykey_pub.pem with public key to use on client to verify signatures.

+
+
+
+

How to verify a signature

+
+

Here is the example how to verify the signature with command line, and it can be easily adapted for your language of choice.

+
+
+
First, let’s prepare all the values:
+
+
export PUBKEY=testing/dshackle/test_key.pub
+export NONCE=10
+
+export UPSTREAM=drpc
+export PAYLOAD='["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]'
+
+export SIGNATURE=3045022100be1d730e0e381e25bff64f0fc598d19e31688a01db751098d0ed21847ca785b0022002f5651a0e8d447b0815aeb7b48738cb470cf46d60ee4e2f5bc9c0dc4e072dc3
+
+
+
+
Then rebuild the signed message:
+
+
echo -n "DSHACKLESIG/$NONCE/$UPSTREAM/" > msg.txt
+echo -n $PAYLOAD | shasum -a 256 - | awk '{ printf $1 }' >> msg.txt
+
+
+
+
And save signature as a binary file:
+
+
rm -f msg.sig && echo $SIGNATURE | xxd -r -p - msg.sig
+
+
+
+
Now you can verify the payload with the following:
+
+
openssl dgst -sha256 -verify $PUBKEY -signature msg.sig msg.txt
+
+
+
+
Which should print:
+
+
Verified OK
+
+
+
+
+

What is the Key Identifier?

+
+

Key Id is the first 64 bits of SHA-256 hash of the x509 encoded Public Key. +It’s provided with the Signed Response for a reference.

+
+
+

You can get it with:

+
+
+
+
cat $PUBKEY | sed -e '$ d' | awk '(NR>1)' | base64 -d | shasum -a 256 - | head -c 16
+
+
+
+
+
+

Wrapped JSON RPC subscriptions

+
+

Most of Ethereum APIs provides subscription to events usually accessed through WebSocket connection. +Dshackle gives access to same events through gRPC protocol via the NativeSubscribe method.

+
+
+ + + + + +
+
Note
+
+Dshackle doesn’t actually wrap existing subscription or dispatch request to an upstream. +It rather generates same events based on the available data, i.e., aggregates it from multiple upstreams. +
+
+
+

Supported subscriptions:

+
+
+
    +
  • +

    newHeads

    +
  • +
  • +

    logs

    +
  • +
  • +

    syncing

    +
  • +
+
+
+

Method data:

+
+
+
+
message NativeSubscribeRequest {
+    ChainRef chain = 1;
+    string method = 2;
+    bytes payload = 3;
+}
+
+message NativeSubscribeReplyItem {
+    bytes payload = 1;
+}
+
+
+
+

Where:

+
+
+
    +
  • +

    method is a subscriptions method (one of newHeads, logs or syncing)

    +
  • +
  • +

    payload in request is optional subscription params object, which exists only for logs methods. +In that case it may be address or topics. +Both address and topics can be a string or array of strings. +Empty payload for logs accepted as subscription to all events.

    +
  • +
  • +

    payload in reply item is as subscription response encoded as JSON

    +
  • +
+
+
+

For example to subscribe to USDC ERC-20 coin Approval events on Ethereum mainnet the request would be:

+
+
+
    +
  • +

    chain=100

    +
  • +
  • +

    method=logs

    +
  • +
  • +

    payload={"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "topics": ["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"]}

    +
  • +
+
+
+
+

SubscribeHead

+
+

This methods provides subscription to the new blocks on the specified chain. +Returns stream of blocks right after it was accepted (and verified by Dshackle) by any of the upstreams.

+
+
+
ChainHead
+
+
message ChainHead {
+    ChainRef chain = 1;
+    uint64 height = 2;
+    string block_id = 3;
+    uint64 timestamp = 4;
+    bytes weight = 5;
+    uint64 reorg = 6;
+}
+
+
+
+

Where:

+
+
+
    +
  • +

    chain - chain id

    +
  • +
  • +

    height - block number

    +
  • +
  • +

    block_id - block hash, as a string (please note that it doesn’t have 0x prefix)

    +
  • +
  • +

    timestamp - timestamp of that block

    +
  • +
  • +

    weight - total network difficulty on that block, as raw bytes

    +
  • +
  • +

    reorg - number of reorganized blocks, if reorg happened

    +
  • +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/08-authentication.adoc b/docs/08-authentication.adoc deleted file mode 100644 index 195767516..000000000 --- a/docs/08-authentication.adoc +++ /dev/null @@ -1,196 +0,0 @@ -== Authentication and encryption - -=== Server authentication - -Dshackle server supports both server and client certificate authentication, and it's strongly recommended to use TLS to -connect to Dshackle server.More to that, the server uses gRPC, which is based on HTTP/2, and most of 3rd party tools and -libraries expect it to be encrypted. - -Please note that for most of use cases for Dshackle, which is designed to be an internal load balancer, a self-signed -Certificates would be enough.In the example below, a https://github.com/square/certstrap[certstrap] tool is used to -generate certificates, but the traditional `openssl` tool can be used as well. - -==== Setup Server certificate - -.Generate a Certificate Authority -[source,bash] ----- -export SERVER_CA="ca.myhost.dev" -export ORG="My Company" -export ORG_UNIT="Blockchain" - -certstrap init --common-name "$SERVER_CA" --passphrase "" -o "$ORG" -ou "$ORG_UNIT CA" -openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$SERVER_CA.key -out out/$SERVER_CA.p8.key -nocrypt ----- - -.Generate a Server Certificate ----- -export SERVER_IP="127.0.0.1" - -certstrap request-cert -ip $SERVER_IP --common-name $SERVER_IP --passphrase "" -o "$ORG" -ou "$ORG_UNIT Server" -certstrap sign $SERVER_IP --CA $SERVER_CA - -openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$SERVER_IP.key -out out/$SERVER_IP.p8.key -nocrypt ----- - -You are going to get following files now in `out` directory: - -- `ca.myhost.dev.crt` your Certification Authority to sign or verify other certificates -- `ca.myhost.dev.p8.key` is the private key for Certification Authority in PKSC 8 format -- `127.0.0.1.crt` server certificate, 127.0.0.1 is an IP address supposed to be used by that instance, and we use local host for demo purposes. -For production use a real IP must be used. -- `127.0.0.1.p8.key` is private key for certificate in PKCS 8 format, it needed by Dshackle server to use certificate - -Copy those files to directory with Dshackle and update configuration. - -.Update dshackle.yaml to have: -[source,yaml] ----- -version: v1 -port: 2449 -tls: - enabled: true - server: - certificate: 127.0.0.1.crt - key: 127.0.0.1.p8.key ----- - -.Verify that server uses the certificate -[source,bash] ----- -openssl s_client -alpn h2 -connect 127.0.0.1:2449 -CAfile out/ca.myhost.dev.crt ----- - -With the configuration above, the server listens using TLS, and the server identity can be verified by a client against a public -server certificate. Please note that a server certificate doesn't prevent a connection from an unauthorized client; it only -verifies the server and encrypts a connection. - -==== Use Client Certificate Authentication - -To have authentication in both ways, you'll need to configure client side certificates as well, in that case the server -also verifies each incoming connection and allow to connect only by a client with a trusted certificate. - -It's possible to connect a Dshackle server to another one, and to do so you'll probably want to use TLS as well. - -.Generate a client certificate -[source,bash] ----- -CLIENT_CA="client-ca.myhost.dev" -CLIENT_ID="client_1" -ORG="My Company" -ORG_UNIT="Client" - -certstrap init --common-name "$CLIENT_CA" --passphrase "" -o "$ORG" -ou "$ORG_UNIT CA" -certstrap request-cert --common-name "$CLIENT_ID" --passphrase "" -certstrap sign "$CLIENT_ID" --CA $CLIENT_CA - -openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$CLIENT_ID.key -out out/$CLIENT_ID.p8.key -nocrypt ----- - -In addition to files mentioned above you got few new files in `out` directory, including: - -- `client-ca.myhost.dev.crt` a certificate to validate connecting clients, all their keys much be signed by that -certificate.Server don't need a private key for that certificate because it's used for verification only. -- `client_1.crt` certificate for a client that will connect to the server -- `client_1.p8.key` private key for that certificate, needed by client - -Copy `client-ca.myhost.dev.crt` to directory with first Dshackle server. - -.Update server dshackle.yaml to have: -[source,yaml] ----- -version: v1 -port: 2449 -tls: - enabled: true - server: - certificate: 127.0.0.1.crt - key: 127.0.0.1.p8.key - client: - require: true - ca: client-ca.myhost.dev.crt ----- - -.Verify connection with client certificate -[source,bash] ----- -openssl s_client -alpn h2 -connect 127.0.0.1:2449 -CAfile out/ca.myhost.dev.crt -cert out/client_1.crt -key out/client_1.key ----- - -Now you need to setup connection from another Dshackle server. I.e. the server we configured above is going be an -upstream to another Dshackle server, which we configure below. - -Setup another Dshackle server on the same machine: - -.Configure dshackle.yaml for second server -[source,yaml] ----- -version: v1 -port: 3449 -tls: - enabled: false ----- - -At this case we run another server on port 3449 in unsecure mode.But to connect to an upstream is still uses a TLS -certificate as described below - -[source,yaml] ----- -version: v1 -cluster: - upstreams: - - id: ds - chain: auto - provider: dshackle - connection: - grpc: - host: 127.0.0.1 - port: 2449 - tls: - ca: ca.myhost.dev.crt - certificate: client_1.crt - key: client_1.p8.key ----- - -Now if you run second server it will connect to first server ("upstream") running on port 2449, will verify upstream with certificate `ca.myhost.dev.crt` and authenticate itself by using pair of `client_1.crt` and `client_1.p8.key` - -=== Server TLS configuration - -|=== -| Name | Example | Description - -a| `enabled` -a| -[source,yaml] ----- -tls: - enabled: true ----- -| Enabled or disable TLS. By default it checks if certificate is set, and then enables it. But if you enable the TLS -but didn't specify the certificate or key, then the DShackle will fails to start with error. - -a| `server.certificate`, `server.key` -a| -[source,yaml] ----- -tls: - server: - certificate: server.com.crt - key: server.com.p8.key ----- -| Path to certificate and certificate private key - -a| `client.ca`, `client.cas`, `client.required` -a| -[source,yaml] ----- -tls: - client: - cas: - - ca1.crt - - ca2.crt - required: true ----- -a| Paths to CA used to authenticate incoming connections, used if `required: true` - -|=== \ No newline at end of file diff --git a/docs/08-authentication.html b/docs/08-authentication.html new file mode 100644 index 000000000..d7e40255e --- /dev/null +++ b/docs/08-authentication.html @@ -0,0 +1,707 @@ + + + + + + + +Authentication and encryption + + + + + +
+
+

Authentication and encryption

+
+
+

Server authentication

+
+

Dshackle server supports both server and client certificate authentication, and it’s strongly recommended to use TLS to +connect to Dshackle server.More to that, the server uses gRPC, which is based on HTTP/2, and most of 3rd party tools and +libraries expect it to be encrypted.

+
+
+

Please note that for most of use cases for Dshackle, which is designed to be an internal load balancer, a self-signed +Certificates would be enough.In the example below, a certstrap tool is used to +generate certificates, but the traditional openssl tool can be used as well.

+
+
+

Setup Server certificate

+
+
Generate a Certificate Authority
+
+
export SERVER_CA="ca.myhost.dev"
+export ORG="My Company"
+export ORG_UNIT="Blockchain"
+
+certstrap init --common-name "$SERVER_CA" --passphrase "" -o "$ORG" -ou "$ORG_UNIT CA"
+openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$SERVER_CA.key -out out/$SERVER_CA.p8.key -nocrypt
+
+
+
+
Generate a Server Certificate
+
+
export SERVER_IP="127.0.0.1"
+
+certstrap request-cert -ip $SERVER_IP --common-name $SERVER_IP --passphrase ""  -o "$ORG" -ou "$ORG_UNIT Server"
+certstrap sign $SERVER_IP --CA $SERVER_CA
+
+openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$SERVER_IP.key -out out/$SERVER_IP.p8.key -nocrypt
+
+
+
+

You are going to get following files now in out directory:

+
+
+
    +
  • +

    ca.myhost.dev.crt your Certification Authority to sign or verify other certificates

    +
  • +
  • +

    ca.myhost.dev.p8.key is the private key for Certification Authority in PKSC 8 format

    +
  • +
  • +

    127.0.0.1.crt server certificate, 127.0.0.1 is an IP address supposed to be used by that instance, and we use local host for demo purposes. +For production use a real IP must be used.

    +
  • +
  • +

    127.0.0.1.p8.key is private key for certificate in PKCS 8 format, it needed by Dshackle server to use certificate

    +
  • +
+
+
+

Copy those files to directory with Dshackle and update configuration.

+
+
+
Update dshackle.yaml to have:
+
+
version: v1
+port: 2449
+tls:
+  enabled: true
+  server:
+    certificate: 127.0.0.1.crt
+    key: 127.0.0.1.p8.key
+
+
+
+
Verify that server uses the certificate
+
+
openssl s_client -alpn h2 -connect 127.0.0.1:2449 -CAfile out/ca.myhost.dev.crt
+
+
+
+

With the configuration above, the server listens using TLS, and the server identity can be verified by a client against a public +server certificate. Please note that a server certificate doesn’t prevent a connection from an unauthorized client; it only +verifies the server and encrypts a connection.

+
+
+
+

Use Client Certificate Authentication

+
+

To have authentication in both ways, you’ll need to configure client side certificates as well, in that case the server +also verifies each incoming connection and allow to connect only by a client with a trusted certificate.

+
+
+

It’s possible to connect a Dshackle server to another one, and to do so you’ll probably want to use TLS as well.

+
+
+
Generate a client certificate
+
+
CLIENT_CA="client-ca.myhost.dev"
+CLIENT_ID="client_1"
+ORG="My Company"
+ORG_UNIT="Client"
+
+certstrap init --common-name "$CLIENT_CA" --passphrase "" -o "$ORG" -ou "$ORG_UNIT CA"
+certstrap request-cert --common-name "$CLIENT_ID" --passphrase ""
+certstrap sign "$CLIENT_ID" --CA $CLIENT_CA
+
+openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$CLIENT_ID.key -out out/$CLIENT_ID.p8.key -nocrypt
+
+
+
+

In addition to files mentioned above you got few new files in out directory, including:

+
+
+
    +
  • +

    client-ca.myhost.dev.crt a certificate to validate connecting clients, all their keys much be signed by that +certificate.Server don’t need a private key for that certificate because it’s used for verification only.

    +
  • +
  • +

    client_1.crt certificate for a client that will connect to the server

    +
  • +
  • +

    client_1.p8.key private key for that certificate, needed by client

    +
  • +
+
+
+

Copy client-ca.myhost.dev.crt to directory with first Dshackle server.

+
+
+
Update server dshackle.yaml to have:
+
+
version: v1
+port: 2449
+tls:
+  enabled: true
+  server:
+    certificate: 127.0.0.1.crt
+    key: 127.0.0.1.p8.key
+  client:
+    require: true
+    ca: client-ca.myhost.dev.crt
+
+
+
+
Verify connection with client certificate
+
+
openssl s_client -alpn h2 -connect 127.0.0.1:2449 -CAfile out/ca.myhost.dev.crt -cert out/client_1.crt -key out/client_1.key
+
+
+
+

Now you need to setup connection from another Dshackle server. I.e. the server we configured above is going be an +upstream to another Dshackle server, which we configure below.

+
+
+

Setup another Dshackle server on the same machine:

+
+
+
Configure dshackle.yaml for second server
+
+
version: v1
+port: 3449
+tls:
+  enabled: false
+
+
+
+

At this case we run another server on port 3449 in unsecure mode.But to connect to an upstream is still uses a TLS +certificate as described below

+
+
+
+
version: v1
+cluster:
+  upstreams:
+    - id: ds
+      chain: auto
+      provider: dshackle
+      connection:
+        grpc:
+          host: 127.0.0.1
+          port: 2449
+          tls:
+            ca: ca.myhost.dev.crt
+            certificate: client_1.crt
+            key: client_1.p8.key
+
+
+
+

Now if you run second server it will connect to first server ("upstream") running on port 2449, will verify upstream with certificate ca.myhost.dev.crt and authenticate itself by using pair of client_1.crt and client_1.p8.key

+
+
+
+
+

Server TLS configuration

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
NameExampleDescription
+

enabled

+
+
+
tls:
+  enabled: true
+
+

Enabled or disable TLS. By default it checks if certificate is set, and then enables it. But if you enable the TLS +but didn’t specify the certificate or key, then the DShackle will fails to start with error.

+

server.certificate, server.key

+
+
+
tls:
+  server:
+    certificate: server.com.crt
+    key: server.com.p8.key
+
+

Path to certificate and certificate private key

+

client.ca, client.cas, client.required

+
+
+
tls:
+  client:
+    cas:
+      - ca1.crt
+      - ca2.crt
+    required: true
+
+
+

Paths to CA used to authenticate incoming connections, used if required: true

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/09-quorum-and-selectors.adoc b/docs/09-quorum-and-selectors.adoc deleted file mode 100644 index 3499b49e6..000000000 --- a/docs/09-quorum-and-selectors.adoc +++ /dev/null @@ -1,7 +0,0 @@ -== Quorum - -TBD - -== Selectors - -TBD \ No newline at end of file diff --git a/docs/09-quorum-and-selectors.html b/docs/09-quorum-and-selectors.html new file mode 100644 index 000000000..b6339bc83 --- /dev/null +++ b/docs/09-quorum-and-selectors.html @@ -0,0 +1,463 @@ + + + + + + + +Quorum + + + + + +
+
+

Quorum

+
+
+

TBD

+
+
+
+
+

Selectors

+
+
+

TBD

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/10-caching.adoc b/docs/10-caching.adoc deleted file mode 100644 index 25ffce514..000000000 --- a/docs/10-caching.adoc +++ /dev/null @@ -1,67 +0,0 @@ -== Caching - -Dshackle can be configured to cache blockchain data. It can be a _hot_ in-memory cache, and optional _cold_ Redis-based -cache. - -Dshackle has enough information to effectively cache data and evict outdated values. If some data has been removed from -the blockchain, for example when block was replaced with another block at the same height, then the old values are -immediately evicted from the caches. - -=== In-memory cache - -Dshackle keeps latest blocks in memory (by default 64 blocks) - -=== Redis cache - -Dshackle can optionally cache blocks and transactions in Redis cache. The values are cached up to 1 hour, but -fresh blocks and transactions are cached for shorter period. - -It makes sense to reuse the same Redis cache between multiple instances of the Dshackle. - -.Basic config (dshackle.yaml) -[source, yaml] ----- -cache: - redis: - enabled: true ----- - -.Full config (dshackle.yaml) -[source, yaml] ----- -cache: - redis: - enabled: true - host: 127.0.0.1 - port: 6379 - db: 0 - password: passw0rd! ----- - - -.Options -|=== -| Name | Default Value | Description - -| enabled -| false -| Set to `true` if Dshackle should use Redis for caching - -| host -| 127.0.0.1 -| Redis host - -| port -| 6379 -| Redis port - -| db -| 0 -| Redis database - -| password -| -- -| Password if Redis requires authentication. The value can be read from Environment variable, to do that - specify it as `${REDIS_PASSWORD}`, where REDIS_PASSWORD is the name of the variable - -|=== \ No newline at end of file diff --git a/docs/10-caching.html b/docs/10-caching.html new file mode 100644 index 000000000..3d9a98e2c --- /dev/null +++ b/docs/10-caching.html @@ -0,0 +1,540 @@ + + + + + + + +Caching + + + + + +
+
+

Caching

+
+
+

Dshackle can be configured to cache blockchain data. It can be a hot in-memory cache, and optional cold Redis-based +cache.

+
+
+

Dshackle has enough information to effectively cache data and evict outdated values. If some data has been removed from +the blockchain, for example when block was replaced with another block at the same height, then the old values are +immediately evicted from the caches.

+
+
+

In-memory cache

+
+

Dshackle keeps latest blocks in memory (by default 64 blocks)

+
+
+
+

Redis cache

+
+

Dshackle can optionally cache blocks and transactions in Redis cache. The values are cached up to 1 hour, but +fresh blocks and transactions are cached for shorter period.

+
+
+

It makes sense to reuse the same Redis cache between multiple instances of the Dshackle.

+
+
+
Basic config (dshackle.yaml)
+
+
cache:
+  redis:
+    enabled: true
+
+
+
+
Full config (dshackle.yaml)
+
+
cache:
+  redis:
+    enabled: true
+    host: 127.0.0.1
+    port: 6379
+    db: 0
+    password: passw0rd!
+
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Options
NameDefault ValueDescription

enabled

false

Set to true if Dshackle should use Redis for caching

host

127.0.0.1

Redis host

port

6379

Redis port

db

0

Redis database

password

 — 

Password if Redis requires authentication. The value can be read from Environment variable, to do that + specify it as ${REDIS_PASSWORD}, where REDIS_PASSWORD is the name of the variable

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/99-ending.adoc b/docs/99-ending.adoc deleted file mode 100644 index b2127a5be..000000000 --- a/docs/99-ending.adoc +++ /dev/null @@ -1,12 +0,0 @@ -== Links - -- Github: https://github.com/p2p-org/dshackle - -== Chat - -Join our https://drpc.org/discord[Discord] - -== Support - -Want to support the project, prioritize a specific feature, or get commercial help with using Dshackle in your project? -Please contact splix@emeraldpay.io to discuss the possibility \ No newline at end of file diff --git a/docs/99-ending.html b/docs/99-ending.html new file mode 100644 index 000000000..92d84df11 --- /dev/null +++ b/docs/99-ending.html @@ -0,0 +1,476 @@ + + + + + + + +Links + + + + + +
+
+ +
+ +
+
+
+

Chat

+
+
+

Join our Discord

+
+
+
+
+

Support

+
+
+

Want to support the project, prioritize a specific feature, or get commercial help with using Dshackle in your project? +Please contact splix@emeraldpay.io to discuss the possibility

+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/README.adoc b/docs/README.adoc deleted file mode 100644 index 8f7878955..000000000 --- a/docs/README.adoc +++ /dev/null @@ -1,57 +0,0 @@ -= Dshackle Documentation - -== What is Dshackle - -Dshackle is a L7 Load Balancer for Blockchain APIs with automatic discovery, health checking, secure access, TLS with -client authentication, and many other features.It can be configured as an edge proxy, middle proxy or API gateway. - -Dshackle provided a high level aggregated API on top of several underlying upstreams (blockchain nodes or providers, -such as DRPC, etc), automatically verifies their availability and the current status of the network, -it routes requests to available node, and makes sure the response is consistent and/or data successfully broadcasted to -the networks. - -Example use cases: - -- Query for a _transaction_ (block, etc) tries to find it on different nodes and/or retry until it's found or there is -a consistent answer from upstreams -- Getting _nonce_ to send a transaction makes sure it's larges value over several nodes -- Sending _transaction_ distributes it to several nodes in parallel - -Availability and fault tolerance: - -- Dshackle connects to several upstreams via JSON RPC, Websockets or gRPC protocols -- It verifies if a node ("upstream") is fully synchronized (not in initial sync mode), has enough peers and its height -is not behind other nodes -- If an upstream lags behind, lost peers, started to resync, or simply goes down then Dshackle temporarily excludes it from -routing and returns back when the the upstream's problem is fixed - -Main goals: - -- stable and fault tolerant access to blockchain nodes -- secure connections and authentication -- allow to build scalable APIs with nodes distributed over multiple data centers - -== Table of Content - -. link:01-architecture-intro.adoc[Architecture Overview] -. link:02-quick-start.adoc[Quick Start] -. link:03-server-config.adoc[Server Configuration] -. link:04-upstream-config.adoc[Upstreams Configuration] -. link:05-start.adoc[How to launch a server] -. link:06-monitoring.adoc[Logging & Monitoring] -. link:07-methods.adoc[API methods] -. link:08-authentication.adoc[Authentication] -. link:09-quorum-and-selectors.adoc[Quorum and Selectors] -. link:10-caching.adoc[Caching] - -== Reference - -. link:reference-configuration.adoc[Configuration Reference] - -== Chat - -Join our https://drpc.org/discord[Discord] - -== Links - -- Github: https://github.com/p2p-org/dshackle \ No newline at end of file diff --git a/docs/README.html b/docs/README.html new file mode 100644 index 000000000..6e86f25ca --- /dev/null +++ b/docs/README.html @@ -0,0 +1,585 @@ + + + + + + + +Dshackle Documentation + + + + + +
+
+

What is Dshackle

+
+
+

Dshackle is a L7 Load Balancer for Blockchain APIs with automatic discovery, health checking, secure access, TLS with +client authentication, and many other features.It can be configured as an edge proxy, middle proxy or API gateway.

+
+
+

Dshackle provided a high level aggregated API on top of several underlying upstreams (blockchain nodes or providers, +such as DRPC, etc), automatically verifies their availability and the current status of the network, +it routes requests to available node, and makes sure the response is consistent and/or data successfully broadcasted to +the networks.

+
+
+

Example use cases:

+
+
+
    +
  • +

    Query for a transaction (block, etc) tries to find it on different nodes and/or retry until it’s found or there is +a consistent answer from upstreams

    +
  • +
  • +

    Getting nonce to send a transaction makes sure it’s larges value over several nodes

    +
  • +
  • +

    Sending transaction distributes it to several nodes in parallel

    +
  • +
+
+
+

Availability and fault tolerance:

+
+
+
    +
  • +

    Dshackle connects to several upstreams via JSON RPC, Websockets or gRPC protocols

    +
  • +
  • +

    It verifies if a node ("upstream") is fully synchronized (not in initial sync mode), has enough peers and its height +is not behind other nodes

    +
  • +
  • +

    If an upstream lags behind, lost peers, started to resync, or simply goes down then Dshackle temporarily excludes it from +routing and returns back when the the upstream’s problem is fixed

    +
  • +
+
+
+

Main goals:

+
+
+
    +
  • +

    stable and fault tolerant access to blockchain nodes

    +
  • +
  • +

    secure connections and authentication

    +
  • +
  • +

    allow to build scalable APIs with nodes distributed over multiple data centers

    +
  • +
+
+
+
+ +
+

Reference

+
+ +
+
+
+

Chat

+
+
+

Join our Discord

+
+
+
+
+ +
+ +
+
+
+ + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 120000 index 000000000..b70e3e805 --- /dev/null +++ b/docs/index.html @@ -0,0 +1 @@ +README.html \ No newline at end of file diff --git a/docs/reference-configuration.adoc b/docs/reference-configuration.adoc deleted file mode 100644 index 0eb6a451d..000000000 --- a/docs/reference-configuration.adoc +++ /dev/null @@ -1,947 +0,0 @@ -= Configuration Reference -:toc: -:toclevels: 2 - -toc::[] - -== Example - -.Example configuration with most options configured -[source,yaml] ----- -host: 0.0.0.0 -port: 2449 - -tls: - enabled: true - server: - certificate: "/path/127.0.0.1.crt" - key: "/path/127.0.0.1.p8.key" - client: - require: true - ca: "/path/ca.dshackle.test.crt" - -monitoring: - enabled: true - jvm: false - extended: false - prometheus: - enabled: true - bind: 127.0.0.1 - port: 8081 - path: /metrics - -health: - port: 8082 - host: 127.0.0.1 - path: /health - blockchains: - - chain: ethereum - min-availability: 1 - -cache: - redis: - enabled: true - host: redis-master - port: 6379 - db: 0 - password: I1y0dGKy01by - -signed-response: - enabled: true - algorithm: SECP256K1 - private-key: /path/key.pem - -proxy: - host: 0.0.0.0 - port: 8080 - websocket: true - preserve-batch-order: false - tls: - enabled: true - server: - certificate: "/path/127.0.0.1.crt" - key: "/path/127.0.0.1.p8.key" - client: - require: true - ca: "/path/ca.dshackle.test.crt" - routes: - - id: eth - blockchain: ethereum - - id: kovan - blockchain: kovan - -tokens: - - id: dai - blockchain: ethereum - name: DAI - type: ERC-20 - address: 0x6B175474E89094C44Da98b954EedeAC495271d0F - - id: tether - blockchain: ethereum - name: Tether - type: ERC-20 - address: 0xdac17f958d2ee523a2206206994597c13d831ec7 - -accessLog: - enabled: true - filename: /var/log/dshackle/access_log.jsonl - -cluster: - defaults: - - chains: - - ethereum - options: - min-peers: 10 - - chains: - - kovan - options: - min-peers: 3 - include: - - "upstreams-extra.yaml" - upstreams: - - id: local - chain: ethereum - labels: - fullnode: true - methods: - enabled: - - name: "parity_trace" - disabled: - - name: "admin_shutdown" - connection: - ethereum-pos: - execution: - rpc: - url: "http://localhost:8545" - ws: - url: "ws://localhost:8546" - origin: "http://localhost" - basic-auth: - username: 9c199ad8f281f20154fc258fe41a6814 - password: 258fe4149c199ad8f2811a68f20154fc - - id: infura - chain: ethereum - options: - disable-validation: true - connection: - ethereum-pos: - execution: - rpc: - url: "https://mainnet.infura.io/v3/fa28c968191849c1aff541ad1d8511f2" - basic-auth: - username: 4fc258fe41a68149c199ad8f281f2015 - password: 1a68f20154fc258fe4149c199ad8f281 - - id: bitcoin - chain: bitcoin - options: - # use the node to fetch balances - balance: true - connection: - bitcoin: - rpc: - url: "http://localhost:8332" - basic-auth: - username: bitcoin - password: e984af45bb888428207c290 - # use Esplora index to fetch balances and utxo for an address - esplora: - url: "http://localhost:3001" - # connect via ZeroMQ to get notifications about new blocks - zeromq: - address: "http://localhost:5555" - - id: remote - connection: - grpc: - host: "10.2.0.15" - tls: - ca: /path/ca.dshackle.test.crt - certificate: /path/client1.dshackle.test.crt - key: /path/client1.dshackle.test.key ----- - -== Top level config - -[cols="2a,2,5"] -|=== -| Option | Default Value | Description - -| `host` -| `127.0.0.0` -| Host to bind gRPC server - -| `port` -| `2449` -| Port to bind gRPC server - -| `tls` -| -| Setup TLS configuration for the gRPC server. -See <> section - -| `monitoring` -| -| Setup Prometheus monitoring. -See <> section - -| `health` -| -| Setup Health Check endpoint See <> section - -| `proxy` -| -| Setup HTTP proxy that emulates all standard JSON RPC requests. -See <> section - -| `accessLog` -| -| Configure access logging. -See <> section - - -| `tokens` -| -| Configure tokens for tracking balance. -See <> section - -| `cache` -| -| Caching configuration. -See <> section. - -| `signed-response` -| -| Signed responses -See <> section. - -| `cluster` -| -| Setup connection to remote nodes.See <> section - -|=== - -[#tls] -== TLS server config - -[source,yaml] ----- -tls: - enabled: true - server: - certificate: "/path/127.0.0.1.crt" - key: "/path/127.0.0.1.p8.key" - client: - require: true - ca: "/path/ca.dshackle.test.crt" ----- - -[cols="2a,2,5"] -|=== -| Option | Default Value | Description - -| `enabled` -a| `true` if any value is set -| Enable/Disable TLS - -| `server.certificate` -| -| Path to x509 certificate - -| `server.key` -| -| Path to a private key to the certificate.The key _MUST BE_ in PKCS 8 format - -| `client.require` -| -| If true then the server will required certificate from a client, otherwise client authentication is optional - -| `client.ca` -| -| Certificate to validate client authentication - -|=== - -[#monitoring] -== Monitoring - -Configure Prometheus monitoring - -[source,yaml] ----- -monitoring: - enabled: true - jvm: false - extended: false - prometheus: - enabled: true - bind: 127.0.0.1 - port: 8081 - path: /metrics ----- - -[cols="2a,2a,5"] -|=== -| Option | Default Value | Description - -| `enabled` -| `true` -| Enable/Disable monitoring endpoint - -| `jvm` -| `false` -| Enable/Disable JVM metrics (threads, GC, memory, etc) - -| `extended` -| `false` -| Enable/Disable additional metrics (query selectors, etc) - -| `prometheus.enabled` -| `true` -| Enable/Disable monitoring endpoint. -_Reserved for future use_, in case of multiple different types of endpoints. - -| `prometheus.bind` -| `127.0.0.1` -| Host to bind the server - -| `prometheus.port` -| `8081` -| Port to bind the server - -| `prometheus.path` -| `/metrics` -| HTTP path to bind the server - -|=== - -[#health] -== Health Check endpoint - -[source,yaml] ----- -health: - port: 8082 - host: 127.0.0.1 - path: /health - blockchains: - - chain: ethereum - min-available: 2 - - chain: bitcoin - min-available: 1 ----- - -[cols="2a,2a,5"] -|=== -| Option | Default Value | Description - -| `port` -| `8082` -| HTTP port to bind the server - -| `host` -| `127.0.0.1` -| HTTP host to bind the server - -| `path` -| `/health` -| HTTP path to respond on requests - -| `blockchains` -| -| List of blockchains that must be available to consider the server _healthy_ - -| `[blockchain].chain` -| -| Blockchain id - -| `[blockchain].min-available` -| 1 -| How many _available_ upstreams for the blockchain is required to pass - -|=== - -[#proxy] -== Proxy config - -[source,yaml] ----- -proxy: - host: 0.0.0.0 - port: 8080 - preserve-batch-order: false - tls: - enabled: true - server: - certificate: "/path/127.0.0.1.crt" - key: "/path/127.0.0.1.p8.key" - client: - require: true - ca: "/path/ca.dshackle.test.crt" - routes: - - id: eth - blockchain: ethereum - - id: kovan - blockchain: kovan ----- - -.Top config -[cols="2a,2,5"] -|=== -| Option | Default Value | Description - -| `host` -| `127.0.0.0` -| Host to bind HTTP server - -| `port` -| `8080` -| Port to bind HTT server - -| `port` -| `false` -| Should proxy preserve request-response correspondence when sending batch request via http - -| `websocket` -| `true` -| Enable WebSocket Proxy - -| `tls` -| -| Setup TLS configuration for the Proxy server. -See <> section - -| `preserve-batch-order` -| false -| If `false` Dshackle may produce _batch_ response in different order, which is correct as per JSON RPC Spec. -If set to `true` then Dshackle preserves _batch_ order based on request order. -Note that latter is ineffective and use this option only when a client cannot reference responses by their IDs. - -| `cors-origin` -| -| Access-Control-Allow-Origin contents. If empty the header will be omitted in response - -| `cors-allowed-headers` -| `Content-Type` -| Access-Control-Allow-Headers contents. Takes effect only if сors-origi is present in config - -| `routes` -| -a| Routing paths for Proxy. -The proxy will handle requests as `https://${HOST}:${PORT}/${ROUTE_ID}` (or `http://` if TLS is not enabled). -For WebSocket it's `wss` / `ws`, accordingly. -|=== - -.Route config -[cols="2a,2,5"] -|=== -| Option | Default Value | Description - -| `id` -| -| Internal _alphanumeric_ id, and a path of binding url - `https://${HOST}:${PORT}/${ROUTE_ID}`. - -| `blockchain` -| -| A blockchain that must be used to handle that route. - -|=== - -[#accessLog] -== Access Log config - -[source,yaml] ----- -accessLog: - enabled: true - filename: /var/log/dshackle/access_log.jsonl ----- - -.Access Log config -[cols="2a,3a,7"] -|=== -| Option | Default | Description - -| `enabled` -| `false` -| Enable/Disable Access logging - -| `include-messages` -| `false` -| Include request params and response result/error (i.e., a JSON) in access log. -It's an expensive operation, use it for debugging only. -Note that for errors it provides only error message, not the error response itself. - -| `filename` -| `access_log.jsonl` -| Path to the access log file - -|=== - -[#tokens] -== Tokens config - -[source,yaml] ----- -tokens: - - id: dai - blockchain: ethereum - name: DAI - type: ERC-20 - address: 0x6B175474E89094C44Da98b954EedeAC495271d0F - - id: tether - blockchain: ethereum - name: Tether - type: ERC-20 - address: 0xdac17f958d2ee523a2206206994597c13d831ec7 ----- - -Tokens config enables tracking of a balance amount in the configured tokens. -After making the configuration above you can request balance (`GetBalance`), or subscribe to balance changes (`SubscribeBalance`), using link:07-methods.adoc[enhanced protocol] - -.Token config -[cols="2a,7"] -|=== -| Option | Description - -| `id` -| Internal id for reference (used in logging, etc) - -| `blockchain` -| An ethereum-based blockchain where the contract is deployed - -| `name` -| Name of the token, used for balance response as asset code (as converted to UPPERCASE) - -| `type` -| Type of token.Only `ERC-20` is supported at this moment - -| `address` -| Address of the deployed contract - -|=== - -[#cache] -== Cache config - -[source,yaml] ----- -cache: - redis: - enabled: true - host: redis-master - port: 6379 - db: 0 - password: I1y0dGKy01by ----- - -.Redis Config -[cols="2a,2,5"] -|=== -| Option | Default Value | Description - -| `enabled` -| `false` -| Enable/disable Redis cache - -| `host` -| `127.0.0.1` -| Redis host address - -| `port` -| `6379` -| Redis port - -| `db` -| `0` -| Redis DB to select - -| `password` -| -| Password for connection, if required - -|=== - -[#signed-response] -== Signed Response - -[source,yaml] ----- -signed-response: - enabled: true - algorithm: SECP256K1 - private-key: /path/key.pem ----- - -.Redis Config -[cols="2a,2,5"] -|=== -| Option | Default Value | Description - -| `enabled` -| `false` -| Enable/disable Signed Responses - -| `algorithm` -| `SECP256K1` -| `SECP256K1` or `NIST-P256` - -| `private-key` -| -| Path to a private key in PEM format - -|=== - -See more details at link:07-methods.adoc#signatures[Signed Response] in gRPC Methods. - -[#cluster] -== Cluster - -The cluster config is the main part, that defines all connection to nodes and other servers - -[source,yaml] ----- -cluster: - defaults: - - chains: - - ethereum - options: - min-peers: 10 - upstreams: - - id: local - chain: ethereum - connection: - ethereum-pos: - execution: - rpc: - url: "http://localhost:8545" - ws: - url: "ws://localhost:8546" - origin: "http://localhost" - include: - - "upstreams-extra.yaml" ----- - -=== Main Cluster Configuration - -.Top Level Config -[cols="2a,5"] -|=== -| Option | Description - -| `defaults` -| Default options applied to all upstreams within the specified blockchain. It's an optional -configuration, and may be omitted for most of the situations. - -| `upstreams` -| List of upstream servers. The main part of the config. There are two types of upstream: <> and <>. - -| `include` -| Path(s) to include configurations for upstream servers. Same as `upstreams`, but load it from an external file. - -|=== - -[#upstream-json] -=== JSON RPC Upstream - -[source,yaml] ----- -- id: local - chain: ethereum - role: standard - labels: - fullnode: true - methods: - enabled: - - name: "parity_trace" - quorum: "not_empty" - disabled: - - name: "admin_shutdown" - connection: - ethereum-pos: - execution: - rpc: - url: "http://localhost:8545" - ws: - url: "ws://localhost:8546" - origin: "http://localhost" - basic-auth: - username: 9c199ad8f281f20154fc258fe41a6814 - password: 258fe4149c199ad8f2811a68f20154fc - frameSize: 5mb - msgSize: 15mb ----- - -.Main Config -[cols="2a,1a,5"] -|=== -| Option | Required | Description - -| `id` -| yes -| Per-cluster identifier of an upstream - -| `role` -| no -| `primary` (default), `secondary` or `fallback`. -First it makes the requests to the upstreams with role `primary`, then if none are available to upstreams with role `secondary`. -Fallback role mean that the upstream is used only after other upstreams failed or didn't return quorum - -| `chain` -| yes -| Blockchain which is the provided by the upstream. -Cluster may have multiple upstreams for a single blockchain. -Accepted types: `bitcoin`, `bitcoin-testnet`, `ethereum`, `ethereum-classic`, `kovan-testnet`, `rinkeby-testnet`, `ropsten-testnet`, or `goerli-testnet` - -| `enabled` -| no -| `true` (default) or `false`. -Enable/disable the upstream. - -| `labels` -| no -| Key-Value pairs that are assigned to the upstream. -Used to select an upstream per-request. -See link:09-quorum-and-selectors.adoc[Quorum and Selectors] - -| `options` -| -| Other configuration options. See <> - -| `methods` -| no -| Enable (`enabled`) or disable (`disabled`) additional JSON RPC methods that are provided by that particular upstream - -| `methods.enabled.name`, `methods.disabled.name` -| yes -| Name of the RPC method to enable/disable. - -| `methods.enabled.quorum` -| no -| Set quorum criteria to accept a response. -`always` (default) - accept any response; -`not_empty` - accept not _null_ value, otherwise retry another upstream; -`not_lagging` - accept response only from a fully synced upstream. - -| `connection.ethereum-pos` -| yes -| Connection configuration for Ethereum API of PoS network - -| `connection.bitcoin` -| yes -| Connection configuration for Bitcoin API - -|=== - -[#general-options] -=== General Upstream Options - -[cols="2a,1,1a,5"] -|=== -| Option | Type | Default | Description - -| `disable-validation` -| boolean -| `false` -| Disables all the validations of the upstream. I.e., it turns off `validate-peers` and `validate-syncing` checks if set to `true`. - -| `validate-chain` -| boolean -| `true` -| Disables validation of the chain settings of the upstream. Prevent of creating an upstream with incorrect chain if it relates to a node with another chain. - -| `validation-interval` -| number -| `30` -| Period in seconds to re-validate the upstream. - -| `validate-peers` -| boolean -| `true` -| Disables validation of the peers connected to the upstream (as `net_peerCount` method). -Dshackle assumes that if there are too few peers then the Upstream is just started and may produce invalid/outdated responses - -| `min-peers` -| number -| `1` -| The minimum number of connected peer to consider the upstream valid if `validate-peers` is enabled. -If it's set to `0` it essentially disables the peer validation. - -| `validate-syncing` -| boolean -| `true` -| Disables checking for the state of syncing on the upstream (as `eth_syncing` method). -If the Upstream is in _syncing_ state then the Dshackle doesn't use it for call until it reaches the blockchain head. - -| `timeout` -| number -| `60` -| Timeout in seconds to wait for an answer from the upstream before considering it as failed. - -| `balance` -| boolean -| -| Suitable for Bitcoin upstream. -Tells if the Upstream can be used to call balance methods, which requires that the node has the indexing as turned on. - -|=== - -==== Ethereum Connection Options - -.Connection Config for Ethereum Upstream -[cols="2a,5"] -|=== -| Option | Description - -| `rpc.url` -a| HTTP URL to connect to.This is required for a connection. + -URL can be configured with Environment Variable placeholders `${ENV_VAR_NAME}`. + -Example: `https://kovan.infura.io/v3/${INFURA_USER}` - -| `rpc.basic-auth` + `rpc.basic-auth.username`, `rpc.basic-auth.password` -a| HTTP Basic Auth configuration, if required by the remote server. + -Values can also reference env variables, for example: -[source,yaml] ----- -rpc: - url: "https://ethereum.com:8545" - basic-auth: - username: "${ETH_USERNAME}" - password: "${ETH_PASSWORD}" ----- - -| `ws.url` -| WebSocket URL to connect to. -Optional, but optimizes performance if it's available. - -| `ws.origin` -| HTTP `Origin` if required by WebSocket remote server. - -| `ws.basic-auth` + ... -| WebSocket Basic Auth configuration, if required by the remote server - -| `ws.frameSize` -| WebSocket frame size limit. -Ex `1kb`, `1024` (same as `1kb), `2mb`, etc. -Default is 5Mb - -| `ws.msgSize` -| Total limit for a message size consisting from multiple frames. -Ex `1kb`, `1024` (same as `1kb), `2mb`, etc. -Default is 15Mb - -| `ws.connections` -| How many concurrent connection to make. If more than one, each used in a robin-round fashion. -Defaults is `1` -|=== - -==== PoS Ethereum Connection Options -.Connection Config for PoS Ethereum Upstream -[cols="2a,5"] -|=== -| Option | Description - -| `execution` -a| Here you can specify any option from plain ethereum connection options listed above + -This is your connection to an execution layer of PoS Ethereum - -| `upstream-rating` -a| Rating for this upstream. We will always consider the head of the chain to be + -the latest block we saw from the upstream with the highest rating. - -|=== - -==== Bitcoin Connection Options - -.Connection Config for Bitcoin Upstream -[cols="2a,5"] -|=== -| Option | Description - -| `rpc.url` -a| HTTP URL to connect to. This is required for a connection. + -URL can be configured with Environment Variable placeholders `${ENV_VAR_NAME}`. + -Example: `http://${NODE_HOST}:${NODE_PORT}` - -| `rpc.basic-auth` + `rpc.basic-auth.username`, `rpc.basic-auth.password` -a| HTTP Basic Auth configuration, which is required by the Bitcoind server. + -Values can also reference env variables, for example: -[source,yaml] ----- -rpc: - url: "http://127.0.0.1:8332" - basic-auth: - username: "${NODE_USERNAME}" - password: "${NODE_PASSWORD}" ----- - -| `zeromq.address` -a| Set up an additional connection via ZeroMQ protocol to subscribe to the new blocks. -The node must be launched with the same address specified as `-zmqpubhashblock="tcp://${HOST}:${POST}"` or in `bitcoin.conf` -[source,yaml] ----- -zeromq: - address: "127.0.0.1:5555" ----- - -|=== - -[#upstream-dshackle] -=== Dshackle Upstream - -Another option is using another Dshackle server as an upstream. -It's more effective, easier to secure connection, and allows to build a distributed network of servers. - -[source,yaml] ----- -- id: test1 - labels: - provider: some - connection: - grpc: - host: eu-api.mycompany.com - port: 2449 - tls: - ca: ca.api.mycompany.crt - certificate: client-1.api.mycompany.crt - key: client-1.api.mycompany.p8.key ----- - -.Main Config -[cols="2a,1a,5"] -|=== -| Option | Required | Description - -| `id` -| yes -| Per-cluster identifier of an upstream - -| `labels` -| no -| Defines the labels can be used for the proper upstream instance selection. Overrides the labels retrieved by the `describe` method - -| `connection.grpc` -| yes -| Connection configuration for Dshackle gRPC -|=== - -.Connection Config -[cols="2a,5"] -|=== -| Option | Description - -| `host` and `port` -| Address to connect to - -| `tls` -a| TLC configuration for the connection. -In general it's an optional configuration, but it's strongly recommended. -Also HTTP2 + gRPC is designed to be used with TLS, and some of the related software is unable to use it without TLS. + -See link:08-authentication.adoc[Authentication] docs and <>. - -| `tls.ca` -| Path to x509 certificate to verify remote server - -| `tls.certificate` + `tls.key` -| Client certificate (x509) and its private key (PKCS 8) used for authentication on the remote server. - -|=== diff --git a/docs/reference-configuration.html b/docs/reference-configuration.html new file mode 100644 index 000000000..88fed6298 --- /dev/null +++ b/docs/reference-configuration.html @@ -0,0 +1,2009 @@ + + + + + + + +Configuration Reference + + + + + +
+
+
+ +
+
+
+

Example

+
+
+
Example configuration with most options configured
+
+
host: 0.0.0.0
+port: 2449
+
+tls:
+  enabled: true
+  server:
+    certificate: "/path/127.0.0.1.crt"
+    key: "/path/127.0.0.1.p8.key"
+  client:
+    require: true
+    ca: "/path/ca.dshackle.test.crt"
+
+monitoring:
+  enabled: true
+  jvm: false
+  extended: false
+  prometheus:
+    enabled: true
+    bind: 127.0.0.1
+    port: 8081
+    path: /metrics
+
+health:
+  port: 8082
+  host: 127.0.0.1
+  path: /health
+  blockchains:
+   - chain: ethereum
+     min-availability: 1
+
+cache:
+  redis:
+    enabled: true
+    host: redis-master
+    port: 6379
+    db: 0
+    password: I1y0dGKy01by
+
+signed-response:
+  enabled: true
+  algorithm: SECP256K1
+  private-key: /path/key.pem
+
+proxy:
+  host: 0.0.0.0
+  port: 8080
+  websocket: true
+  preserve-batch-order: false
+  tls:
+    enabled: true
+    server:
+      certificate: "/path/127.0.0.1.crt"
+      key: "/path/127.0.0.1.p8.key"
+    client:
+      require: true
+      ca: "/path/ca.dshackle.test.crt"
+  routes:
+    - id: eth
+      blockchain: ethereum
+    - id: kovan
+      blockchain: kovan
+
+tokens:
+  - id: dai
+    blockchain: ethereum
+    name: DAI
+    type: ERC-20
+    address: 0x6B175474E89094C44Da98b954EedeAC495271d0F
+  - id: tether
+    blockchain: ethereum
+    name: Tether
+    type: ERC-20
+    address: 0xdac17f958d2ee523a2206206994597c13d831ec7
+
+accessLog:
+  enabled: true
+  filename: /var/log/dshackle/access_log.jsonl
+
+cluster:
+  defaults:
+    - chains:
+        - ethereum
+      options:
+        min-peers: 10
+    - chains:
+        - kovan
+      options:
+        min-peers: 3
+  include:
+    - "upstreams-extra.yaml"
+  upstreams:
+    - id: local
+      chain: ethereum
+      labels:
+        fullnode: true
+      methods:
+        enabled:
+          - name: "parity_trace"
+        disabled:
+          - name: "admin_shutdown"
+      connection:
+        ethereum-pos:
+            execution:
+              rpc:
+                url: "http://localhost:8545"
+              ws:
+                url: "ws://localhost:8546"
+                origin: "http://localhost"
+                basic-auth:
+                  username: 9c199ad8f281f20154fc258fe41a6814
+                  password: 258fe4149c199ad8f2811a68f20154fc
+    - id: infura
+      chain: ethereum
+      options:
+        disable-validation: true
+      connection:
+        ethereum-pos:
+            execution:
+              rpc:
+                url: "https://mainnet.infura.io/v3/fa28c968191849c1aff541ad1d8511f2"
+                basic-auth:
+                  username: 4fc258fe41a68149c199ad8f281f2015
+                  password: 1a68f20154fc258fe4149c199ad8f281
+    - id: bitcoin
+      chain: bitcoin
+      options:
+        # use the node to fetch balances
+        balance: true
+      connection:
+        bitcoin:
+          rpc:
+            url: "http://localhost:8332"
+            basic-auth:
+              username: bitcoin
+              password: e984af45bb888428207c290
+          # use Esplora index to fetch balances and utxo for an address
+          esplora:
+            url: "http://localhost:3001"
+          # connect via ZeroMQ to get notifications about new blocks
+          zeromq:
+            address: "http://localhost:5555"
+    - id: remote
+      connection:
+        grpc:
+          host: "10.2.0.15"
+          tls:
+            ca: /path/ca.dshackle.test.crt
+            certificate: /path/client1.dshackle.test.crt
+            key: /path/client1.dshackle.test.key
+
+
+
+
+
+

Top level config

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefault ValueDescription
+

host

+

127.0.0.0

Host to bind gRPC server

+

port

+

2449

Port to bind gRPC server

+

tls

+

Setup TLS configuration for the gRPC server. +See TLS server config section

+

monitoring

+

Setup Prometheus monitoring. +See Monitoring section

+

health

+

Setup Health Check endpoint See Health Check endpoint section

+

proxy

+

Setup HTTP proxy that emulates all standard JSON RPC requests. +See Proxy config section

+

accessLog

+

Configure access logging. +See Access Log config section

+

tokens

+

Configure tokens for tracking balance. +See Tokens config section

+

cache

+

Caching configuration. +See Cache config section.

+

signed-response

+

Signed responses +See Signed Response section.

+

cluster

+

Setup connection to remote nodes.See Cluster section

+
+
+
+

TLS server config

+
+
+
+
tls:
+  enabled: true
+  server:
+    certificate: "/path/127.0.0.1.crt"
+    key: "/path/127.0.0.1.p8.key"
+  client:
+    require: true
+    ca: "/path/ca.dshackle.test.crt"
+
+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefault ValueDescription
+

enabled

+
+

true if any value is set

+

Enable/Disable TLS

+

server.certificate

+

Path to x509 certificate

+

server.key

+

Path to a private key to the certificate.The key MUST BE in PKCS 8 format

+

client.require

+

If true then the server will required certificate from a client, otherwise client authentication is optional

+

client.ca

+

Certificate to validate client authentication

+
+
+
+

Monitoring

+
+
+

Configure Prometheus monitoring

+
+
+
+
monitoring:
+  enabled: true
+  jvm: false
+  extended: false
+  prometheus:
+    enabled: true
+    bind: 127.0.0.1
+    port: 8081
+    path: /metrics
+
+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefault ValueDescription
+

enabled

+
+

true

+

Enable/Disable monitoring endpoint

+

jvm

+
+

false

+

Enable/Disable JVM metrics (threads, GC, memory, etc)

+

extended

+
+

false

+

Enable/Disable additional metrics (query selectors, etc)

+

prometheus.enabled

+
+

true

+

Enable/Disable monitoring endpoint. +Reserved for future use, in case of multiple different types of endpoints.

+

prometheus.bind

+
+

127.0.0.1

+

Host to bind the server

+

prometheus.port

+
+

8081

+

Port to bind the server

+

prometheus.path

+
+

/metrics

+

HTTP path to bind the server

+
+
+
+

Health Check endpoint

+
+
+
+
health:
+  port: 8082
+  host: 127.0.0.1
+  path: /health
+  blockchains:
+    - chain: ethereum
+      min-available: 2
+    - chain: bitcoin
+      min-available: 1
+
+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefault ValueDescription
+

port

+
+

8082

+

HTTP port to bind the server

+

host

+
+

127.0.0.1

+

HTTP host to bind the server

+

path

+
+

/health

+

HTTP path to respond on requests

+

blockchains

+

List of blockchains that must be available to consider the server healthy

+

[blockchain].chain

+

Blockchain id

+

[blockchain].min-available

+
+

1

+

How many available upstreams for the blockchain is required to pass

+
+
+
+

Proxy config

+
+
+
+
proxy:
+  host: 0.0.0.0
+  port: 8080
+  preserve-batch-order: false
+  tls:
+    enabled: true
+    server:
+      certificate: "/path/127.0.0.1.crt"
+      key: "/path/127.0.0.1.p8.key"
+    client:
+      require: true
+      ca: "/path/ca.dshackle.test.crt"
+  routes:
+    - id: eth
+      blockchain: ethereum
+    - id: kovan
+      blockchain: kovan
+
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Top config
OptionDefault ValueDescription
+

host

+

127.0.0.0

Host to bind HTTP server

+

port

+

8080

Port to bind HTT server

+

port

+

false

Should proxy preserve request-response correspondence when sending batch request via http

+

websocket

+

true

Enable WebSocket Proxy

+

tls

+

Setup TLS configuration for the Proxy server. +See TLS server config section

+

preserve-batch-order

+

false

If false Dshackle may produce batch response in different order, which is correct as per JSON RPC Spec. +If set to true then Dshackle preserves batch order based on request order. +Note that latter is ineffective and use this option only when a client cannot reference responses by their IDs.

+

cors-origin

+

Access-Control-Allow-Origin contents. If empty the header will be omitted in response

+

cors-allowed-headers

+

Content-Type

Access-Control-Allow-Headers contents. Takes effect only if сors-origi is present in config

+

routes

+
+

Routing paths for Proxy. +The proxy will handle requests as https://${HOST}:${PORT}/${ROUTE_ID} (or http:// if TLS is not enabled). +For WebSocket it’s wss / ws, accordingly.

+
+ + +++++ + + + + + + + + + + + + + + + + + + + +
Table 2. Route config
OptionDefault ValueDescription
+

id

+

Internal alphanumeric id, and a path of binding url - https://${HOST}:${PORT}/${ROUTE_ID}.

+

blockchain

+

A blockchain that must be used to handle that route.

+
+
+
+

Access Log config

+
+
+
+
accessLog:
+  enabled: true
+  filename: /var/log/dshackle/access_log.jsonl
+
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 3. Access Log config
OptionDefaultDescription
+

enabled

+
+

false

+

Enable/Disable Access logging

+

include-messages

+
+

false

+

Include request params and response result/error (i.e., a JSON) in access log. +It’s an expensive operation, use it for debugging only. +Note that for errors it provides only error message, not the error response itself.

+

filename

+
+

access_log.jsonl

+

Path to the access log file

+
+
+
+

Tokens config

+
+
+
+
tokens:
+  - id: dai
+    blockchain: ethereum
+    name: DAI
+    type: ERC-20
+    address: 0x6B175474E89094C44Da98b954EedeAC495271d0F
+  - id: tether
+    blockchain: ethereum
+    name: Tether
+    type: ERC-20
+    address: 0xdac17f958d2ee523a2206206994597c13d831ec7
+
+
+
+

Tokens config enables tracking of a balance amount in the configured tokens. +After making the configuration above you can request balance (GetBalance), or subscribe to balance changes (SubscribeBalance), using enhanced protocol

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 4. Token config
OptionDescription
+

id

+

Internal id for reference (used in logging, etc)

+

blockchain

+

An ethereum-based blockchain where the contract is deployed

+

name

+

Name of the token, used for balance response as asset code (as converted to UPPERCASE)

+

type

+

Type of token.Only ERC-20 is supported at this moment

+

address

+

Address of the deployed contract

+
+
+
+

Cache config

+
+
+
+
cache:
+  redis:
+    enabled: true
+    host: redis-master
+    port: 6379
+    db: 0
+    password: I1y0dGKy01by
+
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 5. Redis Config
OptionDefault ValueDescription
+

enabled

+

false

Enable/disable Redis cache

+

host

+

127.0.0.1

Redis host address

+

port

+

6379

Redis port

+

db

+

0

Redis DB to select

+

password

+

Password for connection, if required

+
+
+
+

Signed Response

+
+
+
+
signed-response:
+  enabled: true
+  algorithm: SECP256K1
+  private-key: /path/key.pem
+
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 6. Redis Config
OptionDefault ValueDescription
+

enabled

+

false

Enable/disable Signed Responses

+

algorithm

+

SECP256K1

SECP256K1 or NIST-P256

+

private-key

+

Path to a private key in PEM format

+
+

See more details at Signed Response in gRPC Methods.

+
+
+
+
+

Cluster

+
+
+

The cluster config is the main part, that defines all connection to nodes and other servers

+
+
+
+
cluster:
+  defaults:
+    - chains:
+        - ethereum
+      options:
+        min-peers: 10
+  upstreams:
+    - id: local
+      chain: ethereum
+      connection:
+        ethereum-pos:
+            execution:
+              rpc:
+                url: "http://localhost:8545"
+              ws:
+                url: "ws://localhost:8546"
+                origin: "http://localhost"
+  include:
+    - "upstreams-extra.yaml"
+
+
+
+

Main Cluster Configuration

+ + ++++ + + + + + + + + + + + + + + + + + + + + +
Table 7. Top Level Config
OptionDescription
+

defaults

+

Default options applied to all upstreams within the specified blockchain. It’s an optional +configuration, and may be omitted for most of the situations.

+

upstreams

+

List of upstream servers. The main part of the config. There are two types of upstream: JSON RPC Upstream and Dshackle Upstream.

+

include

+

Path(s) to include configurations for upstream servers. Same as upstreams, but load it from an external file.

+
+
+

JSON RPC Upstream

+
+
+
- id: local
+  chain: ethereum
+  role: standard
+  labels:
+    fullnode: true
+  methods:
+    enabled:
+      - name: "parity_trace"
+        quorum: "not_empty"
+    disabled:
+      - name: "admin_shutdown"
+  connection:
+    ethereum-pos:
+      execution:
+          rpc:
+            url: "http://localhost:8545"
+          ws:
+            url: "ws://localhost:8546"
+            origin: "http://localhost"
+            basic-auth:
+              username: 9c199ad8f281f20154fc258fe41a6814
+              password: 258fe4149c199ad8f2811a68f20154fc
+            frameSize: 5mb
+            msgSize: 15mb
+
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 8. Main Config
OptionRequiredDescription
+

id

+
+

yes

+

Per-cluster identifier of an upstream

+

role

+
+

no

+

primary (default), secondary or fallback. +First it makes the requests to the upstreams with role primary, then if none are available to upstreams with role secondary. +Fallback role mean that the upstream is used only after other upstreams failed or didn’t return quorum

+

chain

+
+

yes

+

Blockchain which is the provided by the upstream. +Cluster may have multiple upstreams for a single blockchain. +Accepted types: bitcoin, bitcoin-testnet, ethereum, ethereum-classic, kovan-testnet, rinkeby-testnet, ropsten-testnet, or goerli-testnet

+

enabled

+
+

no

+

true (default) or false. +Enable/disable the upstream.

+

labels

+
+

no

+

Key-Value pairs that are assigned to the upstream. +Used to select an upstream per-request. +See Quorum and Selectors

+

options

+

Other configuration options. See General Upstream Options

+

methods

+
+

no

+

Enable (enabled) or disable (disabled) additional JSON RPC methods that are provided by that particular upstream

+

methods.enabled.name, methods.disabled.name

+
+

yes

+

Name of the RPC method to enable/disable.

+

methods.enabled.quorum

+
+

no

+

Set quorum criteria to accept a response. +always (default) - accept any response; +not_empty - accept not null value, otherwise retry another upstream; +not_lagging - accept response only from a fully synced upstream.

+

connection.ethereum-pos

+
+

yes

+

Connection configuration for Ethereum API of PoS network

+

connection.bitcoin

+
+

yes

+

Connection configuration for Bitcoin API

+
+
+

General Upstream Options

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionTypeDefaultDescription
+

disable-validation

+

boolean

+

false

+

Disables all the validations of the upstream. I.e., it turns off validate-peers and validate-syncing checks if set to true.

+

validate-chain

+

boolean

+

true

+

Disables validation of the chain settings of the upstream. Prevent of creating an upstream with incorrect chain if it relates to a node with another chain.

+

validation-interval

+

number

+

30

+

Period in seconds to re-validate the upstream.

+

validate-peers

+

boolean

+

true

+

Disables validation of the peers connected to the upstream (as net_peerCount method). +Dshackle assumes that if there are too few peers then the Upstream is just started and may produce invalid/outdated responses

+

min-peers

+

number

+

1

+

The minimum number of connected peer to consider the upstream valid if validate-peers is enabled. +If it’s set to 0 it essentially disables the peer validation.

+

validate-syncing

+

boolean

+

true

+

Disables checking for the state of syncing on the upstream (as eth_syncing method). +If the Upstream is in syncing state then the Dshackle doesn’t use it for call until it reaches the blockchain head.

+

timeout

+

number

+

60

+

Timeout in seconds to wait for an answer from the upstream before considering it as failed.

+

balance

+

boolean

Suitable for Bitcoin upstream. +Tells if the Upstream can be used to call balance methods, which requires that the node has the indexing as turned on.

+
+

Ethereum Connection Options

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 9. Connection Config for Ethereum Upstream
OptionDescription
+

rpc.url

+
+

HTTP URL to connect to.This is required for a connection.
+URL can be configured with Environment Variable placeholders ${ENV_VAR_NAME}.
+Example: https://kovan.infura.io/v3/${INFURA_USER}

+
+

rpc.basic-auth + rpc.basic-auth.username, rpc.basic-auth.password

+
+

HTTP Basic Auth configuration, if required by the remote server.
+Values can also reference env variables, for example:

+
+
+
+
rpc:
+  url: "https://ethereum.com:8545"
+  basic-auth:
+    username: "${ETH_USERNAME}"
+    password: "${ETH_PASSWORD}"
+
+
+

ws.url

+

WebSocket URL to connect to. +Optional, but optimizes performance if it’s available.

+

ws.origin

+

HTTP Origin if required by WebSocket remote server.

+

ws.basic-auth + …​

+

WebSocket Basic Auth configuration, if required by the remote server

+

ws.frameSize

+

WebSocket frame size limit. +Ex 1kb, 1024 (same as 1kb), `2mb, etc. +Default is 5Mb

+

ws.msgSize

+

Total limit for a message size consisting from multiple frames. +Ex 1kb, 1024 (same as 1kb), `2mb, etc. +Default is 15Mb

+

ws.connections

+

How many concurrent connection to make. If more than one, each used in a robin-round fashion. +Defaults is 1

+
+
+

PoS Ethereum Connection Options

+ + ++++ + + + + + + + + + + + + + + + + +
Table 10. Connection Config for PoS Ethereum Upstream
OptionDescription
+

execution

+
+

Here you can specify any option from plain ethereum connection options listed above
+This is your connection to an execution layer of PoS Ethereum

+
+

upstream-rating

+
+

Rating for this upstream. We will always consider the head of the chain to be
+the latest block we saw from the upstream with the highest rating.

+
+
+
+

Bitcoin Connection Options

+ + ++++ + + + + + + + + + + + + + + + + + + + + +
Table 11. Connection Config for Bitcoin Upstream
OptionDescription
+

rpc.url

+
+

HTTP URL to connect to. This is required for a connection.
+URL can be configured with Environment Variable placeholders ${ENV_VAR_NAME}.
+Example: http://${NODE_HOST}:${NODE_PORT}

+
+

rpc.basic-auth + rpc.basic-auth.username, rpc.basic-auth.password

+
+

HTTP Basic Auth configuration, which is required by the Bitcoind server.
+Values can also reference env variables, for example:

+
+
+
+
rpc:
+  url: "http://127.0.0.1:8332"
+  basic-auth:
+    username: "${NODE_USERNAME}"
+    password: "${NODE_PASSWORD}"
+
+
+

zeromq.address

+
+

Set up an additional connection via ZeroMQ protocol to subscribe to the new blocks. +The node must be launched with the same address specified as -zmqpubhashblock="tcp://${HOST}:${POST}" or in bitcoin.conf

+
+
+
+
zeromq:
+  address: "127.0.0.1:5555"
+
+
+
+
+
+

Dshackle Upstream

+
+

Another option is using another Dshackle server as an upstream. +It’s more effective, easier to secure connection, and allows to build a distributed network of servers.

+
+
+
+
- id: test1
+  labels:
+    provider: some
+  connection:
+    grpc:
+      host: eu-api.mycompany.com
+      port: 2449
+      tls:
+        ca: ca.api.mycompany.crt
+        certificate: client-1.api.mycompany.crt
+        key: client-1.api.mycompany.p8.key
+
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 12. Main Config
OptionRequiredDescription
+

id

+
+

yes

+

Per-cluster identifier of an upstream

+

labels

+
+

no

+

Defines the labels can be used for the proper upstream instance selection. Overrides the labels retrieved by the describe method

+

connection.grpc

+
+

yes

+

Connection configuration for Dshackle gRPC

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 13. Connection Config
OptionDescription
+

host and port

+

Address to connect to

+

tls

+
+

TLC configuration for the connection. +In general it’s an optional configuration, but it’s strongly recommended. +Also HTTP2 + gRPC is designed to be used with TLS, and some of the related software is unable to use it without TLS.
+See Authentication docs and TLS server config.

+
+

tls.ca

+

Path to x509 certificate to verify remote server

+

tls.certificate + tls.key

+

Client certificate (x509) and its private key (PKCS 8) used for authentication on the remote server.

+
+
+
+
+ + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 120000 index 000000000..b70e3e805 --- /dev/null +++ b/index.html @@ -0,0 +1 @@ +README.html \ No newline at end of file