diff options
author | Fabio Berger <me@fabioberger.com> | 2018-09-25 21:59:37 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-25 21:59:37 +0800 |
commit | 7570f3db513f1b728e27cdd6273642ab999adbcc (patch) | |
tree | a4c7c16da62f7c3aed4321927d8ef16fc5d23eeb /packages/contract-wrappers | |
parent | 78ef98c27ce954f7e46b261b0809ff9d8d70519b (diff) | |
parent | 977d55c61b9ba8979e0846a780cd8020c821df9b (diff) | |
download | dexon-sol-tools-7570f3db513f1b728e27cdd6273642ab999adbcc.tar dexon-sol-tools-7570f3db513f1b728e27cdd6273642ab999adbcc.tar.gz dexon-sol-tools-7570f3db513f1b728e27cdd6273642ab999adbcc.tar.bz2 dexon-sol-tools-7570f3db513f1b728e27cdd6273642ab999adbcc.tar.lz dexon-sol-tools-7570f3db513f1b728e27cdd6273642ab999adbcc.tar.xz dexon-sol-tools-7570f3db513f1b728e27cdd6273642ab999adbcc.tar.zst dexon-sol-tools-7570f3db513f1b728e27cdd6273642ab999adbcc.zip |
Merge pull request #1080 from 0xProject/upgradeBlockstream
Fix dropped events issue in Order-watcher and Contract-wrappers subscriptions
Diffstat (limited to 'packages/contract-wrappers')
-rw-r--r-- | packages/contract-wrappers/CHANGELOG.json | 23 | ||||
-rw-r--r-- | packages/contract-wrappers/package.json | 2 | ||||
-rw-r--r-- | packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts | 47 |
3 files changed, 53 insertions, 19 deletions
diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index 65aaf15c7..d3e0ad5d1 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -1,21 +1,36 @@ [ { - "timestamp": 1537875740, + "version": "2.0.0", + "changes": [ + { + "note": + "Fixes dropped events in subscriptions by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too.", + "pr": 1080 + }, + { + "note": + "Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it", + "pr": 1080 + } + ] + }, + { "version": "1.0.5", "changes": [ { "note": "Dependencies updated" } - ] + ], + "timestamp": 1537875740 }, { - "timestamp": 1537541580, "version": "1.0.4", "changes": [ { "note": "Dependencies updated" } - ] + ], + "timestamp": 1537541580 }, { "version": "1.0.3", diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 544d667c6..57f994ff1 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -82,7 +82,7 @@ "@0xproject/utils": "^1.0.10", "@0xproject/web3-wrapper": "^3.0.0", "ethereum-types": "^1.0.7", - "ethereumjs-blockstream": "5.0.0", + "ethereumjs-blockstream": "6.0.0", "ethereumjs-util": "^5.1.1", "ethers": "3.0.22", "js-sha3": "^0.7.0", diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts index 19a882712..f7a89e3be 100644 --- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts @@ -1,14 +1,14 @@ import { AbiDecoder, intervalUtils, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper'; import { BlockParamLiteral, - BlockWithoutTransactionData, ContractAbi, ContractArtifact, FilterObject, LogEntry, LogWithDecodedArgs, RawLog, + RawLogEntry, } from 'ethereum-types'; import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; @@ -158,7 +158,8 @@ export abstract class ContractWrapper { return addressIfExists; } } - private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: boolean, log: LogEntry): void { + private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: boolean, rawLog: RawLogEntry): void { + const log: LogEntry = marshaller.unmarshalLog(rawLog); _.forEach(this._filters, (filter: FilterObject, filterToken: string) => { if (filterUtils.matchesFilter(log, filter)) { const decodedLog = this._tryToDecodeLogOrNoop(log) as LogWithDecodedArgs<ArgsType>; @@ -175,8 +176,8 @@ export abstract class ContractWrapper { throw new Error(ContractWrappersError.SubscriptionAlreadyPresent); } this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( - this._getBlockOrNullAsync.bind(this), - this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), + this._blockstreamGetBlockOrNullAsync.bind(this), + this._blockstreamGetLogsAsync.bind(this), ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose), ); const catchAllLogFilter = {}; @@ -196,12 +197,30 @@ export abstract class ContractWrapper { ); } // This method only exists in order to comply with the expected interface of Blockstream's constructor - private async _getBlockOrNullAsync(): Promise<BlockWithoutTransactionData | null> { - const blockIfExists = await this._web3Wrapper.getBlockIfExistsAsync.bind(this._web3Wrapper); - if (_.isUndefined(blockIfExists)) { - return null; - } - return blockIfExists; + private async _blockstreamGetBlockOrNullAsync(hash: string): Promise<Block | null> { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync<Block | null>({ + method: 'eth_getBlockByHash', + params: [hash, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLatestBlockOrNullAsync(): Promise<Block | null> { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync<Block | null>({ + method: 'eth_getBlockByNumber', + params: [BlockParamLiteral.Latest, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLogsAsync(filterOptions: FilterObject): Promise<RawLogEntry[]> { + const logs = await this._web3Wrapper.sendRawPayloadAsync<RawLogEntry[]>({ + method: 'eth_getLogs', + params: [filterOptions], + }); + return logs as RawLogEntry[]; } // HACK: This should be a package-scoped method (which doesn't exist in TS) // We don't want this method available in the public interface for all classes @@ -221,14 +240,14 @@ export abstract class ContractWrapper { delete this._blockAndLogStreamerIfExists; } private async _reconcileBlockAsync(): Promise<void> { - const latestBlockIfExists = await this._web3Wrapper.getBlockIfExistsAsync(BlockParamLiteral.Latest); - if (_.isUndefined(latestBlockIfExists)) { + const latestBlockOrNull = await this._blockstreamGetLatestBlockOrNullAsync(); + if (_.isNull(latestBlockOrNull)) { return; // noop } // We need to coerce to Block type cause Web3.Block includes types for mempool blocks if (!_.isUndefined(this._blockAndLogStreamerIfExists)) { // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined - await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlockIfExists as any) as Block); + await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlockOrNull); } } } |