Skip to content

Commit

Permalink
Merge pull request #223 from project-serum/bulk_cancel
Browse files Browse the repository at this point in the history
Update serum-ts for bulk cancel and max_ts
  • Loading branch information
jhlx committed Apr 5, 2022
2 parents 910bfb0 + 35d39a9 commit 702e710
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ docs/lockup-ui/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
private/
53 changes: 53 additions & 0 deletions packages/serum/src/instructions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
sideLayout,
u128,
u64,
i64,
VersionedLayout,
} from './layout';
import {
Expand All @@ -14,6 +15,7 @@ import {
PublicKey,
} from '@solana/web3.js';
import { TOKEN_PROGRAM_ID } from './token-instructions';
import BN from 'bn.js';

// NOTE: Update these if the position of arguments for the settleFunds instruction changes
export const SETTLE_FUNDS_BASE_WALLET_INDEX = 5;
Expand Down Expand Up @@ -82,6 +84,7 @@ INSTRUCTION_LAYOUT.inner.addVariant(
orderTypeLayout('orderType'),
u64('clientId'),
u16('limit'),
i64('maxTs'),
]),
'newOrderV3',
);
Expand All @@ -99,6 +102,20 @@ INSTRUCTION_LAYOUT.inner.addVariant(14, struct([]), 'closeOpenOrders');
INSTRUCTION_LAYOUT.inner.addVariant(15, struct([]), 'initOpenOrders');
INSTRUCTION_LAYOUT.inner.addVariant(16, struct([u16('limit')]), 'prune');
INSTRUCTION_LAYOUT.inner.addVariant(17, struct([u16('limit')]), 'consumeEventsPermissioned');
INSTRUCTION_LAYOUT.inner.addVariant(
18,
struct([
u64('clientId0'),
u64('clientId1'),
u64('clientId2'),
u64('clientId3'),
u64('clientId4'),
u64('clientId5'),
u64('clientId6'),
u64('clientId7')
]),
'cancelOrdersByClientIds',
);

export function encodeInstruction(instruction) {
const b = Buffer.alloc(100);
Expand Down Expand Up @@ -244,6 +261,7 @@ export class DexInstructions {
programId,
selfTradeBehavior,
feeDiscountPubkey = null,
maxTs = null,
}) {
const keys = [
{ pubkey: market, isSigner: false, isWritable: true },
Expand Down Expand Up @@ -279,6 +297,7 @@ export class DexInstructions {
orderType,
clientId,
limit: 65535,
maxTs: new BN(maxTs ?? '9223372036854775807'),
},
}),
});
Expand Down Expand Up @@ -460,6 +479,40 @@ export class DexInstructions {
});
}

static cancelOrdersByClientIds({
market,
openOrders,
owner,
bids,
asks,
eventQueue,
clientIds,
programId,
}) {
if (clientIds.length > 8) {
throw new Error("Number of client ids cannot exceed 8!");
}

while (clientIds.length < 8) {
clientIds.push(new BN(0));
}

return new TransactionInstruction({
keys: [
{ pubkey: market, isSigner: false, isWritable: false },
{ pubkey: bids, isSigner: false, isWritable: true },
{ pubkey: asks, isSigner: false, isWritable: true },
{ pubkey: openOrders, isSigner: false, isWritable: true },
{ pubkey: owner, isSigner: true, isWritable: false },
{ pubkey: eventQueue, isSigner: false, isWritable: true },
],
programId,
data: encodeInstruction({
cancelOrdersByClientIds: Object.fromEntries(clientIds.map((clientId, i) => [`clientId${i}`, clientId])),
}),
});
}

static settleFunds({
market,
openOrders,
Expand Down
4 changes: 4 additions & 0 deletions packages/serum/src/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export function u64(property) {
return new BNLayout(8, property);
}

export function i64(property) {
return new BNLayout(8, property);
}

export function u128(property) {
return new BNLayout(16, property);
}
Expand Down
59 changes: 53 additions & 6 deletions packages/serum/src/market.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ export class Market {
openOrdersAddressKey,
openOrdersAccount,
feeDiscountPubkey,
maxTs,
}: OrderParams,
) {
const { transaction, signers } = await this.makePlaceOrderTransaction<
Expand All @@ -446,6 +447,7 @@ export class Market {
openOrdersAddressKey,
openOrdersAccount,
feeDiscountPubkey,
maxTs,
});
return await this._sendTransaction(connection, transaction, [
owner,
Expand Down Expand Up @@ -599,6 +601,7 @@ export class Market {
openOrdersAccount,
feeDiscountPubkey = undefined,
selfTradeBehavior = 'decrementTake',
maxTs,
}: OrderParams<T>,
cacheDurationMs = 0,
feeDiscountPubkeyCacheDurationMs = 0,
Expand Down Expand Up @@ -714,6 +717,7 @@ export class Market {
openOrdersAddressKey: openOrdersAddress,
feeDiscountPubkey: useFeeDiscountPubkey,
selfTradeBehavior,
maxTs,
});
transaction.add(placeOrderInstruction);

Expand Down Expand Up @@ -745,6 +749,7 @@ export class Market {
openOrdersAddressKey,
openOrdersAccount,
feeDiscountPubkey = null,
maxTs,
} = params;
// @ts-ignore
const ownerAddress: PublicKey = owner.publicKey ?? owner;
Expand Down Expand Up @@ -796,6 +801,7 @@ export class Market {
feeDiscountPubkey = null,
selfTradeBehavior = 'decrementTake',
programId,
maxTs,
} = params;
// @ts-ignore
const ownerAddress: PublicKey = owner.publicKey ?? owner;
Expand All @@ -822,9 +828,12 @@ export class Market {
clientId,
programId: programId ?? this._programId,
selfTradeBehavior,
// @ts-ignore
feeDiscountPubkey: this.supportsSrmFeeDiscounts
? feeDiscountPubkey
: null,
// @ts-ignore
maxTs,
});
}

Expand Down Expand Up @@ -861,6 +870,21 @@ export class Market {
return await this._sendTransaction(connection, transaction, [owner]);
}

async cancelOrdersByClientIds(
connection: Connection,
owner: Account,
openOrders: PublicKey,
clientIds: BN[],
) {
const transaction = await this.makeCancelOrdersByClientIdsTransaction(
connection,
owner.publicKey,
openOrders,
clientIds,
);
return await this._sendTransaction(connection, transaction, [owner]);
}

async makeCancelOrderByClientIdTransaction(
connection: Connection,
owner: PublicKey,
Expand Down Expand Up @@ -896,6 +920,28 @@ export class Market {
return transaction;
}

async makeCancelOrdersByClientIdsTransaction(
connection: Connection,
owner: PublicKey,
openOrders: PublicKey,
clientIds: BN[],
) {
const transaction = new Transaction();
transaction.add(
DexInstructions.cancelOrdersByClientIds({
market: this.address,
openOrders,
owner,
bids: this._decoded.bids,
asks: this._decoded.asks,
eventQueue: this._decoded.eventQueue,
clientIds,
programId: this._programId,
}),
);
return transaction;
}

async cancelOrder(connection: Connection, owner: Account, order: Order) {
const transaction = await this.makeCancelOrderTransaction(
connection,
Expand Down Expand Up @@ -1194,8 +1240,8 @@ export class Market {
(price *
Math.pow(10, this._quoteSplTokenDecimals) *
this._decoded.baseLotSize.toNumber()) /
(Math.pow(10, this._baseSplTokenDecimals) *
this._decoded.quoteLotSize.toNumber()),
(Math.pow(10, this._baseSplTokenDecimals) *
this._decoded.quoteLotSize.toNumber()),
),
);
}
Expand Down Expand Up @@ -1264,11 +1310,12 @@ export interface OrderParams<T = Account> {
openOrdersAccount?: Account;
feeDiscountPubkey?: PublicKey | null;
selfTradeBehavior?:
| 'decrementTake'
| 'cancelProvide'
| 'abortTransaction'
| undefined;
| 'decrementTake'
| 'cancelProvide'
| 'abortTransaction'
| undefined;
programId?: PublicKey;
maxTs?: number | null;
}

export const _OPEN_ORDERS_LAYOUT_V1 = struct([
Expand Down

0 comments on commit 702e710

Please sign in to comment.