The mini-net Command

Flextesa ships with the flextesa command-line application; this document deals with the ./flextesa mini-net sub-command (also available in the Tezos repository as tezos-sandbox mini-net).

One can use ./flextesa mini-net --help to see all the available options.

Accessing Tezos Software

Flextesa needs to access tezos-node, tezos-client, and, depending on the options, all the “baker deamons.”

An easy way to let flextesa find them is to add them to the PATH, for instance if all the tezos utilities have been build at /path/to/tezos-repo/:

$ export PATH=/path/to/tezos-repo/:$PATH
$ flextesa mini  \
           --size 2 --time-between-blocks 10 --number-of-boot 2

If one does not want to, or cannot, use this method, all the executable paths can be passed with command line options:

$ flextesa mini  \
           --size 3 --time-between-blocks 8 --number-of-boot 2 \
           --tezos-node /path/to/tezos-repo/tezos-node \
           --tezos-client /path/to/tezos-repo/tezos-client \
           --tezos-baker /path/to/tezos-repo/tezos-baker-alpha \
           --tezos-endorser /path/to/tezos-repo/tezos-endorser-alpha \
           --tezos-accuser /path/to/tezos-repo/tezos-accuser-alpha

The above command starts 3 nodes, activates the protocol alpha with a block-time of 8 seconds (alpha is the development protocol of the master branch; it mimics the mainnet one), and starts baking daemons for 2 bootstrap-baker accounts.

A Note On Interactivity

Many sandbox setups in Flextesa, once the sandbox is ready, give the user an interactive command prompt.

You can always type help (or h) to see available commands, and quit (or q) to leave the prompt.

The improve user-experience on normal terminals (i.e. not Emacs …) it is recommended to wrap the flextesa command in command-line edition tool like rlwrap or ledit.

More Examples

“Manual” Sandbox and Shell Environment

A manual sandbox, as opposed to a full one, is a sandbox without baking daemons, the client needs to manually bake blocks on demand (this is very useful to make faster and more reproducible tests for instance).

$ flextesa mini  \
           --size 1 --number-of-boot 1 --base-port 4000 \
           --tezos-node /path/to/tezos-repo/tezos-node \
           --tezos-client /path/to/tezos-repo/tezos-client \
           --no-baking

By typing help we see we can use the command bake to make new blocks:

  Available commands:
    * {q|quit}: Quit this prompt and continue.
...
    * {bake}: Manually bake a block (with C-N000).
...

One can also use tezos-client -P 4000 bake for ... from outside the sandbox.

Luckily such a client has already been configured by Flextesa; type help-env on the prompt:

Flextesa: Please enter command:
  help-env
Flextesa:
  Shell Environment
    * A loadable shell environment is available at
    `/tmp/mininet-test/shell.env`.
    * It contains 1 POSIX-shell aliases (compatible with `bash`, etc.).

    Example:

        . /tmp/mininet-test/shell.env
        tc0 list known addresses
        tc0 rpc get /chains/main/blocks/head/metadata

And indeed we can use such a client to bake a new block:

 $ tc0 list known addresses
bootacc-0: tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU (unencrypted sk known)
dictator-default: tz1aYQcaXmowUu59gAgMGdiX6ARR7gdmikZk (unencrypted sk known)

 $ tc0 bake for bootacc-0
Feb 12 10:30:42 - alpha.baking.forge: found 0 valid operations (0 refused) for timestamp 2020-02-12T15:30:42-00:00 (fitness 01::0000000000000002)
Injected block BLehBRAoyFAB

When running “manual” sandboxes the option --timestamp-delay is also useful (e.g. --timestamp-delay=-3600), it allows the user to bake faster than the expected time between blocks.

Running Another Protocol And History Modes

The ./src/scripts/tutorial-box.sh uses protocol-specific binaries (present in the default docker image) to run non-interactive sandboxes with the “real” Babylon or Carthage protocols.

For instance:

$ flextesa mini-net \
           --root /tmp/mini-box \
           --size 1 \
           --set-history-mode N000:archive
           --number-of-bootstrap-accounts 1 \
           --time-b 5 \
           --until-level 2_000_000 \
           --tezos-baker tezos-baker-005-PsBabyM1 \
           --tezos-endor tezos-endorser-005-PsBabyM1 \
           --tezos-accus tezos-accuser-005-PsBabyM1 \
           --protocol-kind Babylon \
           --protocol-hash PsBabyM1eUXZseaJdmXFApDSBqj8YBfwELoxZHHW77EMcAbbwAS

runs a 1-node sandbox with 1 bootstrap baker, running Babylon (the same as mainnet) but with a time-between-blocks of 5 seconds.

Moreover, instead of becoming interactive, the sandbox will run for 2×10⁶ blocks and the node will be an archive node (see documentation on history modes).

Adding Custom Bootstrap Accounts

The option --add-bootstrap-account adds arbitrary key-pairs as bootstrap-accounts with a given amount of μꜩ; the option --no-daemons-for prevents the sandbox from baking with a given bootstrap-account.

More over flextesa provides a command to generate deterministic key-pairs from any string.

$ alice=$(./flextesa key-of-name alice)
$ flextesa mini  \
           --size 2 --time-between-blocks 10 --number-of-boot 2 \
           --add-bootstrap-account "$alice@2_000_000_000_000 \
           --no-daemons-for=alice

This sandbox has one more account with 2 million ꜩ, that account is not used for baking. See the output of the key generation:

 $ flextesa key-of-name alice
alice,edpkvGfYw3LyB1UcCahKQk4rF2tvbMUk8GFiTuMjL75uGXrpvKXhjn,tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb,unencrypted:edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq

One can use simply tezos-client import secret key the-alice unencrypted:edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq to interact with this account.

Choosing a (Vanity) Chain-id

With the default values the chain id for the sandbox is NetXKMbjQL2SBox (cf. RPC /chains/main/chain_id), but one may want to use a different one.

The chain-id is computed from the hash of the Genesis block, which can be forced with the --genesis-block-hash; and one can brute-force a block-hash to generate vanity chain-id with the flextesa vanity-chain-id command.

 $ flextesa vanity-chain-id Bob  \
            --attempts 1_000_000 --first --seed my-seed-string

Flextesa.vanity-chain-id:  Looking for "Bob"
Flextesa.vanity-chain-id:
  Results:
    * Seed: "my-seed-string140396"
      → block: "BMKZs8QDZ9NmVJqvTeVimXCtKmRiYoASzx4N3gMPv6yqGiuTw2q"
      → chain-id: "NetXLGHj52FuBob"

One can use it like this:

$ flextesa mini  \
           --size 2 --time-between-blocks 10 --number-of-boot 2 \
           --genesis BMKZs8QDZ9NmVJqvTeVimXCtKmRiYoASzx4N3gMPv6yqGiuTw2q

And check interactively that c0 rpc get /chains/main/chain_id returns "NetXLGHj52FuBob".

Root Path & Stopping/Restarting Sandboxes

All the sandboxes keep all their data within a “root path” which can be set with the --root-path option.

By default the mini-net erases that directory at startup but one can try to restart a sandbox from the state it was when it was shut down with the option --keep-root.

Restarting sandboxes is not an exact science because it is not how a blockchain is supposed to work, sometimes bakers and nodes fail while trying to catch-up, it is better to use “small” networks:

$ flextesa mini --root /tmp/longer-running-mini-net \
           --size 1 --time-between-blocks 2 --number-of-boot 1 \
           --keep-root

Stopping the sandbox with quit, and restarting with the same command some time later usually works.

Manpage Of mini-net

For convenience, here is the output of flextesa mini-net --help:

NAME
       flextesa-mini-network - Small network sandbox with bakers, endorsers,
       and accusers.

SYNOPSIS
       flextesa mini-network [OPTION]... 

       This test builds a small sandbox network, start various daemons, and
       then gives the user an interactive command prompt to inspect the
       network.

       One can also run this sandbox with `--no-baking` to make baking
       interactive-only.

       There is also the option of running the sandbox non-interactively for
       a given number of blocks, cf. `--until-level LEVEL`.

