Skip to content

Beacon chain node

ericsson49 edited this page Sep 9, 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 --helpUsage: node [-hV] [--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: <multiaddress>:<node id hex>
                            URL sample: /ip4/10.0.0.128/tcp/40001:
                              1111111111111111111111111111111111111111111111111111111
                              1111111111111
      --db-prefix=db-prefix Specifies db-prefix, used to construct db directory
      --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)
                            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
      --spec-constants=spec-constants
                            Path to a spec constants file in yaml format (flat
                              format)
      --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
  -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='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 also.

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.

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 or --spec-constants minimal.yaml. 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.

Config parameters

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
      keys:
        - !interop
          count: 16
      interopCredentials: true
      # eth1BlockHash: 0x4242424242424242424242424242424242424242424242424242424242424242
#    signer: !insecure
#      keys:
#        - !generate
#          count: 16
#          seed: 0

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

  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
Clone this wiki locally