Commit e0be02e1 authored by Kelvin Fichter's avatar Kelvin Fichter Committed by Mark Tyneway

provider: use fallback provider helper

Allow the DTL to sync from multiple web3 backends using
the `ethers.providers.FallbackProvider`. Multiple URLs
can be passed through as a comma delimited string to
configure multiple providers.

A helper function is added to `core-utils` to allow
easy configuration between services. This PR only introduces
the usage of the fallback provider into the DTL. In the
future, it should be added to other services that query L1
as well.
parent 34927928
---
'@eth-optimism/core-utils': patch
'@eth-optimism/data-transport-layer': patch
---
Add fallback provider support to DTL using helper function in core-utils
......@@ -47,6 +47,7 @@
},
"dependencies": {
"@ethersproject/abstract-provider": "^5.4.1",
"@ethersproject/providers": "^5.4.5",
"ethers": "^5.4.5",
"lodash": "^4.17.21"
}
......
......@@ -6,3 +6,4 @@ export * from './events'
export * from './batches'
export * from './bcfg'
export * from './fees'
export * from './provider'
/**
* Provider Utilities
*/
import { ethers } from 'ethers'
import { Provider } from '@ethersproject/providers'
// Copied from @ethersproject/providers since it is not
// currently exported
export interface FallbackProviderConfig {
// The Provider
provider: Provider
// The priority to favour this Provider; higher values are used first
priority?: number
// Timeout before also triggering the next provider; this does not stop
// this provider and if its result comes back before a quorum is reached
// it will be incorporated into the vote
// - lower values will cause more network traffic but may result in a
// faster retult.
stallTimeout?: number
// How much this provider contributes to the quorum; sometimes a specific
// provider may be more reliable or trustworthy than others, but usually
// this should be left as the default
weight?: number
}
export const FallbackProvider = (config: string | FallbackProviderConfig[]) => {
const configs = []
if (typeof config === 'string') {
const urls = config.split(',')
for (const [i, url] of urls.entries()) {
configs.push({
priority: i,
provider: new ethers.providers.StaticJsonRpcProvider(url),
})
}
return new ethers.providers.FallbackProvider(configs)
}
return new ethers.providers.FallbackProvider(config)
}
/* Imports: External */
import { fromHexString } from '@eth-optimism/core-utils'
import { fromHexString, FallbackProvider } from '@eth-optimism/core-utils'
import { BaseService, Metrics } from '@eth-optimism/common-ts'
import { StaticJsonRpcProvider } from '@ethersproject/providers'
import { StaticJsonRpcProvider, BaseProvider } from '@ethersproject/providers'
import { LevelUp } from 'levelup'
import { ethers, constants } from 'ethers'
import { Gauge, Counter } from 'prom-client'
......@@ -80,7 +80,7 @@ const optionSettings = {
},
l1RpcProvider: {
validate: (val: any) => {
return validators.isUrl(val) || validators.isJsonRpcProvider(val)
return validators.isString(val) || validators.isJsonRpcProvider(val)
},
},
l2ChainId: {
......@@ -98,7 +98,7 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
private state: {
db: TransportDB
contracts: OptimismContracts
l1RpcProvider: StaticJsonRpcProvider
l1RpcProvider: BaseProvider
startingL1BlockNumber: number
} = {} as any
......@@ -107,10 +107,11 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
this.l1IngestionMetrics = registerMetrics(this.metrics)
this.state.l1RpcProvider =
typeof this.options.l1RpcProvider === 'string'
? new StaticJsonRpcProvider(this.options.l1RpcProvider)
: this.options.l1RpcProvider
if (typeof this.options.l1RpcProvider === 'string') {
this.state.l1RpcProvider = FallbackProvider(this.options.l1RpcProvider)
} else {
this.state.l1RpcProvider = this.options.l1RpcProvider
}
this.logger.info('Using AddressManager', {
addressManager: this.options.addressManager,
......
import { JsonRpcProvider } from '@ethersproject/providers'
import { BaseProvider } from '@ethersproject/providers'
import { BigNumber, Event } from 'ethers'
import { TransportDB } from '../db/transport-db'
......@@ -15,7 +15,7 @@ export type TypedEthersEvent<T> = Event & {
export type GetExtraDataHandler<TEventArgs, TExtraData> = (
event?: TypedEthersEvent<TEventArgs>,
l1RpcProvider?: JsonRpcProvider
l1RpcProvider?: BaseProvider
) => Promise<TExtraData>
export type ParseEventHandler<TEventArgs, TExtraData, TParsedEvent> = (
......
/* Imports: External */
import { constants, Contract, Signer } from 'ethers'
import { JsonRpcProvider } from '@ethersproject/providers'
import { BaseProvider } from '@ethersproject/providers'
import { getContractInterface } from '@eth-optimism/contracts'
export const loadContract = (
name: string,
address: string,
provider: JsonRpcProvider
provider: BaseProvider
): Contract => {
return new Contract(address, getContractInterface(name) as any, provider)
}
......@@ -15,7 +15,7 @@ export const loadProxyFromManager = async (
name: string,
proxy: string,
Lib_AddressManager: Contract,
provider: JsonRpcProvider
provider: BaseProvider
): Promise<Contract> => {
const address = await Lib_AddressManager.getAddress(proxy)
......@@ -36,7 +36,7 @@ export interface OptimismContracts {
}
export const loadOptimismContracts = async (
l1RpcProvider: JsonRpcProvider,
l1RpcProvider: BaseProvider,
addressManagerAddress: string,
signer?: Signer
): Promise<OptimismContracts> => {
......
......@@ -922,6 +922,31 @@
bech32 "1.1.4"
ws "7.4.6"
"@ethersproject/providers@^5.4.5":
version "5.4.5"
resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.4.5.tgz#eb2ea2a743a8115f79604a8157233a3a2c832928"
integrity sha512-1GkrvkiAw3Fj28cwi1Sqm8ED1RtERtpdXmRfwIBGmqBSN5MoeRUHuwHPppMtbPayPgpFcvD7/Gdc9doO5fGYgw==
dependencies:
"@ethersproject/abstract-provider" "^5.4.0"
"@ethersproject/abstract-signer" "^5.4.0"
"@ethersproject/address" "^5.4.0"
"@ethersproject/basex" "^5.4.0"
"@ethersproject/bignumber" "^5.4.0"
"@ethersproject/bytes" "^5.4.0"
"@ethersproject/constants" "^5.4.0"
"@ethersproject/hash" "^5.4.0"
"@ethersproject/logger" "^5.4.0"
"@ethersproject/networks" "^5.4.0"
"@ethersproject/properties" "^5.4.0"
"@ethersproject/random" "^5.4.0"
"@ethersproject/rlp" "^5.4.0"
"@ethersproject/sha2" "^5.4.0"
"@ethersproject/strings" "^5.4.0"
"@ethersproject/transactions" "^5.4.0"
"@ethersproject/web" "^5.4.0"
bech32 "1.1.4"
ws "7.4.6"
"@ethersproject/random@5.4.0", "@ethersproject/random@^5.0.0", "@ethersproject/random@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.4.0.tgz#9cdde60e160d024be39cc16f8de3b9ce39191e16"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment