Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/trcl 2812 optimization #51

Merged
merged 10 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,044 changes: 897 additions & 147 deletions v4-client-js/__native__/__ios__/v4-native-client.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion v4-client-js/__native__/__ios__/v4-native-client.js.map

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ async function test(): Promise<void> {
price,
0.01,
clientId,
timeInForce,
goodTilBlock,
timeInForce,
false,
);
console.log('**Order Tx**');
Expand Down
2 changes: 1 addition & 1 deletion v4-client-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dydxprotocol/v4-client-js",
"version": "0.38.4",
"version": "0.38.5",
"description": "General client library for the new dYdX system (v4 decentralized)",
"main": "build/src/index.js",
"scripts": {
Expand Down
152 changes: 129 additions & 23 deletions v4-client-js/src/clients/composite-client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { EncodeObject } from '@cosmjs/proto-signing';
import { GasPrice, IndexedTx, StdFee } from '@cosmjs/stargate';
import {
Account, GasPrice, IndexedTx, StdFee,
} from '@cosmjs/stargate';
import { BroadcastTxAsyncResponse, BroadcastTxSyncResponse } from '@cosmjs/tendermint-rpc/build/tendermint37';
import { Order_ConditionType, Order_TimeInForce } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/order';
import Long from 'long';
Expand All @@ -10,7 +12,13 @@ import { OrderFlags } from '../types';
import {
DYDX_DENOM,
GAS_PRICE,
Network, OrderExecution, OrderSide, OrderTimeInForce, OrderType, SHORT_BLOCK_WINDOW,
Network,
OrderExecution,
OrderSide,
OrderTimeInForce,
OrderType,
SHORT_BLOCK_FORWARD,
SHORT_BLOCK_WINDOW,
} from './constants';
import {
calculateQuantums,
Expand All @@ -35,6 +43,14 @@ import { ValidatorClient } from './validator-client';
protobuf.util.Long = Long;
protobuf.configure();

export interface MarketInfo {
clobPairId: number;
atomicResolution: number;
stepBaseQuantums: number;
quantumConversionExponent: number;
subticksPerTick: number;
}

export class CompositeClient {
public readonly network: Network;
private _indexerClient: IndexerClient;
Expand Down Expand Up @@ -89,8 +105,16 @@ export class CompositeClient {
zeroFee: boolean,
gasPrice: GasPrice = GAS_PRICE,
memo?: string,
account?: () => Promise<Account>,
): Promise<Uint8Array> {
return this.validatorClient.post.sign(wallet, messaging, zeroFee, gasPrice, memo);
return this.validatorClient.post.sign(
wallet,
messaging,
zeroFee,
gasPrice,
memo,
account,
);
}

/**
Expand All @@ -107,8 +131,17 @@ export class CompositeClient {
zeroFee: boolean,
gasPrice: GasPrice = GAS_PRICE,
memo?: string,
account?: () => Promise<Account>,
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
return this.validatorClient.post.send(wallet, messaging, zeroFee, gasPrice, memo);
return this.validatorClient.post.send(
wallet,
messaging,
zeroFee,
gasPrice,
memo,
undefined,
account,
);
}

/**
Expand Down Expand Up @@ -144,8 +177,15 @@ export class CompositeClient {
messaging: () => Promise<EncodeObject[]>,
gasPrice: GasPrice = GAS_PRICE,
memo?: string,
account?: () => Promise<Account>,
): Promise<StdFee> {
return this.validatorClient.post.simulate(wallet, messaging, gasPrice, memo);
return this.validatorClient.post.simulate(
wallet,
messaging,
gasPrice,
memo,
account,
);
}

/**
Expand All @@ -155,9 +195,17 @@ export class CompositeClient {
* at any point.
* @returns The goodTilBlock value
*/
private async calculateGoodTilBlock(): Promise<number> {
const height = await this.validatorClient.get.latestBlockHeight();
return height + 3;

private async calculateGoodTilBlock(
orderFlags: OrderFlags,
currentHeight?: number,
): Promise<number> {
if (orderFlags === OrderFlags.SHORT_TERM) {
const height = currentHeight ?? await this.validatorClient.get.latestBlockHeight();
return height + SHORT_BLOCK_FORWARD;
} else {
return Promise.resolve(0);
}
}

/**
Expand Down Expand Up @@ -247,10 +295,18 @@ export class CompositeClient {
console.log(err);
});
});
const account: Promise<Account> = this.validatorClient.post.account(
subaccount.address,
undefined,
);
return this.send(
subaccount.wallet,
() => msgs,
true);
true,
undefined,
undefined,
() => account,
);
}

/**
Expand All @@ -272,6 +328,12 @@ export class CompositeClient {
* @param execution The execution of the order to place.
* @param postOnly The postOnly of the order to place.
* @param reduceOnly The reduceOnly of the order to place.
* @param triggerPrice The trigger price of conditional orders.
* @param marketInfo optional market information for calculating quantums and subticks.
* This can be constructed from Indexer API. If set to null, additional round
* trip to Indexer API will be made.
* @param currentHeight Current block height. This can be obtained from ValidatorClient.
* If set to null, additional round trip to ValidatorClient will be made.
*
*
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
Expand All @@ -292,6 +354,8 @@ export class CompositeClient {
postOnly?: boolean,
reduceOnly?: boolean,
triggerPrice?: number,
marketInfo?: MarketInfo,
currentHeight?: number,
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
const msg = this.placeOrderMessage(
Expand All @@ -309,15 +373,26 @@ export class CompositeClient {
postOnly,
reduceOnly,
triggerPrice,
marketInfo,
currentHeight,
);
msg.then((it) => resolve([it])).catch((err) => {
console.log(err);
});
});
const orderFlags = calculateOrderFlags(type, timeInForce);
const account: Promise<Account> = this.validatorClient.post.account(
subaccount.address,
orderFlags,
);
return this.send(
subaccount.wallet,
() => msgs,
true);
true,
undefined,
undefined,
() => account,
);
}

/**
Expand Down Expand Up @@ -360,14 +435,22 @@ export class CompositeClient {
postOnly?: boolean,
reduceOnly?: boolean,
triggerPrice?: number,
marketInfo?: MarketInfo,
currentHeight?: number,
): Promise<EncodeObject> {
const marketsResponse = await this.indexerClient.markets.getPerpetualMarkets(marketId);
const market = marketsResponse.markets[marketId];
const clobPairId = market.clobPairId;
const atomicResolution = market.atomicResolution;
const stepBaseQuantums = market.stepBaseQuantums;
const quantumConversionExponent = market.quantumConversionExponent;
const subticksPerTick = market.subticksPerTick;
const orderFlags = calculateOrderFlags(type, timeInForce);

const result = await Promise.all([
this.calculateGoodTilBlock(orderFlags, currentHeight),
this.retrieveMarketInfo(marketId, marketInfo),
],
);
const goodTilBlock = result[0];
const clobPairId = result[1].clobPairId;
const atomicResolution = result[1].atomicResolution;
const stepBaseQuantums = result[1].stepBaseQuantums;
const quantumConversionExponent = result[1].quantumConversionExponent;
const subticksPerTick = result[1].subticksPerTick;
const orderSide = calculateSide(side);
const quantums = calculateQuantums(
size,
Expand All @@ -380,16 +463,13 @@ export class CompositeClient {
quantumConversionExponent,
subticksPerTick,
);
const orderFlags = calculateOrderFlags(type, timeInForce);
const orderTimeInForce = calculateTimeInForce(type, timeInForce, execution, postOnly);
const goodTilBlock = (orderFlags === OrderFlags.SHORT_TERM)
? await this.calculateGoodTilBlock() : 0;
let goodTilBlockTime = 0;
if (orderFlags === OrderFlags.LONG_TERM || orderFlags === OrderFlags.CONDITIONAL) {
if (goodTilTimeInSeconds == null) {
throw new Error('goodTilTimeInSeconds must be set for LONG_TERM or CONDITIONAL order');
} else {
goodTilBlockTime = await this.calculateGoodTilBlockTime(goodTilTimeInSeconds);
goodTilBlockTime = this.calculateGoodTilBlockTime(goodTilTimeInSeconds);
}
}
const clientMetadata = calculateClientMetadata(type);
Expand Down Expand Up @@ -419,6 +499,27 @@ export class CompositeClient {
);
}

private async retrieveMarketInfo(marketId: string, marketInfo?:MarketInfo): Promise<MarketInfo> {
if (marketInfo) {
return Promise.resolve(marketInfo);
} else {
const marketsResponse = await this.indexerClient.markets.getPerpetualMarkets(marketId);
const market = marketsResponse.markets[marketId];
const clobPairId = market.clobPairId;
const atomicResolution = market.atomicResolution;
const stepBaseQuantums = market.stepBaseQuantums;
const quantumConversionExponent = market.quantumConversionExponent;
const subticksPerTick = market.subticksPerTick;
return {
clobPairId,
atomicResolution,
stepBaseQuantums,
quantumConversionExponent,
subticksPerTick,
};
}
}

/**
* @description Calculate and create the short term place order message
*
Expand Down Expand Up @@ -787,7 +888,8 @@ export class CompositeClient {
const signature = await this.sign(
wallet,
() => msgs,
true);
true,
);

return Buffer.from(signature).toString('base64');
}
Expand All @@ -812,7 +914,11 @@ export class CompositeClient {
);
resolve([msg]);
});
const signature = await this.sign(subaccount.wallet, () => msgs, true);
const signature = await this.sign(
subaccount.wallet,
() => msgs,
true,
);

return Buffer.from(signature).toString('base64');
}
Expand Down
2 changes: 2 additions & 0 deletions v4-client-js/src/clients/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ export const MAX_MEMO_CHARACTERS: number = 256;

export const SHORT_BLOCK_WINDOW: number = 20;

export const SHORT_BLOCK_FORWARD: number = 3;

// Querying
export const PAGE_REQUEST: PageRequest = {
key: new Uint8Array(),
Expand Down
Loading