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

Move test-only functions off TradingStateMachine #670

Merged
merged 1 commit into from
Sep 24, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,8 @@ import exchange.dydx.abacus.protocols.ParserProtocol
import exchange.dydx.abacus.protocols.TrackingProtocol
import exchange.dydx.abacus.protocols.asTypedStringMap
import exchange.dydx.abacus.responses.ParsingError
import exchange.dydx.abacus.responses.ParsingErrorType
import exchange.dydx.abacus.responses.ParsingException
import exchange.dydx.abacus.responses.SocketInfo
import exchange.dydx.abacus.responses.StateResponse
import exchange.dydx.abacus.state.app.adaptors.AbUrl
import exchange.dydx.abacus.state.app.helper.Formatter
import exchange.dydx.abacus.state.changes.Changes
import exchange.dydx.abacus.state.changes.StateChanges
Expand All @@ -77,7 +74,6 @@ import exchange.dydx.abacus.utils.mutableMapOf
import exchange.dydx.abacus.utils.safeSet
import exchange.dydx.abacus.utils.typedSafeSet
import exchange.dydx.abacus.validator.InputValidator
import indexer.codegen.IndexerSparklineTimePeriod
import indexer.models.configs.ConfigsMarketAsset
import kollections.JsExport
import kollections.iListOf
Expand All @@ -86,9 +82,6 @@ import kollections.iMutableMapOf
import kollections.toIList
import kollections.toIMap
import kollections.toIMutableMap
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlin.math.max
import kotlin.math.min
import kotlin.time.Duration.Companion.days
Expand Down Expand Up @@ -283,297 +276,6 @@ open class TradingStateMachine(
return StateResponse(state, null)
}

fun socket(
url: AbUrl,
jsonString: String,
subaccountNumber: Int,
height: BlockAndTime?,
): StateResponse {
val errors = iMutableListOf<ParsingError>()
val json =
try {
Json.parseToJsonElement(jsonString).jsonObject.toMap()
} catch (e: SerializationException) {
errors.add(
ParsingError(
ParsingErrorType.ParsingError,
"$jsonString is not a valid JSON object",
e.stackTraceToString(),
),
)
null
}
if (json == null || errors.isNotEmpty()) {
return StateResponse(state, null, errors)
}
return socket(url, json, subaccountNumber, height)
}

