aboutsummaryrefslogtreecommitdiffstats
path: root/packages/0x.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/0x.js')
-rw-r--r--packages/0x.js/src/order_watcher/order_state_watcher.ts48
-rw-r--r--packages/0x.js/src/types.ts2
-rw-r--r--packages/0x.js/test/exchange_wrapper_test.ts2
-rw-r--r--packages/0x.js/test/token_wrapper_test.ts2
4 files changed, 49 insertions, 5 deletions
diff --git a/packages/0x.js/src/order_watcher/order_state_watcher.ts b/packages/0x.js/src/order_watcher/order_state_watcher.ts
index 8c21c1678..1ce111708 100644
--- a/packages/0x.js/src/order_watcher/order_state_watcher.ts
+++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts
@@ -50,6 +50,8 @@ interface OrderStateByOrderHash {
[orderHash: string]: OrderState;
}
+const DEFAULT_CLEANUP_JOB_INTERVAL_MS = 1000 * 60 * 60; // 1h
+
/**
* This class includes all the functionality related to watching a set of orders
* for potential changes in order validity/fillability. The orderWatcher notifies
@@ -68,6 +70,8 @@ export class OrderStateWatcher {
private _orderStateUtils: OrderStateUtils;
private _orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore;
private _balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore;
+ private _cleanupJobInterval: number;
+ private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
constructor(
web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, token: TokenWrapper, exchange: ExchangeWrapper,
config?: OrderStateWatcherConfig,
@@ -92,6 +96,9 @@ export class OrderStateWatcher {
this._expirationWatcher = new ExpirationWatcher(
expirationMarginIfExistsMs, orderExpirationCheckingIntervalMsIfExists,
);
+ this._cleanupJobInterval = _.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs) ?
+ DEFAULT_CLEANUP_JOB_INTERVAL_MS :
+ config.cleanupJobIntervalMs;
}
/**
* Add an order to the orderStateWatcher. Before the order is added, it's
@@ -139,12 +146,15 @@ export class OrderStateWatcher {
this._callbackIfExists = callback;
this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
+ this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
+ this._cleanupAsync.bind(this), this._cleanupJobInterval,
+ );
}
/**
* Ends an orderStateWatcher subscription.
*/
public unsubscribe(): void {
- if (_.isUndefined(this._callbackIfExists)) {
+ if (_.isUndefined(this._callbackIfExists) || _.isUndefined(this._cleanupJobIntervalIdIfExists)) {
throw new Error(ZeroExError.SubscriptionNotFound);
}
this._balanceAndProxyAllowanceLazyStore.deleteAll();
@@ -152,6 +162,34 @@ export class OrderStateWatcher {
delete this._callbackIfExists;
this._eventWatcher.unsubscribe();
this._expirationWatcher.unsubscribe();
+ intervalUtils.clearAsyncExcludingInterval(this._cleanupJobIntervalIdIfExists);
+ }
+ private async _cleanupAsync(): Promise<void> {
+ for (const orderHash of _.keys(this._orderByOrderHash)) {
+ this._cleanupOrderRelatedState(orderHash);
+ await this._emitRevalidateOrdersAsync([orderHash]);
+ }
+ }
+ private _cleanupOrderRelatedState(orderHash: string): void {
+ const signedOrder = this._orderByOrderHash[orderHash];
+
+ this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(orderHash);
+ this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(orderHash);
+
+ this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.makerTokenAddress, signedOrder.maker);
+ this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.makerTokenAddress, signedOrder.maker);
+ this._balanceAndProxyAllowanceLazyStore.deleteBalance(signedOrder.takerTokenAddress, signedOrder.taker);
+ this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(signedOrder.takerTokenAddress, signedOrder.taker);
+
+ const zrxTokenAddress = this._getZRXTokenAddress();
+ if (!signedOrder.makerFee.isZero()) {
+ this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.maker);
+ this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.maker);
+ }
+ if (!signedOrder.takerFee.isZero()) {
+ this._balanceAndProxyAllowanceLazyStore.deleteBalance(zrxTokenAddress, signedOrder.taker);
+ this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(zrxTokenAddress, signedOrder.taker);
+ }
}
private _onOrderExpired(orderHash: string): void {
const orderState: OrderState = {
@@ -266,8 +304,7 @@ export class OrderStateWatcher {
this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress] = new Set();
}
this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress].add(orderHash);
- const exchange = (this._orderFilledCancelledLazyStore as any).exchange as ExchangeWrapper;
- const zrxTokenAddress = exchange.getZRXTokenAddress();
+ const zrxTokenAddress = this._getZRXTokenAddress();
if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress])) {
this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress] = new Set();
}
@@ -282,4 +319,9 @@ export class OrderStateWatcher {
delete this._dependentOrderHashes[makerAddress];
}
}
+ private _getZRXTokenAddress(): string {
+ const exchange = (this._orderFilledCancelledLazyStore as any).exchange as ExchangeWrapper;
+ const zrxTokenAddress = exchange.getZRXTokenAddress();
+ return zrxTokenAddress;
+ }
}
diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts
index 3949c17c5..5363b02ff 100644
--- a/packages/0x.js/src/types.ts
+++ b/packages/0x.js/src/types.ts
@@ -407,11 +407,13 @@ export interface JSONRPCPayload {
* eventPollingIntervalMs: How often to poll the Ethereum node for new events. Defaults: 200
* expirationMarginMs: Amount of time before order expiry that you'd like to be notified
* of an orders expiration. Defaults: 0
+ * cleanupJobIntervalMs: How often to run a cleanup job which revalidates all the orders. Defaults: 1h
*/
export interface OrderStateWatcherConfig {
orderExpirationCheckingIntervalMs?: number;
eventPollingIntervalMs?: number;
expirationMarginMs?: number;
+ cleanupJobIntervalMs?: number;
}
/*
diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts
index f6c823cc4..14559c706 100644
--- a/packages/0x.js/test/exchange_wrapper_test.ts
+++ b/packages/0x.js/test/exchange_wrapper_test.ts
@@ -680,7 +680,7 @@ describe('ExchangeWrapper', () => {
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
})().catch(done);
});
- it('Outstanding subscriptions are cancelled when zeroEx.setProviderAsync called', (done: DoneCallback) => {
+ it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts
index cc61c2324..c853fe0c2 100644
--- a/packages/0x.js/test/token_wrapper_test.ts
+++ b/packages/0x.js/test/token_wrapper_test.ts
@@ -398,7 +398,7 @@ describe('TokenWrapper', () => {
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
})().catch(done);
});
- it('Outstanding subscriptions are cancelled when zeroEx.setProviderAsync called', (done: DoneCallback) => {
+ it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));