Skip to content

Commit

Permalink
Generic L1 Communication (#473)
Browse files Browse the repository at this point in the history
Adding Event and Block subscription capabilities and tests
  • Loading branch information
willmeister committed Sep 27, 2019
1 parent 3239a0e commit cae79c3
Show file tree
Hide file tree
Showing 36 changed files with 861 additions and 948 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"lint": "wsrun -p $(yarn --silent run pkgparse) --parallel --exclude-missing lint",
"fix": "wsrun -p $(yarn --silent run pkgparse) --fast-exit --parallel --exclude-missing fix",
"clean": "wsrun -p $(yarn --silent run pkgparse) -r --fast-exit --parallel --exclude-missing clean",
"clean_modules": "rm -rf node_modules && find ./packages -type d -maxdepth 2 -name \"node_modules\" -exec rm -r {} +",
"test": "wsrun -p $(yarn --silent run pkgparse) --fast-exit --parallel --no-prefix --exclude-missing --timeout 5000 test",
"build": "lerna link && wsrun -p $(yarn --silent run pkgparse) -r --fast-exit --stages --exclude-missing build",
"release": "yarn run build && lerna publish --force-publish --exact -m \"chore(@plasma-group) publish %s release\"",
Expand All @@ -38,7 +39,6 @@
"@types/node": "^11.11.3",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"ganache-cli": "^6.4.5",
"lerna": "^3.13.1",
"mocha": "^6.0.2",
"prettier": "^1.16.4",
Expand All @@ -52,7 +52,6 @@
"dependencies": {
"bignumber.js": "^9.0.0",
"chai-bignumber": "^3.0.0",
"ganache-core": "2.5.7",
"level": "^5.0.1"
}
}
5 changes: 2 additions & 3 deletions packages/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@
"memdown": "^5.0.0",
"mocha": "^6.0.2",
"rimraf": "^2.6.3",
"typescript": "^3.3.3333",
"web3": "^1.0.0-beta.48"
"typescript": "^3.3.3333"
},
"dependencies": {
"@pigi/core": "^0.0.1-alpha.1",
Expand All @@ -50,7 +49,7 @@
"chai": "^4.2.0",
"debug": "^4.1.1",
"ethereum-waffle": "^2.0.12",
"ethers": "^4.0.30",
"ethers": "^4.0.37",
"merkletreejs": "^0.1.7",
"openzeppelin-solidity": "^2.2.0"
}
Expand Down
6 changes: 2 additions & 4 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,14 @@
"chai-as-promised": "^7.1.1",
"debug": "^4.1.1",
"eth-lib": "^0.2.8",
"ethers": "^4.0.30",
"ethers": "^4.0.37",
"express": "^4.17.1",
"ganache-cli": "^6.4.4",
"jayson": "^3.0.2",
"level": "^5.0.1",
"memdown": "^4.0.0",
"ts-md5": "^1.2.4",
"uuid": "^3.3.2",
"web3": "^1.0.0-beta.55",
"web3-utils": "^1.0.0-beta.55"
"uuid": "^3.3.2"
},
"devDependencies": {
"@types/abstract-leveldown": "^5.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/app/utils/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ethers } from 'ethers'
* @returns the hash as a Buffer
*/
export const Md5Hash = (preimage: string): string => {
return Md5.hashStr(preimage) as string
return Md5.hashStr(preimage).toString()
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/example-rollup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"debug": "^4.1.1",
"ethers": "^4.0.30",
"ethers": "^4.0.37",
"mocha": "^6.1.2",
"prettier": "^1.16.4",
"rimraf": "^2.6.3",
Expand Down
36 changes: 0 additions & 36 deletions packages/types/package-lock.json

This file was deleted.

5 changes: 2 additions & 3 deletions packages/wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@
},
"dependencies": {
"async-lock": "^1.2.2",
"@pigi/core": "^0.0.1-alpha.1"
"@pigi/core": "^0.0.2-alpha.1"
},
"devDependencies": {
"@pigi/core": "^0.0.1-alpha.1",
"@pigi/prettier-config": "^0.0.2-alpha.2",
"@types/chai": "^4.1.7",
"@types/debug": "^4.1.2",
"@types/mocha": "^5.2.6",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"debug": "^4.1.1",
"ethers": "^4.0.30",
"ethers": "^4.0.37",
"memdown": "^5.0.0",
"mocha": "^6.1.2",
"prettier": "^1.16.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/wallet/src/types/rollup-state-solver.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Address, SignedStateReceipt, StateReceipt } from './types'
import { ImplicationProofItem } from '@pigi/core/build/src/types'
import { ImplicationProofItem } from '@pigi/core'

export interface RollupStateSolver {
/**
Expand Down
10 changes: 1 addition & 9 deletions packages/watch-eth/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1 @@
export { EventWatcher, EventWatcherOptions } from './src/event-watcher'
export { DefaultEventLog, EventFilter } from './src/models'
export {
EventDB,
EthProvider,
FullEventFilter,
EventFilterOptions,
EventLog,
} from './src/interfaces'
export * from './src'
20 changes: 13 additions & 7 deletions packages/watch-eth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
],
"scripts": {
"lint": "tslint --format stylish --project .",
"fix": "prettier --config ./.prettierrc.js --write 'index.ts' 'src/**/*.ts'",
"fix": "prettier --config ./.prettierrc.js --write 'index.ts' '{src,test}/**/*.ts'",
"build": "tsc -p .",
"clean": "rimraf build/"
"clean": "rimraf build/",
"test": "waffle waffle-config.json && mocha --require ts-node/register 'test/*.spec.ts' --timeout 5000 --exit"
},
"husky": {
"hooks": {
Expand All @@ -31,24 +32,29 @@
"license": "MIT",
"dependencies": {
"@types/node": "^11.10.0",
"web3": "^1.0.0-beta.47"
"@pigi/core": "^0.0.2-alpha.1",
"ethers": "^4.0.37"
},
"devDependencies": {
"@pigi/prettier-config": "^0.0.2-alpha.2",
"@types/chai": "^4.1.7",
"@types/mocha": "^5.2.6",
"@types/web3": "^1.0.18",
"@types/node": "^11.10.0",
"@types/web3": "^1.0.20",
"bn.js": "^5.0.0",
"chai": "^4.2.0",
"ganache-cli": "^6.4.1",
"ethereum-waffle": "^2.0.12",
"ganache-cli": "^6.7.0",
"husky": "^1.3.1",
"lint-staged": "^8.1.5",
"mocha": "^6.0.2",
"mocha": "^6.2.0",
"prettier": "^1.16.4",
"tslint": "^5.13.1",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.0.1",
"typescript": "^3.3.3333",
"rimraf": "^2.6.3",
"chai-as-promised": "^7.1.1"
"chai-as-promised": "^7.1.1",
"chai-bignumber": "^3.0.0"
}
}
50 changes: 0 additions & 50 deletions packages/watch-eth/src/eth-provider.ts

This file was deleted.

132 changes: 132 additions & 0 deletions packages/watch-eth/src/ethereum-block-processor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/* External Imports */
import { DB, getLogger, logError } from '@pigi/core'
import { Block, Provider } from 'ethers/providers'

/* Internal Imports */
import { EthereumListener } from './interfaces/listener'

const log = getLogger('ethereum-block-processor')
const blockKey: Buffer = Buffer.from('latestBlock')

/**
* Ethereum Block Processor
* Single place through which all block subscriptions are handled.
*/
export class EthereumBlockProcessor {
private readonly subscriptions: Set<EthereumListener<Block>>
private currentBlockNumber: number

constructor(
private readonly db: DB,
private readonly earliestBlock: number = 0
) {
this.subscriptions = new Set<EthereumListener<Block>>()
this.currentBlockNumber = 0
}

/**
* Subscribes to new blocks.
* This will also fetch and send the provided event handler all historical blocks not in
* the database unless backfill is set to false.
*
* @param provider The provider with the connection to the blockchain
* @param handler The event handler subscribing
* @param backfill Whether or not to fetch previous events
*/
public async subscribe(
provider: Provider,
handler: EthereumListener<Block>,
backfill: boolean = true
): Promise<void> {
this.subscriptions.add(handler)

provider.on('block', async (blockNumber) => {
log.debug(`Block [${blockNumber}] was mined!`)
await this.fetchAndDisseminateBlock(provider, blockNumber)
this.currentBlockNumber = blockNumber
try {
await this.db.put(
blockKey,
Buffer.from(this.currentBlockNumber.toString())
)
} catch (e) {
logError(
log,
`Error storing most recent block received [${blockNumber}]!`,
e
)
}
})

if (backfill) {
await this.backfillBlocks(provider)
}
}

/**
* Fetches and broadcasts the Block for the provided block number.
*
* @param provider The provider with the connection to the blockchain
* @param blockNumber The block number
*/
private async fetchAndDisseminateBlock(
provider: Provider,
blockNumber: number
): Promise<void> {
log.debug(`Fetching block [${blockNumber}].`)
const block: Block = await provider.getBlock(blockNumber, true)
log.debug(`Received block: [${JSON.stringify(block)}].`)

this.subscriptions.forEach((h) => {
try {
// purposefully ignore promise
h.handle(block)
} catch (e) {
// should be logged in handler
}
})
}

/**
* Fetches historical blocks.
*
* @param provider The provider with the connection to the blockchain.
*/
private async backfillBlocks(provider: Provider): Promise<void> {
log.debug(`Backfilling blocks`)
const blockNumber = await this.getBlockNumber(provider)

const lastSyncedBlockBuffer: Buffer = await this.db.get(blockKey)
const lastSyncedNumber: number = !!lastSyncedBlockBuffer
? parseInt(lastSyncedBlockBuffer.toString(), 10)
: this.earliestBlock - 1

if (blockNumber === lastSyncedNumber) {
log.debug(`Up to date, not backfilling.`)
return
}

for (let i = lastSyncedNumber + 1; i <= blockNumber; i++) {
await this.fetchAndDisseminateBlock(provider, i)
}

log.debug(
`backfilled from block [${lastSyncedNumber + 1}] to [${blockNumber}]!`
)
}

/**
* Fetches the current block number from the given provider.
*
* @param provider The provider connected to a node
* @returns The current block number
*/
private async getBlockNumber(provider: Provider): Promise<number> {
if (this.currentBlockNumber === 0) {
this.currentBlockNumber = await provider.getBlockNumber()
}

log.debug(`Current block number: ${this.currentBlockNumber}`)
return this.currentBlockNumber
}
}

0 comments on commit cae79c3

Please sign in to comment.