Flextesa: Flexible Tezos Sandboxes

This repository contains the Flextesa library used in tezos/tezos to build the tezos-sandbox tests, as well as some extra testing utilities, such as the flextesa application, which may be useful to the greater community (e.g. to test third party tools against fully functional Tezos sandboxes).

Run With Docker

The current released image is oxheadalpha/flextesa:20220715 (also available as oxheadalpha/flextesa:latest):

WARNING: This version is for amd64 architectures only, and was not built for ARM64 hosts like Apple Silicon. This is because of an issue with the Octez distribution: tezos/tezos#3420. For now, Apple Silicon users can still use the previous release oxheadalpha/flextesa:20220510 to run Jakarta sandboxes, but not Kathmandu ones.

image=oxheadalpha/flextesa:latest
script=jakartabox
docker run --rm --name my-sandbox --detach -p 20000:20000 \
       -e block_time=3 \
       "$image" "$script" start

All the available scripts start single-node full-sandboxes (i.e. there is a baker advancing the blockchain):

The default block_time is 5 seconds.

See also the accounts available by default:

$ docker exec my-sandbox $script info
Usable accounts:

- alice
  * edpkvGfYw3LyB1UcCahKQk4rF2tvbMUk8GFiTuMjL75uGXrpvKXhjn
  * tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb
  * unencrypted:edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq
- bob
  * edpkurPsQ8eUApnLUJ9ZPDvu98E8VNj4KtJa1aZr16Cr5ow5VHKnz4
  * tz1aSkwEot3L2kmUvcoxzjMomb9mvBNuzFK6
  * unencrypted:edsk3RFfvaFaxbHx8BMtEW1rKQcPtDML3LXjNqMNLCzC3wLC1bWbAt

Root path (logs, chain data, etc.): /tmp/mini-box (inside container).

The implementation for these scripts is src/scripts/tutorial-box.sh, they are just calls to flextesa mini-net (see its general documentation).

The scripts run sandboxes with archive nodes for which the RPC port is 20 000. You can use any client, including the tezos-client inside the docker container, which happens to be already configured:

$ alias tcli='docker exec my-sandbox tezos-client'
$ tcli get balance for alice
2000000 ꜩ

You can always stop the sandbox, and clean-up your resources with: docker kill my-sandbox.

User-Activated-Upgrades

The scripts inherit the mini-net's support for user-activated-upgrades (a.k.a. “hard forks”). For instance, this command starts a Jakarta sandbox which switches to Kathmandu at level 20:

$ docker run --rm --name my-sandbox --detach -p 20000:20000 \
         -e block_time=2 \
         "$image" jakartabox start --hard-fork 20:Kath:

With tcli above and jq you can keep checking the following to observe the protocol change:

$ tcli rpc get /chains/main/blocks/head/metadata | jq .level_info,.protocol
{
  "level": 24,
  "level_position": 23,
  "cycle": 2,
  "cycle_position": 7,
  "expected_commitment": true
}
"PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg"

Notes:

These scripts correspond to the tutorial at https://assets.tqtezos.com/docs/setup/2-sandbox/ (which is now deprecated but still relevant).

Full Governance Upgrade

The start_upgrade command is included with the docker image.

This implementation of src/scripts/tutorial-box.sh is a call to flextesa daemons-upgrade (see its general daemons-upgrade).

 default
$ docker run --rm --name my-sandbox -p 20000:20000 --detach \
         -e block_time=2 \
         "$image" jakartabox start_upgrade

With start_upgrade the sandbox network will do a full voting round followed by a protocol change. The jakartabox script will start with the Jakarta protocol and upgrade to Kathmandu; with the current version kathmandubox cannot upgrade to Alpha (too early in the development of L at the time of writing).

Voting occurs over five periods. You can adjust the length of the voting periods with the variable blocks_per_voting_period. Batches of dummy proposals will be inserted with extra_dummy_proposals_batch_size. These proposals can be scheduled at specific block-levels within the first (Proposal) voting period, using the variable extra_dummy_proposals_batch_level.

 default