TEST SCENARIO OPTIONS
       --add-external-peer-port=PORT-NUMBER
           Add PORT-NUMBER to the peers of the network nodes.

       --hard-fork=LEVEL:PROTOCOL-HASH
           Make a hard-fork happen

       --keep-root
           Do not erase the root path before starting (this also makes the
           sandbox start-up bypass the protocol-activation step).

       --no-baking
           Completely disable baking/endorsing/accusing (you need to bake
           manually to make the chain advance).

       --no-daemons-for=ACCOUNT-NAME
           Do not start daemons for ACCOUNT-NAME.

       -P VAL, --base-port=VAL (absent=20000)
           Base port number to build upon.

       --random-traffic=VAL
           Generate random traffic (requires `--until-level`).

       -S VAL, --size=VAL (absent=5)
           Set the size of the network.

       --traffic=VAL
           Generate traffic using the dsl syntax. Upon completion of the
           specified commands, the program will wait until the block heigh
           specified by `--until-level` is reached, and then exit. If
           `--until-level is not supplied, the interactive mode will be
           entered upon completion of the commands. 

       --until-level=VAL
           Run the sandbox until a given level (not interactive)

EXECUTABLE PATHS
       --hard-fork-accuser-binary=VAL
           Binary for the `tezos-accuser` to use for the hard-fork (requires
           --hard-fork).

       --hard-fork-baker-binary=VAL
           Binary for the `tezos-baker` to use for the hard-fork (requires
           --hard-fork).

       --hard-fork-endorser-binary=VAL
           Binary for the `tezos-endorser` to use for the hard-fork (requires
           --hard-fork).

       --tezos-accuser-binary=VAL
           Binary for the `tezos-accuser` to use.

       --tezos-baker-binary=VAL
           Binary for the `tezos-baker` to use.

       --tezos-client-binary=VAL
           Binary for the `tezos-client` to use.

       --tezos-endorser-binary=VAL
           Binary for the `tezos-endorser` to use.

       --tezos-node-binary=VAL
           Binary for the `tezos-node` to use.

NODE HISTORY MODES
       One can specify history modes for a given subset of the nodes.

       --set-history-mode=NODEPREFIX:MODE
           Set the history mode for a given (named) node, e.g.
           `N000:archive`.

PROTOCOL OPTIONS
       --add-bootstrap-account=NAME,PUBKEY,PUBKEY-HASH,PRIVATE-URI@MUTEZ-AMOUNT
           Add a custom bootstrap account, e.g.
           `LedgerBaker,edpku...,tz1YPS...,ledger://crouching-tiger.../ed25519/0'/0'@20_000_000_000`.

       --balance-of-bootstrap-accounts=UNIT:FLOAT (absent=tez:4000000.)
           Set the initial balance of bootstrap accounts, for instance:
           `tz:2_000_000.42` or `mutez:42_000_000_000_000`.

       --blocks-per-cycle=NUMBER (absent=8)
           Number of blocks per cycle.

       --blocks-per-voting-period=VAL (absent=16)
           Set the length of voting periods.

       --number-of-bootstrap-accounts=VAL (absent=4)
           Set the number of generated bootstrap accounts.

       --override-protocol-parameters=JSON-FILE
           Use these protocol parameters instead of the generated ones
           (technically this invalidates most other options from a tezos-node
           point of view, use at your own risk).

       --preserved-cycles=NUMBER (absent=2)
           Base constant for baking rights (search for `PRESERVED_CYCLES` in
           the white paper).

       --protocol-hash=VAL
           Set the (initial) protocol hash (the default is to derive it from
           the protocol kind).

       --protocol-kind=VAL (absent=Delphi)
           Set the protocol family.

       --remove-default-bootstrap-accounts
           Do not create any of the default bootstrap accounts (this
           overrides `--number-of-bootstrap-accounts` with 0).

       --time-between-blocks=COMMA-SEPARATED-SECONDS (absent=2,3)
           Set the time between blocks bootstrap-parameter, e.g. `2,3,2`.

       --timestamp-delay=NUMBER
           Protocol activation timestamp delay in seconds.

TOOLS: KILN
       --clean-kiln-configuration
           Delete configuration path before generating it

       --generate-kiln-configuration-path=PATH,PORT
           Generate a kiln configuration at PATH,PORT

ENVIRONMENT
       flextesa_default_events_level
           Set the minimum evenet-level for the event-logging of all
           tezos-executables. The default is `warning`. The value `none`
           means: completely disable the event-logging.

       flextesa_better_call_dev_base_url
           Set the base URL for the better-call.dev explorer. The default is
           `https://better-call.dev/sandbox`.

       flextesa_node_cors_origin
           Add CORS headers to all nodes in the sandbox. An empty value means
           “none.”
OPTIONS
       --color=VAL (absent=auto)
           Control terminal colors (none, yes, auto).

       --genesis-block-hash=BLOCK-HASH|<special-value>
           Set the genesis block hash (from which the chain-id is derived).
           The default behavior (or the values "default" or
           "from-protocol-kind") is to pick a "vanity-suffix-chain-id" which
           depends on the kind of protocol: `Box6` for Carthage and `Box7`
           for Delphi. The value "random" means to pick a random number. The
           value "legacy-default" picks the same default as older versions of
           Flextesa. Any other value is treated as a custom block hash. This
           option is ignored when the `--keep-root` option allows the chain
           to resume (the previously chosen genesis-hash will be still in
           effect). 

       --help[=FMT] (default=auto)
           Show this help in format FMT. The value FMT must be one of `auto',
           `pager', `groff' or `plain'. With `auto', the format is `pager` or
           `plain' whenever the TERM env var is `dumb' or undefined.

       --interactive=VAL (absent=false)
           Add all pauses with command prompts.

       --pause-at-end=VAL (absent=false)
           Add a pause with a command prompt at the end of the test.

       --pause-on-error=VAL (absent=false)
           Add a pause with a command prompt at the end of the test, only in
           case of test failure.

       --root-path=VAL (absent=/tmp/mininet-test)
           Root path for all configs/data to use.

       --with-timestamp
           Display messages with time-stamps.