From d85ae34245b459150a74fc66fb2a0626f1847e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C8=98tefan=20Talpalaru?= Date: Sun, 28 Jun 2020 03:51:00 +0200 Subject: [PATCH] shared_testnet: validator creation [skip ci] --- docker/shared_testnet/README.md | 21 +++++- docker/shared_testnet/validator_keys.sh | 29 ++++++++ scripts/connect_to_testnet.nims | 93 +++++++++++++++++-------- 3 files changed, 113 insertions(+), 30 deletions(-) create mode 100755 docker/shared_testnet/validator_keys.sh diff --git a/docker/shared_testnet/README.md b/docker/shared_testnet/README.md index c63118ce4..fb0369395 100644 --- a/docker/shared_testnet/README.md +++ b/docker/shared_testnet/README.md @@ -31,10 +31,27 @@ ansible nimbus-slaves[5:8] -i ansible/inventory/test -u YOUR_USER -o -m shell -a # build beacon_node in an external volume ansible nimbus-slaves[5:8] -i ansible/inventory/test -u YOUR_USER -o -m shell -a "echo; cd /docker/beacon-node-testnet2-1; docker-compose --compatibility run --rm beacon_node --build; echo '---'" | sed 's/\\n/\n/g' +``` -# TODO: create and copy validator keys +### create and copy validator keys -# start the containers +Back up "build/data/shared\_witti\_0", if you need to. It will be deleted. + +From the nim-beacon-chain repo: + +```bash +# If you have "ignorespace" or "ignoreboth" in HISTCONTROL in your ".bashrc", you can prevent +# the key from being stored in your command history by prefixing it with a space. +# See https://www.linuxjournal.com/content/using-bash-history-more-efficiently-histcontrol + + ./docker/shared_testnet/validator_keys.sh 0xYOUR_ETH1_PRIVATE_GOERLI_KEY +``` + +### start the containers + +From the "infra-nimbus" repo: + +```bash ansible nimbus-slaves[5:8] -i ansible/inventory/test -u YOUR_USER -o -m shell -a "echo; cd /docker/beacon-node-testnet2-1; docker-compose --compatibility up -d beacon_node; echo '---'" | sed 's/\\n/\n/g' ``` diff --git a/docker/shared_testnet/validator_keys.sh b/docker/shared_testnet/validator_keys.sh new file mode 100755 index 000000000..5f1637da1 --- /dev/null +++ b/docker/shared_testnet/validator_keys.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# This script creates validator keys and uploads them to remote servers, +# assuming your local username is the same as the remote one. + +set -e + +cd "$(dirname "${BASH_SOURCE[0]}")/../.." + +[[ -z "$1" ]] && { echo "Usage: $(basename $0) YOUR_ETH1_PRIVATE_GOERLI_KEY"; exit 1; } + +echo -ne "About to delete \"build/data/shared_witti_0\".\nMake a backup, if you need to, then press Enter. >" +read TMP +make clean-witti + +for N in $(seq 6 9); do + make SCRIPT_PARAMS="--becomeValidatorOnly --privateGoerliKey=$1" witti && \ + ssh node-0${N}.aws-eu-central-1a.nimbus.test.statusim.net "sudo rm -rf /docker/beacon-node-testnet2-1/data/nim-beacon-chain/build/data/shared_witti_0/secrets" && \ + ssh node-0${N}.aws-eu-central-1a.nimbus.test.statusim.net "sudo rm -rf /docker/beacon-node-testnet2-1/data/nim-beacon-chain/build/data/shared_witti_0/validators" && \ + rsync -a -zz --rsync-path="sudo rsync" build/data/shared_witti_0/{secrets,validators} node-0${N}.aws-eu-central-1a.nimbus.test.statusim.net:/docker/beacon-node-testnet2-1/data/nim-beacon-chain/build/data/shared_witti_0/ && \ + ssh node-0${N}.aws-eu-central-1a.nimbus.test.statusim.net "sudo chown -R dockremap:dockremap /docker/beacon-node-testnet2-1/data/nim-beacon-chain/build/data/shared_witti_0/secrets" && \ + ssh node-0${N}.aws-eu-central-1a.nimbus.test.statusim.net "sudo chown -R dockremap:dockremap /docker/beacon-node-testnet2-1/data/nim-beacon-chain/build/data/shared_witti_0/validators" + rm -rf build/data/shared_witti_0/{secrets,validators} + # if we're doing it too fast, we get {"code":-32000,"message":"replacement transaction underpriced"} + # or {"code":-32000,"message":"nonce too low"} + echo "Sleeping..." + sleep 120 +done + diff --git a/scripts/connect_to_testnet.nims b/scripts/connect_to_testnet.nims index e4b30deec..bd9bf4b07 100644 --- a/scripts/connect_to_testnet.nims +++ b/scripts/connect_to_testnet.nims @@ -45,13 +45,18 @@ proc makePrometheusConfig(nodeID, baseMetricsPort: int, dataDir: string) = proc buildNode(nimFlags, preset, beaconNodeBinary: string) = exec &"""nim c {nimFlags} -d:"const_preset={preset}" -o:"{beaconNodeBinary}" beacon_chain/beacon_node.nim""" -proc becomeValidator(validatorsDir, beaconNodeBinary, secretsDir, depositContractOpt: string) = +proc becomeValidator(validatorsDir, beaconNodeBinary, secretsDir, depositContractOpt, privateGoerliKey: string, + becomeValidatorOnly: bool) = mode = Silent - echo "\nPlease enter your Goerli Eth1 private key in hex form (e.g. 0x1a2...f3c) in order to become a validator (you'll need access to 32 GoETH)." - echo "Hit Enter to skip this." - # is there no other way to print without a trailing newline? - exec "printf '> '" - let privKey = readLineFromStdin() + var privKey = privateGoerliKey + + if privKey.len == 0: + echo "\nPlease enter your Goerli Eth1 private key in hex form (e.g. 0x1a2...f3c) in order to become a validator (you'll need access to 32 GoETH)." + echo "Hit Enter to skip this." + # is there no other way to print without a trailing newline? + exec "printf '> '" + privKey = readLineFromStdin() + if privKey.len > 0: mkDir validatorsDir mode = Verbose @@ -64,8 +69,11 @@ proc becomeValidator(validatorsDir, beaconNodeBinary, secretsDir, depositContrac {depositContractOpt} """, "\n", " ") mode = Silent - echo "\nDeposit sent, wait for confirmation then press enter to continue" - discard readLineFromStdin() + if becomeValidatorOnly: + echo "\nDeposit sent." + else: + echo "\nDeposit sent, wait for confirmation then press enter to continue" + discard readLineFromStdin() proc runNode(dataDir, beaconNodeBinary, bootstrapFileOpt, depositContractOpt, genesisFileOpt: string, basePort, nodeID, baseMetricsPort, baseRpcPort: int, printCmdOnly: bool) = @@ -75,33 +83,45 @@ proc runNode(dataDir, beaconNodeBinary, bootstrapFileOpt, depositContractOpt, ge logLevelOpt = &"""--log-level="{logLevel}" """ mode = Verbose - let cmd = replace(&"""{beaconNodeBinary} - --data-dir="{dataDir}" - --dump - --web3-url={web3Url} - --tcp-port=""" & $(basePort + nodeID) & &""" - --udp-port=""" & $(basePort + nodeID) & &""" - --metrics - --metrics-port=""" & $(baseMetricsPort + nodeID) & &""" - --rpc - --rpc-port=""" & $(baseRpcPort + nodeID) & &""" - {bootstrapFileOpt} - {logLevelOpt} - {depositContractOpt} - {genesisFileOpt} """, "\n", " ") + var cmd: string if printCmdOnly: + # When you reinvent getopt() and you forget to support repeating the same + # option to overwrite the old value... + cmd = replace(&"""{beaconNodeBinary} + --data-dir="{dataDir}" + --web3-url={web3Url} + {bootstrapFileOpt} + {depositContractOpt} + {genesisFileOpt} """, "\n", " ") echo &"cd {dataDir}; exec {cmd}" else: cd dataDir + cmd = replace(&"""{beaconNodeBinary} + --data-dir="{dataDir}" + --dump + --web3-url={web3Url} + --tcp-port=""" & $(basePort + nodeID) & &""" + --udp-port=""" & $(basePort + nodeID) & &""" + --metrics + --metrics-port=""" & $(baseMetricsPort + nodeID) & &""" + --rpc + --rpc-port=""" & $(baseRpcPort + nodeID) & &""" + {bootstrapFileOpt} + {logLevelOpt} + {depositContractOpt} + {genesisFileOpt} """, "\n", " ") execIgnoringExitCode cmd cli do (skipGoerliKey {. desc: "Don't prompt for an Eth1 Goerli key to become a validator" .}: bool, + privateGoerliKey {. + desc: "Use this private Eth1 Goerli key to become a validator (careful with this option, the private key will end up in your shell's command history)" .} = "", + specVersion {. desc: "Spec version" - name: "spec" .}: string = "v0.11.3", + name: "spec" .} = "v0.11.3", constPreset {. desc: "The Ethereum 2.0 const preset of the network (optional)" @@ -125,6 +145,9 @@ cli do (skipGoerliKey {. buildOnly {. desc: "Just the build, please." .} = false, + becomeValidatorOnly {. + desc: "Just become a validator." .} = false, + runOnly {. desc: "Just run it." .} = false, @@ -141,13 +164,27 @@ cli do (skipGoerliKey {. buildDir = rootDir / "build" allTestnetsDir = buildDir / testnetsRepo - if not runOnly: + if not (runOnly or becomeValidatorOnly): updateTestnetsRepo(allTestnetsDir, buildDir) var depositContractOpt = "" bootstrapFileOpt = "" genesisFileOpt = "" + doBuild, doBecomeValidator, doRun = true + + # step-skipping logic + if skipGoerliKey: + doBecomeValidator = false + if buildOnly: + doBecomeValidator = false + doRun = false + if becomeValidatorOnly: + doBuild = false + doRun = false + if runOnly: + doBuild = false + doBecomeValidator = false let testnetDir = allTestnetsDir / team / testnet @@ -221,14 +258,14 @@ cli do (skipGoerliKey {. cd rootDir mkDir dataDir - if not runOnly: + if doBuild: makePrometheusConfig(nodeID, baseMetricsPort, dataDir) buildNode(nimFlags, preset, beaconNodeBinary) - if not skipGoerliKey and depositContractOpt.len > 0 and not system.dirExists(validatorsDir): - becomeValidator(validatorsDir, beaconNodeBinary, secretsDir, depositContractOpt) + if doBecomeValidator and depositContractOpt.len > 0 and not system.dirExists(validatorsDir): + becomeValidator(validatorsDir, beaconNodeBinary, secretsDir, depositContractOpt, privateGoerliKey, becomeValidatorOnly) - if not buildOnly: + if doRun: runNode(dataDir, beaconNodeBinary, bootstrapFileOpt, depositContractOpt, genesisFileOpt, basePort, nodeID, baseMetricsPort, baseRpcPort, printCmdOnly)