mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-02-23 11:48:33 +00:00
Require properly configured Engine API connection after the merge (#4006)
This commit is contained in:
parent
f1ddcfff0f
commit
4e41ed1d5a
@ -172,6 +172,11 @@ type
|
|||||||
desc: "Force the use of polling when determining the head block of Eth1"
|
desc: "Force the use of polling when determining the head block of Eth1"
|
||||||
name: "web3-force-polling" .}: bool
|
name: "web3-force-polling" .}: bool
|
||||||
|
|
||||||
|
requireEngineAPI* {.
|
||||||
|
defaultValue: true
|
||||||
|
desc: "Require Nimbus to be configured with an Engine API end-point after the Bellatrix fork epoch"
|
||||||
|
name: "require-engine-api-in-bellatrix" .}: bool
|
||||||
|
|
||||||
nonInteractive* {.
|
nonInteractive* {.
|
||||||
desc: "Do not display interative prompts. Quit on missing configuration"
|
desc: "Do not display interative prompts. Quit on missing configuration"
|
||||||
name: "non-interactive" .}: bool
|
name: "non-interactive" .}: bool
|
||||||
|
@ -141,6 +141,8 @@ type
|
|||||||
stopFut: Future[void]
|
stopFut: Future[void]
|
||||||
getBeaconTime: GetBeaconTimeFn
|
getBeaconTime: GetBeaconTimeFn
|
||||||
|
|
||||||
|
requireEngineAPI: bool
|
||||||
|
|
||||||
when hasGenesisDetection:
|
when hasGenesisDetection:
|
||||||
genesisValidators: seq[ImmutableValidatorData]
|
genesisValidators: seq[ImmutableValidatorData]
|
||||||
genesisValidatorKeyToIndex: Table[ValidatorPubKey, ValidatorIndex]
|
genesisValidatorKeyToIndex: Table[ValidatorPubKey, ValidatorIndex]
|
||||||
@ -548,53 +550,67 @@ proc forkchoiceUpdated*(p: Eth1Monitor,
|
|||||||
# TODO can't be defined within exchangeTransitionConfiguration
|
# TODO can't be defined within exchangeTransitionConfiguration
|
||||||
proc `==`(x, y: Quantity): bool {.borrow, noSideEffect.}
|
proc `==`(x, y: Quantity): bool {.borrow, noSideEffect.}
|
||||||
|
|
||||||
proc exchangeTransitionConfiguration*(p: Eth1Monitor): Future[void] {.async.} =
|
type
|
||||||
|
EtcStatus {.pure.} = enum
|
||||||
|
exchangeError
|
||||||
|
mismatch
|
||||||
|
localConfigurationUpdated
|
||||||
|
match
|
||||||
|
|
||||||
|
proc exchangeTransitionConfiguration*(p: Eth1Monitor): Future[EtcStatus] {.async.} =
|
||||||
# Eth1 monitor can recycle connections without (external) warning; at least,
|
# Eth1 monitor can recycle connections without (external) warning; at least,
|
||||||
# don't crash.
|
# don't crash.
|
||||||
if p.isNil:
|
if p.isNil:
|
||||||
debug "exchangeTransitionConfiguration: nil Eth1Monitor"
|
debug "exchangeTransitionConfiguration: nil Eth1Monitor"
|
||||||
|
|
||||||
if p.isNil or p.dataProvider.isNil:
|
if p.isNil or p.dataProvider.isNil:
|
||||||
return
|
return EtcStatus.exchangeError
|
||||||
|
|
||||||
let ccTransitionConfiguration = TransitionConfigurationV1(
|
let consensusCfg = TransitionConfigurationV1(
|
||||||
terminalTotalDifficulty: p.depositsChain.cfg.TERMINAL_TOTAL_DIFFICULTY,
|
terminalTotalDifficulty: p.depositsChain.cfg.TERMINAL_TOTAL_DIFFICULTY,
|
||||||
terminalBlockHash:
|
terminalBlockHash:
|
||||||
if p.terminalBlockHash.isSome:
|
if p.terminalBlockHash.isSome:
|
||||||
p.terminalBlockHash.get
|
p.terminalBlockHash.get
|
||||||
else:
|
else:
|
||||||
# https://github.com/nim-lang/Nim/issues/19802
|
(static default BlockHash),
|
||||||
(static(default(BlockHash))),
|
|
||||||
terminalBlockNumber:
|
terminalBlockNumber:
|
||||||
if p.terminalBlockNumber.isSome:
|
if p.terminalBlockNumber.isSome:
|
||||||
p.terminalBlockNumber.get
|
p.terminalBlockNumber.get
|
||||||
else:
|
else:
|
||||||
# https://github.com/nim-lang/Nim/issues/19802
|
(static default Quantity))
|
||||||
(static(default(Quantity))))
|
let executionCfg =
|
||||||
let ecTransitionConfiguration =
|
|
||||||
try:
|
try:
|
||||||
awaitWithRetries(
|
awaitWithRetries(
|
||||||
p.dataProvider.web3.provider.engine_exchangeTransitionConfigurationV1(
|
p.dataProvider.web3.provider.engine_exchangeTransitionConfigurationV1(
|
||||||
ccTransitionConfiguration),
|
consensusCfg),
|
||||||
timeout = 1.seconds)
|
timeout = 1.seconds)
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
debug "Failed to exchange transition configuration", err = err.msg
|
error "Failed to exchange transition configuration", err = err.msg
|
||||||
return
|
return EtcStatus.exchangeError
|
||||||
|
|
||||||
if ccTransitionConfiguration != ecTransitionConfiguration:
|
if consensusCfg.terminalTotalDifficulty != executionCfg.terminalTotalDifficulty:
|
||||||
warn "exchangeTransitionConfiguration: Configuration mismatch detected",
|
warn "Engine API configured with different terminal total difficulty",
|
||||||
consensusTerminalTotalDifficulty =
|
engineAPI_value = executionCfg.terminalTotalDifficulty,
|
||||||
$ccTransitionConfiguration.terminalTotalDifficulty,
|
localValue = consensusCfg.terminalTotalDifficulty
|
||||||
consensusTerminalBlockHash =
|
return EtcStatus.mismatch
|
||||||
ccTransitionConfiguration.terminalBlockHash,
|
|
||||||
consensusTerminalBlockNumber =
|
if p.terminalBlockNumber.isSome and p.terminalBlockHash.isSome:
|
||||||
ccTransitionConfiguration.terminalBlockNumber.uint64,
|
var res = EtcStatus.match
|
||||||
executionTerminalTotalDifficulty =
|
if consensusCfg.terminalBlockNumber != executionCfg.terminalBlockNumber:
|
||||||
$ecTransitionConfiguration.terminalTotalDifficulty,
|
warn "Engine API reporting different terminal block number",
|
||||||
executionTerminalBlockHash =
|
engineAPI_value = executionCfg.terminalBlockNumber.uint64,
|
||||||
ecTransitionConfiguration.terminalBlockHash,
|
localValue = consensusCfg.terminalBlockNumber.uint64
|
||||||
executionTerminalBlockNumber =
|
res = EtcStatus.mismatch
|
||||||
ecTransitionConfiguration.terminalBlockNumber.uint64
|
if consensusCfg.terminalBlockHash != executionCfg.terminalBlockHash:
|
||||||
|
warn "Engine API reporting different terminal block hash",
|
||||||
|
engineAPI_value = executionCfg.terminalBlockHash,
|
||||||
|
localValue = consensusCfg.terminalBlockHash
|
||||||
|
res = EtcStatus.mismatch
|
||||||
|
return res
|
||||||
|
else:
|
||||||
|
p.terminalBlockNumber = some executionCfg.terminalBlockNumber
|
||||||
|
p.terminalBlockHash = some executionCfg.terminalBlockHash
|
||||||
|
return EtcStatus.localConfigurationUpdated
|
||||||
|
|
||||||
template readJsonField(j: JsonNode, fieldName: string, ValueType: type): untyped =
|
template readJsonField(j: JsonNode, fieldName: string, ValueType: type): untyped =
|
||||||
var res: ValueType
|
var res: ValueType
|
||||||
@ -1037,7 +1053,8 @@ proc init*(T: type Eth1Monitor,
|
|||||||
depositContractSnapshot: Option[DepositContractSnapshot],
|
depositContractSnapshot: Option[DepositContractSnapshot],
|
||||||
eth1Network: Option[Eth1Network],
|
eth1Network: Option[Eth1Network],
|
||||||
forcePolling: bool,
|
forcePolling: bool,
|
||||||
jwtSecret: Option[seq[byte]]): T =
|
jwtSecret: Option[seq[byte]],
|
||||||
|
requireEngineAPI: bool): T =
|
||||||
doAssert web3Urls.len > 0
|
doAssert web3Urls.len > 0
|
||||||
var web3Urls = web3Urls
|
var web3Urls = web3Urls
|
||||||
for url in mitems(web3Urls):
|
for url in mitems(web3Urls):
|
||||||
@ -1055,7 +1072,8 @@ proc init*(T: type Eth1Monitor,
|
|||||||
eth1Progress: newAsyncEvent(),
|
eth1Progress: newAsyncEvent(),
|
||||||
forcePolling: forcePolling,
|
forcePolling: forcePolling,
|
||||||
jwtSecret: jwtSecret,
|
jwtSecret: jwtSecret,
|
||||||
blocksPerLogsRequest: targetBlocksPerLogsRequest)
|
blocksPerLogsRequest: targetBlocksPerLogsRequest,
|
||||||
|
requireEngineAPI: requireEngineAPI)
|
||||||
|
|
||||||
proc safeCancel(fut: var Future[void]) =
|
proc safeCancel(fut: var Future[void]) =
|
||||||
if not fut.isNil and not fut.finished:
|
if not fut.isNil and not fut.finished:
|
||||||
@ -1340,6 +1358,20 @@ proc startEth1Syncing(m: Eth1Monitor, delayBeforeStart: Duration) {.async.} =
|
|||||||
|
|
||||||
await m.ensureDataProvider()
|
await m.ensureDataProvider()
|
||||||
|
|
||||||
|
if m.currentEpoch >= m.cfg.BELLATRIX_FORK_EPOCH:
|
||||||
|
let status = await m.exchangeTransitionConfiguration()
|
||||||
|
if status == EtcStatus.localConfigurationUpdated:
|
||||||
|
info "Obtained terminal block from Engine API",
|
||||||
|
terminalBlockNumber = m.terminalBlockNumber.get.uint64,
|
||||||
|
terminalBlockHash = m.terminalBlockHash.get
|
||||||
|
elif status != EtcStatus.match and isFirstRun and m.requireEngineAPI:
|
||||||
|
fatal "The Bellatrix hard fork requires the beacon node to be connected to a properly configured Engine API end-point. " &
|
||||||
|
"See https://nimbus.guide/merge.html for more details. " &
|
||||||
|
"If you want to temporarily continue operating Nimbus without configuring an Engine API end-point, " &
|
||||||
|
"please specify the command-line option --require-engine-api-in-bellatrix=no when launching it. " &
|
||||||
|
"Please note that you MUST complete the migration before the network TTD is reached (estimated to happen near 13th of September)"
|
||||||
|
quit 1
|
||||||
|
|
||||||
# We might need to reset the chain if the new provider disagrees
|
# We might need to reset the chain if the new provider disagrees
|
||||||
# with the previous one regarding the history of the chain or if
|
# with the previous one regarding the history of the chain or if
|
||||||
# we have detected a conensus violation - our view disagreeing with
|
# we have detected a conensus violation - our view disagreeing with
|
||||||
|
@ -538,7 +538,8 @@ proc init*(T: type BeaconNode,
|
|||||||
getDepositContractSnapshot(),
|
getDepositContractSnapshot(),
|
||||||
eth1Network,
|
eth1Network,
|
||||||
config.web3ForcePolling,
|
config.web3ForcePolling,
|
||||||
optJwtSecret)
|
optJwtSecret,
|
||||||
|
config.requireEngineAPI)
|
||||||
|
|
||||||
eth1Monitor.loadPersistedDeposits()
|
eth1Monitor.loadPersistedDeposits()
|
||||||
|
|
||||||
@ -639,7 +640,8 @@ proc init*(T: type BeaconNode,
|
|||||||
getDepositContractSnapshot(),
|
getDepositContractSnapshot(),
|
||||||
eth1Network,
|
eth1Network,
|
||||||
config.web3ForcePolling,
|
config.web3ForcePolling,
|
||||||
optJwtSecret)
|
optJwtSecret,
|
||||||
|
config.requireEngineAPI)
|
||||||
|
|
||||||
if config.rpcEnabled:
|
if config.rpcEnabled:
|
||||||
warn "Nimbus's JSON-RPC server has been removed. This includes the --rpc, --rpc-port, and --rpc-address configuration options. https://nimbus.guide/rest-api.html shows how to enable and configure the REST Beacon API server which replaces it."
|
warn "Nimbus's JSON-RPC server has been removed. This includes the --rpc, --rpc-port, and --rpc-address configuration options. https://nimbus.guide/rest-api.html shows how to enable and configure the REST Beacon API server which replaces it."
|
||||||
|
@ -61,7 +61,8 @@ programMain:
|
|||||||
cfg, db = nil, getBeaconTime, config.web3Urls,
|
cfg, db = nil, getBeaconTime, config.web3Urls,
|
||||||
none(DepositContractSnapshot), metadata.eth1Network,
|
none(DepositContractSnapshot), metadata.eth1Network,
|
||||||
forcePolling = false,
|
forcePolling = false,
|
||||||
rng[].loadJwtSecret(config, allowCreate = false))
|
rng[].loadJwtSecret(config, allowCreate = false),
|
||||||
|
true)
|
||||||
waitFor res.ensureDataProvider()
|
waitFor res.ensureDataProvider()
|
||||||
res
|
res
|
||||||
else:
|
else:
|
||||||
|
@ -22,6 +22,8 @@ As a node operator, you will need to run both an execution client and a consensu
|
|||||||
|
|
||||||
If you were running an execution client before, make sure to update its configuration to include an option for [JWT secrets](./eth1.md#3-pass-the-jwt-secret-to-nimbus) and engine API.
|
If you were running an execution client before, make sure to update its configuration to include an option for [JWT secrets](./eth1.md#3-pass-the-jwt-secret-to-nimbus) and engine API.
|
||||||
|
|
||||||
|
Please note that once the Bellatrix fork epoch is reached on 6th of September 2022, Nimbus will refuse to start unless connected to a properly configured execution client. If you need more time to complete the transition, you can temporarily run the beacon node with the command-line option `--require-engine-api-in-bellatrix=no`, but please note that such a setup will stop working once the network TTD is reached (currently estimated to happen on 13th of September, see https://wenmerge.com/ for more up-to-date information).
|
||||||
|
|
||||||
### Prepare a suggested fee recipient
|
### Prepare a suggested fee recipient
|
||||||
|
|
||||||
After the merge, validators that propose blocks are eligible to recieve transaction fees - read more about fee recipients [here](https://launchpad.ethereum.org/en/merge-readiness#fee-recipient).
|
After the merge, validators that propose blocks are eligible to recieve transaction fees - read more about fee recipients [here](https://launchpad.ethereum.org/en/merge-readiness#fee-recipient).
|
||||||
|
@ -59,7 +59,7 @@ proc run() {.async.} =
|
|||||||
eth1Monitor = Eth1Monitor.init(
|
eth1Monitor = Eth1Monitor.init(
|
||||||
defaultRuntimeConfig, db = nil, nil, @[paramStr(1)],
|
defaultRuntimeConfig, db = nil, nil, @[paramStr(1)],
|
||||||
none(DepositContractSnapshot), none(Eth1Network), false,
|
none(DepositContractSnapshot), none(Eth1Network), false,
|
||||||
some readJwtSecret(paramStr(2)).get)
|
some readJwtSecret(paramStr(2)).get, true)
|
||||||
|
|
||||||
await eth1Monitor.ensureDataProvider()
|
await eth1Monitor.ensureDataProvider()
|
||||||
try:
|
try:
|
||||||
|
@ -60,7 +60,8 @@ proc run() {.async.} =
|
|||||||
jwtSecret = some readJwtSecret("jwt.hex").get
|
jwtSecret = some readJwtSecret("jwt.hex").get
|
||||||
eth1Monitor = Eth1Monitor.init(
|
eth1Monitor = Eth1Monitor.init(
|
||||||
defaultRuntimeConfig, db = nil, nil, @[web3Url],
|
defaultRuntimeConfig, db = nil, nil, @[web3Url],
|
||||||
none(DepositContractSnapshot), none(Eth1Network), false, jwtSecret)
|
none(DepositContractSnapshot), none(Eth1Network),
|
||||||
|
false, jwtSecret, true)
|
||||||
web3Provider = (await Web3DataProvider.new(
|
web3Provider = (await Web3DataProvider.new(
|
||||||
default(Eth1Address), web3Url, jwtSecret)).get
|
default(Eth1Address), web3Url, jwtSecret)).get
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user