diff options
-rw-r--r-- | packages/order-utils/src/order_state_utils.ts | 4 | ||||
-rw-r--r-- | packages/order-utils/test/order_state_utils_test.ts | 20 | ||||
-rw-r--r-- | packages/order-watcher/src/order_watcher/order_watcher.ts | 25 | ||||
-rw-r--r-- | packages/order-watcher/test/order_watcher_test.ts | 26 | ||||
-rw-r--r-- | packages/types/src/index.ts | 2 |
5 files changed, 64 insertions, 13 deletions
diff --git a/packages/order-utils/src/order_state_utils.ts b/packages/order-utils/src/order_state_utils.ts index 8398776aa..9b21ef6e9 100644 --- a/packages/order-utils/src/order_state_utils.ts +++ b/packages/order-utils/src/order_state_utils.ts @@ -114,7 +114,7 @@ export class OrderStateUtils { * @return State relevant to the signedOrder, as well as whether the signedOrder is "valid". * Validity is defined as a non-zero amount of the order can still be filled. */ - public async getOpenOrderStateAsync(signedOrder: SignedOrder): Promise<OrderState> { + public async getOpenOrderStateAsync(signedOrder: SignedOrder, transactionHash?: string): Promise<OrderState> { const orderRelevantState = await this.getOpenOrderRelevantStateAsync(signedOrder); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); const isOrderCancelled = await this._orderFilledCancelledFetcher.isOrderCancelledAsync(orderHash); @@ -134,6 +134,7 @@ export class OrderStateUtils { isValid: true, orderHash, orderRelevantState, + transactionHash, }; return orderState; } else { @@ -141,6 +142,7 @@ export class OrderStateUtils { isValid: false, orderHash, error: orderValidationResult.error, + transactionHash, }; return orderState; } diff --git a/packages/order-utils/test/order_state_utils_test.ts b/packages/order-utils/test/order_state_utils_test.ts index 91ef23b69..ea88027ae 100644 --- a/packages/order-utils/test/order_state_utils_test.ts +++ b/packages/order-utils/test/order_state_utils_test.ts @@ -120,5 +120,25 @@ describe('OrderStateUtils', () => { const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder); expect(orderState.isValid).to.eq(false); }); + it('should include the transactionHash in orderState if supplied in method invocation', async () => { + const makerAssetAmount = new BigNumber(10); + const takerAssetAmount = new BigNumber(10000000000000000); + const takerBalance = takerAssetAmount; + const orderFilledAmount = new BigNumber(0); + const mockBalanceFetcher = buildMockBalanceFetcher(takerBalance); + const mockOrderFilledFetcher = buildMockOrderFilledFetcher(orderFilledAmount); + const [signedOrder] = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + takerAssetAmount, + }, + 1, + ); + + const orderStateUtils = new OrderStateUtils(mockBalanceFetcher, mockOrderFilledFetcher); + const transactionHash = '0xdeadbeef'; + const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder, transactionHash); + expect(orderState.transactionHash).to.eq(transactionHash); + }); }); }); diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index cab2efa4b..f9a63efe3 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -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/types/src/index.ts b/packages/types/src/index.ts index d27060ee5..5223bf299 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -111,12 +111,14 @@ export interface OrderStateValid { isValid: true; orderHash: string; orderRelevantState: OrderRelevantState; + transactionHash?: string; } export interface OrderStateInvalid { isValid: false; orderHash: string; error: ExchangeContractErrs; + transactionHash?: string; } export type OrderState = OrderStateValid | OrderStateInvalid; |