Commit aa8baefd authored by Georgios Konstantopoulos's avatar Georgios Konstantopoulos Committed by GitHub

refactor: remove base-service dependency (#16)

* chore: cleanup gitignore

* fix: adjust package.json and tsconfigs

* feat: expose base-service in core-utils

* chore(l1-ingestion): use base-service from core-utils

* chore(l2-ingestion): use base-service from core-utils

* chore: use base-service from core-utils in remaining services
parent 8f5982d2
node_modules
**/dist
results
temp
.nyc_output
*.tsbuildinfo
......@@ -5,14 +5,14 @@
"files": [
"dist/index"
],
"types": "build/src/index.d.ts",
"types": "dist/index",
"repository": "git@github.com:ethereum-optimism/core-utils.git",
"author": "Kelvin Fichter <kelvinfichter@gmail.com>",
"license": "MIT",
"scripts": {
"all": "yarn clean && yarn build && yarn test && yarn lint:fix && yarn lint",
"build": "tsc -p tsconfig.build.json",
"clean": "rimraf dist/",
"clean": "rimraf dist/ ./tsconfig.build.tsbuildinfo",
"lint": "tslint --format stylish --project .",
"lint:fix": "prettier --config prettier-config.json --write '{src,test}/**/*.ts'",
"test": "ts-mocha test/**/*.spec.ts"
......
......@@ -12,17 +12,19 @@ type OptionSettings<TOptions> = {
* Base for other "Service" objects. Handles your standard initialization process, can dynamically
* start and stop.
*/
export class BaseService<TServiceOptions> {
export class BaseService<T> {
protected name: string
protected optionSettings: OptionSettings<TServiceOptions>
protected options: T
protected logger: Logger
protected initialized: boolean = false
protected running: boolean = false
/**
* @param options Options to pass to the service.
*/
constructor(protected options: TServiceOptions) {}
constructor(name: string, options: T, optionSettings: OptionSettings<T>) {
validateOptions(options, optionSettings)
this.name = name
this.options = mergeDefaultOptions(options, optionSettings)
this.logger = new Logger({ name })
}
/**
* Initializes the service.
......@@ -32,48 +34,24 @@ export class BaseService<TServiceOptions> {
return
}
// Apparently I'm going crazy and just now finding out that class variables are undefined
// within the constructor? Anyway, this means I have to do all of this initialization logic
// during a separate init function or everything is undefined.
if (this.logger === undefined) {
// tslint:disable-next-line
this.logger = new Logger({name: this.name})
}
this._mergeDefaultOptions()
this._validateOptions()
this.logger.info('Service is initializing...')
await this._init()
this.logger.info('Service has initialized.')
this.initialized = true
try {
this.logger.info('Service is initializing...')
await this._init()
this.logger.info('Service has initialized.')
} catch (err) {
this.initialized = false
throw err
}
}
/**
* Starts the service.
* Starts the service (initializes it if needed).
*/
public async start(): Promise<void> {
if (this.running) {
return
}
if (this.logger === undefined) {
// tslint:disable-next-line
this.logger = new Logger({name: this.name})
}
this.running = true
this.logger.info('Service is starting...')
await this.init()
await this._start()
this.logger.info('Service has started')
this.running = true
}
/**
......@@ -87,7 +65,6 @@ export class BaseService<TServiceOptions> {
this.logger.info('Service is stopping...')
await this._stop()
this.logger.info('Service has stopped')
this.running = false
}
......@@ -111,58 +88,47 @@ export class BaseService<TServiceOptions> {
protected async _stop(): Promise<void> {
return
}
}
/**
* Combines user provided and default options. Honestly there's no point for this function to
* live within this class and be all stateful, but I didn't realize that until after I wrote it.
* So we're gonna have to deal with that for now. Whatever, it's an easy fix if anyone else
* feels like tackling it.
*/
private _mergeDefaultOptions(): void {
if (this.optionSettings === undefined) {
return
/**
* Combines user provided and default options.
*/
function mergeDefaultOptions<T>(
options: T,
optionSettings: OptionSettings<T>
): T {
for (const optionName of Object.keys(optionSettings)) {
const optionDefault = optionSettings[optionName].default
if (optionDefault === undefined) {
continue
}
for (const optionName of Object.keys(this.optionSettings)) {
const optionDefault = this.optionSettings[optionName].default
if (optionDefault === undefined) {
continue
}
if (
this.options[optionName] !== undefined &&
this.options[optionName] !== null
) {
continue
}
// TODO: Maybe make a copy of this default instead of directly assigning?
this.options[optionName] = optionDefault
if (options[optionName] !== undefined && options[optionName] !== null) {
continue
}
options[optionName] = optionDefault
}
/**
* Performs option validation against the option settings attached to this class. Another
* function that really shouldn't be part of this class in particular. Good mini project though!
*/
private _validateOptions(): void {
if (this.optionSettings === undefined) {
return
}
return options
}
for (const optionName of Object.keys(this.optionSettings)) {
const optionValidationFunction = this.optionSettings[optionName].validate
if (optionValidationFunction === undefined) {
continue
}
/**
* Performs option validation against the option settings
*/
function validateOptions<T>(options: T, optionSettings: OptionSettings<T>) {
for (const optionName of Object.keys(optionSettings)) {
const optionValidationFunction = optionSettings[optionName].validate
if (optionValidationFunction === undefined) {
continue
}
const optionValue = this.options[optionName]
const optionValue = options[optionName]
if (optionValidationFunction(optionValue) === false) {
throw new Error(
`Provided input for option "${optionName}" is invalid: ${optionValue}`
)
}
if (optionValidationFunction(optionValue) === false) {
throw new Error(
`Provided input for option "${optionName}" is invalid: ${optionValue}`
)
}
}
}
export * from './coders'
export * from './common'
export * from './watcher'
export * from './base-service'
/db/
node_modules/
yarn-error.log
.env
test/temp/
build/
\ No newline at end of file
{
"name": "@eth-optimism/data-transport-layer",
"version": "0.1.2",
"main": "build/index.js",
"license": "MIT",
"main": "dist/index",
"files": [
"build/**/*.js",
"build/**/*.js.map",
"build/**/*.ts"
"dist/index"
],
"types": "build/index.d.ts",
"types": "dist/index",
"scripts": {
"clean": "rimraf ./build",
"clean": "rimraf ./dist ./tsconfig.build.tsbuildinfo",
"clean:db": "rimraf ./db",
"lint": "yarn run lint:fix && yarn run lint:check",
"lint:check": "tslint --format stylish --project .",
......@@ -23,12 +20,10 @@
"dependencies": {
"@eth-optimism/contracts": "^0.1.6",
"@eth-optimism/core-utils": "^0.1.10",
"@eth-optimism/service-base": "^1.1.5",
"@ethersproject/providers": "^5.0.21",
"@types/express": "^4.17.11",
"bcfg": "^0.1.6",
"browser-or-node": "^1.3.0",
"colors": "^1.4.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"ethers": "^5.0.26",
......@@ -38,7 +33,6 @@
"node-fetch": "^2.6.1"
},
"devDependencies": {
"@eth-optimism/dev": "^1.1.1",
"@nomiclabs/hardhat-ethers": "^2.0.1",
"@types/browser-or-node": "^1.3.0",
"@types/cors": "^2.8.9",
......
/* Imports: External */
import { BaseService } from '@eth-optimism/service-base'
import { fromHexString } from '@eth-optimism/core-utils'
import { fromHexString, BaseService } from '@eth-optimism/core-utils'
import { JsonRpcProvider } from '@ethersproject/providers'
import colors from 'colors/safe'
import { LevelUp } from 'levelup'
/* Imports: Internal */
......@@ -30,37 +28,39 @@ export interface L1IngestionServiceOptions
db: LevelUp
}
export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
protected name = 'L1 Ingestion Service'
protected optionSettings = {
db: {
validate: validators.isLevelUP,
},
addressManager: {
validate: validators.isAddress,
},
confirmations: {
default: 35,
validate: validators.isInteger,
},
pollingInterval: {
default: 5000,
validate: validators.isInteger,
},
logsPerPollingInterval: {
default: 2000,
validate: validators.isInteger,
},
dangerouslyCatchAllErrors: {
default: false,
validate: validators.isBoolean,
},
l1RpcProvider: {
validate: (val: any) => {
return validators.isUrl(val) || validators.isJsonRpcProvider(val)
},
const optionSettings = {
db: {
validate: validators.isLevelUP,
},
addressManager: {
validate: validators.isAddress,
},
confirmations: {
default: 35,
validate: validators.isInteger,
},
pollingInterval: {
default: 5000,
validate: validators.isInteger,
},
logsPerPollingInterval: {
default: 2000,
validate: validators.isInteger,
},
dangerouslyCatchAllErrors: {
default: false,
validate: validators.isBoolean,
},
l1RpcProvider: {
validate: (val: any) => {
return validators.isUrl(val) || validators.isJsonRpcProvider(val)
},
},
}
export class L1IngestionService extends BaseService<L1IngestionServiceOptions> {
constructor(options: L1IngestionServiceOptions) {
super('L1 Ingestion Service', options, optionSettings)
}
private state: {
......
/* Imports: External */
import { BaseService } from '@eth-optimism/service-base'
import { BaseService } from '@eth-optimism/core-utils'
import { JsonRpcProvider } from '@ethersproject/providers'
import colors from 'colors/safe'
import { BigNumber } from 'ethers'
import { LevelUp } from 'levelup'
......@@ -16,41 +15,43 @@ export interface L2IngestionServiceOptions
db: LevelUp
}
export class L2IngestionService extends BaseService<L2IngestionServiceOptions> {
protected name = 'L2 Ingestion Service'
protected optionSettings = {
db: {
validate: validators.isLevelUP,
},
l2RpcProvider: {
validate: (val: any) => {
return validators.isUrl(val) || validators.isJsonRpcProvider(val)
},
},
l2ChainId: {
validate: validators.isInteger,
},
pollingInterval: {
default: 5000,
validate: validators.isInteger,
},
transactionsPerPollingInterval: {
default: 1000,
validate: validators.isInteger,
},
dangerouslyCatchAllErrors: {
default: false,
validate: validators.isBoolean,
},
legacySequencerCompatibility: {
default: false,
validate: validators.isBoolean,
},
stopL2SyncAtBlock: {
default: Infinity,
validate: validators.isInteger,
const optionSettings = {
db: {
validate: validators.isLevelUP,
},
l2RpcProvider: {
validate: (val: any) => {
return validators.isUrl(val) || validators.isJsonRpcProvider(val)
},
},
l2ChainId: {
validate: validators.isInteger,
},
pollingInterval: {
default: 5000,
validate: validators.isInteger,
},
transactionsPerPollingInterval: {
default: 1000,
validate: validators.isInteger,
},
dangerouslyCatchAllErrors: {
default: false,
validate: validators.isBoolean,
},
legacySequencerCompatibility: {
default: false,
validate: validators.isBoolean,
},
stopL2SyncAtBlock: {
default: Infinity,
validate: validators.isInteger,
},
}
export class L2IngestionService extends BaseService<L2IngestionServiceOptions> {
constructor(options: L2IngestionServiceOptions) {
super('L2 Ingestion Service', options, optionSettings)
}
private state: {
......
/* Imports: External */
import { BaseService } from '@eth-optimism/service-base'
import { BaseService } from '@eth-optimism/core-utils'
import { LevelUp } from 'levelup'
import level from 'level'
......@@ -29,18 +29,20 @@ export interface L1DataTransportServiceOptions {
stopL2SyncAtBlock?: number
}
export class L1DataTransportService extends BaseService<L1DataTransportServiceOptions> {
protected name = 'L1 Data Transport Service'
const optionSettings = {
syncFromL1: {
default: true,
validate: validators.isBoolean,
},
syncFromL2: {
default: false,
validate: validators.isBoolean,
},
}
protected optionSettings = {
syncFromL1: {
default: true,
validate: validators.isBoolean,
},
syncFromL2: {
default: false,
validate: validators.isBoolean,
},
export class L1DataTransportService extends BaseService<L1DataTransportServiceOptions> {
constructor(options: L1DataTransportServiceOptions) {
super('L1 Data Transport Service', options, optionSettings)
}
private state: {
......
/* Imports: External */
import { BaseService } from '@eth-optimism/service-base'
import { BaseService } from '@eth-optimism/core-utils'
import express, { Request, Response } from 'express'
import cors from 'cors'
import { BigNumber } from 'ethers'
......@@ -26,31 +26,34 @@ export interface L1TransportServerOptions
db: LevelUp
}
export class L1TransportServer extends BaseService<L1TransportServerOptions> {
protected name = 'L1 Transport Server'
protected optionSettings = {
db: {
validate: validators.isLevelUP,
},
port: {
default: 7878,
validate: validators.isInteger,
},
hostname: {
default: 'localhost',
validate: validators.isString,
},
confirmations: {
validate: validators.isInteger,
},
l1RpcProvider: {
validate: (val: any) => {
return validators.isUrl(val) || validators.isJsonRpcProvider(val)
},
},
showUnconfirmedTransactions: {
validate: validators.isBoolean,
const optionSettings = {
db: {
validate: validators.isLevelUP,
},
port: {
default: 7878,
validate: validators.isInteger,
},
hostname: {
default: 'localhost',
validate: validators.isString,
},
confirmations: {
validate: validators.isInteger,
},
l1RpcProvider: {
validate: (val: any) => {
return validators.isUrl(val) || validators.isJsonRpcProvider(val)
},
},
showUnconfirmedTransactions: {
validate: validators.isBoolean,
},
}
export class L1TransportServer extends BaseService<L1TransportServerOptions> {
constructor(options: L1TransportServerOptions) {
super('L1 Transport Server', options, optionSettings)
}
private state: {
......
{
"extends": "../../tsconfig.build.json",
......@@ -7,5 +8,6 @@
"include": [
"src/**/*"
],
]
}
......@@ -14,7 +14,7 @@
],
"license": "MIT",
"scripts": {
"clean": "rimraf hardhat *.d.ts *.map *.js tsconfig.tsbuildinfo",
"clean": "rimraf hardhat *.d.ts *.map *.js tsconfig.tsbuildinfo dist",
"build": "tsc -p tsconfig.build.json",
"lint": "yarn run lint:fix && yarn run lint:check",
"lint:check": "tslint --format stylish --project .",
......
......@@ -4,7 +4,7 @@
"main": "dist/index",
"types": "dist/index",
"files": [
"dist"
"dist/index"
],
"license": "MIT",
"scripts": {
......@@ -13,7 +13,7 @@
"lint": "yarn lint:fix && yarn lint:check",
"lint:check": "tslint --format stylish --project .",
"lint:fix": "prettier --config ./prettier-config.json --write \"hardhat.config.ts\" \"{src,test}/**/*.ts\"",
"clean": "rimraf ./artifacts ./cache ./dist"
"clean": "rimraf ./artifacts ./cache ./dist ./tsconfig.build.tsbuildinfo"
},
"peerDependencies": {
"@nomiclabs/ethereumjs-vm": "^4",
......
......@@ -53,18 +53,6 @@
ganache-core "^2.12.1"
glob "^7.1.6"
"@eth-optimism/core-utils@0.1.9":
version "0.1.9"
resolved "https://registry.yarnpkg.com/@eth-optimism/core-utils/-/core-utils-0.1.9.tgz#b63d8dc417b1a27977bdb19d4ca435232f88f944"
integrity sha512-esTG0Fi98pWut9EH+7NKPIJvGY+aTtNvcqtffd/p9oXJjj7Z719zrmqwdvhv3oyymxGIqiZSE38HMPTxVDPVrw==
dependencies:
"@ethersproject/abstract-provider" "^5.0.9"
colors "^1.4.0"
debug "^4.3.1"
ethers "^5.0.31"
pino "^6.11.1"
pino-pretty "^4.7.1"
"@eth-optimism/dev@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@eth-optimism/dev/-/dev-1.1.1.tgz#7bae95b975c1d6641b4ae550cb3ec631c667a56b"
......@@ -86,14 +74,6 @@
tslint-plugin-prettier "^2.3.0"
typescript "^4.1.5"
"@eth-optimism/service-base@^1.1.5":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@eth-optimism/service-base/-/service-base-1.1.5.tgz#fddb8f51f2d082a106fced0826a8e45eabf0a16c"
integrity sha512-0xNwZv5aZknj1LKLiob4VXcGDOUKDLc3YKbW1Cub6j9t0bwIZ8/Y5t2sVJ3/d15wBW/LrSSmGkZRL+tR56ZoNA==
dependencies:
"@eth-optimism/core-utils" "0.1.9"
colors "^1.4.0"
"@ethereum-waffle/chai@^3.3.0":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.3.1.tgz#3f20b810d0fa516f19af93c50c3be1091333fa8e"
......@@ -3575,11 +3555,6 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
colors@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
columnify@^1.5.4:
version "1.5.4"
resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
......@@ -3974,7 +3949,7 @@ debug@3.2.6:
dependencies:
ms "^2.1.1"
debug@4, debug@4.3.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1:
debug@4, debug@4.3.1, debug@^4.1.0, debug@^4.1.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
......
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