Skip to content

Beacon chain node

Dmitry S edited this page Sep 13, 2019 · 18 revisions

A tiny command line utility to run beacon chain node.

Installation guide

Prerequisites

To run a node you need to install Java 8 or later. There are many guidelines in Internet, even the official one, from Oracle.

LibP2P

Harmony implementation depends on JVM libp2p implementation, which is not in a public repository yet. So, one should build it manually and push to a local maven repository, to be able to build the node command.

git clone https://github.com/libp2p/jvm-libp2p --branch feature/cleanup
cd jvm-libp2p
./gradlew build
./gradlew publishToMavenLocal

Build from sources

Note: Currently, all work is performed in the interop branch.

Clone the repo (interop branch) and execute build command:

git clone --branch interop https://github.com/harmony-dev/beacon-chain-java.git
cd beacon-chain-java
./gradlew clean build -x test

Unpack the distribution:

unzip start/node/build/distributions/node-0.2.0.zip

Use default config to check it out:

cd node-0.2.0/bin
./node default --validators=0-15

Command line options

./node --help
Usage: node [-hV] [--dump-tuples] [--force-db-clean] [--db-prefix=db-prefix]
            [--genesis-time=time] [--initial-state=initial-state]
            [--listen=port] [--loglevel=level]
            [--metrics-endpoint=matrics-endpoint] [--name=node-name]
            [--spec-constants=spec-constants] [--start-mode=start-mode]
            [--validator-count=initial-deposit-count] [--connect=URL[,
            URL...]]... [--validators=key[,key...]]... config.yml
Beacon chain node
      config.yml            A path to a file containing node config in YAML format.
                            Use 'default' to run a node with default setup.
      --connect=URL[,URL...]
                            Peers that node is actively connecting to.
                            URL format: <network multiaddress>/p2p/<node id>
                            URL sample: /ip4/10.0.0.128
                              /tcp/40001/p2p/16Uiu2HAmCQHi9nZQrWxaxoWVW5Hv5rvoSAkH6rq
                              SkTi9PnPNZH4r
      --db-prefix=db-prefix Specifies db-prefix, used to construct db directory
      --dump-tuples         Specifies whether to dump beacon tuples (state and
                              block).
                            False by default
      --force-db-clean      When an initial-state is specified, but db is not empty
                            specifies how to resolve the problem:
                              force-db-clean=true  - tries to clean db
                              force-db-clean=false - exits with failure status.
                            False by default.
      --genesis-time=time   Genesis time in GMT+0 timezone. In either form:
                              '2019-05-24 11:23'
                              '11:23' (current day is taken)
                              '1568223274' (unix timestamp)
                            Defaults to the beginning of the current hour.
      --initial-state=initial-state
                            Path to an initial state file (SSZ format)
      --listen=port         TCP port to listen for inbound connections.
      --loglevel=level      Log verbosity level: all, debug, info, error.
                            info is set by default.
      --metrics-endpoint=matrics-endpoint
                            Interface and port, Prometheus collection endpoint will
                              be served from.
                            Should have form of interface:port.
                            Default endpoint is 0.0.0.0:8008.
      --name=node-name      Node identity for logs output
                            Useful when several nodes are running
      --node-key=key        Private key of p2p node (32 bytes)
      --spec-constants=spec-constants
                            Path to a spec constants file in yaml format (flat
                              format)
                            Use 'minimal' shortcut to run with interop constants
      --start-mode=start-mode
                            Specifies how to deal with the existing or absent
                              storage. Possible modes:
                              initial - starts from an empty storage only. If it's
                              not, --force-db-clean can be specified.
                              storage - starts from a previously initialized storage
                              only,
                                        ignoring contract/initial-state parameters
                              auto    - starts from an existing storage, if it's non
                              empty
                                        initializes from contract/initial-state
                              parameters otherwise
                            By default, set to auto, if no initial-state is
                              specified,
                                        and to initial, if an initial-state is
                              specified.
      --validator-count, --initial-deposit-count=initial-deposit-count
                            Specifies amount of initial deposits when constructing a
                              genesis state.
      --validators=key[,key...]
                            Validator registry. Entry is either:
                              private key in a hex format prepended with '0x'
                              an index or a range specifying a keypair(s) in
                              emulated deposit contract
                            Example: --validators=1,2,5-9,0x1234567[...]ef
      --validators-file=filename
                            Validator registry as yaml file. Entries are pairs of
                              privkey and pubkey
                            Example: --validators-file=keygen_10_validators.yaml

  -h, --help                Show this help message and exit.
  -V, --version             Print version information and exit.