@Throws(Exception::class)
private fun socket(
url: AbUrl,
payload: Map<String, Any>,
subaccountNumber: Int,
height: BlockAndTime?,
): StateResponse {
var changes: StateChanges? = null
val type = parser.asString(payload["type"])
val channel = parser.asString(payload["channel"])
val id = parser.asString(payload["id"])
val childSubaccountNumber = parser.asInt(payload["subaccountNumber"])
val info = SocketInfo(type, channel, id, childSubaccountNumber)
try {
when (type) {
"subscribed" -> {
val content = parser.asNativeMap(payload["contents"])
?: throw ParsingException(
ParsingErrorType.MissingContent,
payload.toString(),
)
when (channel) {
"v3_markets", "v4_markets" -> {
changes = receivedMarkets(content, subaccountNumber)
}

"v4_subaccounts", "v4_parent_subaccounts" -> {
changes = receivedSubaccountSubscribed(content, height)
}

"v3_orderbook", "v4_orderbook" -> {
val market = parser.asString(payload["id"])
changes = receivedOrderbook(market, content, subaccountNumber)
}

"v3_trades", "v4_trades" -> {
val market = parser.asString(payload["id"])
changes = receivedTrades(market, content)
}

"v4_candles" -> {
val channel = parser.asString(payload["id"])
val (market, resolution) = splitCandlesChannel(channel)
changes = receivedCandles(market, resolution, content)
}

else -> {
throw ParsingException(
ParsingErrorType.UnknownChannel,
"$channel subscribed is not known",
)
}
}
}

"unsubscribed" -> {}

"channel_data" -> {
val content = parser.asNativeMap(payload["contents"])
?: throw ParsingException(
ParsingErrorType.MissingContent,
payload.toString(),
)
when (channel) {
"v3_markets", "v4_markets" -> {
changes = receivedMarketsChanges(content, subaccountNumber)
}

"v4_subaccounts", "v4_parent_subaccounts" -> {
changes = receivedSubaccountsChanges(content, info, height)
}

"v3_orderbook", "v4_orderbook" -> {
throw ParsingException(
ParsingErrorType.UnhandledEndpoint,
"channel_data for $channel is not implemented",
)
// change = receivedOrderbookChanges(market, it)
}

"v3_trades", "v4_trades" -> {
val market = parser.asString(payload["id"])
changes = receivedTradesChanges(market, content)
}

"v4_candles" -> {
val channel = parser.asString(payload["id"])
val (market, resolution) = splitCandlesChannel(channel)
changes = receivedCandlesChanges(market, resolution, content)
}

else -> {
throw ParsingException(
ParsingErrorType.UnknownChannel,
"$channel channel data is not known",
)
}
}
}

"channel_batch_data" -> {
val content = parser.asList(payload["contents"])
?: throw ParsingException(
ParsingErrorType.MissingContent,
payload.toString(),
)
when (channel) {
"v3_markets", "v4_markets" -> {
changes = receivedBatchedMarketsChanges(content, subaccountNumber)
}

"v3_trades", "v4_trades" -> {
val market = parser.asString(payload["id"])
changes = receivedBatchedTradesChanges(market, content)
}

"v4_candles" -> {
val channel = parser.asString(payload["id"])
val (market, resolution) = splitCandlesChannel(channel)
changes = receivedBatchedCandlesChanges(market, resolution, content)
}

"v3_orderbook", "v4_orderbook" -> {
val market = parser.asString(payload["id"])
changes = receivedBatchOrderbookChanges(
market,
content,
subaccountNumber,
)
}

"v4_subaccounts", "v4_parent_subaccounts" -> {
changes = receivedBatchSubaccountsChanges(content, info, height)
}

else -> {
throw ParsingException(
ParsingErrorType.UnknownChannel,
"$channel channel batch data is not known",
)
}
}
}

"connected" -> {}

"error" -> {
throw ParsingException(ParsingErrorType.BackendError, payload.toString())
}

else -> {
throw ParsingException(
ParsingErrorType.Unhandled,
"Type [ $type # $channel ] is not handled",
)
}
}
var realChanges = changes
changes?.let {
realChanges = updateStateChanges(it)
}
return StateResponse(state, realChanges, null, info)
} catch (e: ParsingException) {
return StateResponse(state, null, iListOf(e.toParsingError()), info)
}
}

private fun splitCandlesChannel(channel: String?): Pair<String, String> {
if (channel == null) {
throw ParsingException(
ParsingErrorType.UnknownChannel,
"$channel is not known",
)
}
val marketAndResolution = channel.split("/")
if (marketAndResolution.size != 2) {
throw ParsingException(
ParsingErrorType.UnknownChannel,
"$channel is not known",
)
}
val market = marketAndResolution[0]
val resolution = marketAndResolution[1]
return Pair(market, resolution)
}

/**
* function specifically for testing spoofed rest response processing
*/
fun rest(
url: AbUrl,
payload: String,
subaccountNumber: Int,
height: Int?,
deploymentUri: String? = null,
period: String? = null,
): StateResponse {
/*
For backward compatibility only
*/
var changes: StateChanges? = null
var error: ParsingError? = null
when (url.path) {
"/v3/historical-pnl", "/v4/historical-pnl" -> {
val subaccountNumber =
parser.asInt(url.params?.firstOrNull { param -> param.key == "subaccountNumber" }?.value)
?: 0
changes = historicalPnl(payload, subaccountNumber)
}

"/v3/candles" -> {
changes = candles(payload)
}

"/v4/sparklines" -> {
changes = sparklines(payload, IndexerSparklineTimePeriod.ONEDAY)
}

"/v4/fills" -> {
val subaccountNumber =
parser.asInt(url.params?.firstOrNull { param -> param.key == "subaccountNumber" }?.value)
?: 0
changes = fills(payload, subaccountNumber)
}

"/v4/transfers" -> {
val subaccountNumber =
parser.asInt(url.params?.firstOrNull { param -> param.key == "subaccountNumber" }?.value)
?: 0
changes = transfers(payload, subaccountNumber)
}

"/configs/markets.json" -> {
if (deploymentUri != null) {
changes = configurations(
payload = payload,
subaccountNumber = subaccountNumber,
deploymentUri = deploymentUri,
)
}
}

else -> {
if (url.path.contains("/v3/historical-funding/") || url.path.contains("/v4/historicalFunding/")) {
changes = historicalFundings(payload)
} else if (url.path.contains("/v3/candles/") || url.path.contains("/v4/candles/")) {
changes = candles(payload)
} else if (url.path.contains("/v4/addresses/")) {
changes = account(payload)
} else {
error = ParsingError(
ParsingErrorType.UnhandledEndpoint,
"${url.path} parsing has not be implemented, or is an invalid endpoint",
)
}
}
}
if (changes != null) {
updateStateChanges(changes)
}

val errors = if (error != null) iListOf(error) else null
return StateResponse(state, changes, errors)
}

