rosetta-lbry/README.md
2020-09-21 20:25:14 -07:00

12 KiB

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.

Install

Pre-Built

You can download a pre-built Docker image from GitHub: TODO: cast version as latest somehow? TODO: get latest from release info and then can do automatically? Could do another script...

curl -L https://github.com/coinbase/rosetta-bitcoin/releases/latest/download/rosetta-bitcoin.tar.gz -o rosetta-bitcoin.tar.gz;
docker load --input rosetta-bitcoin.tar.gz;
rm rosetta-bitcoin.tar.gz;

This will print the image tag out that must be used for running in later steps.

From Source

You can clone this repository and run the following command:

docker build -t rosetta-bitcoin:latest

Run

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

Mainnet:Online

docker run -d --ulimit "nofile=100000:100000" -v "$(pwd)/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=MAINNET" -e "PORT=8080" -p 8080:8080 -p 8333:8333 rosetta-bitcoin:latest

Mainnet:Offline

docker run -d -e "MODE=OFFLINE" -e "NETWORK=MAINNET" -e "PORT=8081" -p 8081:8081 rosetta-bitcoin:latest

Testnet:Online

docker run -d --ulimit "nofile=100000:100000" -v "$(pwd)/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=TESTNET" -e "PORT=8080" -p 8080:8080 -p 18333:18333 rosetta-bitcoin:latest

Testnet:Offline

docker run -d -e "MODE=OFFLINE" -e "NETWORK=TESTNET" -e "PORT=8081" -p 8081:8081 rosetta-bitcoin:latest

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