From f4c19e303af8a142a374582506b7208844683654 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 27 Jul 2020 22:26:30 +0300 Subject: [PATCH] Non-interactive generation of keystores in the local sim --- Makefile | 2 +- beacon_chain/deposit_contract.nim | 68 +++++++++++++++++++++++++++---- scripts/launch_local_testnet.sh | 21 +++++----- tests/simulation/start.sh | 19 ++++++--- 4 files changed, 85 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index 601592fe8..623c3c58f 100644 --- a/Makefile +++ b/Makefile @@ -182,7 +182,7 @@ altona-deposit: | beacon_node deposit_contract # TODO # The --min-delay is needed only until we fix the invalid # nonce generation on multiple transactions in web3 - build/deposit_contract makeDeposits \ + build/deposit_contract sendDeposits \ --web3-url=$(GOERLI_WEB3_URL) \ --deposit-contract=$$(cat vendor/eth2-testnets/shared/altona/deposit_contract.txt) \ --deposits-file=nbc-altona-deposits.json \ diff --git a/beacon_chain/deposit_contract.nim b/beacon_chain/deposit_contract.nim index 8be4f1438..16be89086 100644 --- a/beacon_chain/deposit_contract.nim +++ b/beacon_chain/deposit_contract.nim @@ -1,7 +1,8 @@ import - os, strutils, options, json, terminal, random, - chronos, chronicles, confutils, web3, web3/confutils_defs, stint, eth/keys, - spec/[datatypes, crypto], ssz/merkleization, keystore_management + os, sequtils, strutils, options, json, terminal, random, + chronos, chronicles, confutils, stint, json_serialization, + web3, web3/confutils_defs, eth/keys, + spec/[datatypes, crypto, presets], ssz/merkleization, keystore_management # Compiled version of /scripts/depositContract.v.py in this repo # The contract was compiled in Remix (https://remix.ethereum.org/) with vyper (remote) compiler. @@ -14,10 +15,12 @@ type deploy drain sendEth - makeDeposits + generateSimulationDeposits + sendDeposits CliConfig = object web3Url* {. + defaultValue: "", desc: "URL of the Web3 server to observe Eth1" name: "web3-url" }: string @@ -44,7 +47,24 @@ type toAddress {.name: "to".}: Eth1Address valueEth {.name: "eth".}: string - of makeDeposits: + of generateSimulationDeposits: + simulationDepositsCount {. + desc: "The number of validator keystores to generate" + name: "count" }: Natural + + outValidatorsDir {. + desc: "A directory to store the generated validator keystores" + name: "out-validators-dir" }: OutDir + + outSecretsDir {. + desc: "A directory to store the generated keystore password files" + name: "out-secrets-dir" }: OutDir + + outDepositsFile {. + desc: "A LaunchPad deposits file to write" + name: "out-deposits-file" }: OutFile + + of sendDeposits: depositsFile {. desc: "A LaunchPad deposits file" name: "deposits-file" }: InputFile @@ -135,9 +155,37 @@ proc sendDeposits*(deposits: seq[LaunchPadDeposit], proc main() {.async.} = var cfg = CliConfig.load() + let rng = keys.newRng() + + if cfg.cmd == StartUpCommand.generateSimulationDeposits: + let + walletData = WalletDataForDeposits(mnemonic: generateMnemonic(rng[])) + runtimePreset = defaultRuntimePreset() + + createDir(string cfg.outValidatorsDir) + createDir(string cfg.outSecretsDir) + + let deposits = generateDeposits( + runtimePreset, + rng[], + walletData, + cfg.simulationDepositsCount, + string cfg.outValidatorsDir, + string cfg.outSecretsDir) + + if deposits.isErr: + fatal "Failed to generate deposits", err = deposits.error + quit 1 + + let launchPadDeposits = + mapIt(deposits.value, LaunchPadDeposit.init(runtimePreset, it)) + + Json.saveFile(string cfg.outDepositsFile, launchPadDeposits) + info "Deposit data written", filename = cfg.outDepositsFile + quit 0 var deposits: seq[LaunchPadDeposit] - if cfg.cmd == makeDeposits: + if cfg.cmd == StartUpCommand.sendDeposits: deposits = Json.loadFile(string cfg.depositsFile, seq[LaunchPadDeposit]) if cfg.askForKey: @@ -145,7 +193,7 @@ proc main() {.async.} = privateKey: TaintedString reasonForKey = "" - if cfg.cmd == makeDeposits: + if cfg.cmd == StartUpCommand.sendDeposits: let depositsWord = if deposits.len > 1: "deposits" else: "deposit" totalEthNeeded = 32 * deposits.len @@ -182,7 +230,7 @@ proc main() {.async.} = of StartUpCommand.sendEth: echo await sendEth(web3, cfg.toAddress, cfg.valueEth.parseInt) - of StartUpCommand.makeDeposits: + of StartUpCommand.sendDeposits: var delayGenerator: DelayGenerator if cfg.maxDelay > 0.0: delayGenerator = proc (): chronos.Duration {.gcsafe.} = @@ -195,4 +243,8 @@ proc main() {.async.} = await sendDeposits(deposits, cfg.web3Url, cfg.privateKey, cfg.depositContractAddress, delayGenerator) + of StartUpCommand.generateSimulationDeposits: + # This is handled above before the case statement + discard + when isMainModule: waitFor main() diff --git a/scripts/launch_local_testnet.sh b/scripts/launch_local_testnet.sh index 99f3ebe6e..d2a40a194 100755 --- a/scripts/launch_local_testnet.sh +++ b/scripts/launch_local_testnet.sh @@ -123,8 +123,8 @@ rm -rf "${DATA_DIR}" DEPOSITS_FILE="${DATA_DIR}/deposits.json" -DEPOSITS_DIR="${DATA_DIR}/deposits_dir" -mkdir -p "${DEPOSITS_DIR}" +VALIDATORS_DIR="${DATA_DIR}/validators" +mkdir -p "${VALIDATORS_DIR}" SECRETS_DIR="${DATA_DIR}/secrets" mkdir -p "${SECRETS_DIR}" @@ -154,10 +154,11 @@ DEPOSIT_CONTRACT_ADDRESS="0x0000000000000000000000000000000000000000" DEPOSIT_CONTRACT_BLOCK="0x0000000000000000000000000000000000000000000000000000000000000000" NETWORK_METADATA_FILE="${DATA_DIR}/network.json" -./build/beacon_node deposits create \ +make deposit_contract + +./build/deposit_contract generateSimulationDeposits \ --count=${TOTAL_VALIDATORS} \ - --non-interactive \ - --out-deposits-dir="${DEPOSITS_DIR}" \ + --out-validators-dir="${VALIDATORS_DIR}" \ --out-secrets-dir="${SECRETS_DIR}" \ --out-deposits-file="${DEPOSITS_FILE}" @@ -167,7 +168,7 @@ if [[ $USE_GANACHE == "0" ]]; then ./build/beacon_node createTestnet \ --data-dir="${DATA_DIR}/node0" \ - --validators-dir="${DEPOSITS_DIR}" \ + --deposits-file="${DEPOSITS_FILE}" \ --total-validators=${TOTAL_VALIDATORS} \ --last-user-validator=${USER_VALIDATORS} \ --output-genesis="${NETWORK_DIR}/genesis.ssz" \ @@ -178,8 +179,6 @@ if [[ $USE_GANACHE == "0" ]]; then STATE_SNAPSHOT_ARG="--state-snapshot=${NETWORK_DIR}/genesis.ssz" else - make deposit_contract - echo "Launching ganache" ganache-cli --blockTime 17 --gasLimit 100000000 -e 100000 --verbose > "${DATA_DIR}/log_ganache.txt" 2>&1 & PIDS="${PIDS},$!" @@ -200,7 +199,7 @@ else BOOTSTRAP_TIMEOUT=$(( MAX_DELAY * TOTAL_VALIDATORS )) - ./build/deposit_contract makeDeposits \ + ./build/deposit_contract sendDeposits \ --deposits-file="${DEPOSITS_FILE}" \ --min-delay=$MIN_DELAY --max-delay=$MAX_DELAY \ $WEB3_ARG \ @@ -279,8 +278,8 @@ for NUM_NODE in $(seq 0 $(( NUM_NODES - 1 ))); do mkdir -p "${NODE_DATA_DIR}/secrets" if [[ $NUM_NODE -lt $NODES_WITH_VALIDATORS ]]; then - for VALIDATOR in $(ls ${DEPOSITS_DIR} | tail -n +$(( $USER_VALIDATORS + ($VALIDATORS_PER_NODE * $NUM_NODE) + 1 )) | head -n $VALIDATORS_PER_NODE); do - cp -ar "${DEPOSITS_DIR}/$VALIDATOR" "${NODE_DATA_DIR}/validators/" + for VALIDATOR in $(ls ${VALIDATORS_DIR} | tail -n +$(( $USER_VALIDATORS + ($VALIDATORS_PER_NODE * $NUM_NODE) + 1 )) | head -n $VALIDATORS_PER_NODE); do + cp -ar "${VALIDATORS_DIR}/$VALIDATOR" "${NODE_DATA_DIR}/validators/" cp -a "${SECRETS_DIR}/${VALIDATOR}" "${NODE_DATA_DIR}/secrets/" done fi diff --git a/tests/simulation/start.sh b/tests/simulation/start.sh index 13fe3280c..94b3c2dc4 100755 --- a/tests/simulation/start.sh +++ b/tests/simulation/start.sh @@ -67,6 +67,14 @@ else MAKE="make" fi +make_once () { + target_flag_var="$1_name" + if [[ -z "${!target_flag_var}" ]]; then + export $target_flag_var=1 + $MAKE $1 + fi +} + mkdir -p "${METRICS_DIR}" ./scripts/make_prometheus_config.sh \ --nodes ${TOTAL_NODES} \ @@ -109,13 +117,14 @@ if [[ -f "$DEPOSITS_FILE" ]]; then fi if [[ $EXISTING_VALIDATORS -ne $NUM_VALIDATORS ]]; then + make_once deposit_contract + rm -rf "$VALIDATORS_DIR" rm -rf "$SECRETS_DIR" - $BEACON_NODE_BIN deposits create \ + build/deposit_contract generateSimulationDeposits \ --count="${NUM_VALIDATORS}" \ - --new-wallet-file="${SIMULATION_DIR}/wallet.json" \ - --out-deposits-dir="$VALIDATORS_DIR" \ + --out-validators-dir="$VALIDATORS_DIR" \ --out-secrets-dir="$SECRETS_DIR" \ --out-deposits-file="$DEPOSITS_FILE" @@ -165,7 +174,7 @@ DEPOSIT_CONTRACT_ADDRESS="0x0000000000000000000000000000000000000000" DEPOSIT_CONTRACT_BLOCK="0x0000000000000000000000000000000000000000000000000000000000000000" if [ "$USE_GANACHE" != "no" ]; then - make deposit_contract + make_once deposit_contract echo Deploying the validator deposit contract... DEPLOY_CMD_OUTPUT=$($DEPOSIT_CONTRACT_BIN deploy $WEB3_ARG) @@ -177,7 +186,7 @@ if [ "$USE_GANACHE" != "no" ]; then echo Contract deployed at $DEPOSIT_CONTRACT_ADDRESS:$DEPOSIT_CONTRACT_BLOCK if [[ "$WAIT_GENESIS" == "yes" ]]; then - run_cmd "(deposit maker)" "$DEPOSIT_CONTRACT_BIN makeDeposits \ + run_cmd "(deposit maker)" "$DEPOSIT_CONTRACT_BIN sendDeposits \ --deposits-file='$DEPOSITS_FILE' \ --min-delay=0 --max-delay=1 \ $WEB3_ARG \