Run a small chain

In order to start building a chain you have to run a node with several validators. There is a built-in default config that can be used for a quick start. The default config is specified with 16 initial deposits. So, one can run upto 16 validators.

Let's run a node that carries 8 first validators with the following command:

./node default --name=v-01 --db-prefix=db1 --listen=40001 --validators=0-7 default

Let's add another nodes with 8 next validators and connect them:

./node --name=v-02 --db-prefix=db2 --validators=8-15 --connect=/ip4/127.0.0.1/tcp/40001:11111111111111111111111111111111111111111111111111111111111111111111 default

Note that in order to run commands in the same directory, one has to specify different --db-prefix values. This is because nodes stores data in a database in the current directory. So, to avoid conflicts, different DB directories should be used, which can be accomplished by specifying different db prefixes with the --db-prefix option.

Check out logs:

#V-01:
13:35:17.044 #  INFO  - Trying to import existing block: Block[? <~ c657749d, @slot 209, state=ec1457a5, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000]
13:35:17.056 #  INFO  - Trying to import existing block: Block[? <~ 4119754e, @slot 210, state=83d7183c, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000, atts: [epoch=52/1/4119754e/2+3]]
13:35:17.060 #  INFO  - Trying to import existing block: Block[? <~ c72ee0f9, @slot 211, state=b397d2e9, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000, atts: [epoch=52/2/c72ee0f9/2]]
13:35:20.057 #v-01  INFO  - validator 2: proposed a Block[058d8cbc <~ 6e0b59f7, @slot 212, state=5a5d2c2a, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000]:
  Attestation[AttestationData{crosslink=Crosslink{shard=3, startEpoch=31, endEpoch=52, parentRoot=d3dd96ba, dataRoot=00000000}, beaconBlockRoot=6e0b59f7, sourceEpoch=31, sourceRoot=be4623c7, targetEpoch=52, targetRoot=c657749d}, attesters=1+2, custodyBits=0b00000000, sig=c000...0000]
 in 0,010s
13:35:20.096 #v-01  INFO  - new block inserted: Block[058d8cbc <~ 6e0b59f7, @slot 212, state=5a5d2c2a, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000, atts: [epoch=52/3/6e0b59f7/1+2]] in 0,037s#1:
15:34:00.125 #1  INFO  - new block inserted: Block[5c631e0d <~ 6d2ae3fe, @slot 204, state=84a7b69d, randao=c000...0000, Eth1Data{depositRoot=b3f59c3f, depositCount=16, block=078cbf50}, sig=c000...0000, atts: [epoch=50/1/6d2ae3fe/0+1+2+3]] in 0.039s

#V-02:
13:35:18.136 #  INFO  - new block inserted: Block[4119754e <~ c657749d, @slot 209, state=ec1457a5, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000] in 0,435s
13:35:18.176 #  INFO  - new block inserted: Block[c72ee0f9 <~ 4119754e, @slot 210, state=83d7183c, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000, atts: [epoch=52/1/4119754e/2+3]] in 0,026s
13:35:18.208 #  INFO  - new block inserted: Block[6e0b59f7 <~ c72ee0f9, @slot 211, state=b397d2e9, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000, atts: [epoch=52/2/c72ee0f9/2]] in 0,023s
13:35:20.040 #v-02  INFO  - initialized validators: [8, 9, 10, 11, 12, 13, 14, 15]
13:35:20.177 #  INFO  - new block inserted: Block[058d8cbc <~ 6e0b59f7, @slot 212, state=5a5d2c2a, randao=c000...0000, Eth1Data{depositRoot=4d60649a, depositCount=16, block=42424242}, sig=c000...0000, atts: [epoch=52/3/6e0b59f7/1+2]] in 0,053s
13:35:20.177 #v-02  INFO  - Switch sync to mode Short

Interop scenarios

The default configuration is aligned with the interop mocked start document.

Quick start genesis (validator count and genesis time specified)

Both genesis_time and validator_count can be specified via CLI options.

  • --initial-deposit-count, e.g. --initial-deposit-count=32 (or one can use an alias --validator-count alternatively)
  • --genesis-time, e.g. --genesis-time=1568223274 or --genesis-time='2019-09-09 11:20' or --genesis-time='11:20'

Or via YAML config file.

  • config.validator.contract.keys[0].count for validator_count
  • config.validator.contract.genesisTime for genesis_time

See Config parameters section below.

Start from a specified state

Node can be configured to start from a specified state file (in SSZ format) with --initial-state state_file.ssz option.

Note that one also should specify appropriate beacon chain specification constants to be able to load the file successfully. This can be done with --spec-constants config.yaml option. See the section below also.

Example

./node default --initial-state genesis.ssz --spec-constants config.yaml --validators=0-7

Another note: when --initial-state is specified, a node starts in INITIAL start-mode, which means it should start from an empty storage. If a node has been already started with the state, then a second attempt can fail, because the node command will find a non-empty storage. One should either manually move or remove DB directory (starting with db-prefix, e.g. db). Or specify --force-db-clean option which will clean storage (for a given <dv-prefix,genesis-time,deposit-root> triple.

Specify a common configuration of constants

Use --spec-constants config.yaml option to specify a common configuration of constants, e.g. --spec-constants mainnet.yaml, use --spec-constants minimal as a shortcut to the interop constants. Alternatively, the constants configuration can be specified via the node config file, but it's more tedious, because it does not support flat format, as used in common presets.

Distribution of validators across nodes

To specify some subset of validators to be run on the given node, use --validators option, e.g. --validators=0..7 or --validators=0,1,2,3,4-7. For example,

./node default --spec-constants=minimal --genesis-time=1568223274 --initial-deposit-count=32 --validators=0,1,2,3,4-7

Config parameters

Sample YAML node config file.

config:
  db: db
  networks:
    # Libp2p based network conforming to spec
    - type: libp2p
      # TCP port the node should listen for incoming connections
      # listenPort: 40001

  validator:
    contract: !emulator
      # balance: 32
      # genesisTime: 2019-09-09 12:00:00
      keys:
        - !interop
          count: 32
      interopCredentials: true
      # eth1_block_hash value is used according to mocked start spec by default
      # eth1BlockHash: 0x4242424242424242424242424242424242424242424242424242424242424242
# One can speciy a subset of validators to be run with, by filling `signer` section
#    signer: !insecure
#      keys:
#        - !interop
#          startIndex: 0
#          count: 8
#        - !interop
#          startIndex: 8
#          count: 4

# One can specify beacon chain constants
# Since it's not a flat format, it may be easier to use `--spec-constants` option
chainSpec:
  specConstants:
    initialValues:
      GENESIS_SLOT: 0
    miscParameters:
      SHARD_COUNT: 4
      TARGET_COMMITTEE_SIZE: 2
    timeParameters:
      SECONDS_PER_SLOT: 10
      MIN_ATTESTATION_INCLUSION_DELAY: 1
      SLOTS_PER_EPOCH: 4
      SLOTS_PER_HISTORICAL_ROOT: 64

    honestValidatorParameters:
      ETH1_FOLLOW_DISTANCE: 1
    stateListLengths:
      EPOCHS_PER_HISTORICAL_VECTOR: 64
      EPOCHS_PER_SLASHINGS_VECTOR: 64

  # Additional options affecting caching and BLS calculations can be specified
  specHelpersOptions:
    blsVerify: false
    blsVerifyProofOfPossession: false
    blsSign: false
    enableCache: false
    # for interop, genesis time should be overridden with the specified value, so ignore computation
    computableGenesisTime: false