nimbus-eth2/beacon_chain/validator_keygen.nim

90 lines
3.0 KiB
Nim
Raw Normal View History

import
os, strutils,
chronicles, chronos, blscurve, nimcrypto, json_serialization, serialization,
2019-11-05 18:16:10 +00:00
web3, stint, eth/keys,
initial 0.9.0 spec sync (#509) * rename compute_epoch_of_slot(...) to compute_epoch_at_slot(...) * remove some unnecessary imports; remove some crosslink-related code and tests; complete renaming of compute_epoch_of_slot(...) to compute_epoch_at_slot(...) * rm more transfer-related code and tests; rm more unnecessary strutils imports * rm remaining unused imports * remove useless get_empty_per_epoch_cache(...)/compute_start_slot_of_epoch(...) calls * rename compute_start_slot_of_epoch(...) to compute_start_slot_at_epoch(...) * rename ACTIVATION_EXIT_DELAY to MAX_SEED_LOOKAHEAD * update domain types to 0.9.0 * mark AttesterSlashing, IndexedAttestation, AttestationDataAndCustodyBit, DepositData, BeaconBlockHeader, Fork, integer_squareroot(...), and process_voluntary_exit(...) as 0.9.0 * mark increase_balance(...), decrease_balance(...), get_block_root(...), CheckPoint, Deposit, PendingAttestation, HistoricalBatch, is_active_validator(...), and is_slashable_attestation_data(...) as 0.9.0 * mark compute_activation_exit_epoch(...), bls_verify(...), Validator, get_active_validator_indices(...), get_current_epoch(...), get_total_active_balance(...), and get_previous_epoch(...) as 0.9.0 * mark get_block_root_at_slot(...), ProposerSlashing, get_domain(...), VoluntaryExit, mainnet preset Gwei values, minimal preset max operations, process_block_header(...), and is_slashable_validator(...) as 0.9.0 * mark makeWithdrawalCredentials(...), get_validator_churn_limit(...), get_total_balance(...), is_valid_indexed_attestation(...), bls_aggregate_pubkeys(...), initial genesis value/constants, Attestation, get_randao_mix(...), mainnet preset max operations per block constants, minimal preset Gwei values and time parameters, process_eth1_data(...), get_shuffled_seq(...), compute_committee(...), and process_slots(...) as 0.9.0; partially update get_indexed_attestation(...) to 0.9.0 by removing crosslink refs and associated tests * mark initiate_validator_exit(...), process_registry_updates(...), BeaconBlock, Eth1Data, compute_domain(...), process_randao(...), process_attester_slashing(...), get_base_reward(...), and process_slot(...) as 0.9.0
2019-10-30 19:41:19 +00:00
spec/[datatypes, digest, crypto], conf, ssz, interop
2019-07-12 14:24:11 +00:00
contract(DepositContract):
2019-09-09 15:59:02 +00:00
proc deposit(pubkey: Bytes48, withdrawalCredentials: Bytes32, signature: Bytes96, deposit_data_root: FixedBytes[32])
2019-07-12 14:24:11 +00:00
proc writeTextFile(filename: string, contents: string) =
writeFile(filename, contents)
2019-10-17 13:18:58 +00:00
# echo "Wrote ", filename
proc writeFile(filename: string, value: auto) =
Json.saveFile(filename, value, pretty = true)
2019-10-17 13:18:58 +00:00
# echo "Wrote ", filename
2019-07-12 14:24:11 +00:00
proc ethToWei(eth: UInt256): UInt256 =
eth * 1000000000000000000.u256
proc generateDeposits*(totalValidators: int,
outputDir: string,
randomKeys: bool,
firstIdx = 0): seq[Deposit] =
info "Generating deposits", totalValidators, outputDir, randomKeys
for i in 0 ..< totalValidators:
let
v = validatorFileBaseName(firstIdx + i)
depositFn = outputDir / v & ".deposit.json"
privKeyFn = outputDir / v & ".privkey"
if existsFile(depositFn) and existsFile(privKeyFn):
try:
result.add Json.loadFile(depositFn, Deposit)
continue
2019-09-02 13:09:55 +00:00
except SerializationError as err:
debug "Rewriting unreadable deposit", err = err.formatMsg(depositFn)
discard
let
privKey = if randomKeys: ValidatorPrivKey.random
else: makeInteropPrivKey(i)
pubKey = privKey.pubKey()
let dp = makeDeposit(pubKey, privKey)
writeTextFile(privKeyFn, $privKey)
2019-07-12 14:24:11 +00:00
writeFile(depositFn, dp)
result.add(dp)
2019-07-12 14:24:11 +00:00
proc sendDeposits*(
deposits: seq[Deposit],
2019-11-05 18:16:10 +00:00
depositWeb3Url, depositContractAddress, privateKey: string) {.async.} =
var web3 = await newWeb3(depositWeb3Url)
2019-11-05 18:16:10 +00:00
if privateKey.len != 0:
web3.privateKey = initPrivateKey(privateKey)
else:
let accounts = await web3.provider.eth_accounts()
if accounts.len == 0:
error "No account offered by the web3 provider", web3url = depositWeb3Url
return
web3.defaultAccount = accounts[0]
let contractAddress = Address.fromHex(depositContractAddress)
for i, dp in deposits:
let depositContract = web3.contractSender(DepositContract, contractAddress)
2019-11-18 12:48:41 +00:00
discard await depositContract.deposit(
Bytes48(dp.data.pubKey.getBytes()),
Bytes32(dp.data.withdrawal_credentials.data),
2019-09-09 15:59:02 +00:00
Bytes96(dp.data.signature.getBytes()),
2019-11-05 18:16:10 +00:00
FixedBytes[32](hash_tree_root(dp.data).data)).send(value = 32.u256.ethToWei, gasPrice = 1)
when isMainModule:
import confutils
cli do (totalValidators: int = 125000,
outputDir: string = "validators",
randomKeys: bool = false,
depositWeb3Url: string = "",
depositContractAddress: string = ""):
let deposits = generateDeposits(totalValidators, outputDir, randomKeys)
if depositWeb3Url.len() > 0 and depositContractAddress.len() > 0:
2019-09-09 15:59:02 +00:00
echo "Sending deposits to eth1..."
2019-11-05 18:16:10 +00:00
waitFor sendDeposits(deposits, depositWeb3Url, depositContractAddress, "")
2019-09-09 15:59:02 +00:00
echo "Done"