aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonid Logvinov <logvinov.leon@gmail.com>2017-06-07 22:42:02 +0800
committerLeonid Logvinov <logvinov.leon@gmail.com>2017-06-07 22:42:02 +0800
commit5bb04528d3a8fb99afc2bffc52706eda646249f3 (patch)
treec9da76cab0c00e3208cfebed075909c6d192375e
parentefbd81df0273a2b29b072b737bd04c4b3c065913 (diff)
parentc3cd5812e61359b18c469f70c9f0240db777e67a (diff)
downloaddexon-sol-tools-5bb04528d3a8fb99afc2bffc52706eda646249f3.tar
dexon-sol-tools-5bb04528d3a8fb99afc2bffc52706eda646249f3.tar.gz
dexon-sol-tools-5bb04528d3a8fb99afc2bffc52706eda646249f3.tar.bz2
dexon-sol-tools-5bb04528d3a8fb99afc2bffc52706eda646249f3.tar.lz
dexon-sol-tools-5bb04528d3a8fb99afc2bffc52706eda646249f3.tar.xz
dexon-sol-tools-5bb04528d3a8fb99afc2bffc52706eda646249f3.tar.zst
dexon-sol-tools-5bb04528d3a8fb99afc2bffc52706eda646249f3.zip
Merge branch 'batchCancelAsync' into batchFillAsync
-rw-r--r--src/contract_wrappers/exchange_wrapper.ts36
-rw-r--r--src/types.ts5
-rw-r--r--test/exchange_wrapper_test.ts34
3 files changed, 46 insertions, 29 deletions
diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts
index 1ae5b260b..326f0e812 100644
--- a/src/contract_wrappers/exchange_wrapper.ts
+++ b/src/contract_wrappers/exchange_wrapper.ts
@@ -18,7 +18,7 @@ import {
CreateContractEvent,
ContractEventObj,
EventCallback,
- ContractResponse,
+ ContractResponse, OrderCancellationRequest,
} from '../types';
import {assert} from '../utils/assert';
import {utils} from '../utils/utils';
@@ -232,29 +232,31 @@ export class ExchangeWrapper extends ContractWrapper {
/**
* Batch version of cancelOrderAsync. Atomically cancels multiple orders in a single transaction.
*/
- public async batchCancelOrderAsync(
- orders: Array<Order|SignedOrder>, takerTokenCancelAmounts: BigNumber.BigNumber[]): Promise<void> {
- const makers = _.map(orders, order => order.maker);
- assert.isSameLength('orders', orders, 'takerTokenCancelAmounts', takerTokenCancelAmounts);
- assert.assert(!_.isEmpty(orders), 'Can not cancel an empty batch');
+ public async batchCancelOrderAsync(cancellationRequestsBatch: OrderCancellationRequest[]): Promise<void> {
+ const makers = _.map(cancellationRequestsBatch, cancellationRequest => cancellationRequest.order.maker);
+ assert.assert(!_.isEmpty(cancellationRequestsBatch), 'Can not cancel an empty batch');
assert.assert(_.uniq(makers).length === 1, 'Can not cancel orders from multiple makers in a single batch');
const maker = makers[0];
- // _.zip doesn't type check if values have different types :'(
- const ordersAndTakerTokenCancelAmounts = _.zip<any>(orders, takerTokenCancelAmounts);
- _.forEach(ordersAndTakerTokenCancelAmounts,
- async ([order, takerTokenCancelAmount]: [Order|SignedOrder, BigNumber.BigNumber]) => {
+ _.forEach(cancellationRequestsBatch,
+ async (cancellationRequest: OrderCancellationRequest) => {
assert.doesConformToSchema('order',
- SchemaValidator.convertToJSONSchemaCompatibleObject(order as object), orderSchema);
- assert.isBigNumber('takerTokenCancelAmount', takerTokenCancelAmount);
- await assert.isSenderAddressAvailableAsync(this.web3Wrapper, 'order.maker', order.maker);
- await this.validateCancelOrderAndThrowIfInvalidAsync(order, takerTokenCancelAmount);
+ SchemaValidator.convertToJSONSchemaCompatibleObject(cancellationRequest.order as object), orderSchema);
+ assert.isBigNumber('takerTokenCancelAmount', cancellationRequest.takerTokenCancelAmount);
+ await assert.isSenderAddressAvailableAsync(this.web3Wrapper, 'order.maker',
+ cancellationRequest.order.maker);
+ await this.validateCancelOrderAndThrowIfInvalidAsync(
+ cancellationRequest.order, cancellationRequest.takerTokenCancelAmount);
});
const exchangeInstance = await this.getExchangeContractAsync();
- const orderAddressesAndValues = _.map(orders, order => {
- return ExchangeWrapper.getOrderAddressesAndValues(order);
+ const orderAddressesValuesAndTakerTokenCancelAmounts = _.map(cancellationRequestsBatch, cancellationRequest => {
+ return [
+ ...ExchangeWrapper.getOrderAddressesAndValues(cancellationRequest.order),
+ cancellationRequest.takerTokenCancelAmount,
+ ];
});
// _.unzip doesn't type check if values have different types :'(
- const [orderAddresses, orderValues] = _.unzip<any>(orderAddressesAndValues);
+ const [orderAddresses, orderValues, takerTokenCancelAmounts] =
+ _.unzip<any>(orderAddressesValuesAndTakerTokenCancelAmounts);
const gas = await exchangeInstance.batchCancel.estimateGas(
orderAddresses,
orderValues,
diff --git a/src/types.ts b/src/types.ts
index a1bd6d19e..84f16b9b9 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -228,3 +228,8 @@ export interface SubscriptionOpts {
}
export type DoneCallback = (err?: Error) => void;
+
+export interface OrderCancellationRequest {
+ order: Order|SignedOrder;
+ takerTokenCancelAmount: BigNumber.BigNumber;
+}
diff --git a/test/exchange_wrapper_test.ts b/test/exchange_wrapper_test.ts
index 43f8683c8..683c4b17d 100644
--- a/test/exchange_wrapper_test.ts
+++ b/test/exchange_wrapper_test.ts
@@ -16,7 +16,7 @@ import {
ExchangeEvents,
ContractEvent,
DoneCallback,
- ExchangeContractErrs,
+ ExchangeContractErrs, OrderCancellationRequest,
} from '../src/types';
import {FillScenarios} from './utils/fill_scenarios';
import {TokenUtils} from './utils/token_utils';
@@ -120,7 +120,7 @@ describe('ExchangeWrapper', () => {
expect(isValid).to.be.true();
});
});
- describe('fill order', () => {
+ describe('fill order(s)', () => {
let makerTokenAddress: string;
let takerTokenAddress: string;
let coinbase: string;
@@ -392,34 +392,44 @@ describe('ExchangeWrapper', () => {
describe('#batchCancelOrderAsync', () => {
let anotherSignedOrder: SignedOrder;
let anotherOrderHashHex: string;
+ let cancelBatch: OrderCancellationRequest[];
beforeEach(async () => {
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
);
anotherOrderHashHex = await zeroEx.getOrderHashHexAsync(anotherSignedOrder);
+ cancelBatch = [
+ {
+ order: signedOrder,
+ takerTokenCancelAmount: cancelAmount,
+ },
+ {
+ order: anotherSignedOrder,
+ takerTokenCancelAmount: cancelAmount,
+ },
+ ];
});
describe('failed batch cancels', () => {
- it('should throw when length of orders and cancelAmounts mismatch', async () => {
- return expect(zeroEx.exchange.batchCancelOrderAsync([signedOrder], []))
- .to.be.rejectedWith('orders and takerTokenCancelAmounts length mismatch. 1 != 0');
- });
it('should throw when orders are empty', async () => {
- return expect(zeroEx.exchange.batchCancelOrderAsync([], []))
+ return expect(zeroEx.exchange.batchCancelOrderAsync([]))
.to.be.rejectedWith('Can not cancel an empty batch');
});
it.only('should throw when orders have different makers', async () => {
const signedOrderWithADifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress, takerTokenAddress, takerAddress, takerAddress, fillableAmount,
);
- return expect(zeroEx.exchange.batchCancelOrderAsync(
- [signedOrder, signedOrderWithADifferentMaker], [cancelAmount, cancelAmount]))
- .to.be.rejectedWith('Can not cancel orders from multiple makers in a single batch');
+ return expect(zeroEx.exchange.batchCancelOrderAsync([
+ cancelBatch[0],
+ {
+ order: signedOrderWithADifferentMaker,
+ takerTokenCancelAmount: cancelAmount,
+ },
+ ])).to.be.rejectedWith('Can not cancel orders from multiple makers in a single batch');
});
});
describe('successful batch cancels', () => {
it('should cancel a batch of orders', async () => {
- await zeroEx.exchange.batchCancelOrderAsync(
- [signedOrder, anotherSignedOrder], [cancelAmount, cancelAmount]);
+ await zeroEx.exchange.batchCancelOrderAsync(cancelBatch);
const cancelledAmount = await zeroEx.exchange.getCanceledTakerAmountAsync(orderHashHex);
const anotherCancelledAmount = await zeroEx.exchange.getCanceledTakerAmountAsync(
anotherOrderHashHex);