diff options
Diffstat (limited to 'packages/order-watcher')
-rw-r--r-- | packages/order-watcher/CHANGELOG.json | 75 | ||||
-rw-r--r-- | packages/order-watcher/CHANGELOG.md | 26 | ||||
-rw-r--r-- | packages/order-watcher/package.json | 47 | ||||
-rw-r--r-- | packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts | 74 | ||||
-rw-r--r-- | packages/order-watcher/src/fetchers/order_filled_cancelled_fetcher.ts | 27 | ||||
-rw-r--r-- | packages/order-watcher/src/index.ts | 1 | ||||
-rw-r--r-- | packages/order-watcher/src/order_watcher/event_watcher.ts | 46 | ||||
-rw-r--r-- | packages/order-watcher/src/order_watcher/order_watcher.ts | 29 | ||||
-rw-r--r-- | packages/order-watcher/test/order_watcher_test.ts | 26 | ||||
-rw-r--r-- | packages/order-watcher/tsconfig.json | 3 | ||||
-rw-r--r-- | packages/order-watcher/typedoc-tsconfig.json | 7 |
11 files changed, 212 insertions, 149 deletions
diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json index 04ec38fe3..3abd67fda 100644 --- a/packages/order-watcher/CHANGELOG.json +++ b/packages/order-watcher/CHANGELOG.json @@ -1,5 +1,80 @@ [ { + "version": "2.1.0", + "changes": [ + { + "note": "Export ExpirationWatcher", + "pr": 1097 + } + ] + }, + { + "version": "2.0.0", + "changes": [ + { + "note": + "Fixes dropped events issue 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 + }, + { + "note": + "Add `transactionHash` to `OrderState` emitted by `OrderWatcher` subscriptions if the order's state change originated from a transaction.", + "pr": 1087 + } + ], + "timestamp": 1537907159 + }, + { + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537875740 + }, + { + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537541580 + }, + { + "version": "1.0.3", + "changes": [ + { + "note": "Drastically reduce the bundle size by removing unused parts of included contract artifacts." + } + ], + "timestamp": 1537369748 + }, + { + "version": "1.0.2", + "changes": [ + { + "note": "Add ZRX & WETH mainnet contract addresses into the included artifacts" + } + ], + "timestamp": 1537265493 + }, + { + "timestamp": 1536142250, + "version": "1.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { "version": "1.0.1-rc.5", "changes": [ { diff --git a/packages/order-watcher/CHANGELOG.md b/packages/order-watcher/CHANGELOG.md index 5f34ea726..32837337a 100644 --- a/packages/order-watcher/CHANGELOG.md +++ b/packages/order-watcher/CHANGELOG.md @@ -5,6 +5,32 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.0 - _September 25, 2018_ + + * Fixes dropped events issue 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. (#1080) + * Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it (#1080) + * Add `transactionHash` to `OrderState` emitted by `OrderWatcher` subscriptions if the order's state change originated from a transaction. (#1087) + +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.4 - _September 21, 2018_ + + * Dependencies updated + +## v1.0.3 - _September 19, 2018_ + + * Drastically reduce the bundle size by removing unused parts of included contract artifacts. + +## v1.0.2 - _September 18, 2018_ + + * Add ZRX & WETH mainnet contract addresses into the included artifacts + +## v1.0.1 - _September 5, 2018_ + + * Dependencies updated + ## v1.0.1-rc.5 - _August 27, 2018_ * Fix missing `BlockParamLiteral` type import issue diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index 0d5bfd48c..001f6c048 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/order-watcher", - "version": "1.0.1-rc.5", + "version": "2.0.0", "description": "An order watcher daemon that watches for order validity", "keywords": [ "0x", @@ -12,8 +12,7 @@ "main": "lib/src/index.js", "types": "lib/src/index.d.ts", "scripts": { - "watch_without_deps": "yarn pre_build && tsc -w", - "build": "yarn pre_build && tsc", + "build": "yarn pre_build && tsc -b", "pre_build": "run-s update_artifacts copy_artifacts generate_contract_wrappers", "lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/*", "generate_contract_wrappers": "abi-gen --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers", @@ -23,13 +22,13 @@ "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov", "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info", "copy_artifacts": "copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts", - "update_artifacts": "for i in ${npm_package_config_contracts_v2_beta}; do copyfiles -u 4 ../migrations/artifacts/2.0.0-beta-testnet/$i.json src/artifacts; done;", + "update_artifacts": "for i in ${npm_package_config_contracts_v2}; do copyfiles -u 4 ../migrations/artifacts/2.0.0-trimmed/$i.json src/artifacts; done;", "clean": "shx rm -rf _bundles lib test_temp test/artifacts src/generated_contract_wrappers generated_docs", "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit", - "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES" + "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" }, "config": { - "contracts_v2_beta": "AssetProxyOwner ERC20Proxy ERC20Token ERC721Proxy ERC721Token Exchange Forwarder OrderValidator WETH9 ZRXToken", + "contracts_v2": "AssetProxyOwner ERC20Proxy ERC20Token ERC721Proxy ERC721Token Exchange Forwarder OrderValidator WETH9 ZRXToken", "postpublish": { "assets": [] } @@ -43,14 +42,14 @@ "node": ">=6.0.0" }, "devDependencies": { - "@0xproject/abi-gen": "^1.0.7", - "@0xproject/dev-utils": "^1.0.6", - "@0xproject/migrations": "^1.0.6", - "@0xproject/tslint-config": "^1.0.6", + "@0xproject/abi-gen": "^1.0.11", + "@0xproject/dev-utils": "^1.0.10", + "@0xproject/migrations": "^1.0.12", + "@0xproject/tslint-config": "^1.0.7", "@types/bintrees": "^1.0.2", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/sinon": "^2.2.2", "awesome-typescript-loader": "^3.1.3", "chai": "^4.0.1", @@ -71,20 +70,20 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/assert": "^1.0.7", - "@0xproject/base-contract": "^2.0.1", - "@0xproject/contract-wrappers": "^1.0.1-rc.5", - "@0xproject/fill-scenarios": "^1.0.1-rc.5", - "@0xproject/json-schemas": "^1.0.1-rc.6", - "@0xproject/order-utils": "^1.0.1-rc.6", - "@0xproject/types": "^1.0.1-rc.6", - "@0xproject/typescript-typings": "^1.0.5", - "@0xproject/utils": "^1.0.7", - "@0xproject/web3-wrapper": "^2.0.1", + "@0xproject/assert": "^1.0.11", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/contract-wrappers": "^2.0.0", + "@0xproject/fill-scenarios": "^1.0.5", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "bintrees": "^1.0.2", - "ethereum-types": "^1.0.5", - "ethereumjs-blockstream": "5.0.0", - "ethers": "3.0.22", + "ethereum-types": "^1.0.8", + "ethereumjs-blockstream": "6.0.0", + "ethers": "4.0.0-beta.14", "lodash": "^4.17.5" }, "publishConfig": { diff --git a/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts b/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts deleted file mode 100644 index a1de22a5e..000000000 --- a/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts +++ /dev/null @@ -1,74 +0,0 @@ -// tslint:disable:no-unnecessary-type-assertion -import { BlockParamLiteral, ERC20TokenWrapper, ERC721TokenWrapper } from '@0xproject/contract-wrappers'; -import { AbstractBalanceAndProxyAllowanceFetcher, assetDataUtils } from '@0xproject/order-utils'; -import { AssetProxyId, ERC20AssetData, ERC721AssetData } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; - -export class AssetBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher { - private readonly _erc20Token: ERC20TokenWrapper; - private readonly _erc721Token: ERC721TokenWrapper; - private readonly _stateLayer: BlockParamLiteral; - constructor(erc20Token: ERC20TokenWrapper, erc721Token: ERC721TokenWrapper, stateLayer: BlockParamLiteral) { - this._erc20Token = erc20Token; - this._erc721Token = erc721Token; - this._stateLayer = stateLayer; - } - public async getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber> { - const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); - if (decodedAssetData.assetProxyId === AssetProxyId.ERC20) { - const decodedERC20AssetData = decodedAssetData as ERC20AssetData; - const balance = await this._erc20Token.getBalanceAsync(decodedERC20AssetData.tokenAddress, userAddress, { - defaultBlock: this._stateLayer, - }); - return balance; - } else { - const decodedERC721AssetData = decodedAssetData as ERC721AssetData; - const tokenOwner = await this._erc721Token.getOwnerOfAsync( - decodedERC721AssetData.tokenAddress, - decodedERC721AssetData.tokenId, - { - defaultBlock: this._stateLayer, - }, - ); - const balance = tokenOwner === userAddress ? new BigNumber(1) : new BigNumber(0); - return balance; - } - } - public async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber> { - const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); - if (decodedAssetData.assetProxyId === AssetProxyId.ERC20) { - const decodedERC20AssetData = decodedAssetData as ERC20AssetData; - const proxyAllowance = await this._erc20Token.getProxyAllowanceAsync( - decodedERC20AssetData.tokenAddress, - userAddress, - { - defaultBlock: this._stateLayer, - }, - ); - return proxyAllowance; - } else { - const decodedERC721AssetData = decodedAssetData as ERC721AssetData; - - const isApprovedForAll = await this._erc721Token.isProxyApprovedForAllAsync( - decodedERC721AssetData.tokenAddress, - userAddress, - { - defaultBlock: this._stateLayer, - }, - ); - if (isApprovedForAll) { - return new BigNumber(this._erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); - } else { - const isApproved = await this._erc721Token.isProxyApprovedAsync( - decodedERC721AssetData.tokenAddress, - decodedERC721AssetData.tokenId, - { - defaultBlock: this._stateLayer, - }, - ); - const proxyAllowance = isApproved ? new BigNumber(1) : new BigNumber(0); - return proxyAllowance; - } - } - } -} diff --git a/packages/order-watcher/src/fetchers/order_filled_cancelled_fetcher.ts b/packages/order-watcher/src/fetchers/order_filled_cancelled_fetcher.ts deleted file mode 100644 index bfad1a48c..000000000 --- a/packages/order-watcher/src/fetchers/order_filled_cancelled_fetcher.ts +++ /dev/null @@ -1,27 +0,0 @@ -// tslint:disable:no-unnecessary-type-assertion -import { BlockParamLiteral, ExchangeWrapper } from '@0xproject/contract-wrappers'; -import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils'; -import { BigNumber } from '@0xproject/utils'; - -export class OrderFilledCancelledFetcher implements AbstractOrderFilledCancelledFetcher { - private readonly _exchange: ExchangeWrapper; - private readonly _stateLayer: BlockParamLiteral; - constructor(exchange: ExchangeWrapper, stateLayer: BlockParamLiteral) { - this._exchange = exchange; - this._stateLayer = stateLayer; - } - public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber> { - const filledTakerAmount = this._exchange.getFilledTakerAssetAmountAsync(orderHash, { - defaultBlock: this._stateLayer, - }); - return filledTakerAmount; - } - public async isOrderCancelledAsync(orderHash: string): Promise<boolean> { - const isCancelled = await this._exchange.isCancelledAsync(orderHash); - return isCancelled; - } - public getZRXAssetData(): string { - const zrxAssetData = this._exchange.getZRXAssetData(); - return zrxAssetData; - } -} diff --git a/packages/order-watcher/src/index.ts b/packages/order-watcher/src/index.ts index 8efca6217..d7ad4fba7 100644 --- a/packages/order-watcher/src/index.ts +++ b/packages/order-watcher/src/index.ts @@ -1,4 +1,5 @@ export { OrderWatcher } from './order_watcher/order_watcher'; +export { ExpirationWatcher } from './order_watcher/expiration_watcher'; export { OrderStateValid, diff --git a/packages/order-watcher/src/order_watcher/event_watcher.ts b/packages/order-watcher/src/order_watcher/event_watcher.ts index 9509c75de..9ea301815 100644 --- a/packages/order-watcher/src/order_watcher/event_watcher.ts +++ b/packages/order-watcher/src/order_watcher/event_watcher.ts @@ -1,6 +1,6 @@ import { intervalUtils, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import { BlockParamLiteral, LogEntry, Provider } from 'ethereum-types'; +import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper'; +import { BlockParamLiteral, FilterObject, LogEntry, Provider, RawLogEntry } from 'ethereum-types'; import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; @@ -20,7 +20,6 @@ enum LogEventState { */ export class EventWatcher { private readonly _web3Wrapper: Web3Wrapper; - private readonly _stateLayer: BlockParamLiteral; private readonly _isVerbose: boolean; private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined; private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer; @@ -35,7 +34,6 @@ export class EventWatcher { ) { this._isVerbose = isVerbose; this._web3Wrapper = new Web3Wrapper(provider); - this._stateLayer = stateLayer; this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs) ? DEFAULT_EVENT_POLLING_INTERVAL_MS : pollingIntervalIfExistsMs; @@ -62,8 +60,8 @@ export class EventWatcher { throw new Error(OrderWatcherError.SubscriptionAlreadyPresent); } this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( - this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper), - this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), + this._blockstreamGetBlockOrNullAsync.bind(this), + this._blockstreamGetLogsAsync.bind(this), this._onBlockAndLogStreamerError.bind(this), ); const catchAllLogFilter = {}; @@ -82,6 +80,32 @@ export class EventWatcher { this._onLogStateChangedAsync.bind(this, callback, isRemoved), ); } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + 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[]; + } private _stopBlockAndLogStream(): void { if (_.isUndefined(this._blockAndLogStreamerIfExists)) { throw new Error(OrderWatcherError.SubscriptionNotFound); @@ -95,16 +119,20 @@ export class EventWatcher { private async _onLogStateChangedAsync( callback: EventWatcherCallback, isRemoved: boolean, - log: LogEntry, + rawLog: RawLogEntry, ): Promise<void> { + const log: LogEntry = marshaller.unmarshalLog(rawLog); await this._emitDifferencesAsync(log, isRemoved ? LogEventState.Removed : LogEventState.Added, callback); } private async _reconcileBlockAsync(): Promise<void> { - const latestBlock = await this._web3Wrapper.getBlockAsync(this._stateLayer); + 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((latestBlock as any) as Block); + await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlockOrNull); } } private async _emitDifferencesAsync( diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index d4c5cca4b..f9a63efe3 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -1,5 +1,6 @@ // tslint:disable:no-unnecessary-type-assertion import { + AssetBalanceAndProxyAllowanceFetcher, ContractWrappers, ERC20TokenApprovalEventArgs, ERC20TokenEventArgs, @@ -15,6 +16,7 @@ import { ExchangeEventArgs, ExchangeEvents, ExchangeFillEventArgs, + OrderFilledCancelledFetcher, WETH9DepositEventArgs, WETH9EventArgs, WETH9Events, @@ -34,8 +36,6 @@ import { BlockParamLiteral, LogEntryEvent, LogWithDecodedArgs, Provider } from ' import * as _ from 'lodash'; import { artifacts } from '../artifacts'; -import { AssetBalanceAndProxyAllowanceFetcher } from '../fetchers/asset_balance_and_proxy_allowance_fetcher'; -import { OrderFilledCancelledFetcher } from '../fetchers/order_filled_cancelled_fetcher'; import { orderWatcherPartialConfigSchema } from '../schemas/order_watcher_partial_config_schema'; import { OnOrderStateChangeCallback, OrderWatcherConfig, OrderWatcherError } from '../types'; import { assert } from '../utils/assert'; @@ -275,6 +275,7 @@ export class OrderWatcher { return; // noop } const decodedLog = (maybeDecodedLog as any) as LogWithDecodedArgs<ContractEventArgs>; + const transactionHash = decodedLog.transactionHash; switch (decodedLog.event) { case ERC20TokenEvents.Approval: case ERC721TokenEvents.Approval: { @@ -290,7 +291,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } else { // ERC721 @@ -303,7 +304,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } } @@ -322,7 +323,7 @@ export class OrderWatcher { args._from, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } else { // ERC721 @@ -336,7 +337,7 @@ export class OrderWatcher { args._from, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } } @@ -350,7 +351,7 @@ export class OrderWatcher { args._owner, tokenAddress, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case WETH9Events.Deposit: { @@ -363,7 +364,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case WETH9Events.Withdrawal: { @@ -376,7 +377,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case ExchangeEvents.Fill: { @@ -387,7 +388,7 @@ export class OrderWatcher { const orderHash = args.orderHash; const isOrderWatched = !_.isUndefined(this._orderByOrderHash[orderHash]); if (isOrderWatched) { - await this._emitRevalidateOrdersAsync([orderHash]); + await this._emitRevalidateOrdersAsync([orderHash], transactionHash); } break; } @@ -399,7 +400,7 @@ export class OrderWatcher { const orderHash = args.orderHash; const isOrderWatched = !_.isUndefined(this._orderByOrderHash[orderHash]); if (isOrderWatched) { - await this._emitRevalidateOrdersAsync([orderHash]); + await this._emitRevalidateOrdersAsync([orderHash], transactionHash); } break; } @@ -410,7 +411,7 @@ export class OrderWatcher { this._orderFilledCancelledLazyStore.deleteAllIsCancelled(); // Revalidate orders const orderHashes = this._dependentOrderHashesTracker.getDependentOrderHashesByMaker(args.makerAddress); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } @@ -418,12 +419,12 @@ export class OrderWatcher { throw errorUtils.spawnSwitchErr('decodedLog.event', decodedLog.event); } } - private async _emitRevalidateOrdersAsync(orderHashes: string[]): Promise<void> { + private async _emitRevalidateOrdersAsync(orderHashes: string[], transactionHash?: string): Promise<void> { for (const orderHash of orderHashes) { const signedOrder = this._orderByOrderHash[orderHash]; // Most of these calls will never reach the network because the data is fetched from stores // and only updated when cache is invalidated - const orderState = await this._orderStateUtils.getOpenOrderStateAsync(signedOrder); + const orderState = await this._orderStateUtils.getOpenOrderStateAsync(signedOrder, transactionHash); if (_.isUndefined(this._callbackIfExists)) { break; // Unsubscribe was called } diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts index 38bfde7ef..60d9069e8 100644 --- a/packages/order-watcher/test/order_watcher_test.ts +++ b/packages/order-watcher/test/order_watcher_test.ts @@ -250,6 +250,32 @@ describe('OrderWatcher', () => { await contractWrappers.exchange.fillOrderAsync(signedOrder, fillableAmount, takerAddress); })().catch(done); }); + it('should include transactionHash in emitted orderStateInvalid when watched order fully filled', (done: DoneCallback) => { + (async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + ); + await orderWatcher.addOrderAsync(signedOrder); + + let transactionHash: string; + const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { + expect(orderState.isValid).to.be.false(); + const invalidOrderState = orderState as OrderStateInvalid; + expect(invalidOrderState.transactionHash).to.be.equal(transactionHash); + }); + orderWatcher.subscribe(callback); + + transactionHash = await contractWrappers.exchange.fillOrderAsync( + signedOrder, + fillableAmount, + takerAddress, + ); + })().catch(done); + }); it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( diff --git a/packages/order-watcher/tsconfig.json b/packages/order-watcher/tsconfig.json index e35816553..2ee711adc 100644 --- a/packages/order-watcher/tsconfig.json +++ b/packages/order-watcher/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig", "compilerOptions": { - "outDir": "lib" + "outDir": "lib", + "rootDir": "." }, "include": ["./src/**/*", "./test/**/*"] } diff --git a/packages/order-watcher/typedoc-tsconfig.json b/packages/order-watcher/typedoc-tsconfig.json new file mode 100644 index 000000000..c9b0af1ae --- /dev/null +++ b/packages/order-watcher/typedoc-tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../typedoc-tsconfig", + "compilerOptions": { + "outDir": "lib" + }, + "include": ["./src/**/*", "./test/**/*"] +} |