From f5e0fd8de5a3201ac17a8dde68aec3314674f1c4 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 22 Nov 2017 14:21:07 -0600 Subject: Upgrade to latest 0x.js version and refactor subscriptions to use latest interface --- packages/website/package.json | 2 +- packages/website/ts/blockchain.ts | 64 ++++++++++++++-------- .../ts/local_storage/trade_history_storage.tsx | 14 ++++- yarn.lock | 4 -- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/packages/website/package.json b/packages/website/package.json index ba71ee0eb..d6d92d0f8 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -16,6 +16,7 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { + "0x.js": "^0.26.0", "accounting": "^0.4.1", "basscss": "^8.0.3", "bignumber.js": "~4.1.0", @@ -69,7 +70,6 @@ "@types/accounting": "^0.4.1", "@types/dateformat": "^1.0.1", "@types/deep-equal": "^1.0.0", - "@types/es6-promise": "0.0.32", "@types/jsonschema": "^1.1.1", "@types/lodash": "^4.14.55", "@types/material-ui": "0.18.0", diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index d891acdb6..3a1b62164 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -27,7 +27,7 @@ import contract = require('truffle-contract'); import ethUtil = require('ethereumjs-util'); import ProviderEngine = require('web3-provider-engine'); import FilterSubprovider = require('web3-provider-engine/subproviders/filters'); -import {TransactionSubmitted} from 'ts/components/flash_messages/transaction_submitted'; +import { TransactionSubmitted } from 'ts/components/flash_messages/transaction_submitted'; import {TokenSendCompleted} from 'ts/components/flash_messages/token_send_completed'; import {RedundantRPCSubprovider} from 'ts/subproviders/redundant_rpc_subprovider'; import {InjectedWeb3SubProvider} from 'ts/subproviders/injected_web3_subprovider'; @@ -496,7 +496,16 @@ export class Blockchain { this.stopWatchingExchangeLogFillEventsAsync(); // fire and forget return; } else { - await this.addFillEventToTradeHistoryAsync(decodedLogEvent); + if (this.doesLogEventInvolveUser(decodedLogEvent)) { + return; // We aren't interested in the fill event + } + this.updateLatestFillsBlockIfNeeded(decodedLogEvent.blockNumber); + const fill = await this.convertDecodedLogToFillAsync(decodedLogEvent); + if (decodedLogEvent.removed) { + tradeHistoryStorage.removeFillFromUser(this.userAddress, this.networkId, fill); + } else { + tradeHistoryStorage.addFillToUser(this.userAddress, this.networkId, fill); + } } }); } @@ -510,30 +519,16 @@ export class Blockchain { ExchangeEvents.LogFill, subscriptionOpts, indexFilterValues, ); for (const decodedLog of decodedLogs) { - console.log('decodedLog', decodedLog); - await this.addFillEventToTradeHistoryAsync(decodedLog); + if (this.doesLogEventInvolveUser(decodedLog)) { + continue; // We aren't interested in the fill event + } + this.updateLatestFillsBlockIfNeeded(decodedLog.blockNumber); + const fill = await this.convertDecodedLogToFillAsync(decodedLog); + tradeHistoryStorage.addFillToUser(this.userAddress, this.networkId, fill); } } - private async addFillEventToTradeHistoryAsync(decodedLog: LogWithDecodedArgs) { + private async convertDecodedLogToFillAsync(decodedLog: LogWithDecodedArgs) { const args = decodedLog.args as LogFillContractEventArgs; - const isUserMakerOrTaker = args.maker === this.userAddress || - args.taker === this.userAddress; - if (!isUserMakerOrTaker) { - return; // We aren't interested in the fill event - } - const isBlockPending = _.isNull(decodedLog.blockNumber); - if (!isBlockPending) { - // Hack: I've observed the behavior where a client won't register certain fill events - // and lowering the cache blockNumber fixes the issue. As a quick fix for now, simply - // set the cached blockNumber 50 below the one returned. This way, upon refreshing, a user - // would still attempt to re-fetch events from the previous 50 blocks, but won't need to - // re-fetch all events in all blocks. - // TODO: Debug if this is a race condition, and apply a more precise fix - const blockNumberToSet = decodedLog.blockNumber - BLOCK_NUMBER_BACK_TRACK < 0 ? - 0 : - decodedLog.blockNumber - BLOCK_NUMBER_BACK_TRACK; - tradeHistoryStorage.setFillsLatestBlock(this.userAddress, this.networkId, blockNumberToSet); - } const blockTimestamp = await this.web3Wrapper.getBlockTimestampAsync(decodedLog.blockHash); const fill = { filledTakerTokenAmount: args.filledTakerTokenAmount, @@ -549,7 +544,28 @@ export class Blockchain { transactionHash: decodedLog.transactionHash, blockTimestamp, }; - tradeHistoryStorage.addFillToUser(this.userAddress, this.networkId, fill); + return fill; + } + private doesLogEventInvolveUser(decodedLog: LogWithDecodedArgs) { + const args = decodedLog.args as LogFillContractEventArgs; + const isUserMakerOrTaker = args.maker === this.userAddress || + args.taker === this.userAddress; + return isUserMakerOrTaker; + } + private updateLatestFillsBlockIfNeeded(blockNumber: number) { + const isBlockPending = _.isNull(blockNumber); + if (!isBlockPending) { + // Hack: I've observed the behavior where a client won't register certain fill events + // and lowering the cache blockNumber fixes the issue. As a quick fix for now, simply + // set the cached blockNumber 50 below the one returned. This way, upon refreshing, a user + // would still attempt to re-fetch events from the previous 50 blocks, but won't need to + // re-fetch all events in all blocks. + // TODO: Debug if this is a race condition, and apply a more precise fix + const blockNumberToSet = blockNumber - BLOCK_NUMBER_BACK_TRACK < 0 ? + 0 : + blockNumber - BLOCK_NUMBER_BACK_TRACK; + tradeHistoryStorage.setFillsLatestBlock(this.userAddress, this.networkId, blockNumberToSet); + } } private async stopWatchingExchangeLogFillEventsAsync() { this.zeroEx.exchange.unsubscribeAll(); diff --git a/packages/website/ts/local_storage/trade_history_storage.tsx b/packages/website/ts/local_storage/trade_history_storage.tsx index 415b380b7..dd5872609 100644 --- a/packages/website/ts/local_storage/trade_history_storage.tsx +++ b/packages/website/ts/local_storage/trade_history_storage.tsx @@ -31,13 +31,25 @@ export const tradeHistoryStorage = { const fillHash = this._getFillHash(fill); const doesFillExist = !_.isUndefined(fillsByHash[fillHash]); if (doesFillExist) { - return; + return; // noop } fillsByHash[fillHash] = fill; const userFillsJSONString = JSON.stringify(fillsByHash); const userFillsKey = this._getUserFillsKey(userAddress, networkId); localStorage.setItem(userFillsKey, userFillsJSONString); }, + removeFillFromUser(userAddress: string, networkId: number, fill: Fill) { + const fillsByHash = this.getUserFillsByHash(userAddress, networkId); + const fillHash = this._getFillHash(fill); + const doesFillExist = !_.isUndefined(fillsByHash[fillHash]); + if (!doesFillExist) { + return; // noop + } + delete fillsByHash[fillHash]; + const userFillsJSONString = JSON.stringify(fillsByHash); + const userFillsKey = this._getUserFillsKey(userAddress, networkId); + localStorage.setItem(userFillsKey, userFillsJSONString); + }, getUserFillsByHash(userAddress: string, networkId: number): {[fillHash: string]: Fill} { const userFillsKey = this._getUserFillsKey(userAddress, networkId); const userFillsJSONString = localStorage.getItemIfExists(userFillsKey); diff --git a/yarn.lock b/yarn.lock index 71fa75f7a..6b7bb615d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14,10 +14,6 @@ version "1.0.1" resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03" -"@types/es6-promise@0.0.32": - version "0.0.32" - resolved "https://registry.yarnpkg.com/@types/es6-promise/-/es6-promise-0.0.32.tgz#3bcf44fb1e429f3df76188c8c6d874463ba371fd" - "@types/fetch-mock@^5.12.1": version "5.12.2" resolved "https://registry.yarnpkg.com/@types/fetch-mock/-/fetch-mock-5.12.2.tgz#8c96517ff74303031c65c5da2d99858e34c844d2" -- cgit