Story: How to setup/move the node to PebbleDB

Story  guide  installation  pebbledb  cosmossdk 

The Story node standard installation guide

Official Story installation docs could be found here. Story' full node consist of two layers: Consensus Client (story), which based on cometbft (ex tendermint) and Execution Client (story-geth). By default Story' Consensus Client uses the Goleveldb for data storge.

Alternative Data Base Storage (PebbleDB)

Why PebbleDB

According to this article pebbledb has a few pros over classic goleveldb, such as:

  • Lower disk usage
  • faster block synchronization rate
  • Less duration for REST RPC requests

For more detailed information we recommend to visit original repo.

Initia is the "fast" blockchain with 2-3s block time.Which means high load on disks and longer synchronization time. Besides that, Initia implements latest cometbft and cometbft-db, which already has a built-in implementation of pebbledb (tendermint-db hasn't). That makes easier to maintain the node.

With all this in mind usage of pebbledb seems to be reasonable choice to run Story node.

Story' Consensus Client installation guide for Pebbledb

Dependencies

cd $HOME
ver="1.22.3"
wget "https://golang.org/dl/go$ver.linux-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.linux-amd64.tar.gz"
rm "go$ver.linux-amd64.tar.gz"
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.bash_profile
source $HOME/.bash_profile
go version

Build Consensus Client (story) with Pebbledb

# find out the current consensus node version. At this moment the latest version is:
vers="v0.10.2"

Clone Story repo

git clone https://github.com/piplabs/story.git;
cd $HOME/story;
git pull;
git fetch;
git reset --hard;

Select and check branch

git checkout ${vers};

git log -1 --pretty=oneline ;
>f7b649df3c5e73dc92b16f4ec390c97c310b310f (HEAD, tag: v0.10.2, origin/release/0.10) Merge remote-tracking branch 'origin/iliad' into release/0.10

Replace cometbft-db

go mod edit -replace github.com/cometbft/cometbft-db=github.com/cometbft/cometbft-db@v0.12.0
go mod tidy

Binary build

go build -o ./build/story -ldflags "-w -s -X github.com/cosmos/cosmos-sdk/types.DBBackend=pebbledb \
 -X github.com/cosmos/cosmos-sdk/version.Version=${vers}-pebble \
 -X github.com/cosmos/cosmos-sdk/version.Commit=$(git log -1 --format='%H') \
 -X github.com/cosmos/cosmos-sdk/version.ServerName=story \
 -X github.com/cosmos/cosmos-sdk/version.ClientName=story \
 -X github.com/cosmos/cosmos-sdk/version.Name=story \
 -X github.com/cosmos/cosmos-sdk/version.AppName=story" -tags pebbledb ./client


cd $HOME/story/build;
./story version
>Version       v0.10.2-stable
>Git Commit    f7b649d
>Git Timestamp 2024-10-03T01:59:08Z

Set or find out current binary path

# bin path
bin_path=$(which story) && echo ${bin_path}
# example of the output
>~/go/bin/story
# OR
bin_path=$HOME/go/bin/

move bin to bin_path

mv $HOME/story/build/story ${bin_path}

# check version
geth version;
>Version       v0.10.2-stable

Story' Execution Client

# find out the current Execution Client version. At this moment the latest version is:
vers="v0.9.3"

Clone Story Geth repo

git clone https://github.com/piplabs/story-geth.git;
cd $HOME/story-geth;
git pull;
git fetch;

Select and check branch

git checkout ${vers};
git log -1 --pretty=oneline ;
>51e15d89e98b28193cb3be4a19b28ba26a670805 (HEAD, tag: v0.9.3, origin/release/0.9) Merge remote-tracking branch 'origin/iliad' into release/0.9

Build client

make geth

cd $HOME/story-geth/build/bin/
./geth version
>Version: 0.9.3-stable
>Git Commit: 51e15d89e98b28193cb3be4a19b28ba26a670805
>Architecture: amd64
>Go Version: go1.22.3

Set or find out current binary path

bin_path=$(which geth) && echo ${bin_path};
# example of the output
>~/go/bin/story
# OR
bin_path=$HOME/go/bin/

move bin to bin_path

mv $HOME/story-geth/build/bin/geth ${bin_path}

# check version
geth version;
>Version: 0.9.3-stable

Init node

STORY_HOME="$HOME/.story/story"
STORY_CHAIN=iliad;
STORY_PORT=26657;
STORY_NODENAME="Put_your_moniker_here";

echo 'export STORY_CHAIN='$STORY_CHAIN >> $HOME/.bash_profile;
echo "export STORY_HOME=${STORY_HOME}" >> $HOME/.bash_profile;
echo "export STORY_NODENAME=${STORY_NODENAME}" >> $HOME/.bash_profile;
echo "export STORY_PORT=${STORY_PORT}" >> $HOME/.bash_profile;
source $HOME/.bash_profile

story init --moniker ${STORY_NODENAME} --network ${STORY_CHAIN};


# genesis
wget -O genesis.json https://snapshots.polkachu.com/testnet-genesis/story/genesis.json --inet4-only
mv genesis.json ${STORY_HOME}/config

Geth variables

GETH_DATA_ROOT="$HOME/.story/geth";
ETH_RAM_USE=16384;      
ETH_RPC_PORT="8545" ;                     
ETH_WS_PORT="8546" ;                       
ETH_P2P_PORT="40403" ;                     
ETH_ENGINE_PORT=8151;

echo 'export ETH_RAM_USE='${ETH_RAM_USE} >> $HOME/.bash_profile;
echo 'export ETH_RPC_PORT='${ETH_RPC_PORT} >> $HOME/.bash_profile;
echo 'export ETH_WS_PORT='${ETH_WS_PORT} >> $HOME/.bash_profile;
echo 'export ETH_P2P_PORT='${ETH_P2P_PORT} >> $HOME/.bash_profile;
echo 'export ETH_ENGINE_PORT='${ETH_ENGINE_PORT} >> $HOME/.bash_profile;
echo 'export GETH_DATA_ROOT='${GETH_DATA_ROOT} >> $HOME/.bash_profile;

source $HOME/.bash_profile;

Config

blocks=20000;
sed -i -e "s/^min-retain-blocks *=.*/min-retain-blocks = $blocks/" ${STORY_HOME}/story/story.toml;

snapshot=5000;
sed -i -e "s/^snapshot-interval *=.*/snapshot-interval = $snapshot/" ${STORY_HOME}/story/story.toml;

seed="ade4d8bc8cbe014af6ebdf3cb7b1e9ad36f412c0@testnet-seeds.polkachu.com:29256,86bd5cb6e762f673f1706e5889e039d5406b4b90@seed.story.testnet.node75.org:35616";
sed -i.bak -e "s/^seeds *=.*/seeds = \"$seed\"/" ${STORY_HOME}/story/config.toml;
cat "${STORY_HOME}/config.toml" | grep seeds;

peer="95937ce9971e81f61c3249f50404868bcedc77e7@peer.story.testnet.node75.org:27136,a035f10b1f4d3aa63941a42d507504137c7fdcb3@149.202.88.223:27136,54a80c1ebac879c698e361621e338753c0510a17@5.9.73.13:25136,7ed2e34f5e80948e862ba96d3051c08e4fb3b696@194.48.168.43:26656,a320f8a15892bddd7b5502527e0d11c5b5b9d0e3@69.67.150.107:29931"; 

sed -i.bak -e "s/^persistent_peers *=.*/persistent_peers = \"$peer\"/" ${STORY_HOME}/story/config.toml;
cat "${STORY_HOME}/config.toml" | grep persistent_peers

chunks=1;
sed -i.bak -e "s/^chunk_fetchers *=.*/chunk_fetchers = \"${chunks}\"/" ${STORY_HOME}/story/config.toml;

check=5
sed -i -e "s/^double_sign_check_height *=.*/double_sign_check_height = $check/" ${STORY_HOME}/story/config.toml

engine_port=${ETH_ENGINE_PORT};
sed -i -e "s/^engine-endpoint *=.*/engine-endpoint = \"http:\/\/127.0.0.1:${engine_port}\"/" ${STORY_HOME}/story/story.toml;


# set pebbledb
db_backend="pebbledb";
sed -i "s/^db_backend *=.*/db_backend = \"$db_backend\"/" ${STORY_HOME}/story/config.toml;
sed -i "s/^app-db-backend *=.*/app-db-backend = \"$db_backend\"/" ${STORY_HOME}/story/story.toml

Firewall rules

#check firewall status
sudo ufw status verbose

#add rules for geth ports: 
sudo ufw allow ${ETH_RPC_PORT}
sudo ufw allow ${ETH_WS_PORT}
sudo ufw allow ${ETH_P2P_PORT}
sudo ufw allow ${ETH_ENGINE_PORT}

#add rules for consensus node ports:
sudo ufw allow $(( ${STORY_PORT} - 1 ))
sudo ufw allow $(( ${STORY_PORT} + 1 ))

Systemd service for Consensus Clien setup

tee $HOME/storyd.service > /dev/null <<EOF
[Unit]
  Description=Story consesnsus Testnet Service
  After=network-online.target
[Service]
  User=$USER
  WorkingDirectory=${HOME}
  ExecStart=$(which story) run --home ${STORY_HOME}
  Restart=on-failure
  RestartSec=5
  LimitNOFILE=65535
[Install]
  WantedBy=multi-user.target
EOF

sudo chown ${USER}:${USER} -R "/home/${USER}/storyd.service"
sudo ln -s $HOME/storyd.service /etc/systemd/system

sudo systemctl daemon-reload
sudo systemctl enable storyd

Systemd service for Execution Clien setup

tee $HOME/story_gethd.service > /dev/null <<EOF
[Unit]
  Description=Story Testnet Geth Service
  After=network-online.target
[Service]
  User=$USER
  WorkingDirectory=${HOME}
  ExecStart=$(which geth) \
      --cache $ETH_RAM_USE \
      --syncmode "full" \
      --iliad \
      --port $ETH_P2P_PORT \
      --http.port $ETH_RPC_PORT \
      --http --http.vhosts "*" --http.api "eth,net,web3" --http.corsdomain '*' --http.addr 0.0.0.0 \
      --ws --ws.api eth,net,web3 --ws.addr 0.0.0.0 \
      --ws.port $ETH_WS_PORT \
      --datadir $GETH_DATA_ROOT/iliad \
      --authrpc.addr localhost \
      --authrpc.port ${ETH_ENGINE_PORT} \
      --authrpc.vhosts localhost \
      --bootnodes enode://0d90b99162d5f42af610f73c1766cbbecb4fb17cf94fd431ede0cf0458de2933655d92de54eafb9279c39b399cc8d0f772610082c09e613d2462ba5f1b7d4bd2@88.99.61.173:30303,enode://08e4b916327f2b9ef47d6b76fb77619eacb045c1054e2cb1e3abcc4c355907e3791a2f6f873cacfe2d99671f53299c575663d647e6bc855bf9d2c73751d1208e@b1.testnet.storyrpc.io:30303,enode://3bae9a46ddf39b805f678dd8ba8624c28285417d4bdbf5212234ee83a4cf94335bfd32b449a37bcf39b609208f8556ce42d6ee60c657f2a75b893350c1bd347f@b2.testnet.storyrpc.io:30303
  Restart=on-failure
  RestartSec=5
  LimitNOFILE=65535
[Install]
  WantedBy=multi-user.target
EOF

sudo chown ${USER}:${USER} -R "/home/${USER}/story_gethd.service"
sudo ln -s $HOME/story_gethd.service /etc/systemd/system

sudo systemctl daemon-reload;
sudo systemctl enable story_gethd;
sudo systemctl restart story_gethd && journalctl -u story_gethd -f -o cat

IMPORTANT NOTES !!!

If the node has started correct with pebbledb then extension of the database should be *.sst you can check it in data folder:

~/.story/story/data/blockstore.db/xxxx.sst

You could find the link to our Story' full (not the State-Sync) Pebbledb snapshots here.

Snapshot is taken on 2 times a day at 7.00 UTC and 19.00 UTC!!!

Start the node using full pebbledb snapshot

Consensus Client snapshot

consensus_snap_name="story_cometbft_snap"

# backup state
cp "$HOME/.story/story/data/priv_validator_state.json" $HOME

# check backup
cat $HOME/priv_validator_state.json


# our snapshots could be found here:
# https://snap.story.testnet.node75.org
# Example: URL to the Pebbledb Snapshot:
URL_comet="https://snap.story.testnet.node75.org/iliad-0_pebbledb_842487_2024-09-24T16.33.21.tar.lz4" 

# download the pebbledb cometbft snapshot:
wget -O $HOME/${consensus_snap_name}.tar.lz4 ${URL_comet} --inet4-only

# stop the Story consensus client service
sudo systemctl stop storyd; sudo systemctl status storyd

# clear the current cometbft DB
rm -rf $HOME/.story/story/data

# unpuck the snapshot
home_dir="$HOME/.story/story"  && echo ${home_dir} 
lz4 -c -d $HOME/${consensus_snap_name}.tar.lz4  | tar -x -C ${home_dir}

# if unpacking was successful, then delete the snapshot (optional)
rm -v $HOME/${consensus_snap_name}.tar.lz4

# get fresh addrbook
wget -O $HOME/addrbook.json https://snapshots.polkachu.com/testnet-addrbook/story/addrbook.json --inet4-only
mv $HOME/addrbook.json $HOME/.story/story/config/

# restore validator' state
cp $HOME/priv_validator_state.json "$HOME/.story/story/data/priv_validator_state.json"

# check state
cat $HOME/.story/story/data/priv_validator_state.json

# restart the Story Consensus client service
sudo systemctl restart storyd; journalctl -u storyd -f -o cat

Execution Client snapshot

execution_snap_name="story_geth_snap"

# Example: URL to the geth snapshot:
URL_geth="https://snap.story.testnet.node75.org/iliad-0_geth_842486_2024-09-24T16.33.21.tar.lz4" 

# download the geth snapshot:
wget -O $HOME/${execution_snap_name}.tar.lz4 ${URL_geth} --inet4-only

# stop the Story execution client service
sudo systemctl stop story_gethd; sudo systemctl status story_gethd

# clear the current geth DB
rm -rf "$HOME/.story/geth"

# unpuck the snapshot
home_dir="$HOME/.story/geth"  && echo ${home_dir} 
lz4 -c -d $HOME/${execution_snap_name}.tar.lz4  | tar -x -C ${home_dir}

# if unpacking was successful, then delete the snapshot (optional)
rm -v $HOME/${execution_snap_name}.tar.lz4

# restart the Story Geth service
sudo systemctl restart story_gethd; journalctl -u story_gethd -f -o cat

Best regards and Good luck with your Story node installation!❤️👍

Pro-Nodes75 team📡🗻