Node Setup

This section will guide you through how to setup a Story node. This currently involves running two separate clients, a forked version of geth story-geth for the execution client, and a custom consensus client called story.

story draws inspiration from ETH PoS in decoupling execution and consensus clients. The execution client relays EVM blocks into theย storyย consesus client via Engine ABI, using an ABCI++ adapter to make EVM state compatible with that of CometBFT. With this architecture, consensus efficiency is no longer bottlenecked by execution transaction throughput.

The story and geth binaries, which make up the clients required for running Story nodes, are available from our latest release page:

Please download the binary matching your system architecture

System Specs

HardwareRequirement
CPU4 Cores
RAM8 GB
Disk200 GB
Bandwidth10 MBit/s

Default Folder

By default, we setup the following default data folders for consensus and execution clients:

  • Mac OS X
    • story data root: ~/Library/Story/story
    • story-geth data root: ~/Library/Story/geth
  • Linux
    • story data root: ~/.story/story
    • story-geth data root: ~/.story/geth

For the remainder of this tutorial, we will refer to the story data root as ${STORY_DATA_ROOT} and the geth data root as ${GETH_DATA_ROOT}.

You are able to override these configs on the story client side by passing --home ${STORY_DATA_ROOT}.

Execution Client Setup (story-geth)

  1. (Mac OS X only) The OS X binaries have yet to be signed by our build process, so you may need to unquarantine them manually:

    sudo xattr -rd com.apple.quarantine ./geth
    
  2. You may now run geth with the following command:

    ./geth --iliad --syncmode full
    
    • Currently, snap sync mode, the default, is still undergoing development

Clear State

If you ever run into issues and would like to try joining the network from a cleared state, run the following:

rm -rf ${GETH_DATA_ROOT} && ./geth --iliad --syncmode full
  • Mac OS X: rm -rf ~/Library/Story/geth/* && ./geth --iliad --syncmode full
  • Linux: rm -rf ~/.story/geth/* && ./geth --iliad --syncmode full

Debugging

If you would like to check the status of geth while it is running, it is helpful to communicate via its built-in IPC-RPC server by running the following:

geth attach ${GETH_DATA_ROOT}/iliad/geth.ipc
  • Mac OS X:
    • geth attach ~/Library/Story/geth/iliad/geth.ipc
  • Linux:
    • geth attach ~/.story/geth/iliad/geth.ipc

This will connect you to the IPC server from which you can run some helpful queries:

  • eth.blockNumber will print out the latest block geth is syncโ€™d to - if this is undefined there is likely a peer connection or syncing issue
  • admin.peers will print out a list of other geth nodes your client is connected to - if this is blank there is a peer connectivity issue
  • eth.syncing will return true if geth is in the process of syncing, false otherwise

Consensus Client Setup (story)

  1. (Mac OS X Only) The OS X binaries have yet to be signed by our build process, so you may need to unquarantine them manually:

    sudo xattr -rd com.apple.quarantine ./story
    
  2. Initialize the story client with the following command:

    ./story init  --network iliad 
    
    • By default, this uses your username for the moniker (the human-readable identifier for your node), you may override this by passing in --moniker ${NODE_MONIKER}
    • If you would like to initialize the node using your own data directory, you can pass in --home ${STORY_DATA_DIR}
    • If you already have config and data files, and would like to re-initialize from scratch, you can add the --clean flag
  3. Now, you may run story with the following command:

    ./story run
    

Note: currently you might see a bunch of Stopping peer for error logs - this is a known issue around peer connection stability with our bootnodes that we are currently fixing - for now please ignore it and rest assured that it does not impact block progression.

Clear State

If you ever run into issues and would like to try joining the network from a fresh state, run the following:

rm -rf ${STORY_DATA_ROOT} && ./story init --network iliad && ./story run
  • Mac OS X:
    • rm -rf ~/Library/Story/story/* && ./story init --network iliad && ./story run
  • Linux:
    • rm -rf ~/.story/story/* && ./story init --network iliad && ./story run

To quickly check if the node is syncing, you could

  • Check the geth RPC endpoint to see if blocks are increasing:
    curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' [http://localhost:8545](http://localhost:8545/)
    
  • Attach to geth as explained above and see if the eth.blockNumber is increasing

Custom Configuration

To override your own node settings, you can do the following:

  • ${STORY_DATA_ROOT}/config/config.toml can be modified to change network and consensus settings
  • ${STORY_DATA_ROOT}/config/story.toml to update various client configs
  • ${STORY_DATA_ROOT}/priv_validator_key.json is a sensitive file containing your validator key, but may be replaced with your own

Debugging

If you would like to check the status of story while it is running, it is helpful to query its internal JSONRPC/HTTP endpoint. Here are a few helpful commands to run:

  • curl localhost:26657/net_info | jq '.result.peers[].node_info.moniker'
    • This will give you a list of consesus peers the node is syncโ€™d with by moniker
  • curl localhost:26657/health
    • This will let you know if the node is healthy - {} indicates it is

Automated Upgrades

To manage consesus client upgrades more easily, especially for hard forks, we recommend using cosmovisor, which allows you to automate the process of upgrading client binaries without having to restart your client.

As an example, here is how the process would work for setting up automated client upgrades for story on iliad:

After making sure story-geth is setup and running, setup story with your client by running

rm -rf ${STORY_DATA_ROOT} && ${STORY_CLIENT} init --network iliad

Then, make sure the appropriate environment variables are set for running cosmovisor:

 export DAEMON_HOME=${STORY_DATA_ROOT}
 export DAEMON_NAME=story
 export DAEMON_DATA_BACKUP_DIR=~/story_backup_folder # make this any backup dir

Assuming cosmovisor was properly installed, you can initialize cosmovisor with:

 cosmovisor init ${STORY_CLIENT}

Now, you can start story as a managed process to cosmovisor by running:

cosmovisor run run

Then, whenever you would like to add an upgrade to a new client for a specific height, you may open up a separate terminal instance and run the following:

 cosmovisor add-upgrade ${CLIENT_VERSION} ${NEW_STORY_CLIENT} --force --upgrade-height ${UPGRADE_HEIGHT}

Once run, cosmovisor will automatically replace the consensus client with that of the new binary.