Check the web3 provider for network compatibility

This commit is contained in:
Zahary Karadjov 2020-11-06 23:45:56 +02:00 committed by zah
parent f3254fd754
commit 4a710252d8
4 changed files with 43 additions and 7 deletions

View File

@ -67,13 +67,15 @@ func enrForkIdFromState(state: BeaconState): ENRForkID =
next_fork_epoch: FAR_FUTURE_EPOCH) next_fork_epoch: FAR_FUTURE_EPOCH)
proc startEth1Monitor(db: BeaconChainDB, proc startEth1Monitor(db: BeaconChainDB,
eth1Network: Option[Eth1Network],
conf: BeaconNodeConf): Future[Eth1Monitor] {.async.} = conf: BeaconNodeConf): Future[Eth1Monitor] {.async.} =
let eth1MonitorRes = await Eth1Monitor.init( let eth1MonitorRes = await Eth1Monitor.init(
db, db,
conf.runtimePreset, conf.runtimePreset,
conf.web3Url, conf.web3Url,
conf.depositContractAddress.get, conf.depositContractAddress.get,
conf.depositContractDeployedAt.get) conf.depositContractDeployedAt.get,
eth1Network)
result = if eth1MonitorRes.isOk: result = if eth1MonitorRes.isOk:
eth1MonitorRes.get eth1MonitorRes.get
@ -90,7 +92,8 @@ proc startEth1Monitor(db: BeaconChainDB,
proc init*(T: type BeaconNode, proc init*(T: type BeaconNode,
rng: ref BrHmacDrbgContext, rng: ref BrHmacDrbgContext,
conf: BeaconNodeConf, conf: BeaconNodeConf,
genesisStateContents: ref string): Future[BeaconNode] {.async.} = genesisStateContents: ref string,
eth1Network: Option[Eth1Network]): Future[BeaconNode] {.async.} =
let let
netKeys = getPersistentNetKeys(rng[], conf) netKeys = getPersistentNetKeys(rng[], conf)
nickname = if conf.nodeName == "auto": shortForm(netKeys) nickname = if conf.nodeName == "auto": shortForm(netKeys)
@ -159,7 +162,7 @@ proc init*(T: type BeaconNode,
# TODO Could move this to a separate "GenesisMonitor" process or task # TODO Could move this to a separate "GenesisMonitor" process or task
# that would do only this - see Paul's proposal for this. # that would do only this - see Paul's proposal for this.
eth1Monitor = await startEth1Monitor(db, conf) eth1Monitor = await startEth1Monitor(db, eth1Network, conf)
genesisState = await eth1Monitor.waitGenesis() genesisState = await eth1Monitor.waitGenesis()
if bnStatus == BeaconNodeStatus.Stopping: if bnStatus == BeaconNodeStatus.Stopping:
@ -233,7 +236,7 @@ proc init*(T: type BeaconNode,
conf.depositContractDeployedAt.isSome: conf.depositContractDeployedAt.isSome:
# TODO if we don't have any validators attached, # TODO if we don't have any validators attached,
# we don't need a mainchain monitor # we don't need a mainchain monitor
eth1Monitor = await startEth1Monitor(db, conf) eth1Monitor = await startEth1Monitor(db, eth1Network, conf)
let rpcServer = if conf.rpcEnabled: let rpcServer = if conf.rpcEnabled:
RpcServer.init(conf.rpcAddress, conf.rpcPort) RpcServer.init(conf.rpcAddress, conf.rpcPort)
@ -981,6 +984,7 @@ programMain:
config = makeBannerAndConfig(clientId, BeaconNodeConf) config = makeBannerAndConfig(clientId, BeaconNodeConf)
# This is ref so we can mutate it (to erase it) after the initial loading. # This is ref so we can mutate it (to erase it) after the initial loading.
genesisStateContents: ref string genesisStateContents: ref string
eth1Network: Option[Eth1Network]
setupStdoutLogging(config.logLevel) setupStdoutLogging(config.logLevel)
@ -1029,9 +1033,10 @@ programMain:
checkForIncompatibleOption "deposit-contract", depositContractAddress checkForIncompatibleOption "deposit-contract", depositContractAddress
checkForIncompatibleOption "deposit-contract-block", depositContractDeployedAt checkForIncompatibleOption "deposit-contract-block", depositContractDeployedAt
config.depositContractAddress = some metadata.depositContractAddress config.depositContractAddress = some metadata.depositContractAddress
config.depositContractDeployedAt = some metadata.depositContractDeployedAt config.depositContractDeployedAt = some metadata.depositContractDeployedAt
eth1Network = metadata.eth1Network
else: else:
config.runtimePreset = defaultRuntimePreset config.runtimePreset = defaultRuntimePreset
when const_preset == "mainnet": when const_preset == "mainnet":
@ -1041,6 +1046,7 @@ programMain:
if config.depositContractDeployedAt.isNone: if config.depositContractDeployedAt.isNone:
config.depositContractDeployedAt = config.depositContractDeployedAt =
some mainnetMetadata.depositContractDeployedAt some mainnetMetadata.depositContractDeployedAt
eth1Network = some mainnet
# Single RNG instance for the application - will be seeded on construction # Single RNG instance for the application - will be seeded on construction
# and avoid using system resources (such as urandom) after that # and avoid using system resources (such as urandom) after that
@ -1129,7 +1135,8 @@ programMain:
# There are no managed event loops in here, to do a graceful shutdown, but # There are no managed event loops in here, to do a graceful shutdown, but
# letting the default Ctrl+C handler exit is safe, since we only read from # letting the default Ctrl+C handler exit is safe, since we only read from
# the db. # the db.
var node = waitFor BeaconNode.init(rng, config, genesisStateContents) var node = waitFor BeaconNode.init(
rng, config, genesisStateContents, eth1Network)
if bnStatus == BeaconNodeStatus.Stopping: if bnStatus == BeaconNodeStatus.Stopping:
return return

View File

@ -388,7 +388,8 @@ proc init*(T: type Eth1Monitor,
preset: RuntimePreset, preset: RuntimePreset,
web3Url: string, web3Url: string,
depositContractAddress: Eth1Address, depositContractAddress: Eth1Address,
depositContractDeployedAt: string): Future[Result[T, string]] {.async.} = depositContractDeployedAt: string,
eth1Network: Option[Eth1Network]): Future[Result[T, string]] {.async.} =
var web3Url = web3Url var web3Url = web3Url
fixupInfuraUrls web3Url fixupInfuraUrls web3Url
@ -399,6 +400,17 @@ proc init*(T: type Eth1Monitor,
ns = web3.contractSender(DepositContract, depositContractAddress) ns = web3.contractSender(DepositContract, depositContractAddress)
dataProvider = Web3DataProviderRef(url: web3Url, web3: web3, ns: ns) dataProvider = Web3DataProviderRef(url: web3Url, web3: web3, ns: ns)
if eth1Network.isSome:
let
providerNetwork = await web3.provider.net_version()
expectedNetwork = case eth1Network.get
of mainnet: "1"
of rinkeby: "4"
of goerli: "5"
if expectedNetwork != providerNetwork:
return err("The specified we3 provider is not attached to the " &
$eth1Network.get & " network")
let let
previouslyPersistedTo = db.getEth1PersistedTo() previouslyPersistedTo = db.getEth1PersistedTo()
knownStart = previouslyPersistedTo.get: knownStart = previouslyPersistedTo.get:

View File

@ -35,6 +35,11 @@ type
Eth2NetworkMetadata* = object Eth2NetworkMetadata* = object
case incompatible*: bool case incompatible*: bool
of false: of false:
# TODO work-around a Nim codegen issue where upon constant assignment
# the compiler will copy `incompatibilityDesc` even when the case
# branch is not active and thus it will override the first variable
# in this branch.
dummy: string
eth1Network*: Option[Eth1Network] eth1Network*: Option[Eth1Network]
runtimePreset*: RuntimePreset runtimePreset*: RuntimePreset

View File

@ -5,6 +5,18 @@ set -e
cd "$(dirname $0)" cd "$(dirname $0)"
if [[ "$WEB3_URL" == "" ]]; then if [[ "$WEB3_URL" == "" ]]; then
cat <<WEB3_HELP
To monitor the Eth1 validator deposit contract, you'll need to pair
the Nimbus beacon node with a Web3 provider capable of serving Eth1
event logs. This could be a locally running Eth1 client such as Geth
or a cloud service such as Infura. For more information please see
our setup guides:
https://status-im.github.io/nimbus-eth2/infura-guide.html
WEB3_HELP
echo -n "Please enter a Web3 provider URL: " echo -n "Please enter a Web3 provider URL: "
read WEB3_URL read WEB3_URL
fi fi