coinbase / mesh-bitcoin

Bitcoin Mesh API Implementation
Apache License 2.0
110 stars 121 forks source link

Mesh Bitcoin

MESH-BITCOIN IS CONSIDERED ALPHA SOFTWARE. USE AT YOUR OWN RISK.

This project is available open source under the terms of the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).

## Overview The `mesh-bitcoin` repository provides a reference implementation of the Mesh API for Bitcoin in Golang. This repository was created for developers of Bitcoin-like (a.k.a., UTXO) blockchains, who may find it easier to fork this reference implementation than write one from scratch. [Mesh](https://docs.cdp.coinbase.com/mesh/docs/welcome/) is an open-source specification and set of tools that makes integrating with blockchains simpler, faster, and more reliable. The Mesh API is specified in the [OpenAPI 3.0 format](https://www.openapis.org). Requests and responses can be crafted with auto-generated code using [Swagger Codegen](https://swagger.io/tools/swagger-codegen) or [OpenAPI Generator](https://openapi-generator.tech), are human-readable (easy to debug and understand), and can be used in servers and browsers. ## Features * Mesh API implementation (both Data API and Construction API) * UTXO cache for all accounts (accessible using the Mesh `/account/balance` API) * Stateless, offline, curve-based transaction construction from any SegWit-Bech32 Address * Automatically prune bitcoind while indexing blocks * Reduce sync time with concurrent block indexing * Use [Zstandard compression](https://github.com/facebook/zstd) to reduce the size of data stored on disk without needing to write a manual byte-level encoding ## System Requirements The `mesh-bitcoin` implementation has been tested on an [AWS c5.2xlarge instance](https://aws.amazon.com/ec2/instance-types/c5). This instance type has 8 vCPU and 16 GB of RAM. ## Getting Started 1. Adjust your [network settings](#network-settings) to the recommended connections. 2. Install and run Docker as directed in the [Deployment](#deployment) section below. 3. Run the [`Testnet:Online`](#testnetonline) command. ### Network Settings To increase the load that `mesh-bitcoin` can handle, we recommend tunning your OS settings to allow for more connections. On a linux-based OS, you can run these commands ([source](http://www.tweaked.io/guide/kernel)): ```text 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 `mesh-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`. ### Memory-Mapped Files `mesh-bitcoin` uses [memory-mapped files](https://en.wikipedia.org/wiki/Memory-mapped_file) to persist data in the `indexer`. As a result, you **must** run `mesh-bitcoin` on a 64-bit architecture (the virtual address space easily exceeds 100s of GBs). If you receive a kernel OOM, you may need to increase the allocated size of swap space on your OS. There is a great tutorial for how to do this on Linux [here](https://linuxize.com/post/create-a-linux-swap-file/). ## Development While working on improvements to this repository, we recommend that you use these commands to check your code: * `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 #### Image Installation Running these commands will create a Docker image called `mesh-bitcoin:latest`. ##### Installing from GitHub To download the pre-built Docker image from the latest release, run: ```text curl -sSfL https://raw.githubusercontent.com/coinbase/mesh-bitcoin/master/install.sh | sh -s ``` _Do not try to install mesh-bitcoin using GitHub Packages!_ ##### Installing from Source After cloning this repository, run: ```text make build-local ``` #### Run Docker Running these commands will start a Docker container in [detached mode](https://docs.docker.com/engine/reference/run/#detached--d) with a data directory at `/bitcoin-data` and the Mesh API accessible at port `8080`. ##### Required Arguments **`MODE`** - Determines whether Mesh can make outbound connections. - **Type:** `String` - **Options:** `ONLINE`, `OFFLINE` - **Default:** None **`NETWORK`** - The Ethereum network to launch or communicate with. - **Type:** `String` - **Options:** `MAINNET`, `ROPSTEN`, `RINKEBY`, `GOERLI` or `TESTNET` - **Default:** `ROPSTEN`, but only for backwards compatibility if you use `TESTNET` **`PORT`** - The port to use for Mesh. - **Type:** `Integer` - **Options:** `8080`, any compatible port number. - **Default:** None ##### Command Examples You can run these commands from the command line. If you cloned the repository, you can use the `make` commands shown after the examples. ###### **Mainnet:Online** Uncloned repo: ```text docker run -d --rm --ulimit "nofile=100000:100000" -v "$(pwd)/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=MAINNET" -e "PORT=8080" -p 8080:8080 -p 8333:8333 mesh-bitcoin:latest ``` Cloned repo: ```text make run-mainnet-online ``` ###### **Mainnet:Offline** Uncloned repo: ```text docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=MAINNET" -e "PORT=8081" -p 8081:8081 mesh-bitcoin:latest ``` Cloned repo: ```text make run-mainnet-offline ``` ###### **Testnet:Online** Uncloned repo: ```text docker run -d --rm --ulimit "nofile=100000:100000" -v "$(pwd)/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=TESTNET" -e "PORT=8080" -p 8080:8080 -p 18333:18333 mesh-bitcoin:latest ``` Cloned repo: ```text make run-testnet-online ``` ###### **Testnet:Offline** Uncloned repo: ```text docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=TESTNET" -e "PORT=8081" -p 8081:8081 mesh-bitcoin:latest ``` Cloned repo: ```text make run-testnet-offline ``` ## Architecture `mesh-bitcoin` uses the `syncer`, `storage`, `parser`, and `server` package from [`mesh-sdk-go`](https://github.com/coinbase/mesh-sdk-go) instead of a new Bitcoin-specific implementation of packages of similar functionality. Below you can find an overview of how everything fits together: ### Concurrent Block Syncing To speed up indexing, `mesh-bitcoin` uses concurrent block processing with a "wait free" design (using [the channels function](https://golangdocs.com/channels-in-golang) instead of [the sleep function](https://pkg.go.dev/time#Sleep) to signal which threads are unblocked). This allows `mesh-bitcoin` to fetch multiple inputs from disk while it waits for inputs that appeared in recently processed blocks to save to disk. ## Test the Implementation with the mesh-cli Tool To validate `mesh-bitcoin`, [install `mesh-cli`](https://github.com/coinbase/mesh-cli#install) and run one of these commands: * `mesh-cli check:data --configuration-file mesh-cli-conf/testnet/config.json` - This command validates that the Data API information in the `testnet` network is correct. It also ensures that the implementation does not miss any balance-changing operations. * `mesh-cli check:construction --configuration-file mesh-cli-conf/testnet/config.json` - This command validates the blockchain’s construction, signing, and broadcasting. * `mesh-cli check:data --configuration-file mesh-cli-conf/mainnet/config.json` - This command validates that the Data API information in the `mainnet` network is correct. It also ensures that the implementation does not miss any balance-changing operations. Read the [How to Test your Mesh Implementation](https://docs.cdp.coinbase.com/mesh/docs/mesh-test/) documentation for additional details. ## Contributing You may contribute to the `mesh-bitcoin` project in various ways: * [Asking Questions](CONTRIBUTING.md/#asking-questions) * [Providing Feedback](CONTRIBUTING.md/#providing-feedback) * [Reporting Issues](CONTRIBUTING.md/#reporting-issues) Read our [Contributing](CONTRIBUTING.MD) documentation for more information. You can also find community implementations for a variety of blockchains in the [mesh-ecosystem](https://github.com/coinbase/mesh-ecosystem) repository. ## Documentation You can find the Mesh API documentation [here](https://docs.cdp.coinbase.com/mesh/docs/welcome/). Check out the [Getting Started](https://docs.cdp.coinbase.com/mesh/docs/getting-started/) section to start diving into Mesh. ## Related Projects * [mesh-sdk-go](https://github.com/coinbase/mesh-sdk-go) — The `mesh-sdk-go` SDK provides a collection of packages used for interaction with the Mesh API specification. * [mesh-specifications](https://github.com/coinbase/mesh-specifications) — Much of the SDK code is generated from this repository. * [mesh-cli](https://github.com/coinbase/mesh-ecosystem) — Use the `mesh-cli` tool to test your Mesh API implementation. The tool also provides the ability to look up block contents and account balances. ### Sample Implementations You can find community implementations for a variety of blockchains in the [mesh-ecosystem](https://github.com/coinbase/mesh-ecosystem) repository. ## License This project is available open source under the terms of the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0). © 2022 Coinbase