diff --git a/service/src/main/kotlin/io/provenance/explorer/domain/entities/Blocks.kt b/service/src/main/kotlin/io/provenance/explorer/domain/entities/Blocks.kt index 01512d59..9d527068 100644 --- a/service/src/main/kotlin/io/provenance/explorer/domain/entities/Blocks.kt +++ b/service/src/main/kotlin/io/provenance/explorer/domain/entities/Blocks.kt @@ -65,6 +65,7 @@ import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.update import org.joda.time.DateTime import org.joda.time.DateTimeZone +import java.math.BigDecimal import java.sql.ResultSet object BlockCacheTable : CacheIdTable(name = "block_cache") { @@ -171,7 +172,6 @@ object BlockProposerTable : IdTable(name = "block_proposer") { override val id = blockHeight.entityId() val proposerOperatorAddress = varchar("proposer_operator_address", 96) val blockTimestamp = datetime("block_timestamp") - val blockLatency = decimal("block_latency", 50, 25).nullable() } fun BlockProposer.buildInsert() = listOf( @@ -187,18 +187,27 @@ class BlockProposerRecord(id: EntityID) : IntEntity(id) { fun buildInsert(height: Int, minGasFee: Double, timestamp: DateTime, proposer: String) = listOf(height, proposer, minGasFee, timestamp, null).toProcedureObject() - fun calcLatency() = transaction { - val query = "CALL update_block_latency();" - this.exec(query) - } - - fun findAvgBlockCreation(limit: Int) = transaction { - BlockProposerTable.slice(BlockProposerTable.blockLatency) - .select { BlockProposerTable.blockLatency.isNotNull() } - .orderBy(BlockProposerTable.blockHeight, SortOrder.DESC) - .limit(limit) - .mapNotNull { it[BlockProposerTable.blockLatency] } - .average() + fun findAvgBlockCreation(limit: Int): BigDecimal = transaction { + val sqlQuery = """ + WITH limited_blocks AS ( + SELECT block_height, block_timestamp + FROM BlockProposerTable + WHERE block_timestamp IS NOT NULL + ORDER BY block_height DESC + LIMIT $limit + ) + SELECT AVG(EXTRACT(EPOCH FROM (block_timestamp - LAG(block_timestamp) + OVER (ORDER BY block_height)))::numeric) AS avg_block_creation_time + FROM limited_blocks + WHERE block_timestamp IS NOT NULL; + """ + exec(sqlQuery) { resultSet -> + if (resultSet.next()) { + resultSet.getBigDecimal("avg_block_creation_time") + } else { + BigDecimal.ZERO + } + } ?: BigDecimal.ZERO } fun findMissingRecords(min: Int, max: Int, limit: Int) = transaction { @@ -213,7 +222,7 @@ class BlockProposerRecord(id: EntityID) : IntEntity(id) { fun getRecordsForProposer(address: String, limit: Int) = transaction { BlockProposerRecord.find { - (BlockProposerTable.proposerOperatorAddress eq address) and (BlockProposerTable.blockLatency.isNotNull()) + (BlockProposerTable.proposerOperatorAddress eq address) }.orderBy(Pair(BlockProposerTable.blockHeight, SortOrder.DESC)) .limit(limit) .toList() @@ -223,7 +232,6 @@ class BlockProposerRecord(id: EntityID) : IntEntity(id) { var blockHeight by BlockProposerTable.blockHeight var proposerOperatorAddress by BlockProposerTable.proposerOperatorAddress var blockTimestamp by BlockProposerTable.blockTimestamp - var blockLatency by BlockProposerTable.blockLatency } object MissedBlocksTable : IntIdTable(name = "missed_blocks") { diff --git a/service/src/main/kotlin/io/provenance/explorer/service/ValidatorService.kt b/service/src/main/kotlin/io/provenance/explorer/service/ValidatorService.kt index 27942e04..0430fb62 100644 --- a/service/src/main/kotlin/io/provenance/explorer/service/ValidatorService.kt +++ b/service/src/main/kotlin/io/provenance/explorer/service/ValidatorService.kt @@ -544,14 +544,14 @@ class ValidatorService( } } - fun getBlockLatencyData(address: String, blockCount: Int) = - getValidatorOperatorAddress(address)?.let { addr -> - BlockProposerRecord.getRecordsForProposer(addr.operatorAddress, blockCount).let { res -> - val average = res.map { it.blockLatency!! }.average() - val data = res.associate { it.blockHeight to it.blockLatency!! } - BlockLatencyData(addr.operatorAddress, data, average) - } - } ?: throw ResourceNotFoundException("Invalid validator address: '$address'") +// fun getBlockLatencyData(address: String, blockCount: Int) = +// getValidatorOperatorAddress(address)?.let { addr -> +// BlockProposerRecord.getRecordsForProposer(addr.operatorAddress, blockCount).let { res -> +// val average = res.map { it.blockLatency!! }.average() +// val data = res.associate { it.blockHeight to it.blockLatency!! } +// BlockLatencyData(addr.operatorAddress, data, average) +// } +// } ?: throw ResourceNotFoundException("Invalid validator address: '$address'") private fun getLatestHeight() = SpotlightCacheRecord.getSpotlight()?.latestBlock?.height ?: blockService.getMaxBlockCacheHeight() diff --git a/service/src/main/kotlin/io/provenance/explorer/service/async/ScheduledTaskService.kt b/service/src/main/kotlin/io/provenance/explorer/service/async/ScheduledTaskService.kt index 845b7e08..f84f1a36 100644 --- a/service/src/main/kotlin/io/provenance/explorer/service/async/ScheduledTaskService.kt +++ b/service/src/main/kotlin/io/provenance/explorer/service/async/ScheduledTaskService.kt @@ -10,7 +10,6 @@ import io.provenance.explorer.config.ExplorerProperties.Companion.UTILITY_TOKEN_ import io.provenance.explorer.config.ExplorerProperties.Companion.UTILITY_TOKEN_BASE_MULTIPLIER import io.provenance.explorer.domain.core.logger import io.provenance.explorer.domain.entities.BlockCacheRecord -import io.provenance.explorer.domain.entities.BlockProposerRecord import io.provenance.explorer.domain.entities.BlockTxCountsCacheRecord import io.provenance.explorer.domain.entities.BlockTxRetryRecord import io.provenance.explorer.domain.entities.CacheKeys @@ -152,7 +151,6 @@ class ScheduledTaskService( } BlockTxCountsCacheRecord.updateTxCounts() - BlockProposerRecord.calcLatency() if (!cacheService.getCacheValue(CacheKeys.SPOTLIGHT_PROCESSING.key)!!.cacheValue.toBoolean()) { cacheService.updateCacheValue(CacheKeys.SPOTLIGHT_PROCESSING.key, true.toString()) } diff --git a/service/src/main/kotlin/io/provenance/explorer/web/v2/ValidatorControllerV2.kt b/service/src/main/kotlin/io/provenance/explorer/web/v2/ValidatorControllerV2.kt index f009ead4..fc604a18 100644 --- a/service/src/main/kotlin/io/provenance/explorer/web/v2/ValidatorControllerV2.kt +++ b/service/src/main/kotlin/io/provenance/explorer/web/v2/ValidatorControllerV2.kt @@ -165,16 +165,16 @@ class ValidatorControllerV2( dayCount: Int ) = validatorService.getValidatorMarketRateStats(address, fromDate, toDate, dayCount) - @ApiOperation("Returns block latency data for the validator") - @GetMapping("/{address}/latency") - fun blockLatency( - @ApiParam(value = "The Validator's operator, owning account, or consensus address") - @PathVariable - address: String, - @ApiParam(value = "The number of blocks of data returned", defaultValue = "100", required = false) - @RequestParam(defaultValue = "100") - blockCount: Int - ) = validatorService.getBlockLatencyData(address, blockCount) +// @ApiOperation("Returns block latency data for the validator") +// @GetMapping("/{address}/latency") +// fun blockLatency( +// @ApiParam(value = "The Validator's operator, owning account, or consensus address") +// @PathVariable +// address: String, +// @ApiParam(value = "The number of blocks of data returned", defaultValue = "100", required = false) +// @RequestParam(defaultValue = "100") +// blockCount: Int +// ) = validatorService.getBlockLatencyData(address, blockCount) @ApiOperation("Returns distinct validators with missed blocks for the timeframe") @GetMapping("/missed_blocks/distinct")