mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-09 05:52:45 +00:00
Automate the creation of the network metadata files
With these changes, running a simulation is very close to running an actual testnet. Some checks have been added in the client to make sure you are not connecting to an incompatible network (e.g. a network running with a different number of shards).
This commit is contained in:
parent
8bab6fd51f
commit
6a35d3584d
@ -15,7 +15,7 @@ const
|
|||||||
dataDirValidators = "validators"
|
dataDirValidators = "validators"
|
||||||
networkMetadataFile = "network.json"
|
networkMetadataFile = "network.json"
|
||||||
genesisFile = "genesis.json"
|
genesisFile = "genesis.json"
|
||||||
testnetsBaseUrl = "http://node-01.do-ams3.nimbus.misc.statusim.net:8000/nimbus_testnets"
|
testnetsBaseUrl = "https://serenity-testnets.status.im"
|
||||||
|
|
||||||
# #################################################
|
# #################################################
|
||||||
# Careful handling of beacon_node <-> sync_protocol
|
# Careful handling of beacon_node <-> sync_protocol
|
||||||
@ -46,28 +46,25 @@ proc downloadFile(url: string): Future[string] {.async.} =
|
|||||||
raise newException(IOError, "Failed to download URL: " & url)
|
raise newException(IOError, "Failed to download URL: " & url)
|
||||||
return fileContents
|
return fileContents
|
||||||
|
|
||||||
proc doUpdateTestnet(conf: BeaconNodeConf) {.async.} =
|
proc updateTestnetMetadata(conf: BeaconNodeConf): Future[NetworkMetadata] {.async.} =
|
||||||
let latestMetadata = await downloadFile(testnetsBaseUrl // $conf.network // networkMetadataFile)
|
let latestMetadata = await downloadFile(testnetsBaseUrl // $conf.network // networkMetadataFile)
|
||||||
|
|
||||||
let localMetadataFile = conf.dataDir / networkMetadataFile
|
let localMetadataFile = conf.dataDir / networkMetadataFile
|
||||||
if fileExists(localMetadataFile) and readFile(localMetadataFile).string == latestMetadata:
|
if fileExists(localMetadataFile) and readFile(localMetadataFile).string == latestMetadata:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
result = Json.decode(latestMetadata, NetworkMetadata)
|
||||||
|
|
||||||
|
info "New testnet genesis data received. Starting with a fresh database."
|
||||||
removeDir conf.databaseDir
|
removeDir conf.databaseDir
|
||||||
writeFile localMetadataFile, latestMetadata
|
writeFile localMetadataFile, latestMetadata
|
||||||
|
|
||||||
let newGenesis = await downloadFile(testnetsBaseUrl // $conf.network // genesisFile)
|
let newGenesis = await downloadFile(testnetsBaseUrl // $conf.network // genesisFile)
|
||||||
writeFile conf.dataDir / genesisFile, newGenesis
|
writeFile conf.dataDir / genesisFile, newGenesis
|
||||||
|
|
||||||
info "New testnet genesis data received. Starting with a fresh database."
|
|
||||||
|
|
||||||
proc loadTestnetMetadata(conf: BeaconNodeConf): TestnetMetadata =
|
|
||||||
Json.loadFile(conf.dataDir / networkMetadataFile, TestnetMetadata)
|
|
||||||
|
|
||||||
proc obtainTestnetKey(conf: BeaconNodeConf): Future[ValidatorPrivKey] {.async.} =
|
proc obtainTestnetKey(conf: BeaconNodeConf): Future[ValidatorPrivKey] {.async.} =
|
||||||
await doUpdateTestnet(conf)
|
|
||||||
let
|
let
|
||||||
metadata = loadTestnetMetadata(conf)
|
metadata = await updateTestnetMetadata(conf)
|
||||||
privKeyName = validatorFileBaseName(rand(metadata.userValidatorsRange)) & ".privkey"
|
privKeyName = validatorFileBaseName(rand(metadata.userValidatorsRange)) & ".privkey"
|
||||||
privKeyContent = await downloadFile(testnetsBaseUrl // $conf.network // privKeyName)
|
privKeyContent = await downloadFile(testnetsBaseUrl // $conf.network // privKeyName)
|
||||||
|
|
||||||
@ -81,8 +78,34 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
|
|||||||
new result
|
new result
|
||||||
result.config = conf
|
result.config = conf
|
||||||
|
|
||||||
if conf.network in {testnet0, testnet1}:
|
template fail(args: varargs[untyped]) =
|
||||||
await doUpdateTestnet(conf)
|
stderr.write args, "\n"
|
||||||
|
quit 1
|
||||||
|
|
||||||
|
case conf.network
|
||||||
|
of "mainnet":
|
||||||
|
fail "The Serenity mainnet hasn't been launched yet"
|
||||||
|
of "testnet0", "testnet1":
|
||||||
|
result.networkMetadata = await updateTestnetMetadata(conf)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
result.networkMetadata = Json.loadFile(conf.network, NetworkMetadata)
|
||||||
|
except:
|
||||||
|
fail "Failed to load network metadata: ", getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
var metadataErrorMsg = ""
|
||||||
|
|
||||||
|
template checkCompatibility(metadataField, LOCAL_CONSTANT) =
|
||||||
|
let metadataValue = metadataField
|
||||||
|
if metadataValue != LOCAL_CONSTANT:
|
||||||
|
metadataErrorMsg.add " -d:" & astToStr(LOCAL_CONSTANT) & "=" & $metadataValue
|
||||||
|
|
||||||
|
checkCompatibility result.networkMetadata.numShards , SHARD_COUNT
|
||||||
|
checkCompatibility result.networkMetadata.slotDuration , SECONDS_PER_SLOT
|
||||||
|
checkCompatibility result.networkMetadata.slotsPerEpoch , SLOTS_PER_EPOCH
|
||||||
|
|
||||||
|
if metadataErrorMsg.len > 0:
|
||||||
|
fail "To connect to the ", conf.network, " network, please compile with ", metadataErrorMsg
|
||||||
|
|
||||||
result.attachedValidators = ValidatorPool.init
|
result.attachedValidators = ValidatorPool.init
|
||||||
init result.mainchainMonitor, "", Port(0) # TODO: specify geth address and port
|
init result.mainchainMonitor, "", Port(0) # TODO: specify geth address and port
|
||||||
@ -126,10 +149,7 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
|
|||||||
result.network = await createEth2Node(conf)
|
result.network = await createEth2Node(conf)
|
||||||
|
|
||||||
let sync = result.network.protocolState(BeaconSync)
|
let sync = result.network.protocolState(BeaconSync)
|
||||||
sync.networkId = case conf.network
|
sync.networkId = result.networkMetadata.networkId
|
||||||
of mainnet: 1.uint64
|
|
||||||
of ephemeralNetwork: 1000.uint64
|
|
||||||
of testnet0, testnet1: loadTestnetMetadata(conf).networkId
|
|
||||||
sync.node = result
|
sync.node = result
|
||||||
sync.db = result.db
|
sync.db = result.db
|
||||||
|
|
||||||
@ -141,20 +161,16 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
|
|||||||
result.network.saveConnectionAddressFile(addressFile)
|
result.network.saveConnectionAddressFile(addressFile)
|
||||||
|
|
||||||
proc connectToNetwork(node: BeaconNode) {.async.} =
|
proc connectToNetwork(node: BeaconNode) {.async.} =
|
||||||
var bootstrapNodes = newSeq[BootstrapAddr]()
|
var bootstrapNodes = node.networkMetadata.bootstrapNodes
|
||||||
|
|
||||||
for node in node.config.bootstrapNodes:
|
for bootNode in node.config.bootstrapNodes:
|
||||||
bootstrapNodes.add BootstrapAddr.init(node)
|
bootstrapNodes.add BootstrapAddr.init(bootNode)
|
||||||
|
|
||||||
let bootstrapFile = string node.config.bootstrapNodesFile
|
let bootstrapFile = string node.config.bootstrapNodesFile
|
||||||
if bootstrapFile.len > 0:
|
if bootstrapFile.len > 0:
|
||||||
for ln in lines(bootstrapFile):
|
for ln in lines(bootstrapFile):
|
||||||
bootstrapNodes.add BootstrapAddr.init(string ln)
|
bootstrapNodes.add BootstrapAddr.init(string ln)
|
||||||
|
|
||||||
if node.config.network in {testnet0, testnet1}:
|
|
||||||
let metadata = loadTestnetMetadata(node.config)
|
|
||||||
bootstrapNodes.add metadata.bootstrapNodes
|
|
||||||
|
|
||||||
if bootstrapNodes.len > 0:
|
if bootstrapNodes.len > 0:
|
||||||
info "Connecting to bootstrap nodes", bootstrapNodes
|
info "Connecting to bootstrap nodes", bootstrapNodes
|
||||||
else:
|
else:
|
||||||
@ -665,11 +681,40 @@ when isMainModule:
|
|||||||
setLogLevel(config.logLevel)
|
setLogLevel(config.logLevel)
|
||||||
|
|
||||||
case config.cmd
|
case config.cmd
|
||||||
of createChain:
|
of createTestnet:
|
||||||
createStateSnapshot(
|
var deposits: seq[Deposit]
|
||||||
config.validatorsDir.string, config.numValidators, config.firstValidator,
|
for i in config.firstValidator.int ..< config.numValidators.int:
|
||||||
config.genesisOffset, config.outputStateFile.string)
|
let depositFile = config.validatorsDir /
|
||||||
quit 0
|
validatorFileBaseName(i) & ".deposit.json"
|
||||||
|
deposits.add Json.loadFile(depositFile, Deposit)
|
||||||
|
|
||||||
|
let initialState = get_genesis_beacon_state(
|
||||||
|
deposits,
|
||||||
|
uint64(int(fastEpochTime() div 1000) + config.genesisOffset),
|
||||||
|
Eth1Data(), {})
|
||||||
|
|
||||||
|
Json.saveFile(config.outputGenesis.string, initialState, pretty = true)
|
||||||
|
echo "Wrote ", config.outputGenesis.string
|
||||||
|
|
||||||
|
var
|
||||||
|
bootstrapAddress = getPersistenBootstrapAddr(
|
||||||
|
config, parseIpAddress(config.bootstrapAddress), Port config.bootstrapPort)
|
||||||
|
|
||||||
|
testnetMetadata = NetworkMetadata(
|
||||||
|
networkId: config.networkId,
|
||||||
|
genesisRoot: hash_tree_root_final(initialState),
|
||||||
|
bootstrapNodes: @[bootstrapAddress],
|
||||||
|
numShards: SHARD_COUNT,
|
||||||
|
slotDuration: SECONDS_PER_SLOT,
|
||||||
|
slotsPerEpoch: SLOTS_PER_EPOCH,
|
||||||
|
totalValidators: config.numValidators,
|
||||||
|
firstUserValidator: config.firstUserValidator)
|
||||||
|
|
||||||
|
Json.saveFile(config.outputNetwork.string, testnetMetadata, pretty = true)
|
||||||
|
echo "Wrote ", config.outputNetwork.string
|
||||||
|
|
||||||
|
of updateTestnet:
|
||||||
|
discard waitFor updateTestnetMetadata(config)
|
||||||
|
|
||||||
of importValidator:
|
of importValidator:
|
||||||
template reportFailureFor(keyExpr) =
|
template reportFailureFor(keyExpr) =
|
||||||
@ -693,9 +738,11 @@ when isMainModule:
|
|||||||
reportFailureFor config.keyFile.get.string
|
reportFailureFor config.keyFile.get.string
|
||||||
|
|
||||||
if downloadKey:
|
if downloadKey:
|
||||||
if config.network in {testnet0, testnet1}:
|
if config.network in ["testnet0", "testnet1"]:
|
||||||
try:
|
try:
|
||||||
(waitFor obtainTestnetKey(config)).saveValidatorKey(config)
|
let key = waitFor obtainTestnetKey(config)
|
||||||
|
saveValidatorKey(key, config)
|
||||||
|
info "Imported validator", pubkey = key.pubKey
|
||||||
except:
|
except:
|
||||||
error "Failed to download key", err = getCurrentExceptionMsg()
|
error "Failed to download key", err = getCurrentExceptionMsg()
|
||||||
quit 1
|
quit 1
|
||||||
@ -703,9 +750,6 @@ when isMainModule:
|
|||||||
echo "Validator keys can be downloaded only for testnets"
|
echo "Validator keys can be downloaded only for testnets"
|
||||||
quit 1
|
quit 1
|
||||||
|
|
||||||
of updateTestnet:
|
|
||||||
waitFor doUpdateTestnet(config)
|
|
||||||
|
|
||||||
of noCommand:
|
of noCommand:
|
||||||
waitFor synchronizeClock()
|
waitFor synchronizeClock()
|
||||||
createPidFile(config.dataDir.string / "beacon_node.pid")
|
createPidFile(config.dataDir.string / "beacon_node.pid")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import # Beacon Node
|
import # Beacon Node
|
||||||
eth/[p2p, keys],
|
eth/[p2p, keys],
|
||||||
spec/digest,
|
spec/digest,
|
||||||
beacon_chain_db, conf, mainchain_monitor
|
beacon_chain_db, conf, mainchain_monitor, eth2_network
|
||||||
|
|
||||||
import # Attestation Pool
|
import # Attestation Pool
|
||||||
spec/[datatypes, crypto, digest],
|
spec/[datatypes, crypto, digest],
|
||||||
@ -25,6 +25,7 @@ type
|
|||||||
# #############################################
|
# #############################################
|
||||||
BeaconNode* = ref object
|
BeaconNode* = ref object
|
||||||
network*: EthereumNode
|
network*: EthereumNode
|
||||||
|
networkMetadata*: NetworkMetadata
|
||||||
db*: BeaconChainDB
|
db*: BeaconChainDB
|
||||||
config*: BeaconNodeConf
|
config*: BeaconNodeConf
|
||||||
keys*: KeyPair
|
keys*: KeyPair
|
||||||
@ -230,3 +231,17 @@ type
|
|||||||
|
|
||||||
ValidatorPool* = object
|
ValidatorPool* = object
|
||||||
validators*: Table[ValidatorPubKey, AttachedValidator]
|
validators*: Table[ValidatorPubKey, AttachedValidator]
|
||||||
|
|
||||||
|
NetworkMetadata* = object
|
||||||
|
networkId*: uint64
|
||||||
|
genesisRoot*: Eth2Digest
|
||||||
|
bootstrapNodes*: seq[BootstrapAddr]
|
||||||
|
numShards*: uint64
|
||||||
|
slotDuration*: uint64
|
||||||
|
slotsPerEpoch*: uint64
|
||||||
|
totalValidators*: uint64
|
||||||
|
firstUserValidator*: uint64
|
||||||
|
|
||||||
|
proc userValidatorsRange*(d: NetworkMetadata): HSlice[int, int] =
|
||||||
|
d.firstUserValidator.int ..< d.totalValidators.int
|
||||||
|
|
||||||
|
@ -11,37 +11,32 @@ type
|
|||||||
|
|
||||||
StartUpCommand* = enum
|
StartUpCommand* = enum
|
||||||
noCommand
|
noCommand
|
||||||
createChain
|
createTestnet
|
||||||
importValidator
|
importValidator
|
||||||
updateTestnet
|
updateTestnet
|
||||||
|
|
||||||
Network* = enum
|
|
||||||
ephemeralNetwork
|
|
||||||
testnet0
|
|
||||||
testnet1
|
|
||||||
mainnet
|
|
||||||
|
|
||||||
BeaconNodeConf* = object
|
BeaconNodeConf* = object
|
||||||
logLevel* {.
|
logLevel* {.
|
||||||
desc: "Sets the log level",
|
desc: "Sets the log level",
|
||||||
defaultValue: enabledLogLevel.}: LogLevel
|
defaultValue: enabledLogLevel.}: LogLevel
|
||||||
|
|
||||||
network* {.
|
network* {.
|
||||||
desc: "The network Nimbus should connect to"
|
desc: "The network Nimbus should connect to. " &
|
||||||
|
"Possible values: testnet0, testnet1, mainnet, custom-network.json"
|
||||||
longform: "network"
|
longform: "network"
|
||||||
shortform: "n"
|
shortform: "n"
|
||||||
defaultValue: testnet0.}: Network
|
defaultValue: "testnet0".}: string
|
||||||
|
|
||||||
|
dataDir* {.
|
||||||
|
desc: "The directory where nimbus will store all blockchain data."
|
||||||
|
shortform: "d"
|
||||||
|
defaultValue: config.defaultDataDir().}: OutDir
|
||||||
|
|
||||||
case cmd* {.
|
case cmd* {.
|
||||||
command
|
command
|
||||||
defaultValue: noCommand.}: StartUpCommand
|
defaultValue: noCommand.}: StartUpCommand
|
||||||
|
|
||||||
of noCommand:
|
of noCommand:
|
||||||
dataDir* {.
|
|
||||||
desc: "The directory where nimbus will store all blockchain data."
|
|
||||||
shortform: "d"
|
|
||||||
defaultValue: config.defaultDataDir().}: OutDir
|
|
||||||
|
|
||||||
bootstrapNodes* {.
|
bootstrapNodes* {.
|
||||||
desc: "Specifies one or more bootstrap nodes to use when connecting to the network."
|
desc: "Specifies one or more bootstrap nodes to use when connecting to the network."
|
||||||
longform: "bootstrapNode"
|
longform: "bootstrapNode"
|
||||||
@ -74,27 +69,43 @@ type
|
|||||||
desc: "Json file specifying a recent state snapshot"
|
desc: "Json file specifying a recent state snapshot"
|
||||||
shortform: "s".}: Option[TypedInputFile[BeaconState, Json, "json"]]
|
shortform: "s".}: Option[TypedInputFile[BeaconState, Json, "json"]]
|
||||||
|
|
||||||
of createChain:
|
of createTestnet:
|
||||||
|
networkId* {.
|
||||||
|
desc: "An unique numeric identifier for the network".}: uint64
|
||||||
|
|
||||||
validatorsDir* {.
|
validatorsDir* {.
|
||||||
desc: "Directory containing validator descriptors named vXXXXXXX.deposit.json"
|
desc: "Directory containing validator descriptors named vXXXXXXX.deposit.json"
|
||||||
shortform: "d".}: InputDir
|
shortform: "d".}: InputDir
|
||||||
|
|
||||||
numValidators* {.
|
numValidators* {.
|
||||||
desc: "The number of validators in the newly created chain".}: int
|
desc: "The number of validators in the newly created chain".}: uint64
|
||||||
|
|
||||||
firstValidator* {.
|
firstValidator* {.
|
||||||
desc: "index of first validator to add to validator list"
|
desc: "Index of first validator to add to validator list"
|
||||||
defaultValue: 0.}: int
|
defaultValue: 0 .}: uint64
|
||||||
|
|
||||||
|
firstUserValidator* {.
|
||||||
|
desc: "The first validator index that will free for taking from a testnet participant"
|
||||||
|
defaultValue: 0 .}: uint64
|
||||||
|
|
||||||
|
bootstrapAddress* {.
|
||||||
|
desc: "The public IP address that will be advertised as a bootstrap node for the testnet"
|
||||||
|
defaultValue: "127.0.0.1".}: string
|
||||||
|
|
||||||
|
bootstrapPort* {.
|
||||||
|
desc: "The TCP/UDP port that will be used by the bootstrap node"
|
||||||
|
defaultValue: config.defaultPort().}: int
|
||||||
|
|
||||||
genesisOffset* {.
|
genesisOffset* {.
|
||||||
desc: "Seconds from now to add to genesis time"
|
desc: "Seconds from now to add to genesis time"
|
||||||
shortForm: "g"
|
shortForm: "g"
|
||||||
defaultValue: 5 .}: int
|
defaultValue: 5 .}: int
|
||||||
|
|
||||||
outputStateFile* {.
|
outputGenesis* {.
|
||||||
desc: "Output file where to write the initial state snapshot"
|
desc: "Output file where to write the initial state snapshot".}: OutFile
|
||||||
longform: "out"
|
|
||||||
shortform: "o".}: OutFile
|
outputNetwork* {.
|
||||||
|
desc: "Output file where to write the initial state snapshot".}: OutFile
|
||||||
|
|
||||||
of importValidator:
|
of importValidator:
|
||||||
keyFile* {.
|
keyFile* {.
|
||||||
@ -107,21 +118,24 @@ type
|
|||||||
discard
|
discard
|
||||||
|
|
||||||
proc defaultDataDir*(conf: BeaconNodeConf): string =
|
proc defaultDataDir*(conf: BeaconNodeConf): string =
|
||||||
if conf.network == ephemeralNetwork:
|
let dataDir = when defined(windows):
|
||||||
getCurrentDir() / "beacon-node-cache"
|
"AppData" / "Roaming" / "Nimbus"
|
||||||
|
elif defined(macosx):
|
||||||
|
"Library" / "Application Support" / "Nimbus"
|
||||||
else:
|
else:
|
||||||
let dataDir = when defined(windows):
|
".cache" / "nimbus"
|
||||||
"AppData" / "Roaming" / "Nimbus"
|
|
||||||
elif defined(macosx):
|
|
||||||
"Library" / "Application Support" / "Nimbus"
|
|
||||||
else:
|
|
||||||
".cache" / "nimbus"
|
|
||||||
|
|
||||||
getHomeDir() / dataDir / "BeaconNode" / $conf.network
|
let networkId = if conf.network in ["testnet0", "testnet1", "mainnet"]:
|
||||||
|
conf.network
|
||||||
|
else:
|
||||||
|
# TODO: This seems silly. Perhaps we should error out here and ask
|
||||||
|
# the user to specify dataDir as well.
|
||||||
|
"tempnet"
|
||||||
|
|
||||||
|
getHomeDir() / dataDir / "BeaconNode" / networkId
|
||||||
|
|
||||||
proc defaultPort*(conf: BeaconNodeConf): int =
|
proc defaultPort*(conf: BeaconNodeConf): int =
|
||||||
(if conf.network == testnet0: 9630 else: 9632) + ord(useRLPx)
|
(if conf.network == "testnet0": 9630 else: 9632) + ord(useRLPx)
|
||||||
|
|
||||||
proc validatorFileBaseName*(validatorIdx: int): string =
|
proc validatorFileBaseName*(validatorIdx: int): string =
|
||||||
# there can apparently be tops 4M validators so we use 7 digits..
|
# there can apparently be tops 4M validators so we use 7 digits..
|
||||||
|
@ -27,6 +27,26 @@ when useRLPx:
|
|||||||
else:
|
else:
|
||||||
parseIpAddress("127.0.0.1")
|
parseIpAddress("127.0.0.1")
|
||||||
|
|
||||||
|
proc ensureNetworkKeys(conf: BeaconNodeConf): KeyPair =
|
||||||
|
let privateKeyFile = conf.dataDir / "network.privkey"
|
||||||
|
var privKey: PrivateKey
|
||||||
|
if not fileExists(privateKeyFile):
|
||||||
|
privKey = newPrivateKey()
|
||||||
|
createDir conf.dataDir.string
|
||||||
|
writeFile(privateKeyFile, $privKey)
|
||||||
|
else:
|
||||||
|
privKey = initPrivateKey(readFile(privateKeyFile).string)
|
||||||
|
|
||||||
|
KeyPair(seckey: privKey, pubkey: privKey.getPublicKey())
|
||||||
|
|
||||||
|
proc getPersistenBootstrapAddr*(conf: BeaconNodeConf,
|
||||||
|
ip: IpAddress, port: Port): BootstrapAddr =
|
||||||
|
let
|
||||||
|
keys = ensureNetworkKeys(conf)
|
||||||
|
address = Address(ip: ip, tcpPort: port, udpPort: port)
|
||||||
|
|
||||||
|
initENode(keys.pubKey, address)
|
||||||
|
|
||||||
proc writeValue*(writer: var JsonWriter, value: BootstrapAddr) {.inline.} =
|
proc writeValue*(writer: var JsonWriter, value: BootstrapAddr) {.inline.} =
|
||||||
writer.writeValue $value
|
writer.writeValue $value
|
||||||
|
|
||||||
@ -34,22 +54,14 @@ when useRLPx:
|
|||||||
value = initENode reader.readValue(string)
|
value = initENode reader.readValue(string)
|
||||||
|
|
||||||
proc createEth2Node*(conf: BeaconNodeConf): Future[EthereumNode] {.async.} =
|
proc createEth2Node*(conf: BeaconNodeConf): Future[EthereumNode] {.async.} =
|
||||||
let privateKeyFile = conf.dataDir / "network.privkey"
|
|
||||||
var privKey: PrivateKey
|
|
||||||
if not fileExists(privateKeyFile):
|
|
||||||
privKey = newPrivateKey()
|
|
||||||
writeFile(privateKeyFile, $privKey)
|
|
||||||
else:
|
|
||||||
privKey = initPrivateKey(readFile(privateKeyFile).string)
|
|
||||||
|
|
||||||
# TODO there are more networking options to add here: local bind ip, ipv6
|
|
||||||
# etc.
|
|
||||||
let
|
let
|
||||||
keys = KeyPair(seckey: privKey, pubkey: privKey.getPublicKey())
|
keys = ensureNetworkKeys(conf)
|
||||||
address = Address(ip: parseNat(conf.nat),
|
address = Address(ip: parseNat(conf.nat),
|
||||||
tcpPort: Port conf.tcpPort,
|
tcpPort: Port conf.tcpPort,
|
||||||
udpPort: Port conf.udpPort)
|
udpPort: Port conf.udpPort)
|
||||||
|
|
||||||
|
# TODO there are more networking options to add here: local bind ip, ipv6
|
||||||
|
# etc.
|
||||||
return newEthereumNode(keys, address, 0,
|
return newEthereumNode(keys, address, 0,
|
||||||
nil, clientId, minPeers = 1)
|
nil, clientId, minPeers = 1)
|
||||||
|
|
||||||
@ -107,15 +119,3 @@ else:
|
|||||||
proc loadConnectionAddressFile*(filename: string): PeerInfo =
|
proc loadConnectionAddressFile*(filename: string): PeerInfo =
|
||||||
Json.loadFile(filename, PeerInfo)
|
Json.loadFile(filename, PeerInfo)
|
||||||
|
|
||||||
type
|
|
||||||
TestnetMetadata* = object
|
|
||||||
networkId*: uint64
|
|
||||||
genesisRoot*: Eth2Digest
|
|
||||||
bootstrapNodes*: BootstrapAddr
|
|
||||||
totalValidators*: int
|
|
||||||
userValidatorsStart*: int
|
|
||||||
userValidatorsEnd*: int
|
|
||||||
|
|
||||||
proc userValidatorsRange*(d: TestnetMetadata): HSlice[int, int] =
|
|
||||||
d.userValidatorsStart .. d.userValidatorsEnd
|
|
||||||
|
|
||||||
|
@ -29,19 +29,3 @@ proc obtainTrustedStateSnapshot*(db: BeaconChainDB): Future[BeaconState] {.async
|
|||||||
|
|
||||||
doAssert(false, "Not implemented")
|
doAssert(false, "Not implemented")
|
||||||
|
|
||||||
proc createStateSnapshot*(
|
|
||||||
validatorDir: string, numValidators, firstValidator, genesisOffset: int,
|
|
||||||
outFile: string) =
|
|
||||||
|
|
||||||
var deposits: seq[Deposit]
|
|
||||||
for i in firstValidator..<numValidators:
|
|
||||||
deposits.add Json.loadFile(validatorDir / &"v{i:07}.deposit.json", Deposit)
|
|
||||||
|
|
||||||
let initialState = get_genesis_beacon_state(
|
|
||||||
deposits,
|
|
||||||
uint64(int(fastEpochTime() div 1000) + genesisOffset),
|
|
||||||
Eth1Data(), {})
|
|
||||||
|
|
||||||
var vr: Validator
|
|
||||||
Json.saveFile(outFile, initialState, pretty = true)
|
|
||||||
echo "Wrote ", outFile
|
|
||||||
|
@ -4,8 +4,6 @@ set -eux
|
|||||||
|
|
||||||
. $(dirname $0)/vars.sh
|
. $(dirname $0)/vars.sh
|
||||||
|
|
||||||
BOOTSTRAP_NODES_FLAG="--bootstrapNodesFile:$MASTER_NODE_ADDRESS_FILE"
|
|
||||||
|
|
||||||
if [[ "$1" == "0" ]]; then
|
if [[ "$1" == "0" ]]; then
|
||||||
BOOTSTRAP_NODES_FLAG=""
|
BOOTSTRAP_NODES_FLAG=""
|
||||||
fi
|
fi
|
||||||
@ -17,7 +15,7 @@ PORT=$(printf '5%04d' ${1})
|
|||||||
MYIP=$(curl -s ifconfig.me)
|
MYIP=$(curl -s ifconfig.me)
|
||||||
|
|
||||||
$BEACON_NODE_BIN \
|
$BEACON_NODE_BIN \
|
||||||
--network:ephemeralNetwork \
|
--network:$NETWORK_METADATA_FILE \
|
||||||
--dataDir:$DATA_DIR \
|
--dataDir:$DATA_DIR \
|
||||||
--validator:${V_PREFIX}0.privkey \
|
--validator:${V_PREFIX}0.privkey \
|
||||||
--validator:${V_PREFIX}1.privkey \
|
--validator:${V_PREFIX}1.privkey \
|
||||||
@ -32,5 +30,5 @@ $BEACON_NODE_BIN \
|
|||||||
--tcpPort:$PORT \
|
--tcpPort:$PORT \
|
||||||
--udpPort:$PORT \
|
--udpPort:$PORT \
|
||||||
--nat:extip:$MYIP \
|
--nat:extip:$MYIP \
|
||||||
--stateSnapshot:$SNAPSHOT_FILE \
|
--stateSnapshot:$SNAPSHOT_FILE
|
||||||
$BOOTSTRAP_NODES_FLAG
|
|
||||||
|
@ -41,10 +41,14 @@ if [[ -z "$SKIP_BUILDS" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f $SNAPSHOT_FILE ]; then
|
if [ ! -f $SNAPSHOT_FILE ]; then
|
||||||
$BEACON_NODE_BIN createChain \
|
$BEACON_NODE_BIN --dataDir=$SIMULATION_DIR/node-0 createTestnet \
|
||||||
--validatorsDir:$VALIDATORS_DIR \
|
--networkId=1000 \
|
||||||
--out:$SNAPSHOT_FILE \
|
--validatorsDir=$VALIDATORS_DIR \
|
||||||
--numValidators=$NUM_VALIDATORS \
|
--numValidators=$NUM_VALIDATORS \
|
||||||
|
--outputGenesis=$SNAPSHOT_FILE \
|
||||||
|
--outputNetwork=$NETWORK_METADATA_FILE \
|
||||||
|
--bootstrapAddress=127.0.0.1 \
|
||||||
|
--bootstrapPort=50001 \
|
||||||
--genesisOffset=5 # Delay in seconds
|
--genesisOffset=5 # Delay in seconds
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ GIT_ROOT="$($PWD_CMD)"
|
|||||||
SIMULATION_DIR="$SIM_ROOT/data"
|
SIMULATION_DIR="$SIM_ROOT/data"
|
||||||
VALIDATORS_DIR="$SIM_ROOT/validators"
|
VALIDATORS_DIR="$SIM_ROOT/validators"
|
||||||
SNAPSHOT_FILE="$SIMULATION_DIR/state_snapshot.json"
|
SNAPSHOT_FILE="$SIMULATION_DIR/state_snapshot.json"
|
||||||
|
NETWORK_METADATA_FILE="$SIMULATION_DIR/network.json"
|
||||||
BEACON_NODE_BIN=$BUILD_OUTPUTS_DIR/beacon_node
|
BEACON_NODE_BIN=$BUILD_OUTPUTS_DIR/beacon_node
|
||||||
VALIDATOR_KEYGEN_BIN=$BUILD_OUTPUTS_DIR/validator_keygen
|
VALIDATOR_KEYGEN_BIN=$BUILD_OUTPUTS_DIR/validator_keygen
|
||||||
MASTER_NODE_ADDRESS_FILE="$SIMULATION_DIR/node-0/beacon_node.address"
|
MASTER_NODE_ADDRESS_FILE="$SIMULATION_DIR/node-0/beacon_node.address"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user