Skip to content

Instantly share code, notes, and snippets.

@tgrospic
Last active February 12, 2019 11:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tgrospic/62ef42c4b4557ddc80d2cf80914b2ac4 to your computer and use it in GitHub Desktop.
Save tgrospic/62ef42c4b4557ddc80d2cf80914b2ac4 to your computer and use it in GitHub Desktop.
RChain network

RChain network scripts

Download

# Download gist files to `rchain-network` folder
git clone https://gist.github.com/62ef42c4b4557ddc80d2cf80914b2ac4.git rchain-network
# change folder
cd rchain-network

Load control functions

Load all functions defined in rnode-control.sh script in the current shell.

The initial .env file will be created if it does not already exist.

# Load control functions
. rnode-control.sh

Configuration: .env file

.env file contains all configuration of running nodes.

docker-compose.yml uses configuration from .env file.

HOST_IP is rnode external IP address. For internal network can be set to 127.0.0.1.

For each node there are 3 main parameters:

  • BOOTSTRAP: address of bootstrap rnode (except bootstrap)
  • VALIDATOR: validator public key
  • VALIDATOR_PRIVATE: validator private key

For custom network parameters are numbered.

Validator public/private keys can be generated with generate_validator_keys function.

# .env file

# External IP address, used in rnode://.... address
HOST_IP=127.0.0.1

# Docker image (version) of RNode
RNODE_IMAGE=rchain/rnode:master

# RNode
# ---------------------------------------------------------------------------------------------------
BOOTSTRAP="rnode://3b2eb1308c23b1bef2f3f29f4500d39cbea6ac6d@boot?protocol=50400&discovery=50404"

VALIDATOR=099c1b56ac1fad402591b967a5b1daa26389a3957e573b6db646b1b72768ed91

VALIDATOR_PRIVATE=a67cdeb79b32040d6d3241945f1f2b2c6b7049914c142770a385dfdb63ef5ed7

Install all dependencies

# Install Docker, Docker compose, ...
install_dependencies

Generate public/private key-pairs (with rnode)

# Print keys generated by standalone rnode
generate_validator_keys

Connect to bootstrap

Example for VALIDATOR. In .env file enter bootstrap address (BOOTSTRAP) and public and private keys (VALIDATOR, VALIDATOR_PRIVATE).

Start rnode and attach to Docker logs.

# start VALIDATOR (CTRL+C to detach from log)
start rnode

RNode Docker container will write files with root permissions. If you want to edit files you can set permissions to current user.

# Set owner of ./data folder to current user
sudo chown -R $USER: ./data

Example of deploy and propose

# Deploy on VALIDATOR node
rnode deploy --nonce 0 --phlo-limit 100000 --phlo-price 1 /opt/docker/examples/tut-philosophers.rho

# Propose on VALIDATOR node
rnode propose

Bonding

Example for VALIDATOR.

# Generate bonding files (deploys)
bond_generate_faucet $VALIDATOR $VALIDATOR_PRIVATE

# Execute bonding (deploy and propose bonding files)
# to e.g. Kelly's host (defined in .env file)
# - skip propose when bonding to Kelly's node
bond_quick $KELLY_HOST $VALIDATOR

Run your own internal network (running bootstrap rnode)

# Generate bonding files (deploys)
bond_generate_faucet $VALIDATOR_1 $VALIDATOR_PRIVATE_1
bond_generate_faucet $VALIDATOR_2 $VALIDATOR_PRIVATE_2

# Copy VALIDATOR_BOOT key to bootstrap `genesis/bonds.txt` file
# - ensures that bootstrap is bonded with the key-pair defined in `.env` file
bond_bootstrap

# start VALIDATOR_BOOT node (CTRL+C to detach from log)
start boot

# Read boot address `rnode://...` and update `.env` file BOOTSTRAP_1

# start VALIDATOR_1 node
start rnode1

# Read rnode1 address `rnode://...` and update `.env` file BOOTSTRAP_2

# Bond VALIDATOR_1 on boot node
bond_quick boot $VALIDATOR_1

# Check bonding on rnode1 (after received blocks from boot)
bond_check_last_block rnode1 $VALIDATOR_1

# start VALIDATOR_2 node
start rnode2

