aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonid <logvinov.leon@gmail.com>2017-09-07 00:32:02 +0800
committerGitHub <noreply@github.com>2017-09-07 00:32:02 +0800
commitc56724981970f90dfe68212d0447e8c7c9866b07 (patch)
tree0d57265a1d2a405987a6764e0c3c858fc87f26c0
parent912d15cb73de0d44394c9d2e11e8dfdb248ade9c (diff)
parentd2dc4d18be93fd04f237bef7fe7e29e4a9447517 (diff)
downloaddexon-sol-tools-c56724981970f90dfe68212d0447e8c7c9866b07.tar
dexon-sol-tools-c56724981970f90dfe68212d0447e8c7c9866b07.tar.gz
dexon-sol-tools-c56724981970f90dfe68212d0447e8c7c9866b07.tar.bz2
dexon-sol-tools-c56724981970f90dfe68212d0447e8c7c9866b07.tar.lz
dexon-sol-tools-c56724981970f90dfe68212d0447e8c7c9866b07.tar.xz
dexon-sol-tools-c56724981970f90dfe68212d0447e8c7c9866b07.tar.zst
dexon-sol-tools-c56724981970f90dfe68212d0447e8c7c9866b07.zip
Merge pull request #157 from 0xProject/feature/throw-for-exchange-errors
Feature/throw for exchange errors
-rw-r--r--CHANGELOG.md6
-rw-r--r--src/0x.ts5
-rw-r--r--src/contract_wrappers/exchange_wrapper.ts22
-rw-r--r--src/utils/abi_decoder.ts5
-rw-r--r--src/utils/interval_utils.ts20
-rw-r--r--test/0x.js_test.ts8
6 files changed, 57 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 62c3bbc3a..6a61de712 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# CHANGELOG
+v0.13.1 - _September 6, 2017_
+------------------------
+ * Added `zeroEx.exchange.throwLogErrorsAsErrors` method to public interface (#157)
+ * Fixed an issue with overlapping async intervals in `zeroEx.awaitTransactionMinedAsync` (#157)
+ * Fixed an issue with log decoder returning `BigNumber`s as `strings` (#157)
+
v0.13.0 - _September 6, 2017_
------------------------
* Made all the functions submitting transactions to the network to immediately return transaction hash (#151)
diff --git a/src/0x.ts b/src/0x.ts
index bde9360c3..5d5604780 100644
--- a/src/0x.ts
+++ b/src/0x.ts
@@ -13,6 +13,7 @@ import {utils} from './utils/utils';
import {signatureUtils} from './utils/signature_utils';
import {assert} from './utils/assert';
import {AbiDecoder} from './utils/abi_decoder';
+import {intervalUtils} from './utils/interval_utils';
import {artifacts} from './artifacts';
import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper';
import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper';
@@ -280,10 +281,10 @@ export class ZeroEx {
txHash: string, pollingIntervalMs: number = 1000): Promise<TransactionReceiptWithDecodedLogs> {
const txReceiptPromise = new Promise(
(resolve: (receipt: TransactionReceiptWithDecodedLogs) => void, reject) => {
- const intervalId = setInterval(async () => {
+ const intervalId = intervalUtils.setAsyncExcludingInterval(async () => {
const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash);
if (!_.isNull(transactionReceipt)) {
- clearInterval(intervalId);
+ intervalUtils.clearAsyncExcludingInterval(intervalId);
const logsWithDecodedArgs = _.map(transactionReceipt.logs, (log: Web3.LogEntry) => {
const decodedLog = this._abiDecoder.decodeLog(log);
if (_.isUndefined(decodedLog)) {
diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts
index 115bd1110..47a066a8f 100644
--- a/src/contract_wrappers/exchange_wrapper.ts
+++ b/src/contract_wrappers/exchange_wrapper.ts
@@ -26,6 +26,7 @@ import {
LogErrorContractEventArgs,
LogFillContractEventArgs,
LogCancelContractEventArgs,
+ LogWithDecodedArgs,
} from '../types';
import {assert} from '../utils/assert';
import {utils} from '../utils/utils';
@@ -46,6 +47,14 @@ export class ExchangeWrapper extends ContractWrapper {
private _exchangeLogEventEmitters: ContractEventEmitter[];
private _orderValidationUtils: OrderValidationUtils;
private _tokenWrapper: TokenWrapper;
+ private _exchangeContractErrCodesToMsg = {
+ [ExchangeContractErrCodes.ERROR_FILL_EXPIRED]: ExchangeContractErrs.OrderFillExpired,
+ [ExchangeContractErrCodes.ERROR_CANCEL_EXPIRED]: ExchangeContractErrs.OrderFillExpired,
+ [ExchangeContractErrCodes.ERROR_FILL_NO_VALUE]: ExchangeContractErrs.OrderRemainingFillAmountZero,
+ [ExchangeContractErrCodes.ERROR_CANCEL_NO_VALUE]: ExchangeContractErrs.OrderRemainingFillAmountZero,
+ [ExchangeContractErrCodes.ERROR_FILL_TRUNCATION]: ExchangeContractErrs.OrderFillRoundingError,
+ [ExchangeContractErrCodes.ERROR_FILL_BALANCE_ALLOWANCE]: ExchangeContractErrs.FillBalanceAllowanceError,
+ };
private static _getOrderAddressesAndValues(order: Order): [OrderAddresses, OrderValues] {
const orderAddresses: OrderAddresses = [
order.maker,
@@ -674,6 +683,19 @@ export class ExchangeWrapper extends ContractWrapper {
);
return isRoundingError;
}
+ /**
+ * Checks if logs contain LogError, which is emmited by Exchange contract on transaction failure.
+ * @param logsWithDecodedArgs Transaction logs as returned by `zeroEx.awaitTransactionMinedAsync`
+ */
+ public throwLogErrorsAsErrors(logsWithDecodedArgs: LogWithDecodedArgs[]): void {
+ const errLog = _.find(logsWithDecodedArgs, {event: ExchangeEvents.LogError});
+ if (!_.isUndefined(errLog)) {
+ const logArgs: LogErrorContractEventArgs = errLog.args as any;
+ const errCode = logArgs.errorId.toNumber();
+ const errMessage = this._exchangeContractErrCodesToMsg[errCode];
+ throw new Error(errMessage);
+ }
+ }
private async _invalidateContractInstancesAsync(): Promise<void> {
await this.stopWatchingAllEventsAsync();
delete this._exchangeContractIfExists;
diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts
index f988a5695..61c8eecd4 100644
--- a/src/utils/abi_decoder.ts
+++ b/src/utils/abi_decoder.ts
@@ -1,5 +1,6 @@
import * as Web3 from 'web3';
import * as _ from 'lodash';
+import * as BigNumber from 'bignumber.js';
import {AbiType, DecodedLogArgs, DecodedArgs} from '../types';
import * as SolidityCoder from 'web3/lib/solidity/coder';
@@ -31,9 +32,9 @@ export class AbiDecoder {
dataIndex++;
}
if (param.type === 'address') {
- value = this.padZeros(new Web3().toBigNumber(value).toString(16));
+ value = this.padZeros(new BigNumber(value).toString(16));
} else if (param.type === 'uint256' || param.type === 'uint8' || param.type === 'int' ) {
- value = new Web3().toBigNumber(value).toString(10);
+ value = new BigNumber(value);
}
decodedParams[param.name] = value;
});
diff --git a/src/utils/interval_utils.ts b/src/utils/interval_utils.ts
new file mode 100644
index 000000000..1656318e6
--- /dev/null
+++ b/src/utils/interval_utils.ts
@@ -0,0 +1,20 @@
+import * as _ from 'lodash';
+
+export const intervalUtils = {
+ setAsyncExcludingInterval(fn: () => Promise<void>, intervalMs: number) {
+ let locked = false;
+ const intervalId = setInterval(async () => {
+ if (locked) {
+ return;
+ } else {
+ locked = true;
+ await fn();
+ locked = false;
+ }
+ });
+ return intervalId;
+ },
+ clearAsyncExcludingInterval(intervalId: number): void {
+ clearInterval(intervalId);
+ },
+};
diff --git a/test/0x.js_test.ts b/test/0x.js_test.ts
index 5182275a8..5461a7d3f 100644
--- a/test/0x.js_test.ts
+++ b/test/0x.js_test.ts
@@ -226,11 +226,9 @@ describe('ZeroEx library', () => {
const txReceiptWithDecodedLogs = await zeroEx.awaitTransactionMinedAsync(txHash);
const log = txReceiptWithDecodedLogs.logs[0] as LogWithDecodedArgs;
expect(log.event).to.be.equal('Approval');
- expect(log.args).to.be.deep.equal({
- _owner: coinbase,
- _spender: proxyAddress,
- _value: zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS.toString(),
- });
+ expect(log.args._owner).to.be.equal(coinbase);
+ expect(log.args._spender).to.be.equal(proxyAddress);
+ expect(log.args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
});
});