aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-watcher/src/order_watcher
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-watcher/src/order_watcher')
-rw-r--r--packages/order-watcher/src/order_watcher/event_watcher.ts46
-rw-r--r--packages/order-watcher/src/order_watcher/order_watcher.ts25
2 files changed, 50 insertions, 21 deletions
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 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
}