# Bond VALIDATOR_2 on rnode1 node
bond_quick rnode1 $VALIDATOR_2

# Check bonding on rnode2
bond_check_last_block rnode2 $VALIDATOR_2

Clear nodes data

Clears all nodes data except rnode certificates (.pem) to keep rnode address.

clean_all
version: '3.4'
x-rnode:
&default-rnode
image: $RNODE_IMAGE
user: root
restart: always
networks:
- rchain-net
services:
rnode:
<< : *default-rnode
container_name: rnode
command: run --validator-private-key $VALIDATOR_PRIVATE -b $BOOTSTRAP --host $HOST_IP -n -p 40400
ports:
- $HOST_IP:40400:40400
- $HOST_IP:40404:40404
- $HOST_IP:40403:40403
volumes:
- ./data/rnode:/var/lib/rnode
# My network
# ------------------------------------------------------------------------------------
rnode1:
<< : *default-rnode
container_name: rnode1
command: run --validator-private-key $VALIDATOR_PRIVATE_1 -b $BOOTSTRAP_1 --host rnode1 -n -p 40400
ports:
- $MY_NET_IP:40400:40400
- $MY_NET_IP:40404:40404
- $MY_NET_IP:40403:40403
volumes:
- ./data/rnode1:/var/lib/rnode
rnode2:
<< : *default-rnode
container_name: rnode2
command: run --validator-private-key $VALIDATOR_PRIVATE_2 -b $BOOTSTRAP_2 --host rnode2 -n -p 40410 --kademlia-port 40424
ports:
- $MY_NET_IP:40420:40420
- $MY_NET_IP:40424:40424
- $MY_NET_IP:40423:40403
volumes:
- ./data/rnode2:/var/lib/rnode
boot:
<< : *default-rnode
container_name: boot
command: run -s --has-faucet --validator-private-key $VALIDATOR_PRIVATE_BOOT --host boot -n -p 50400 --kademlia-port 50404
ports:
- $MY_NET_IP:50400:50400
- $MY_NET_IP:50404:50404
- $MY_NET_IP:50403:50403
volumes:
- ./data/boot:/var/lib/rnode
networks:
rchain-net:
#!/usr/bin/env sh
CWD=$(realpath $(dirname $BASH_SOURCE))
# SETUP SERVER
# --------------------------------------------------------------------------------------
# git clone https://gist.github.com/62ef42c4b4557ddc80d2cf80914b2ac4.git rchain-network
# Install dependencies (Docker, Docker compose, ...)
install_dependencies () {
apt-get update
# Random generator (rnode crypto)
apt-get install -y haveged
update-rc.d haveged defaults
# Docker dependencies
apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# Add Docker repo key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Add Docker repo
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# Install Docker
apt-get update
apt-get install -y docker-ce
# Install Docker Compose
curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# Install rdoctor
install_rdoctor
}
install_rdoctor () {
# Install rdoctor
curl -O https://build.rchain-dev.tk/misc/rdoctor/latest/linux.amd64/rdoctor
sudo cp rdoctor /usr/local/bin
sudo chmod +x /usr/local/bin/rdoctor
}
# DOCKER COMPOSE SERVICES
# --------------------------------------------------------------------------------------
rnode () {
_rnode_grpc rnode $*
}
boot () {
_rnode_grpc boot $*
}
rnode1 () {
_rnode_grpc rnode1 $*
}
rnode2 () {
_rnode_grpc rnode2 $*
}
_rnode () {
dockerOpt="$1"
shift
# execute rnode command
docker run -it --rm $dockerOpt $RNODE_IMAGE $*
}
_rnode_grpc () {
grpcHost=$1
shift
grpcPort=40401
# execute rnode command
_rnode "--network $(_rchain_network) -v $CWD/data/contracts:/contracts" --grpc-host $grpcHost -g $grpcPort $*
}
# Docker run, bash entry point
_rnode_entry () {
dockerOpt="$1 --entrypoint bash"
shift
docker run -it --rm $dockerOpt $RNODE_IMAGE -c "$*"
}
# Docker compose network name
_rchain_network () {
docker network ls | grep rchain-net | sed -r 's/\w+\W+((\w|-)*_rchain-net).+/\1/'
}
# BONDING
# --------------------------------------------------------------------------------------
BOND_VOLUME="-v $CWD/data/.bonding:/bonding"
# bond_generate_faucet $VALIDATOR $VALIDATOR_PRIVATE
# bond_generate_faucet $VALIDATOR_1 $VALIDATOR_PRIVATE_1
# bond_generate_faucet $VALIDATOR_2 $VALIDATOR_PRIVATE_2
bond_generate_faucet () {
pubKey="$1"
privKey="$2"
cmd="./bin/rnode generateFaucetBondingDeploys --amount 2000000 --private-key $privKey --public-key $pubKey -s ed25519;
cp ./forward_$pubKey.rho /bonding/;
cp ./bond_$pubKey.rho /bonding/;"
_rnode_entry "$BOND_VOLUME" $cmd
}
# bond_deploy_forward $KELLY_HOST $VALIDATOR
# bond_deploy_forward rnode1 $VALIDATOR_1
# bond_deploy_forward boot $VALIDATOR_1
bond_deploy_forward () {
host="$1"
pubKey="$2"
_rnode "$BOND_VOLUME --network $(_rchain_network)" --grpc-host $host deploy --phlo-limit 10000000000 --phlo-price 1 /bonding/forward_$pubKey.rho
}
# bond_deploy_bond $KELLY_HOST $VALIDATOR
# bond_deploy_bond rnode1 $VALIDATOR_1
# bond_deploy_bond boot $VALIDATOR_1
bond_deploy_bond () {
host="$1"
pubKey="$2"
_rnode "$BOND_VOLUME --network $(_rchain_network)" --grpc-host $host deploy --phlo-limit 10000000000 --phlo-price 1 /bonding/bond_$pubKey.rho
}
# bond_quick $KELLY_HOST $VALIDATOR
# bond_quick boot $VALIDATOR_1
# bond_quick boot $VALIDATOR_2
# bond_quick rnode1 $VALIDATOR_2
bond_quick () {
service="$1"
pubKey="$2"
# Forward
bond_deploy_forward $service $pubKey
# Bond
bond_deploy_bond $service $pubKey
# Propose
echo "Deploy bonding contracts successful."
echo "If this is not your RNode you should probably skip propose."
read -r -p "Propose bonding? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
_rnode_grpc $service propose
fi
}
# bond_check_last_block $KELLY_HOST $VALIDATOR
# bond_check_last_block rnode1 $VALIDATOR_1
# bond_check_last_block rnode1 $VALIDATOR_2
bond_check_last_block () {
service="$1"
pubKey="$2"
# get last block hash
lastBlock=`$service show-blocks | grep blockHash | sed -r 's/blockHash: "([0-9a-f]+)"\r/\1/'`
# check bonding in last block
_rnode_grpc $service show-block $lastBlock | bond_check "$pubKey"
}
# rnode1 show-block 3c | bond_check $VALIDATOR_1
# rnode1 show-block 3c | bond_check $VALIDATOR_2
bond_check () {
pubKey="$1"
tupleSpace="echo -e \"$(cat -)\""
# Check "Bond successful!"
# 30ad95c25f3ce80a0057cba0ab3cd3a3c0fb069a1473fd26c28cb60c0da61b03_bondingOut\"}!((true, \"Bond successful!\")
echo $tupleSpace | awk /${pubKey}'_bondingOut[\\"}!\(\)]*true[\\", ]*Bond successful[!\\"\)]*/ { print "Bond successful!!!!!" }'
# Check phlogiston status
# (199999, \"ed25519Verify\", \"30ad95c25f3ce80a0057cba0ab3cd3a3c0fb069a1473fd26c28cb60c0da61b03\", 9)
echo $tupleSpace | awk 'match($0, /([[:digit:]]+), \\"ed25519Verify\\", \\"'"${pubKey}"'/, xs) { print "Phlo: " xs[1] }'
}
# GENERATE VALIDATOR KEY-PAIRS
# --------------------------------------------------------------------------------------
# Generate and print validator public/private key-pairs
generate_validator_keys () {
cmd="timeout 15s ./bin/rnode run -s --no-upnp --host localhost;
RED='\033[0;31m';
GREEN='\033[0;32m';
NC='\033[0m';
printKey () {
while read fn; do
echo -----------------------------------------------------------------------------;
echo -e \$GREEN'PUBLIC KEY: ' \$(echo \$fn | sed -e 's/.sk$//') \$NC;
echo -e \$RED'PRIVATE KEY:' \$(cat ~/.rnode/genesis/\$fn) \$NC;
done;
};
ls ~/.rnode/genesis | awk '!/^bonds.txt$/' | printKey;"
# run node and print generated key-pairs
_rnode_entry "" $cmd
}
# CLEAN
# --------------------------------------------------------------------------------------
clean_all () {
# Set owner of ./data folder to current user (Docker uses root)
sudo chown -R $USER: ./data
_rm () {
DIR="$1"
if [ -d $DIR ]; then
ls $DIR | awk -v dir="$DIR" '!/.pem$/ { print dir"/"$0 }' | xargs rm -rf
fi
}
docker-compose down
_rm $CWD/data/boot
_rm $CWD/data/rnode
_rm $CWD/data/rnode1
_rm $CWD/data/rnode2
}
# --------------------------------------------------------------------------------------
# HELPERS
start () {
services="$*"
docker-compose up -d $services
docker-compose logs -f $services
}
stop () {
services="$*"
docker-compose stop $services
docker-compose rm $services
}
bond_bootstrap () {
bondsFile="$CWD/data/boot/genesis/bonds.txt"
if [ ! -f $bondsFile ] || (! grep $VALIDATOR_BOOT $bondsFile); then
mkdir -p $CWD/data/boot/genesis
echo "$VALIDATOR_BOOT 1" >> $CWD/data/boot/genesis/bonds.txt
fi
}
# Creates initial .env file
_create_dot_env () {
envPath="$1"
host_ip=`ip addr show eth0 | awk 'match($0, /inet ([[:digit:]\.]+)/, a) {print a[1]}'`
if [ ! $host_ip ]; then
host_ip="127.0.0.1"
fi
tee $envPath <<EOF
# RNode configuration
# ---------------------------------------------------------------------------------------------------
# External IP address, used in rnode://.... address
HOST_IP=$host_ip
KELLY_HOST=52.119.8.64
RNODE_IMAGE=rchain/rnode:master
# RNode
# ---------------------------------------------------------------------------------------------------
BOOTSTRAP="rnode://ccbf2e88536bcfbd9d7bbcdb733418c1ea6d5e8d@boot?protocol=50400&discovery=50404"
VALIDATOR=23427b53971ae7fabbdf7e4797d96551fe65c27c21f4693bfd0bed3f421dea51
VALIDATOR_PRIVATE=aa2b78b2dfece918b49652e077f72210207b755853f2b9e3ae839ca6edbd36cd
# My network
# ---------------------------------------------------------------------------------------------------
MY_NET_IP=127.0.0.1
# Bootstrap
# ---------------------------------------------------------------------------------------------------
VALIDATOR_BOOT=0e81170cdf1d894691b045232c7289285b1d4c240efb05a54eec4cc5fc58b7a1
VALIDATOR_PRIVATE_BOOT=6092a0e433edc499c472a891b988388cb5365baf10107b9a9d8d6665cbfb6cc5
# RNode 1
# ---------------------------------------------------------------------------------------------------
BOOTSTRAP_1="rnode://961551792718e37ad77489d16356aee6fa416cb3@boot?protocol=50400&discovery=50404"
VALIDATOR_1=099c1b56ac1fad402591b967a5b1daa26389a3957e573b6db646b1b72768ed91
VALIDATOR_PRIVATE_1=a67cdeb79b32040d6d3241945f1f2b2c6b7049914c142770a385dfdb63ef5ed7
# RNode 2
# ---------------------------------------------------------------------------------------------------
BOOTSTRAP_2="rnode://961551792718e37ad77489d16356aee6fa416cb3@boot?protocol=50400&discovery=50404"
VALIDATOR_2=10e129b0ef2d7a31d7efd3cab734d822e1b8a0f6a8853ab49885b091ca014ed1
VALIDATOR_PRIVATE_2=72d678c964e87d7e70f5402cab3081f57939c52c0e779ea7c7260a3e68fd2ac0
EOF
}
if [ ! -f $CWD/.env ]; then
# Create initial .env from template
_create_dot_env $CWD/.env
fi
. $CWD/.env
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment