LBRY Rosetta API Implementation
Go to file
Patrick O'Grady ba9d9ce367
Merge pull request #11 from coinbase/patrick/add-versioning-info
[Services] Add versioning info
2020-09-20 21:07:19 -07:00
.circleci Update linter 2020-09-20 15:24:43 -07:00
.github Initial commit 2020-09-17 14:40:16 -07:00
assets Add warning to config files 2020-09-18 08:01:47 -07:00
bitcoin Add test for bitcoin mempool implementation 2020-09-18 18:10:56 -07:00
configuration Initial commit 2020-09-17 14:40:16 -07:00
indexer Use small index cache in tests 2020-09-18 12:18:57 -07:00
mocks Add support for mempool 2020-09-18 18:04:37 -07:00
rosetta-cli-conf Initial commit 2020-09-17 14:40:16 -07:00
services Update version info 2020-09-20 15:20:34 -07:00
utils Initial commit 2020-09-17 14:40:16 -07:00
.dockerignore Initial commit 2020-09-17 14:40:16 -07:00
.gitignore Initial commit 2020-09-17 14:40:16 -07:00
CONTRIBUTING.md Initial commit 2020-09-17 14:40:16 -07:00
Dockerfile Initial commit 2020-09-17 14:40:16 -07:00
go.mod Merge pull request #7 from coinbase/dependabot/go_modules/go.uber.org/zap-1.16.0 2020-09-18 17:29:22 -07:00
go.sum Merge pull request #7 from coinbase/dependabot/go_modules/go.uber.org/zap-1.16.0 2020-09-18 17:29:22 -07:00
LICENSE.txt Initial commit 2020-09-17 14:40:16 -07:00
main.go Use small index cache in tests 2020-09-18 12:18:57 -07:00
Makefile Update linter 2020-09-20 15:24:43 -07:00
README.md Update README 2020-09-18 18:12:07 -07:00
zstd-train.sh Initial commit 2020-09-17 14:40:16 -07:00

Rosetta

Rosetta Bitcoin

ROSETTA-BITCOIN IS CONSIDERED ALPHA SOFTWARE. USE AT YOUR OWN RISK! COINBASE ASSUMES NO RESPONSIBILITY NOR LIABILITY IF THERE IS A BUG IN THIS IMPLEMENTATION.

Overview

rosetta-bitcoin provides a reference implementation of the Rosetta API for Bitcoin in Golang. If you haven't heard of the Rosetta API, you can find more information here.

Features

  • Rosetta API implementation (both Data API and Construction API)
  • UTXO cache for all accounts (accessible using /account/balance)
  • Stateless, offline, curve-based transaction construction from any SegWit-Bech32 Address

Usage

As specified in the Rosetta API Principles, all Rosetta implementations must be deployable via Docker and support running via either an online or offline mode.

To build a Docker image from this repository, run the command make build. To start rosetta-bitcoin, you can run:

  • make run-mainnet-online
  • make run-mainnet-offline
  • make run-testnet-online
  • make run testnet-offline

By default, running these commands will create a data directory at <working directory>/bitcoin-data and start the rosetta-bitcoin server at port 8080.

System Requirements

rosetta-bitcoin has been tested on an AWS c5.2xlarge instance. This instance type has 8 vCPU and 16 GB of RAM. If you use a computer with less than 16 GB of RAM, it is possible that rosetta-bitcoin will exit with an OOM error.

To increase the load rosetta-bitcoin can handle, it is recommended to tune your OS settings to allow for more connections. On a linux-based OS, you can run the following commands (source):

sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_max_syn_backlog=10000
sysctl -w net.core.somaxconn=10000
sysctl -p (when done)

We have not tested rosetta-bitcoin with net.ipv4.tcp_tw_recycle and do not recommend enabling it.

You should also modify your open file settings to 100000. This can be done on a linux-based OS with the command: ulimit -n 100000.

Architecture

