Skip to content

Latest commit

 

History

History
174 lines (132 loc) · 12.4 KB

step-by-step.md

File metadata and controls

174 lines (132 loc) · 12.4 KB

Instructions for Building Savanna Network

Environment

Many linux OS will work, these instructions have been validated on ubuntu 22.04.

Prerequisites

Apt-get and install the following https://github.com/eosnetworkfoundation/bootstrap-private-network/blob/main/AntelopeDocker#L3-L20 You will also need to install the following python packages https://github.com/eosnetworkfoundation/bootstrap-private-network/blob/main/AntelopeDocker#L21

Build Antelope Software

You will need to build the following Antelope software from source, using the specified git branches. The software should be built in the following order to satisfy dependancies Spring, followed by CDT, followed by Reference Contracts.

These Git Commit Hashes or Tags are current to the following date.

# Jul 10th 2024 Build Spring v1.0.0-beta2

Branches

  • Spring: branch release/1.0-beta4 repo AntelopeIO/spring
  • CDT: branch release/4.1 repo AntelopeIO/cdt
  • Reference Contracts: branch main repo AntelopeIO/reference-contracts

Full Instructions for Building Spring, Full Instructions for Building CDT or you can review the Reference Script to Build Spring and CDT. Full Instructions for Building Reference Contracts or you can review Reference Script to Build Contracts.

Install Antelope Software

Now that the binaries are build you need to add CDT and Spring to your path or install them into well know locations. The Reference Install Script must be run as root and demonstrates one way to install the software.

Note, the Reference Contracts are install later during the initialization of the EOS blockchain.

Initialize Block Chain

Before we can start up our multi-producer blockchain a few preparations are needed.

Create New Key Pair

We will create a new key pair for the root user of the blockchain. You will use the Public Key often in the setup, so please save these keys for use later. You will see a PublicKey and PrivateKey printed to the console using the following command. cleos create key --to-console We create three additional key pairs for each of our producers. Here the producers are named bpa, bpb, bpc.

[ ! -s "$WALLET_DIR"/finality-test-network.keys ] && cleos create key --to-console > "$WALLET_DIR"/finality-test-network.keys
# head because we want the first match; they may be multiple keys
EOS_ROOT_PRIVATE_KEY=$(grep Private "${WALLET_DIR}"/finality-test-network.keys | head -1 | cut -d: -f2 | sed 's/ //g')
EOS_ROOT_PUBLIC_KEY=$(grep Public "${WALLET_DIR}"/finality-test-network.keys | head -1 | cut -d: -f2 | sed 's/ //g')
# create keys for first three producers
for producer_name in bpa bpb bpc
do
[ ! -s "$WALLET_DIR/${producer_name}.keys" ] && cleos create key --to-console > "$WALLET_DIR/${producer_name}.keys"
done

Create Genesis File

Take the reference Genesis File and replace the value for Initial Key with the PublicKey generated previously. Replace the the value for Initial Timestamp with now. In linux you can get the correct format for the date with the following command date +%FT%T.%3N.

Create Shared Config

We will create a shared config file for the common configuration values. Configuration here is only for preview development purposes and should not be used as a reference production config. Copy config.ini to your filesystem. Additional configuration values will be added on the command line.

Create Log and Data Dir

You will need to create three data directories, one for each instance of nodeos you will run. You will need a place for log files as well. For example:

[ ! -d "$LOG_DIR" ] && mkdir -p "$LOG_DIR"
[ ! -d "$ROOT_DIR"/nodeos-one/data ] && mkdir -p "$ROOT_DIR"/nodeos-one/data
[ ! -d "$ROOT_DIR"/nodeos-two/data ] && mkdir -p "$ROOT_DIR"/nodeos-two/data
[ ! -d "$ROOT_DIR"/nodeos-three/data ] && mkdir -p "$ROOT_DIR"/nodeos-three/data

Create Wallet

You need to create and import the root private key into a wallet. This will allow you to run initialization commands on the blockchain. In the example below we have a named wallet and we save the wallet password to a file.

[ ! -s "$WALLET_DIR"/finality-test-network.keys ] && cleos create key --to-console > "$WALLET_DIR"/finality-test-network.keys
Then import your Root PrivateKey adding it to the wallet. We do not need to import our keys for each of the block producers.
# Import Root Private Key
cleos wallet import --name finality-test-network-wallet --private-key $EOS_ROOT_PRIVATE_KEY
If you have already created a wallet you may need to unlock your wallet using your password
cat "${WALLET_DIR}"/finality-test-network-wallet.pw | cleos wallet unlock --name finality-test-network-wallet --password

Initialization Data

Taking everything we have prepared we will now start a nodoes instance. We will be issuing commands while nodes is running so run this command in the background, or be prepared to open multiple terminals on your host. You'll notice we specified the

  • genesis file
  • config file
  • data directory for first instance
  • public and private key from our very first step It is very important to include the option --enable-stale-production, we will need that to bootstrap our network.
    nodeos --genesis-json ${ROOT_DIR}/genesis.json --agent-name "Finality Test Node One" \
    --http-server-address 0.0.0.0:${NODEOS_ONE_PORT} \
    --p2p-listen-endpoint 0.0.0.0:1444 \
    --enable-stale-production \
    --producer-name eosio \
    --signature-provider ${EOS_ROOT_PUBLIC_KEY}=KEY:${EOS_ROOT_PRIVATE_KEY} \
    --config "$ROOT_DIR"/config.ini \
    --data-dir "$ROOT_DIR"/nodeos-one/data > $LOG_DIR/nodeos-one.log 2>&1 &

Creating Contracts and Accounts

One the node is running we need to run two scripts to add accounts and contracts. We break down this process into three steps.

  • boot actions
  • create accounts
  • block producer setup

Boot Actions

boot_actions.sh is the reference script. You pass in the following values, reference contracts is your locale git repository where you build the reference contracts software.

  • 127.0.0.1:8888
  • $DIR/reference-contracts/build/contracts
  • PublicKey

This script creates the system accounts.

cleos --url $ENDPOINT create account eosio eosio.bpay $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.msig $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.names $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.ram $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.ramfee $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.saving $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.stake $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.token $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.vpay $PUBLIC_KEY
cleos --url $ENDPOINT create account eosio eosio.rex $PUBLIC_KEY

We create 380,000,000 EOS tokens.

cleos --url $ENDPOINT set contract eosio.token "$CONTRACT_DIR"/eosio.token/
cleos --url $ENDPOINT push action eosio.token create '[ "eosio", "380000000.0000 EOS" ]' -p eosio.token@active
cleos --url $ENDPOINT push action eosio.token issue '[ "eosio", "380000000.0000 EOS", "initial issuance" ]' -p eosio

Below we activate the protocols needed to support Savanna and create the boot, and system contracts.

