Skip to content

Commit

Permalink
fix(bonsai-core): clean up some common errors in networking layer (#1406
Browse files Browse the repository at this point in the history
)
  • Loading branch information
tyleroooo authored Jan 7, 2025
1 parent 661155a commit 886e560
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 25 deletions.
11 changes: 6 additions & 5 deletions src/abacus-ts/calculators/transfers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IndexerTransferResponseObject } from '@/types/indexer/indexerApiGen';
import { IndexerTransferCommonResponseObject } from '@/types/indexer/indexerManual';
import { keyBy, maxBy } from 'lodash';

import { EMPTY_ARR } from '@/constants/objects';
Expand All @@ -8,11 +8,12 @@ import { MustBigNumber } from '@/lib/numbers';
import { mergeObjects } from '../lib/mergeObjects';

export function calculateTransfers(
liveTransfers: IndexerTransferResponseObject[] | undefined,
restTransfers: IndexerTransferResponseObject[] | undefined
liveTransfers: IndexerTransferCommonResponseObject[] | undefined,
restTransfers: IndexerTransferCommonResponseObject[] | undefined
) {
const getTransfersById = (data: IndexerTransferResponseObject[]) =>
keyBy(data, (transfer) => transfer.id);
// TODO had to switch to keying by transaction hash, we should switch back when indexer is fixed
const getTransfersById = (data: IndexerTransferCommonResponseObject[]) =>
keyBy(data, (transfer) => transfer.transactionHash);
return mergeObjects(
getTransfersById(liveTransfers ?? EMPTY_ARR),
getTransfersById(restTransfers ?? EMPTY_ARR),
Expand Down
4 changes: 2 additions & 2 deletions src/abacus-ts/rawTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import {
IndexerPerpetualMarketResponseObject,
IndexerPerpetualPositionResponseObject,
IndexerTradeResponseObject,
IndexerTransferResponseObject,
} from '@/types/indexer/indexerApiGen';
import {
IndexerCompositeFillObject,
IndexerCompositeOrderObject,
IndexerTransferCommonResponseObject,
} from '@/types/indexer/indexerManual';

import { MetadataServiceAssetInfo, MetadataServicePrice } from '@/constants/assetMetadata';
Expand Down Expand Up @@ -40,7 +40,7 @@ export interface ParentSubaccountData {
tradingRewards?: IndexerHistoricalBlockTradingReward[];
fills?: IndexerCompositeFillObject[];
orders?: OrdersData;
transfers?: IndexerTransferResponseObject[];
transfers?: IndexerTransferCommonResponseObject[];
};
}

Expand Down
29 changes: 17 additions & 12 deletions src/abacus-ts/websocket/lib/indexerWebsocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export class IndexerWebsocket {
try {
const message = isWsMessage(messagePre);
if (message.type === 'error') {
// todo we should unsub and resub to the connection if we can
logAbacusTsError('IndexerWebsocket', 'encountered server side error:', message.message);
} else if (message.type === 'connected' || message.type === 'unsubscribed') {
// do nothing
Expand All @@ -127,21 +128,25 @@ export class IndexerWebsocket {
const channel = message.channel;
const id = message.id;
if (this.subscriptions[channel] == null) {
logAbacusTsError(
'IndexerWebsocket',
'encountered message with unknown target',
channel,
id
);
if (channel !== 'v4_orderbook') {
logAbacusTsError(
'IndexerWebsocket',
'encountered message with unknown target',
channel,
id
);
}
return;
}
if (this.subscriptions[channel][id ?? NO_ID_SPECIAL_STRING_ID] == null) {
logAbacusTsError(
'IndexerWebsocket',
'encountered message with unknown target',
channel,
id
);
if (channel !== 'v4_orderbook') {
logAbacusTsError(
'IndexerWebsocket',
'encountered message with unknown target',
channel,
id
);
}
return;
}
if (message.type === 'subscribed') {
Expand Down
2 changes: 1 addition & 1 deletion src/abacus-ts/websocket/orderbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function orderbookWebsocketValue(
}

const selectMarketAndWsInfo = createAppSelector(
[selectWebsocketUrl, (state) => state.perpetuals.currentMarketId],
[selectWebsocketUrl, (state) => state.perpetuals.currentMarketIdIfTradeable],
(wsUrl, currentMarketId) => ({ wsUrl, currentMarketId })
);

Expand Down
21 changes: 19 additions & 2 deletions src/abacus-ts/websocket/parentSubaccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { createAppSelector } from '@/state/appTypes';
import { setParentSubaccountRaw } from '@/state/raw';

import { isTruthy } from '@/lib/isTruthy';
import { MustBigNumber } from '@/lib/numbers';

import { accountRefreshSignal } from '../accountRefreshSignal';
import { createStoreEffect } from '../lib/createStoreEffect';
Expand Down Expand Up @@ -74,10 +75,26 @@ function accountWebsocketValue(
{
channel: 'v4_parent_subaccounts',
id: `${address}/${parentSubaccountNumber}`,
handleBaseData: (baseMessage) => {
const message = isWsParentSubaccountSubscribed(baseMessage);
handleBaseData: (baseMessage): Loadable<ParentSubaccountData> => {
accountRefreshSignal.notify();

// null message means account has had no transfers yet, but it's still valid
if (baseMessage == null) {
const parentSubaccountNumberParsed = MustBigNumber(parentSubaccountNumber).toNumber();
return loadableLoaded({
address,
parentSubaccount: parentSubaccountNumberParsed,
live: {},
childSubaccounts: {
[parentSubaccountNumberParsed]: freshChildSubaccount({
address,
subaccountNumber: parentSubaccountNumberParsed,
}),
},
});
}

const message = isWsParentSubaccountSubscribed(baseMessage);
return loadableLoaded({
address: message.subaccount.address,
parentSubaccount: message.subaccount.parentSubaccountNumber,
Expand Down
14 changes: 12 additions & 2 deletions src/hooks/useCurrentMarketId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { useAppDispatch, useAppSelector } from '@/state/appTypes';
import { closeDialogInTradeBox, openDialog } from '@/state/dialogs';
import { getActiveTradeBoxDialog } from '@/state/dialogsSelectors';
import { getHasSeenPredictionMarketIntroDialog } from '@/state/dismissableSelectors';
import { setCurrentMarketId } from '@/state/perpetuals';
import { setCurrentMarketId, setCurrentMarketIdIfTradeable } from '@/state/perpetuals';
import {
getLaunchedMarketIds,
getMarketIds,
Expand Down Expand Up @@ -143,21 +143,31 @@ export const useCurrentMarketId = () => {
// Check for marketIds otherwise Abacus will silently fail its isMarketValid check
if (isViewingUnlaunchedMarket) {
abacusStateManager.setMarket(DEFAULT_MARKETID);
dispatch(setCurrentMarketIdIfTradeable(undefined));
abacusStateManager.setTradeValue({ value: null, field: null });
} else if (hasMarketIds) {
if (marketId) {
const isMarketReadyForSubscription = hasMarketOraclePrice;

if (isMarketReadyForSubscription) {
abacusStateManager.setMarket(marketId);
dispatch(setCurrentMarketIdIfTradeable(marketId));
}
} else {
abacusStateManager.setMarket(DEFAULT_MARKETID);
dispatch(setCurrentMarketIdIfTradeable(undefined));
}

abacusStateManager.setTradeValue({ value: null, field: null });
}
}, [isViewingUnlaunchedMarket, selectedNetwork, hasMarketIds, hasMarketOraclePrice, marketId]);
}, [
isViewingUnlaunchedMarket,
selectedNetwork,
hasMarketIds,
hasMarketOraclePrice,
marketId,
dispatch,
]);

return {
isViewingUnlaunchedMarket,
Expand Down
10 changes: 10 additions & 0 deletions src/state/perpetuals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ interface CandleDataByMarket {

export interface PerpetualsState {
currentMarketId?: string;
// if user is viewing is a live, tradeable market: its id; otherwise: undefined
currentMarketIdIfTradeable?: string;
candles: Record<string, CandleDataByMarket>;
liveTrades?: Record<string, MarketTrade[]>;
markets?: Record<string, PerpetualMarket>;
Expand All @@ -41,6 +43,7 @@ export interface PerpetualsState {

const initialState: PerpetualsState = {
currentMarketId: undefined,
currentMarketIdIfTradeable: undefined,
candles: {},
liveTrades: {},
markets: undefined,
Expand All @@ -63,6 +66,12 @@ export const perpetualsSlice = createSlice({
setCurrentMarketId: (state: PerpetualsState, action: PayloadAction<string>) => {
state.currentMarketId = action.payload;
},
setCurrentMarketIdIfTradeable: (
state: PerpetualsState,
action: PayloadAction<string | undefined>
) => {
state.currentMarketIdIfTradeable = action.payload;
},
setCandles: (
state: PerpetualsState,
action: PayloadAction<{ candles: Candle[]; marketId: string; resolution: string }>
Expand Down Expand Up @@ -163,6 +172,7 @@ export const perpetualsSlice = createSlice({

export const {
setCurrentMarketId,
setCurrentMarketIdIfTradeable,
setCandles,
setLiveTrades,
setMarkets,
Expand Down
4 changes: 3 additions & 1 deletion src/types/indexer/indexerManual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,16 @@ export type IndexerWsOrderUpdate = Partial<
Omit<IndexerCompositeOrderObject, 'subaccountNumber'>
> & { id: string };

export type IndexerTransferCommonResponseObject = Omit<IndexerTransferResponseObject, 'id'>;

export interface IndexerWsParentSubaccountUpdateObject {
blockHeight: string;
assetPositions?: Array<IndexerAssetPositionResponseObject | IndexerWsAssetUpdate>;
perpetualPositions?: Array<IndexerPerpetualPositionResponseObject | IndexerWsPositionUpdate>;
tradingReward?: IndexerHistoricalBlockTradingReward;
fills?: IndexerCompositeFillObject[];
orders?: Array<IndexerWsOrderUpdate | IndexerCompositeOrderObject>;
transfers?: IndexerTransferResponseObject;
transfers?: IndexerTransferCommonResponseObject;
}

export interface IndexerWsTradesUpdateObject {
Expand Down

0 comments on commit 886e560

Please sign in to comment.