rosetta-bitcoin uses the syncer, storage, parser, and server package from rosetta-sdk-go instead of a new Bitcoin-specific implementation of packages of similar functionality. Below you can find a high-level overview of how everything fits together:

                               +------------------------------------------------------------------+
                               |                                                                  |
                               |                 +--------------------------------------+         |
                               |                 |                                      |         |
                               |                 |                 indexer              |         |
                               |                 |                                      |         |
                               |                 | +--------+                           |         |
                               +-------------------+ pruner <----------+                |         |
                               |                 | +--------+          |                |         |
                         +-----v----+            |                     |                |         |
                         | bitcoind |            |              +------+--------+       |         |
                         +-----+----+            |     +--------> block_storage <----+  |         |
                               |                 |     |        +---------------+    |  |         |
                               |                 | +---+----+                        |  |         |
                               +-------------------> syncer |                        |  |         |
                                                 | +---+----+                        |  |         |
                                                 |     |        +--------------+     |  |         |
                                                 |     +--------> coin_storage |     |  |         |
                                                 |              +------^-------+     |  |         |
                                                 |                     |             |  |         |
                                                 +--------------------------------------+         |
                                                                       |             |            |
+-------------------------------------------------------------------------------------------+     |
|                                                                      |             |      |     |
|         +------------------------------------------------------------+             |      |     |
|         |                                                                          |      |     |
|         |                     +---------------------+-----------------------+------+      |     |
|         |                     |                     |                       |             |     |
| +-------+---------+   +-------+---------+   +-------+-------+   +-----------+----------+  |     |
| | account_service |   | network_service |   | block_service |   | construction_service +--------+
| +-----------------+   +-----------------+   +---------------+   +----------------------+  |
|                                                                                           |
|                                         server                                            |
|                                                                                           |
+-------------------------------------------------------------------------------------------+

Optimizations

  • Automatically prune bitcoind while indexing blocks
  • Reduce sync time with concurrent block indexing
  • Use Zstandard compression to reduce the size of data stored on disk without needing to write a manual byte-level encoding

Concurrent Block Syncing

To speed up indexing, rosetta-bitcoin uses concurrent block processing with a "wait free" design (using channels instead of sleeps to signal which threads are unblocked). This allows rosetta-bitcoin to fetch multiple inputs from disk while it waits for inputs that appeared in recently processed blocks to save to disk.

                                                   +----------+
                                                   | bitcoind |
                                                   +-----+----+
                                                         |
                                                         |
          +---------+ fetch block data / unpopulated txs |
          | block 1 <------------------------------------+
          +---------+                                    |
       +-->   tx 1  |                                    |
       |  +---------+                                    |
       |  |   tx 2  |                                    |
       |  +----+----+                                    |
       |       |                                         |
       |       |           +---------+                   |
       |       |           | block 2 <-------------------+
       |       |           +---------+                   |
       |       +----------->   tx 3  +--+                |
       |                   +---------+  |                |
       +------------------->   tx 4  |  |                |
       |                   +---------+  |                |
       |                                |                |
       | retrieve previously synced     |   +---------+  |
       | inputs needed for future       |   | block 3 <--+
       | blocks while waiting for       |   +---------+
       | populated blocks to save to    +--->   tx 5  |
       | disk                               +---------+
       +------------------------------------>   tx 6  |
       |                                    +---------+
       |
       |
+------+--------+
|  coin_storage |
+---------------+

Testing with rosetta-cli

To validate rosetta-bitcoin, install rosetta-cli and run one of the following commands:

  • rosetta-cli check:data --configuration-file rosetta-cli-conf/bitcoin_testnet.json
  • rosetta-cli check:construction --configuration-file rosetta-cli-conf/bitcoin_testnet.json
  • rosetta-cli check:data --configuration-file rosetta-cli-conf/bitcoin_mainnet.json
  • rosetta-cli check:construction --configuration-file rosetta-cli-conf/bitcoin_mainnet.json

Future Work

  • Publish benchamrks for sync speed, storage usage, and load testing
  • Rosetta API /mempool/transaction implementation
  • Add CI test using rosetta-cli to run on each PR (likely on a regtest network)
  • Add performance mode to use unlimited RAM (implementation currently optimized to use <= 16 GB of RAM)
  • Support Multi-Sig Sends

Please reach out on our community if you want to tackle anything on this list!

Development

  • make deps to install dependencies
  • make test to run tests
  • make lint to lint the source code
  • make salus to check for security concerns
  • make build-local to build a Docker image from the local context
  • make coverage-local to generate a coverage report

License

This project is available open source under the terms of the Apache 2.0 License.

© 2020 Coinbase