aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-watcher
diff options
context:
space:
mode:
authorBrandon Millman <brandon.millman@gmail.com>2018-10-03 07:13:16 +0800
committerBrandon Millman <brandon.millman@gmail.com>2018-10-03 07:13:16 +0800
commit343b922ec11a6108caaf3095e59be0e56d45ee4a (patch)
treead38a124853c4cd153f5a290a0dc461447f8c799 /packages/order-watcher
parent6deb027bdf4e57f8918fd2413f0fdc55311508d3 (diff)
parentf1ecb8c5cb28a0a7ca6f7ad2ff11194091df62a4 (diff)
downloaddexon-sol-tools-343b922ec11a6108caaf3095e59be0e56d45ee4a.tar
dexon-sol-tools-343b922ec11a6108caaf3095e59be0e56d45ee4a.tar.gz
dexon-sol-tools-343b922ec11a6108caaf3095e59be0e56d45ee4a.tar.bz2
dexon-sol-tools-343b922ec11a6108caaf3095e59be0e56d45ee4a.tar.lz
dexon-sol-tools-343b922ec11a6108caaf3095e59be0e56d45ee4a.tar.xz
dexon-sol-tools-343b922ec11a6108caaf3095e59be0e56d45ee4a.tar.zst
dexon-sol-tools-343b922ec11a6108caaf3095e59be0e56d45ee4a.zip
Merge branch 'development' into feature/asset-buyer/improve-asset-buyer-manager
* development: (178 commits) Change cache key back to repo from repo-built Change the lint command back Merge build & install Remove deps cache all together Cache all nested node_modules directories Explicitly specify yarn cache folder Ignore linter issues Fix linter issue Separate deps and built caches Build tslint rules before running linter Cache yarn cache directory without node modules Run linter before prettier as it fails more often Add yarn cache path Split CI install and build steps Move bundle-size out of static tests and don't wait for a build with static tests Introduce a build:ci command that doesn't build webpack bundles Measure only one bundle size as they're the same Fix linter errors Fix no_website CI builds Check bundle size on CI ...
Diffstat (limited to 'packages/order-watcher')
-rw-r--r--packages/order-watcher/CHANGELOG.json48
-rw-r--r--packages/order-watcher/CHANGELOG.md14
-rw-r--r--packages/order-watcher/package.json35
-rw-r--r--packages/order-watcher/src/index.ts1
-rw-r--r--packages/order-watcher/src/order_watcher/event_watcher.ts49
-rw-r--r--packages/order-watcher/src/order_watcher/order_watcher.ts25
-rw-r--r--packages/order-watcher/test/order_watcher_test.ts26
7 files changed, 149 insertions, 49 deletions
diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json
index d4b0e6607..f26bf4ca4 100644
--- a/packages/order-watcher/CHANGELOG.json
+++ b/packages/order-watcher/CHANGELOG.json
@@ -1,7 +1,7 @@
[
{
- "timestamp": 1537875740,
- "version": "1.0.5",
+ "timestamp": 1538475601,
+ "version": "2.1.1",
"changes": [
{
"note": "Dependencies updated"
@@ -9,13 +9,53 @@
]
},
{
- "timestamp": 1537541580,
+ "version": "2.1.0",
+ "changes": [
+ {
+ "note": "Export ExpirationWatcher",
+ "pr": 1097
+ }
+ ],
+ "timestamp": 1538157789
+ },
+ {
+ "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",
diff --git a/packages/order-watcher/CHANGELOG.md b/packages/order-watcher/CHANGELOG.md
index d179b2e1a..7bc74cf2a 100644
--- a/packages/order-watcher/CHANGELOG.md
+++ b/packages/order-watcher/CHANGELOG.md
@@ -5,6 +5,20 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.1.1 - _October 2, 2018_
+
+ * Dependencies updated
+
+## v2.1.0 - _September 28, 2018_
+
+ * Export ExpirationWatcher (#1097)
+
+## 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
diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json
index d383211a8..9f57dd6fd 100644
--- a/packages/order-watcher/package.json
+++ b/packages/order-watcher/package.json
@@ -1,6 +1,6 @@
{
"name": "@0xproject/order-watcher",
- "version": "1.0.5",
+ "version": "2.1.0",
"description": "An order watcher daemon that watches for order validity",
"keywords": [
"0x",
@@ -13,6 +13,7 @@
"types": "lib/src/index.d.ts",
"scripts": {
"build": "yarn pre_build && tsc -b",
+ "build:ci": "yarn build",
"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",
@@ -42,9 +43,9 @@
"node": ">=6.0.0"
},
"devDependencies": {
- "@0xproject/abi-gen": "^1.0.10",
- "@0xproject/dev-utils": "^1.0.9",
- "@0xproject/migrations": "^1.0.11",
+ "@0xproject/abi-gen": "^1.0.12",
+ "@0xproject/dev-utils": "^1.0.11",
+ "@0xproject/migrations": "^1.0.13",
"@0xproject/tslint-config": "^1.0.7",
"@types/bintrees": "^1.0.2",
"@types/lodash": "4.14.104",
@@ -70,20 +71,20 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0xproject/assert": "^1.0.10",
- "@0xproject/base-contract": "^2.0.4",
- "@0xproject/contract-wrappers": "^1.0.5",
- "@0xproject/fill-scenarios": "^1.0.4",
- "@0xproject/json-schemas": "^1.0.3",
- "@0xproject/order-utils": "^1.0.4",
- "@0xproject/types": "^1.1.0",
- "@0xproject/typescript-typings": "^2.0.1",
- "@0xproject/utils": "^1.0.10",
- "@0xproject/web3-wrapper": "^3.0.0",
+ "@0xproject/assert": "^1.0.12",
+ "@0xproject/base-contract": "^3.0.0",
+ "@0xproject/contract-wrappers": "^2.0.1",
+ "@0xproject/fill-scenarios": "^1.0.6",
+ "@0xproject/json-schemas": "^1.0.5",
+ "@0xproject/order-utils": "^1.0.6",
+ "@0xproject/types": "^1.1.2",
+ "@0xproject/typescript-typings": "^3.0.0",
+ "@0xproject/utils": "^2.0.0",
+ "@0xproject/web3-wrapper": "^3.0.2",
"bintrees": "^1.0.2",
- "ethereum-types": "^1.0.7",
- "ethereumjs-blockstream": "5.0.0",
- "ethers": "3.0.22",
+ "ethereum-types": "^1.0.9",
+ "ethereumjs-blockstream": "6.0.0",
+ "ethers": "4.0.0-beta.14",
"lodash": "^4.17.5"
},
"publishConfig": {
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 eca235e26..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, BlockWithoutTransactionData, 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._getBlockOrNullAsync.bind(this),
- this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
+ this._blockstreamGetBlockOrNullAsync.bind(this),
+ this._blockstreamGetLogsAsync.bind(this),
this._onBlockAndLogStreamerError.bind(this),
);
const catchAllLogFilter = {};
@@ -83,12 +81,30 @@ export class EventWatcher {
);
}
// This method only exists in order to comply with the expected interface of Blockstream's constructor
- private async _getBlockOrNullAsync(): Promise<BlockWithoutTransactionData | null> {
- const blockIfExists = await this._web3Wrapper.getBlockIfExistsAsync.bind(this._web3Wrapper);
- if (_.isUndefined(blockIfExists)) {
- return null;
- }
- return blockIfExists;
+ 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)) {
@@ -103,19 +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 latestBlockIfExists = await this._web3Wrapper.getBlockIfExistsAsync(this._stateLayer);
- if (_.isUndefined(latestBlockIfExists)) {
+ 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((latestBlockIfExists 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
}
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(