Skip to content

Commit c66fb7c

Browse files
author
Karl Ranna
authored
feat: enable USDT/DAI trading pair (#100)
* feat: enable USDT/DAI trading pair * remove timeout from price feed * add more verbose logging to unrecoverable error * attempt to recover from ccxt.NetworkError
1 parent 8e60f97 commit c66fb7c

File tree

7 files changed

+60
-39
lines changed

7 files changed

+60
-39
lines changed

src/__snapshots__/config.spec.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`checkConfigOptions LIVE_CEX disabled does not allow LTC/LTC trading pair 1`] = `"Invalid trading pair LTC/LTC. Supported trading pairs are: ETH/BTC, BTC/USDT, BTC/DAI, LTC/BTC, LTC/USDT"`;
3+
exports[`checkConfigOptions LIVE_CEX disabled does not allow LTC/LTC trading pair 1`] = `"Invalid trading pair LTC/LTC. Supported trading pairs are: ETH/BTC, BTC/USDT, BTC/DAI, LTC/BTC, LTC/USDT, USDT/DAI"`;
44

55
exports[`checkConfigOptions LIVE_CEX disabled requires TEST_CENTRALIZED_EXCHANGE_BASEASSET_BALANCE 1`] = `"Incomplete configuration. Please add the following options to .env or as environment variables: TEST_CENTRALIZED_EXCHANGE_BASEASSET_BALANCE"`;
66

src/arby.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ export const startArby = ({
111111
CEX,
112112
})
113113
).pipe(
114-
catchError(() => {
115-
loggers.global.info('Unrecoverable error. Cleaning up.');
114+
catchError(e => {
115+
loggers.global.info(
116+
`Unrecoverable error: ${JSON.stringify(e)} - cleaning up.`
117+
);
116118
return cleanup$({
117119
config,
118120
loggers,

src/centralized/exchange-price.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import BigNumber from 'bignumber.js';
22
import { Observable, throwError } from 'rxjs';
3-
import {
4-
catchError,
5-
timeout,
6-
share,
7-
distinctUntilChanged,
8-
} from 'rxjs/operators';
3+
import { catchError, share, distinctUntilChanged } from 'rxjs/operators';
94
import WebSocket from 'ws';
105
import { Config } from '../config';
116
import { Logger } from '../logger';
@@ -55,8 +50,6 @@ const getCentralizedExchangePrice$ = ({
5550
};
5651
});
5752
return priceObservable.pipe(
58-
// if we have not received a price value in 20 seconds we'll error
59-
timeout(10000),
6053
catchError(() => {
6154
return throwError(errors.CENTRALIZED_EXCHANGE_PRICE_FEED_ERROR);
6255
}),

src/config.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ describe('checkConfigOptions', () => {
102102
});
103103
});
104104

105+
it('allows USDT/DAI trading pair', () => {
106+
const config = checkConfigOptions({
107+
...validLiveCEXenabledConf,
108+
...{ BASEASSET: 'USDT', QUOTEASSET: 'DAI' },
109+
});
110+
expect(config).toEqual({
111+
...config,
112+
CEX: 'KRAKEN',
113+
LIVE_CEX: true,
114+
});
115+
});
116+
105117
it('allows ETH/BTC trading pair', () => {
106118
const config = checkConfigOptions({
107119
...validLiveCEXenabledConf,

src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ const ALLOWED_TRADING_PAIRS: string[] = [
9090
'BTC/DAI',
9191
'LTC/BTC',
9292
'LTC/USDT',
93+
'USDT/DAI',
9394
];
9495

9596
const checkConfigOptions = (dotEnvConfig: DotenvParseOutput): Config => {

src/opendex/catch-error.spec.ts

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { status } from '@grpc/grpc-js';
2-
import { AuthenticationError, Exchange } from 'ccxt';
2+
import { AuthenticationError, Exchange, NetworkError } from 'ccxt';
33
import { TestScheduler } from 'rxjs/testing';
44
import { errors } from '../opendex/errors';
55
import { ArbyStore, getArbyStore } from '../store';
@@ -64,6 +64,34 @@ const assertCatchOpenDEXerror = ({
6464

6565
const ASSERTIONS_PER_TEST = 3;
6666

67+
const assertCEXerror = (error: any) => {
68+
return () => {
69+
// 1 extra assertion after assertCatchOpenDEXerror
70+
expect.assertions(ASSERTIONS_PER_TEST + 1);
71+
const inputEvents = '1s #';
72+
const inputError = error;
73+
const expected = '';
74+
const expectedSubscriptions = {
75+
input$: ['^ 999ms !', '7001ms ^ 999ms !'],
76+
cleanup$: ['1s ^ 1s !', '8001ms ^ 1s !'],
77+
};
78+
const store = {
79+
...getArbyStore(),
80+
...{ resetLastOrderUpdatePrice: jest.fn() },
81+
};
82+
const unsubscribe = '10s !';
83+
assertCatchOpenDEXerror({
84+
inputEvents,
85+
inputError,
86+
expected,
87+
unsubscribe,
88+
expectedSubscriptions,
89+
store,
90+
});
91+
expect(store.resetLastOrderUpdatePrice).toHaveBeenCalledTimes(2);
92+
};
93+
};
94+
6795
describe('catchOpenDEXerror', () => {
6896
beforeEach(testSchedulerSetup);
6997

@@ -189,31 +217,15 @@ describe('catchOpenDEXerror', () => {
189217
});
190218
});
191219

192-
it('cancels orders, updates store lastPriceUpdate, retries CENTRALIZED_EXCHANGE_PRICE_FEED_ERROR', () => {
193-
// 1 extra assertion after assertCatchOpenDEXerror
194-
expect.assertions(ASSERTIONS_PER_TEST + 1);
195-
const inputEvents = '1s #';
196-
const inputError = errors.CENTRALIZED_EXCHANGE_PRICE_FEED_ERROR;
197-
const expected = '';
198-
const expectedSubscriptions = {
199-
input$: ['^ 999ms !', '7001ms ^ 999ms !'],
200-
cleanup$: ['1s ^ 1s !', '8001ms ^ 1s !'],
201-
};
202-
const store = {
203-
...getArbyStore(),
204-
...{ resetLastOrderUpdatePrice: jest.fn() },
205-
};
206-
const unsubscribe = '10s !';
207-
assertCatchOpenDEXerror({
208-
inputEvents,
209-
inputError,
210-
expected,
211-
unsubscribe,
212-
expectedSubscriptions,
213-
store,
214-
});
215-
expect(store.resetLastOrderUpdatePrice).toHaveBeenCalledTimes(2);
216-
});
220+
it(
221+
'cancels orders, updates store lastPriceUpdate, retries CENTRALIZED_EXCHANGE_PRICE_FEED_ERROR',
222+
assertCEXerror(errors.CENTRALIZED_EXCHANGE_PRICE_FEED_ERROR)
223+
);
224+
225+
it(
226+
'cancels orders, updates store lastPriceUpdate, retries NetworkError',
227+
assertCEXerror(new NetworkError('CEX connection lost'))
228+
);
217229

218230
it('retries recoverable gRPC errors', () => {
219231
const recoverableGRPCerrors = [

src/opendex/catch-error.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { status } from '@grpc/grpc-js';
2-
import { AuthenticationError, Exchange } from 'ccxt';
2+
import { AuthenticationError, Exchange, NetworkError } from 'ccxt';
33
import { concat, Observable, throwError, timer } from 'rxjs';
44
import { ignoreElements, mergeMap, retryWhen } from 'rxjs/operators';
55
import { ArbyStore } from 'src/store';
@@ -62,7 +62,8 @@ const catchOpenDEXerror = (
6262
logMessage(loggers.opendex);
6363
return timer(RETRY_INTERVAL);
6464
} else if (
65-
e.code === errorCodes.CENTRALIZED_EXCHANGE_PRICE_FEED_ERROR
65+
e.code === errorCodes.CENTRALIZED_EXCHANGE_PRICE_FEED_ERROR ||
66+
e instanceof NetworkError
6667
) {
6768
logMessage(loggers.centralized);
6869
store.resetLastOrderUpdatePrice();

0 commit comments

Comments
 (0)