Terraforming Bitcoin Testnets — Part 1/3

Yan Pritzker
bloXroute Labs
Published in
4 min readOct 11, 2018

At bloXroute Labs, we are developing a block propagation network in order to reduce propagation times and therefore reduce orphan rates in any blockchain network, allowing for throughput increases. We developed a Proof of Concept (to be released in 2018 Q4) to show how our technology worked. In order to do this, we needed to deploy large Bitcoin and Ethereum networks of varying topologies.

In this three part series, we’ll take a look at how to build Bitcoin networks for development and research. Today, we’ll cover building a basic network of a full node and a miner. In Part 2, we will discuss how we created our Bitcoin docker images, and simple scripts for managing and interacting with networks. In Part 3, we’ll cover how Bitcoin peering works and how we automated the specification of peering topologies.

Goals

  • Bring up Bitcoin networks with an arbitrary number of miners and non-mining full nodes, so that we can see the effect of larger networks on block propagation.
  • Control peering in order to get specific nodes to peer with specific other nodes, so we can experiment with how network topology affects block propagation times.

Technology Stack

  • We will use AWS because it provides us the flexibility of launching large number of instances across many geographic regions
  • We’re using Terraform to automate the launching so that we have repeatable and configurable provisioning builds.

Our terraform scripts will refer to pre-existing infrastructure such as Amazon VPCs and Security Groups that have been terraformed prior to this tutorial. If you’re interested in how we set these up, please leave a comment and we can cover it in a future post.

Provisioning a Node

Let’s start by covering our workflow. First, we will create a terraform resource for a bitcoin full node. This resource will take as parameters a handful of tags that tell Bitcoin how to behave.

Below is a simplified version of what we use. We’ll cover how to specify peering in a later blog post. For the miner, we duplicate this setup but change mining = "true".

In this terraform, there are a handful of data elements which reference existing infrastructure. There are also some var elements which refer to the types of things we can control at runtime before we hit terraform apply. If you’re familiar with terraform, this should be self-explanatory, but we will likely open source this whole setup in the future, which will make it easier for others to use.

Next, we’ll use a “user data” script (AWS terminology for a boot script). The boot script will read the tags and launch a Bitcoin node using Docker, using the tag values to inject params into the launch. We’ll cover the pieces of the script below.

Step 1 — Read tags that were sent to us by terraform

Step 2 — Restore a chain state backup

We found that while testing, it was convenient to save chain state so we didn’t have to wait to mine the first 101 blocks in order to spend coins. We’ll look at the backup script later, but basically it was something similar to tarring up /var/bitcoin. In our boot script, we restore the backup if the tag was specified:

Step 3 — Start the bitcoin image via Docker

For our research, we are using a modified Bitcoin Unlimited image where we’ve patched the difficulty algorithm so we can mine more quickly. We are using BU’s codebase because we needed something that had been optimized for large blocks and a high mempool ingestion rate, since we are testing network propagation, but this image can be replaced with a Bitcoin Core or any other implementation for testing purposes. In Part 2, we’ll cover building Bitcoin docker images.

Step 4 — Turn on mining

If the mining="true" flag is set in terraform, we will start mining. In our setup, we’ve patched Bitcoin so we can use setgenerate for mining. But you can also use a traditional cpuminer setup. The below snippet shows both.

Wrap this all up in a terraform module

I cheated a little bit by showing you just a piece of the terraform configuration. In reality, it’s all wrapped in a terraform module that looks like this:

variable "clients" {
description = "Clients in US East 1 (Virginia) Region"
default = 2
}
variable "miners" {
description = "Miners in US East 1 (Virginia) Region"
default = 2
}
# ... lots more variables ...
# ... lots more resource declarations ...

In order to use this setup, we create an instance of it like this:

And hit terraform apply

That’s all folks!

In the next part, we’ll cover how the docker images were created, and some scripts for managing the instances at runtime.

If you think this is cool and want to work on cutting edge block propagation tech with some of the smartest folks in the industry, bloXroute is hiring. Stay up to date on the project by following us on Twitter @bloXrouteLabs.

--

--