Skip to content

Commit

Permalink
fix a few things, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nullpointer0x00 committed Nov 12, 2024
1 parent 0446f53 commit 6d40313
Show file tree
Hide file tree
Showing 7 changed files with 10,102 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ class NavEventsRecord(id: EntityID<Int>) : IntEntity(id) {
fun getLatestNavEvents(
priceDenom: String,
includeMarkers: Boolean,
includeScope: Boolean,
optionalFromDate: DateTime? = null
includeScopes: Boolean,
fromDate: DateTime? = null
) = transaction {
require(includeMarkers || includeScope) { "Either includeMarkers or includeScope must be true" }
require(includeMarkers || includeScopes) { "Either includeMarkers or includeScope must be true" }

var query = """
SELECT DISTINCT ON (denom, scope_id)
Expand All @@ -146,15 +146,15 @@ class NavEventsRecord(id: EntityID<Int>) : IntEntity(id) {
Pair(VarCharColumnType(), priceDenom)
)

optionalFromDate?.let {
fromDate?.let {
query += " AND block_time >= ?"
args.add(Pair(DateColumnType(true), it))
}

when {
includeMarkers && includeScope -> query += " AND (denom IS NOT NULL OR scope_id IS NOT NULL)"
includeMarkers && includeScopes -> query += " AND (denom IS NOT NULL OR scope_id IS NOT NULL)"
includeMarkers -> query += " AND denom IS NOT NULL"
includeScope -> query += " AND scope_id IS NOT NULL"
includeScopes -> query += " AND scope_id IS NOT NULL"
}

query += " ORDER BY denom, scope_id, block_height DESC, event_order DESC"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package io.provenance.explorer.domain.extensions

Check failure on line 1 in service/src/main/kotlin/io/provenance/explorer/domain/extensions/NavEventExtensions.kt

View workflow job for this annotation

GitHub Actions / ktlint

File must end with a newline (\n)

import io.provenance.explorer.model.base.USD_LOWER
import io.provlabs.flow.api.NavEvent
import java.math.BigDecimal
import java.math.RoundingMode

fun io.provlabs.flow.api.NavEvent.calculateUsdPricePerUnit(): BigDecimal {
return calculateUsdPrice(this.priceDenom, this.priceAmount, this.volume)
}

fun io.provenance.explorer.domain.entities.NavEvent.calculateUsdPricePerUnit(): BigDecimal {
return calculateUsdPrice(this.priceDenom, this.priceAmount, this.volume)
}

/**
* Calculates the USD price per unit for a NAV event.
*
Expand All @@ -13,17 +20,17 @@ import java.math.RoundingMode
*
* @return The USD price per unit or `BigDecimal.ZERO` if not a USD event or volume is 0.
*/
fun NavEvent.calculateUsdPricePerUnit(): BigDecimal {
if (this.priceDenom != USD_LOWER) {
private fun calculateUsdPrice(priceDenom: String?, priceAmount: Long?, volume: Long): BigDecimal {
if (priceDenom != USD_LOWER) {
return BigDecimal.ZERO
}

if (this.volume == 0L) {
if (volume == 0L) {
return BigDecimal.ZERO
}

return BigDecimal(this.priceAmount)
return BigDecimal(priceAmount ?: 0)
.setScale(3, RoundingMode.DOWN)
.divide(BigDecimal(1000), RoundingMode.DOWN)
.divide(BigDecimal(this.volume), 3, RoundingMode.DOWN)
}
.divide(BigDecimal(volume), 3, RoundingMode.DOWN)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import io.provenance.explorer.domain.entities.AssetPricingRecord
import io.provenance.explorer.domain.entities.BaseDenomType
import io.provenance.explorer.domain.entities.MarkerCacheRecord
import io.provenance.explorer.domain.entities.MarkerUnitRecord
import io.provenance.explorer.domain.entities.NavEventsRecord
import io.provenance.explorer.domain.entities.TxMarkerJoinRecord
import io.provenance.explorer.domain.exceptions.requireNotNullToMessage
import io.provenance.explorer.domain.extensions.calculateUsdPricePerUnit
Expand Down Expand Up @@ -244,22 +245,22 @@ class AssetService(
val now = OffsetDateTime.now().withOffsetSameInstant(ZoneOffset.UTC)
logger.info("Updating asset pricing, last run at: $assetPricinglastRun")

val latestPrices = flowApiGrpcClient.getAllLatestNavPrices(
val latestPrices = NavEventsRecord.getLatestNavEvents(
priceDenom = USD_LOWER,
includeMarkers = true,
includeScopes = false,
fromDate = assetPricinglastRun?.toDateTime()
)
latestPrices.forEach { price ->
if (price.denom != UTILITY_TOKEN) {
val marker = getAssetRaw(price.denom)
val marker = getAssetRaw(price.denom!!)
insertAssetPricing(
marker = marker,
markerDenom = price.denom,
markerAddress = marker.second.markerAddress,
pricingDenom = price.priceDenom,
pricingDenom = price.priceDenom!!,
pricingAmount = price.calculateUsdPricePerUnit(),
timestamp = DateTime(price.blockTime * 1000)
timestamp = price.blockTime
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package io.provenance.explorer.domain.entities
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.transactions.transaction
import org.junit.jupiter.api.BeforeAll
import java.nio.file.Files
import java.nio.file.Paths

abstract class BaseDbTest {

Expand All @@ -21,4 +23,15 @@ abstract class BaseDbTest {
}
}
}

fun executeSqlFile(filePath: String) {
val path = Paths.get(filePath)
if (!Files.exists(path)) {
throw IllegalArgumentException("SQL file not found: $filePath")
}
val sqlStatements = Files.readString(path)
transaction {
exec(sqlStatements)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class NavEventsRecordTest : BaseDbTest() {
val events = NavEventsRecord.getLatestNavEvents(
priceDenom = "usd",
includeMarkers = true,
includeScope = false
includeScopes = false
)
assertEquals(1, events.size)
assertNotNull(events.first().denom)
Expand All @@ -93,7 +93,7 @@ class NavEventsRecordTest : BaseDbTest() {
val events = NavEventsRecord.getLatestNavEvents(
priceDenom = "usd",
includeMarkers = false,
includeScope = true
includeScopes = true
)
assertEquals(1, events.size)
assertNull(events.first().denom)
Expand All @@ -105,7 +105,7 @@ class NavEventsRecordTest : BaseDbTest() {
val events = NavEventsRecord.getLatestNavEvents(
priceDenom = "usd",
includeMarkers = true,
includeScope = true
includeScopes = true
)
assertEquals(2, events.size)
}
Expand All @@ -116,8 +116,8 @@ class NavEventsRecordTest : BaseDbTest() {
val events = NavEventsRecord.getLatestNavEvents(
priceDenom = "usd",
includeMarkers = true,
includeScope = true,
optionalFromDate = fromDate
includeScopes = true,
fromDate = fromDate
)
assertEquals(2, events.size)
events.forEach {
Expand All @@ -131,7 +131,7 @@ class NavEventsRecordTest : BaseDbTest() {
NavEventsRecord.getLatestNavEvents(
priceDenom = "usd",
includeMarkers = false,
includeScope = false
includeScopes = false
)
}
}
Expand All @@ -141,8 +141,13 @@ class NavEventsRecordTest : BaseDbTest() {
val events = NavEventsRecord.getLatestNavEvents(
priceDenom = "nonexistent",
includeMarkers = true,
includeScope = true
includeScopes = true
)
assertTrue(events.isEmpty())
}

@Test
fun `TODO test`() = transaction {
executeSqlFile("src/test/resources/navs/marker-nav-inserts.sql")
}
}
Original file line number Diff line number Diff line change
@@ -1,58 +1,93 @@
package io.provenance.explorer.domain.extensions

import io.provlabs.flow.api.NavEvent
import org.joda.time.DateTime

Check failure on line 3 in service/src/test/kotlin/io/provenance/explorer/domain/extensions/NavEventExtensionsKtTest.kt

View workflow job for this annotation

GitHub Actions / ktlint

Imports must be ordered in lexicographic order without any empty lines in-between with "java", "javax", "kotlin" and aliases in the end
import io.provlabs.flow.api.NavEvent as FlowNavEvent
import io.provenance.explorer.domain.entities.NavEvent as ExplorerNavEvent
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.math.BigDecimal

class NavEventExtensionsKtTest {

@Test
fun `test calculateUsdPricePerUnit for flow nav events`() {
fun `test calculateUsdPricePerUnit for flow NavEvent`() {
val usdDenom = "usd"
val nonUsdDenom = "non-usd"

val navEventUsdVolume1Price1 = NavEvent.newBuilder()
val navEventUsdVolume1Price1 = FlowNavEvent.newBuilder()
.setPriceAmount(1)
.setPriceDenom(usdDenom)
.setVolume(1L)
.build()

val navEventUsdVolume1Price12 = NavEvent.newBuilder()
val navEventUsdVolume1Price12 = FlowNavEvent.newBuilder()
.setPriceAmount(12)
.setPriceDenom(usdDenom)
.setVolume(1L)
.build()

val navEventUsdVolume1Price123 = NavEvent.newBuilder()
val navEventUsdVolume1Price123 = FlowNavEvent.newBuilder()
.setPriceAmount(123)
.setPriceDenom(usdDenom)
.setVolume(1L)
.build()

val navEventUsdVolume1Price1234 = NavEvent.newBuilder()
val navEventUsdVolume1Price1234 = FlowNavEvent.newBuilder()
.setPriceAmount(1234)
.setPriceDenom(usdDenom)
.setVolume(1L)
.build()

val navEventNonUsd = NavEvent.newBuilder()
val navEventNonUsd = FlowNavEvent.newBuilder()
.setPriceAmount(1234)
.setPriceDenom(nonUsdDenom)
.setVolume(1L)
.build()

val navEventZeroVolume = NavEvent.newBuilder()
val navEventZeroVolume = FlowNavEvent.newBuilder()
.setPriceAmount(1234)
.setPriceDenom(usdDenom)
.setVolume(0L)
.build()

assertEquals(BigDecimal("0.001"), navEventUsdVolume1Price1.calculateUsdPricePerUnit(), "Price amount 1 should be converted to 0.001")
assertEquals(BigDecimal("0.012"), navEventUsdVolume1Price12.calculateUsdPricePerUnit(), "Price amount 12 should be converted to 0.012")
assertEquals(BigDecimal("0.123"), navEventUsdVolume1Price123.calculateUsdPricePerUnit(), "Price amount 123 should be converted to 0.123")
assertEquals(BigDecimal("1.234"), navEventUsdVolume1Price1234.calculateUsdPricePerUnit(), "Price amount 1234 should be converted to 1.234")
assertEquals(BigDecimal.ZERO, navEventNonUsd.calculateUsdPricePerUnit(), "Non-USD denomination should return 0")
assertEquals(BigDecimal.ZERO, navEventZeroVolume.calculateUsdPricePerUnit(), "Zero volume should return 0")
assertEquals(BigDecimal("0.001"), navEventUsdVolume1Price1.calculateUsdPricePerUnit())
assertEquals(BigDecimal("0.012"), navEventUsdVolume1Price12.calculateUsdPricePerUnit())
assertEquals(BigDecimal("0.123"), navEventUsdVolume1Price123.calculateUsdPricePerUnit())
assertEquals(BigDecimal("1.234"), navEventUsdVolume1Price1234.calculateUsdPricePerUnit())
assertEquals(BigDecimal.ZERO, navEventNonUsd.calculateUsdPricePerUnit())
assertEquals(BigDecimal.ZERO, navEventZeroVolume.calculateUsdPricePerUnit())
}

@Test
fun `test calculateUsdPricePerUnit for explorer NavEvent`() {
val usdDenom = "usd"
val nonUsdDenom = "non-usd"

val navEventUsdVolume1Price1 = ExplorerNavEvent(
blockHeight = 1,
blockTime = DateTime.now(),
txHash = "hash1",
eventOrder = 1,
eventType = "type",
scopeId = "scope1",
denom = "denom1",
priceAmount = 1,
priceDenom = usdDenom,
volume = 1L,
source = "source1"
)

val navEventUsdVolume1Price12 = navEventUsdVolume1Price1.copy(priceAmount = 12)
val navEventUsdVolume1Price123 = navEventUsdVolume1Price1.copy(priceAmount = 123)
val navEventUsdVolume1Price1234 = navEventUsdVolume1Price1.copy(priceAmount = 1234)
val navEventNonUsd = navEventUsdVolume1Price1.copy(priceDenom = nonUsdDenom)
val navEventZeroVolume = navEventUsdVolume1Price1.copy(volume = 0L)

assertEquals(BigDecimal("0.001"), navEventUsdVolume1Price1.calculateUsdPricePerUnit())
assertEquals(BigDecimal("0.012"), navEventUsdVolume1Price12.calculateUsdPricePerUnit())
assertEquals(BigDecimal("0.123"), navEventUsdVolume1Price123.calculateUsdPricePerUnit())
assertEquals(BigDecimal("1.234"), navEventUsdVolume1Price1234.calculateUsdPricePerUnit())
assertEquals(BigDecimal.ZERO, navEventNonUsd.calculateUsdPricePerUnit())
assertEquals(BigDecimal.ZERO, navEventZeroVolume.calculateUsdPricePerUnit())
}
}
Loading

0 comments on commit 6d40313

Please sign in to comment.