@@ -391,6 +391,21 @@ proc getBlockProposalData*(m: Eth1Monitor,
391391
392392 swap (result [1 ], deposits)
393393
394+ proc new (T: type Web3DataProvider ,
395+ depositContractAddress: Eth1Address ,
396+ web3Url: string ): Future [Result [Web3DataProviderRef , string ]] {.async .} =
397+ let web3Fut = newWeb3 (web3Url)
398+ yield web3Fut or sleepAsync (chronos.seconds (5 ))
399+ if (not web3Fut.finished) or web3Fut.failed:
400+ await cancelAndWait (web3Fut)
401+ return err " Failed to setup web3 connection"
402+
403+ let
404+ web3 = web3Fut.read
405+ ns = web3.contractSender (DepositContract , depositContractAddress)
406+
407+ return ok Web3DataProviderRef (url: web3Url, web3: web3, ns: ns)
408+
394409proc init * (T: type Eth1Monitor ,
395410 db: BeaconChainDB ,
396411 preset: RuntimePreset ,
@@ -401,16 +416,13 @@ proc init*(T: type Eth1Monitor,
401416 var web3Url = web3Url
402417 fixupWeb3Urls web3Url
403418
404- let web3Fut = newWeb3 (web3Url)
405- yield web3Fut or sleepAsync (chronos.seconds (5 ))
406- if (not web3Fut.finished) or web3Fut.failed:
407- await cancelAndWait (web3Fut)
408- return err " Failed to setup web3 connection"
419+ let dataProviderRes = await Web3DataProvider .new (depositContractAddress, web3Url)
420+ if dataProviderRes.isErr:
421+ return err (dataProviderRes.error)
409422
410423 let
411- web3 = web3Fut.read
412- ns = web3.contractSender (DepositContract , depositContractAddress)
413- dataProvider = Web3DataProviderRef (url: web3Url, web3: web3, ns: ns)
424+ dataProvider = dataProviderRes.get
425+ web3 = dataProvider.web3
414426
415427 if eth1Network.isSome:
416428 let
@@ -590,11 +602,11 @@ proc syncBlockRange(m: Eth1Monitor, fromBlock, toBlock: Eth1BlockNumber) {.async
590602 notice " Eth1 sync progress" ,
591603 blockNumber = lastBlock.number,
592604 depositsProcessed = lastBlock.voteData.deposit_count
593-
605+
594606 if m.genesisStateFut != nil and m.chainHasEnoughValidators:
595607 let lastIdx = m.eth1Chain.blocks.len - 1
596608 template lastBlock : auto = m.eth1Chain.blocks[lastIdx]
597-
609+
598610 if maxBlockNumberRequested == toBlock and
599611 (m.eth1Chain.blocks.len == 0 or lastBlock.number != toBlock):
600612 let web3Block = await m.dataProvider.getBlockByNumber (toBlock)
@@ -711,9 +723,18 @@ proc run(m: Eth1Monitor, delayBeforeStart: Duration) {.async.} =
711723 blk = await m.dataProvider.getBlockByNumber (m.depositContractDeployedAt.number)
712724 break
713725 except CatchableError as err:
714- error " Failed to obtain details for the starting block of the deposit contract sync. " &
715- " The Web3 provider may still be not fully synced" , error = err.msg
726+ error " Failed to obtain details for the starting block " &
727+ " of the deposit contract sync. The Web3 provider " &
728+ " may still be not fully synced" , error = err.msg
716729 await sleepAsync (chronos.seconds (10 ))
730+ # TODO : After a single failure, the web3 object may enter a state
731+ # where it's no longer possible to make additional requests.
732+ # Until this is fixed upstream, we'll just try to recreate
733+ # the web3 provider before retrying. In case this fails,
734+ # the Eth1Monitor will be restarted.
735+ m.dataProvider = tryGet (await Web3DataProvider .new (
736+ m.depositContractAddress,
737+ m.web3Url))
717738 blk.hash.asEth2Digest
718739 Eth1Data (block_hash: deployedAtHash, deposit_count: 0 )
719740
0 commit comments