$ docker run --rm --name my-sandbox -p 20000:20000 --detach \
         -e blocks_per_voting_period=12 \
         -e extra_dummy_proposals_batch_size=2 \
         -e extra_dummy_proposals_batch_level=2,4 \
         "$image" jakartabox start_upgrade

The above command will result in 5 total proposals and upgrade to the Alpha proposal.

The default values are:

Note: As with the start command start_upgrade comes with the Alice and Bob accounts by default.

Build

With Opam ≥ 2.1:

opam switch create . --deps-only \
     --formula='"ocaml-base-compiler" {>= "4.13" & < "4.14"}'
eval $(opam env)
opam pin add -n tezai-base58-digest https://gitlab.com/oxheadalpha/tezai-base58-digest.git
opam install --deps-only --with-test --with-doc \
     ./tezai-tz1-crypto.opam \
     ./flextesa.opam ./flextesa-cli.opam # Most of this should be already done.
opam install merlin ocamlformat.0.19.0    # For development.

Then:

make

The above builds the flextesa library, the flextesa command line application (see ./flextesa --help) and the tests (in src/test).

MacOSX Users

At runtime, sandboxes usually depend on a couple of linux utilities.

If you are on Mac OS X, you can do brew install coreutils util-linux. Then run the tests with:

export PATH="/usr/local/opt/coreutils/libexec/gnubin:/usr/local/opt/util-linux/bin:$PATH"

Build Of The Docker Image

See ./Dockerfile, it often requires modifications with each new version of Octez or for new protocols, the version of the Octez static binaries (x86_64 and arm64) is set in src/scripts/get-octez-static-binaries.sh.

There are 2 images: -build (all dependencies) and -run (stripped down image with only runtime requirements).

The x86_64 images are built by the CI, see the job docker:images: in ./.gitlab-ci.yml.

To build locally:

docker build --target build_step -t flextesa-build .
docker build --target run_image -t flextesa-run .

Do not forget to test it: docker run -it "$image" hangzbox start

To build the released multi-architecture images, we use buildx. In short, this is the build itself:

docker buildx build --platform linux/arm64/v8,linux/amd64  . \
       --target run_image \
       --tag oxheadalpha/flextesa:test-20220320 \
       --tag oxheadalpha/flextesa:test-latest \
       --push

The build does not fit within the limits of Gitlab-CI. Here are the instructions for Ubuntu 20.04 (Using a “click next” AWS instance: start an “Ubuntu Server 20.04 LTS” host, the build can use quite a few CPUs at once and requires a larger disk, e.g. 128 GiB).

Setting up Docker:

sudo apt update
sudo apt install docker.io
sudo adduser ubuntu docker

(may have to sudo su ubuntu to really get into the group)

Install the buildx CLI plugin:

mkdir -p ~/.docker/cli-plugins/
curl -L -o ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.7.1/buildx-v0.7.1.linux-amd64
chmod a+x ~/.docker/cli-plugins/docker-buildx
docker buildx --help # Test it !

Prepare the Qemu setup:

docker run --rm --privileged multiarch/qemu-user-static \
       --reset -p yes --credential yes

Prepare the buildx environment:

docker login # Interactive, asks for user/password
docker buildx create --use # Starts a container to clean-up later

Get the checkout of Flextesa you want to build:

git clone https://gitlab.com/smondet/flextesa -b smondet-docker-arm64
cd flextesa

And, finally, start the build/tag/push in one go:

docker buildx build --platform linux/arm64/v8,linux/amd64  . \
       --target run_image \
       --tag oxheadalpha/flextesa:rc-20211210 \
       --tag oxheadalpha/flextesa:rc-latest \
       --push

More Documentation

The command flextesa mini-net [...] has a dedicated documentation page: The mini-net Command.

Documentation regarding flextesa daemons-upgrade [...] can be found here: The daemons-upgrade Command.

The API documentation of the Flextesa OCaml library starts here: Flextesa: API.

Some documentation, including many examples, is part of the tezos/tezos repository: Flexible Network Sandboxes (it uses the tezos-sandbox executable which is implemented there).

Blog posts:

TQ Tezos' Digital Assets on Tezos documentation shows how to quickly set up a docker sandbox (uses the docker images from this repository).