Skip to content
This repository has been archived by the owner on Jan 15, 2021. It is now read-only.

Commit

Permalink
getTrades service now also fetches trade reversions
Browse files Browse the repository at this point in the history
  • Loading branch information
Leandro Boscariol committed Jun 4, 2020
1 parent c52f459 commit 879fe3f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/hooks/useTrades.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function useTrades(): Trade[] {
toBlock,
orders,
}
const newTrades = await getTrades(params)
const [newTrades, reverts] = await getTrades(params)
dispatch(newTrades.length > 0 ? appendTrades(newTrades, toBlock) : updateLastCheckedBlock(toBlock))
}
}
Expand Down
52 changes: 41 additions & 11 deletions src/services/factories/getTrades.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ import Web3 from 'web3'

import { TokenDetails, calculatePrice } from '@gnosis.pm/dex-js'

import ExchangeApiImpl, { ExchangeApi, Trade, Order, AuctionElement } from 'api/exchange/ExchangeApi'
import ExchangeApiImpl, {
ExchangeApi,
Trade,
TradeReversion,
Order,
AuctionElement,
BaseTradeEvent,
} from 'api/exchange/ExchangeApi'

import { getTokensFactory } from 'services/factories/tokenList'
import { addUnlistedTokensToUserTokenListByIdFactory } from 'services/factories/addUnlistedTokensToUserTokenListById'
Expand All @@ -22,15 +29,28 @@ export function getTradesFactory(factoryParams: {
exchangeApi: ExchangeApi
getTokens: ReturnType<typeof getTokensFactory>
addUnlistedTokensToUserTokenListById: ReturnType<typeof addUnlistedTokensToUserTokenListByIdFactory>
}): (params: GetTradesParams) => Promise<Trade[]> {
}): (params: GetTradesParams) => Promise<[Trade[], TradeReversion[]]> {
const { web3, exchangeApi, getTokens, addUnlistedTokensToUserTokenListById } = factoryParams

async function getBlockTimePair(blockNumber: number): Promise<[number, number]> {
// js timestamp == unix timestamp * 1000
return [blockNumber, +(await web3.eth.getBlock(blockNumber)).timestamp * 1000]
}

async function _getTrades(
async function assembleTradeReversions(
events: BaseTradeEvent[],
blockTimes: Map<number, number>,
): Promise<TradeReversion[]> {
return events.map(event => {
const timestamp = blockTimes.get(event.blockNumber) as number
const batchId = dateToBatchId(timestamp)
const revertKey = ExchangeApiImpl.buildTradeRevertKey(batchId, event.orderId)

return { ...event, timestamp, batchId, revertKey }
})
}

async function assembleTrades(
events: BaseTradeEvent[],
blockTimes: Map<number, number>,
orders: Map<string, Order>,
Expand Down Expand Up @@ -70,14 +90,14 @@ export function getTradesFactory(factoryParams: {
})
}

async function getTrades(params: GetTradesParams): Promise<Trade[]> {
async function getTradesAndTradeReversions(params: GetTradesParams): Promise<[Trade[], TradeReversion[]]> {
const { userAddress, networkId, orders: existingOrders } = params

const tradeEvents = await exchangeApi.getPastTrades(params)

// Minor optimization: return early when empty
if (tradeEvents.length === 0) {
return []
return [[], []]
}

const blocksSet = new Set<number>()
Expand All @@ -97,6 +117,15 @@ export function getTradesFactory(factoryParams: {
tokenIdsSet.add(sellTokenId)
})

// TODO: should fetch in parallel with trade events and risk being discarded,
// or not and delay a bit the execution but possibly saving resources?
const tradeReversionEvents = await exchangeApi.getPastTradeReversions(params)
// Go over trade reversion blocks as well
// Only add blocks though, no need to check orders nor tokens
tradeReversionEvents.forEach(event => {
blocksSet.add(event.blockNumber)
})

// ### ORDERS ###
const orders = new Map<string, Order>()
// Add all existing orders to map. No problem to have more than what we need since it'll be picked by id later.
Expand Down Expand Up @@ -162,12 +191,13 @@ export function getTradesFactory(factoryParams: {
// Create tokens map. No need to do the extra hop to filter, since it'll be picked by id later
const tokens = new Map(getTokens(networkId).map(token => [token.id, token]))

// ### TRADES ###
// Final step, put all together into Trade objects
const trades = await _getTrades(tradeEvents, blockTimes, orders, tokens)

return trades
// ### TRADES and TRADE REVERSIONS ###
// Final step, put all together
return await Promise.all([
assembleTrades(tradeEvents, blockTimes, orders, tokens),
assembleTradeReversions(tradeReversionEvents, blockTimes),
])
}

return getTrades
return getTradesAndTradeReversions
}

0 comments on commit 879fe3f

Please sign in to comment.