curl --request POST --url "$ENDPOINT"/v1/producer/schedule_protocol_feature_activations -d '{"protocol_features_to_activate": ["0ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd"]}'
sleep 1
cleos --url $ENDPOINT set contract eosio "$CONTRACT_DIR"/eosio.boot/
# DISABLE_DEFERRED_TRXS_STAGE_1
cleos --url $ENDPOINT push action eosio activate '["fce57d2331667353a0eac6b4209b67b843a7262a848af0a49a6e2fa9f6584eb4"]' -p eosio
# DISABLE_DEFERRED_TRXS_STAGE_2
cleos --url $ENDPOINT push action eosio activate '["09e86cb0accf8d81c9e85d34bea4b925ae936626d00c984e4691186891f5bc16"]' -p eosio
# WTMSIG_BLOCK_SIGNATURES
cleos --url $ENDPOINT push action eosio activate '["299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707"]' -p eosio
# BLS_PRIMITIVES2
cleos --url $ENDPOINT push action eosio activate '["63320dd4a58212e4d32d1f58926b73ca33a247326c2a5e9fd39268d2384e011a"]' -p eosio
# DISALLOW_EMPTY_PRODUCER_SCHEDULE
cleos --url $ENDPOINT push action eosio activate '["68dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428"]' -p eosio
# ACTION_RETURN_VALUE
cleos --url $ENDPOINT push action eosio activate '["c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071"]' -p eosio
# INSTANT_FINALITY
# Depends on WTMSIG_BLOCK_SIGNATURES , BLS_PRIMITIVES2 , DISALLOW_EMPTY_PRODUCER_SCHEDULE , ACTION_RETURN_VALUE
cleos --url $ENDPOINT push action eosio activate '["18b790108f5e277cf7141dc626a98f7edeb776912278e4cd14a50b763d1d6390"]' -p eosio
# ONLY_LINK_TO_EXISTING_PERMISSION
cleos --url $ENDPOINT push action eosio activate '["1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241"]' -p eosio
# FORWARD_SETCODE
cleos --url $ENDPOINT push action eosio activate '["2652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25"]' -p eosio
# GET_BLOCK_NUM
cleos --url $ENDPOINT push action eosio activate '["35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b"]' -p eosio
# REPLACE_DEFERRED
cleos --url $ENDPOINT push action eosio activate '["ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99"]' -p eosio
# NO_DUPLICATE_DEFERRED_ID
cleos --url $ENDPOINT push action eosio activate '["4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f"]' -p eosio
# RAM_RESTRICTIONS
cleos --url $ENDPOINT push action eosio activate '["4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d67"]' -p eosio
# WEBAUTHN_KEY
cleos --url $ENDPOINT push action eosio activate '["4fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2"]' -p eosio
# BLOCKCHAIN_PARAMETERS
cleos --url $ENDPOINT push action eosio activate '["5443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4"]' -p eosio
# CRYPTO_PRIMITIVES
cleos --url $ENDPOINT push action eosio activate '["6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc"]' -p eosio
# ONLY_BILL_FIRST_AUTHORIZER
cleos --url $ENDPOINT push action eosio activate '["8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405"]' -p eosio
# RESTRICT_ACTION_TO_SELF
cleos --url $ENDPOINT push action eosio activate '["ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43"]' -p eosio
# GET_CODE_HASH
cleos --url $ENDPOINT push action eosio activate '["bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99"]' -p eosio
# CONFIGURABLE_WASM_LIMITS2
cleos --url $ENDPOINT push action eosio activate '["d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40"]' -p eosio
# FIX_LINKAUTH_RESTRICTION
cleos --url $ENDPOINT push action eosio activate '["e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526"]' -p eosio
# GET_SENDER
cleos --url $ENDPOINT push action eosio activate '["f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d"]' -p eosio
sleep 1

Create Accounts

create_accounts.sh takes two arguments

  • 127.0.0.1:8888
  • $WALLET_DIR

Next we create 3 producer accounts, one for each of our nodes. After creating the keys, we create the accounts, allocate EOS, and add some resources.

cleos --url $ENDPOINT_ONE system newaccount eosio ${producer_name:?} ${PUBLIC_KEY:?} --stake-net "500 EOS" --stake-cpu "500 EOS" --buy-ram "1000 EOS"
# get some spending money
cleos --url $ENDPOINT_ONE transfer eosio ${producer_name} "10000 EOS" "init funding"
# self stake some net and cpu
cleos --url $ENDPOINT_ONE system delegatebw ${producer_name} ${producer_name} "4000.0 EOS" "4000.0 EOS"

We create 26 users accounts. These accounts will stake resources and vote for producers. Same commands we used to create the producers. The only difference is funding amounts.

cleos --url $ENDPOINT_ONE system newaccount eosio ${user_name:?} ${USER_PUBLIC_KEY:?} --stake-net "50 EOS" --stake-cpu "50 EOS" --buy-ram "100 EOS"
# get some spending money
cleos --url $ENDPOINT_ONE transfer eosio ${user_name} "11540000 EOS" "init funding"
# stake 1154K EOS x26 accounts = 300,004,000 EOS Total Staked
cleos --url $ENDPOINT_ONE system delegatebw ${user_name} ${user_name} "5770000.000 EOS" "5770000.0000 EOS"

Block Producer Setup

block_producer_setup is the reference script. You pass in the following values

  • 127.0.0.1:8888
  • $WALLET_DIR

This script create registers new block producers and users vote for producers.

cleos --url $ENDPOINT_ONE system regproducer ${producer_name} ${PUBLIC_KEY}
cleos --url $ENDPOINT_ONE system voteproducer prods ${user_name} bpa bpb bpc

Shutdown

Now that we have initialized our first instance we need to shut it down and restart. Find the pid and send kill -15 $pid to terminate the instance.

Create Network