internal fun resetWallet(accountAddress: String?): StateResponse {
val wallet = if (accountAddress != null) iMapOf("walletAddress" to accountAddress) else null
this.wallet = wallet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import exchange.dydx.abacus.state.app.adaptors.AbUrl
import exchange.dydx.abacus.state.model.AdjustIsolatedMarginInputField
import exchange.dydx.abacus.state.model.adjustIsolatedMargin
import exchange.dydx.abacus.tests.extensions.parseOnChainEquityTiers
import exchange.dydx.abacus.tests.extensions.rest
import exchange.dydx.abacus.tests.extensions.socket
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import exchange.dydx.abacus.state.model.closePosition
import exchange.dydx.abacus.state.model.trade
import exchange.dydx.abacus.state.model.tradeInMarket
import exchange.dydx.abacus.tests.extensions.parseOnChainEquityTiers
import exchange.dydx.abacus.tests.extensions.socket
import kotlin.test.BeforeTest
import kotlin.test.DefaultAsserter.assertTrue
import kotlin.test.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import exchange.dydx.abacus.responses.StateResponse
import exchange.dydx.abacus.state.app.adaptors.AbUrl
import exchange.dydx.abacus.state.model.TriggerOrdersInputField
import exchange.dydx.abacus.state.model.triggerOrders
import exchange.dydx.abacus.tests.extensions.rest
import exchange.dydx.abacus.utils.Rounder
import kotlin.math.abs
import kotlin.test.Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package exchange.dydx.abacus.payload.v3

import exchange.dydx.abacus.tests.extensions.socket
import exchange.dydx.abacus.utils.Logger
import kotlin.test.Test
import kotlin.test.assertNotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package exchange.dydx.abacus.payload.v3

import exchange.dydx.abacus.state.model.setOrderbookGrouping
import exchange.dydx.abacus.tests.extensions.socket
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package exchange.dydx.abacus.payload.v4
import exchange.dydx.abacus.calculator.CalculationPeriod
import exchange.dydx.abacus.tests.extensions.loadv4SubaccountsWithPositions
import exchange.dydx.abacus.tests.extensions.log
import exchange.dydx.abacus.tests.extensions.socket
import exchange.dydx.abacus.utils.SHORT_TERM_ORDER_DURATION
import exchange.dydx.abacus.utils.ServerTime
import kotlin.test.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import exchange.dydx.abacus.tests.extensions.loadv4SubaccountWithOrdersAndFillsC
import exchange.dydx.abacus.tests.extensions.loadv4SubaccountsWithPositions
import exchange.dydx.abacus.tests.extensions.log
import exchange.dydx.abacus.tests.extensions.parseOnChainEquityTiers
import exchange.dydx.abacus.tests.extensions.rest
import exchange.dydx.abacus.tests.extensions.socket
import exchange.dydx.abacus.utils.JsonEncoder
import exchange.dydx.abacus.utils.Parser
import exchange.dydx.abacus.utils.ServerTime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package exchange.dydx.abacus.payload.v4
import exchange.dydx.abacus.calculator.CalculationPeriod
import exchange.dydx.abacus.responses.StateResponse
import exchange.dydx.abacus.state.app.adaptors.AbUrl
import exchange.dydx.abacus.tests.extensions.rest
import exchange.dydx.abacus.tests.extensions.socket
import kotlin.test.Test
import kotlin.test.assertEquals

Expand Down
Loading
Loading