Skip to content
This repository has been archived by the owner on Dec 5, 2021. It is now read-only.

Commit

Permalink
provider: use fallback provider helper
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
smartcontracts authored and tynes committed Sep 30, 2021
1 parent 3492792 commit e0be02e
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 14 deletions.
6 changes: 6 additions & 0 deletions .changeset/eleven-moles-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@eth-optimism/core-utils': patch
'@eth-optimism/data-transport-layer': patch
---

Add fallback provider support to DTL using helper function in core-utils
1 change: 1 addition & 0 deletions packages/core-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
},
"dependencies": {
"@ethersproject/abstract-provider": "^5.4.1",
"@ethersproject/providers": "^5.4.5",
"ethers": "^5.4.5",
"lodash": "^4.17.21"
}
Expand Down
1 change: 1 addition & 0 deletions packages/core-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './events'
export * from './batches'
export * from './bcfg'
export * from './fees'
export * from './provider'
40 changes: 40 additions & 0 deletions packages/core-utils/src/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 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)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* 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'
Expand Down Expand Up @@ -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: {
Expand All @@ -98,7 +98,7 @@ export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
private state: {
db: TransportDB
contracts: OptimismContracts
l1RpcProvider: StaticJsonRpcProvider
l1RpcProvider: BaseProvider
startingL1BlockNumber: number
} = {} as any

Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JsonRpcProvider } from '@ethersproject/providers'
import { BaseProvider } from '@ethersproject/providers'
import { BigNumber, Event } from 'ethers'

import { TransportDB } from '../db/transport-db'
Expand All @@ -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> = (
Expand Down
8 changes: 4 additions & 4 deletions packages/data-transport-layer/src/utils/contracts.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* 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)
}
Expand All @@ -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)

Expand All @@ -36,7 +36,7 @@ export interface OptimismContracts {
}

export const loadOptimismContracts = async (
l1RpcProvider: JsonRpcProvider,
l1RpcProvider: BaseProvider,
addressManagerAddress: string,
signer?: Signer
): Promise<OptimismContracts> => {
Expand Down
25 changes: 25 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit e0be02e

Please sign in to comment.