Now we start our three nodes peer'd to each other. The Second and Third nodes will start from genesis and pull updates from the First node. The First nodes has already been initialized and it will start from its existing state. Soon each node will have the same information and the same head block number.

In the examples below we user different PublicKey and PrivateKey for each producer.

Node One

nodeos --agent-name "Finality Test Node One" \
--http-server-address 0.0.0.0:${NODEOS_ONE_PORT} \
--p2p-listen-endpoint 0.0.0.0:1444 \
--enable-stale-production \
--producer-name bpa \
--signature-provider ${BPA_PUBLIC_KEY}=KEY:${BPA_PRIVATE_KEY} \
--config "$ROOT_DIR"/config.ini \
--data-dir "$ROOT_DIR"/nodeos-one/data \
--p2p-peer-address 127.0.0.1:2444 \
--p2p-peer-address 127.0.0.1:3444 > $LOG_DIR/nodeos-one.log 2>&1 &

Node Two

nodeos --genesis-json ${ROOT_DIR}/genesis.json --agent-name "Finality Test Node Two" \
--http-server-address 0.0.0.0:${NODEOS_TWO_PORT} \
--p2p-listen-endpoint 0.0.0.0:2444 \
--enable-stale-production \
--producer-name bpb \
--signature-provider ${BPB_PUBLIC_KEY}=KEY:${BPB_PRIVATE_KEY} \
--config "$ROOT_DIR"/config.ini \
--data-dir "$ROOT_DIR"/nodeos-two/data \
--p2p-peer-address 127.0.0.1:1444 \
--p2p-peer-address 127.0.0.1:3444 > $LOG_DIR/nodeos-two.log 2>&1 &

Node Three

nodeos --genesis-json ${ROOT_DIR}/genesis.json --agent-name "Finality Test Node Three" \
--http-server-address 0.0.0.0:${NODEOS_THREE_PORT} \
--p2p-listen-endpoint 0.0.0.0:3444 \
--enable-stale-production \
--producer-name bpc \
--signature-provider ${BPC_PUBLIC_KEY}=KEY:${BPC_PRIVATE_KEY} \
--config "$ROOT_DIR"/config.ini \
--data-dir "$ROOT_DIR"/nodeos-three/data \
--p2p-peer-address 127.0.0.1:1444 \
--p2p-peer-address 127.0.0.1:2444 > $LOG_DIR/nodeos-three.log 2>&1 &

Check Blocks Behind

Here you can check the Head Block Number and Last Irreversible Block and see there are far apart. cleos get info

Activate Savanna

For the last step we will activate the new Savanna algorithm.

Generate Finalizer Keys

We need to generate the new BLS finalizer keys and add them to our configuration file. Each producer needs to generate a finalizer key. We have three nodes and that requires calling spring-util bls create key three times. spring-util bls create key --to-console Save the output from the command. The public and private keys will be added as signature-provider lines to config.ini. This configuration file is shared across all three instances and each instance will have all three lines.

  • BLS Public keys start with PUB_BLS_
  • BLS Private keys start with PVT_BLS_
  • BLS Proof of possession signatures start with SIG_BLS_
echo "signature-provider = ""${NODE_ONE_PUBLIC_KEY}""=KEY:""${NODE_ONE_PRIVATE_KEY}" >> config.ini
echo "signature-provider = ""${NODE_TWO_PUBLIC_KEY}""=KEY:""${NODE_TWO_PRIVATE_KEY}" >> config.ini
echo "signature-provider = ""${NODE_THREE_PUBLIC_KEY}""=KEY:""${NODE_THREE_PRIVATE_KEY}" >> config.ini

Apply New Configuration

Now that the configuration is in the shared config.ini we need to stop and re-start all three nodes to load the new configuration. Find the pid and send kill -15 $pid to terminate all three instances. Now start up the nodes. Here are examples from our reference development script. The signature-provider argument on the command line is the EOS Root Key Pair we created earlier, and it is still needed for this restart step.

nodeos --agent-name "Finality Test Node One" \
--http-server-address 0.0.0.0:${NODEOS_ONE_PORT} \
--p2p-listen-endpoint 0.0.0.0:1444 \
--enable-stale-production \
--producer-name bpa \
--signature-provider ${BPA_PUBLIC_KEY}=KEY:${BPA_PRIVATE_KEY} \
--config "$ROOT_DIR"/config.ini \
--data-dir "$ROOT_DIR"/nodeos-one/data \
--p2p-peer-address 127.0.0.1:2444 \
--p2p-peer-address 127.0.0.1:3444 > $LOG_DIR/nodeos-one.log 2>&1 &

nodeos --agent-name "Finality Test Node Two" \
--http-server-address 0.0.0.0:${NODEOS_TWO_PORT} \
--p2p-listen-endpoint 0.0.0.0:2444 \
--enable-stale-production \
--producer-name bpb \
--signature-provider ${BPB_PUBLIC_KEY}=KEY:${BPB_PRIVATE_KEY} \
--config "$ROOT_DIR"/config.ini \
--data-dir "$ROOT_DIR"/nodeos-two/data \
--p2p-peer-address 127.0.0.1:1444 \
--p2p-peer-address 127.0.0.1:3444 > $LOG_DIR/nodeos-two.log 2>&1 &

nodeos --agent-name "Finality Test Node Three" \
--http-server-address 0.0.0.0:${NODEOS_THREE_PORT} \
--p2p-listen-endpoint 0.0.0.0:3444 \
--enable-stale-production \
--producer-name bpc \
--signature-provider ${BPC_PUBLIC_KEY}=KEY:${BPC_PRIVATE_KEY} \
--config "$ROOT_DIR"/config.ini \
--data-dir "$ROOT_DIR"/nodeos-three/data \
--p2p-peer-address 127.0.0.1:1444 \
--p2p-peer-address 127.0.0.1:2444 > $LOG_DIR/nodeos-three.log 2>&1 &

Register Finalizer Key

The activate_savanna.sh script registers the finalizer keys. In this example we register one for each producer.

# Execute the cleos command error if vars not set
# void system_contract::regfinkey( const name& finalizer_name, const std::string& finalizer_key, const std::string& proof_of_possession)
cleos --url $ENDPOINT push action eosio regfinkey "{\"finalizer_name\":\"${producer_name:?}\", \
\"finalizer_key\":\"${PUBLIC_KEY[$counter]:?}\", \
\"proof_of_possession\":\"${PROOF_POSSESION[$counter]:?}\"}" -p ${producer_name:?}

Here is an example using the regfinkey action. Note the permission used is the block producer's.

cleos --url $ENDPOINT push action eosio regfinkey '{"finalizer_name":"NewBlockProducer", \
      "finalizer_key":"PUB_BLS_v8-ZaaZZ5ZZaZ5ZaZZZZaa5aZaZaaZZa5aZZ5aZaZ5aaZZa5a-ZaZZ555Z55aZZZ5aZaZZaZaaZ5aZ55ZaZZaaaaaaZa5Z-5aa5aaaaZaaZ5Zaaaaa5ZaaZZaaa5ZaZZZaZa5a", \
      "proof_of_possession":"SIG_BLS_aa5Z-aZZZ5aaaZZZ5ZaaaZ5a-aZaa_aaZZ5aaa55aZa-ZaZZaZZZ5ZZZaaZZZ5ZZZZ-aaZ_55ZZZ5Z5a5ZZaaa5aZZ5aZaaZ5aa5ZaaZ-ZZZZa5ZaaaZZa5aaZZZZaaZ5ZZZZZa5ZZZ5Z55a5ZZZ5aaZa5Z5ZZ5Z5-aaZZZZZ-ZZZaZZ5a5aaZZZaZa5ZZ5ZaZaaaZaZaa5aaaaaaa5aZZaaZ5aZ5ZZ5aaaZZaaaaaZZaZa55ZaZaaaaaaZaZZZZZa5aZa"}' \
      -p NewBlockProducer

Activate Savanna

The final step is to activate savanna. This is done with a action that takes no arguments. The permission required is eosio@active

cleos --url $ENDPOINT push action eosio switchtosvnn '{}' -p eosio

Verify Faster Finality

Here you can check the Head Block Number and Last Irreversible Block and see they are three apart. cleos get info

In addition you can check your logs for the following strings, the will provide information on the exact block where the transition will/does occur.

  • Transitioning to savanna
  • Transition to instant finality

Congratulations you are running a Private EOS network with the new, faster finality, Savanna algorithm.