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

make additional request for blockhash in polkadot #537

Merged
merged 1 commit into from
Aug 2, 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 @@ -45,20 +45,22 @@ object BeaconChainSpecific : AbstractPollChainSpecific() {
return ChainRequest("GET#/eth/v1/beacon/headers/head", RestParams.emptyParams())
}

override fun parseBlock(data: ByteArray, upstreamId: String): BlockContainer {
override fun parseBlock(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer> {
val blockHeader = Global.objectMapper.readValue<BeaconChainBlockHeader>(data)

return BlockContainer(
height = blockHeader.height,
hash = BlockId.from(blockHeader.hash),
difficulty = BigInteger.ZERO,
timestamp = Instant.EPOCH,
full = false,
json = data,
parsed = blockHeader,
transactions = emptyList(),
upstreamId = upstreamId,
parentHash = BlockId.from(blockHeader.parentHash),
return Mono.just(
BlockContainer(
height = blockHeader.height,
hash = BlockId.from(blockHeader.hash),
difficulty = BigInteger.ZERO,
timestamp = Instant.EPOCH,
full = false,
json = data,
parsed = blockHeader,
transactions = emptyList(),
upstreamId = upstreamId,
parentHash = BlockId.from(blockHeader.parentHash),
),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,22 @@ object CosmosChainSpecific : AbstractPollChainSpecific() {
val log = LoggerFactory.getLogger(this::class.java)
override fun latestBlockRequest(): ChainRequest = ChainRequest("block", ObjectParams())

override fun parseBlock(data: ByteArray, upstreamId: String): BlockContainer {
override fun parseBlock(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer> {
val result = Global.objectMapper.readValue(data, CosmosBlockResult::class.java)

return BlockContainer(
height = result.block.header.height.toLong(),
hash = BlockId.from(result.blockId.hash),
difficulty = BigInteger.ZERO,
timestamp = result.block.header.time,
full = false,
json = data,
parsed = result,
transactions = emptyList(),
upstreamId = upstreamId,
parentHash = BlockId.from(result.block.header.lastBlockId.hash),
return Mono.just(
BlockContainer(
height = result.block.header.height.toLong(),
hash = BlockId.from(result.blockId.hash),
difficulty = BigInteger.ZERO,
timestamp = result.block.header.time,
full = false,
json = data,
parsed = result,
transactions = emptyList(),
upstreamId = upstreamId,
parentHash = BlockId.from(result.block.header.lastBlockId.hash),
),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ object EthereumChainSpecific : AbstractPollChainSpecific() {

private val log: Logger = LoggerFactory.getLogger(EthereumChainSpecific::class.java)

override fun parseBlock(data: ByteArray, upstreamId: String): BlockContainer {
return BlockContainer.fromEthereumJson(data, upstreamId)
override fun parseBlock(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer> {
return Mono.just(BlockContainer.fromEthereumJson(data, upstreamId))
}

override fun getFromHeader(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer> {
return Mono.just(parseBlock(data, upstreamId))
return parseBlock(data, upstreamId, api)
}

override fun latestBlockRequest() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ abstract class AbstractChainSpecific : ChainSpecific {
abstract class AbstractPollChainSpecific : AbstractChainSpecific() {

override fun getLatestBlock(api: ChainReader, upstreamId: String): Mono<BlockContainer> {
return api.read(latestBlockRequest()).map {
parseBlock(it.getResult(), upstreamId)
return api.read(latestBlockRequest()).flatMap {
parseBlock(it.getResult(), upstreamId, api)
}
}

abstract fun latestBlockRequest(): ChainRequest

abstract fun parseBlock(data: ByteArray, upstreamId: String): BlockContainer
abstract fun parseBlock(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer>
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,22 @@ import java.time.Instant
import java.util.concurrent.TimeUnit

object NearChainSpecific : AbstractPollChainSpecific() {
override fun parseBlock(data: ByteArray, upstreamId: String): BlockContainer {
override fun parseBlock(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer> {
val block = Global.objectMapper.readValue(data, NearBlock::class.java).header

return BlockContainer(
height = block.height,
hash = BlockId.fromBase64(block.hash),
difficulty = BigInteger.ZERO,
timestamp = Instant.ofEpochMilli(TimeUnit.MILLISECONDS.convert(block.timestamp, TimeUnit.NANOSECONDS)),
full = false,
json = data,
parsed = block,
transactions = emptyList(),
upstreamId = upstreamId,
parentHash = BlockId.fromBase64(block.prevHash),
return Mono.just(
BlockContainer(
height = block.height,
hash = BlockId.fromBase64(block.hash),
difficulty = BigInteger.ZERO,
timestamp = Instant.ofEpochMilli(TimeUnit.MILLISECONDS.convert(block.timestamp, TimeUnit.NANOSECONDS)),
full = false,
json = data,
parsed = block,
transactions = emptyList(),
upstreamId = upstreamId,
parentHash = BlockId.fromBase64(block.prevHash),
),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,22 @@ import java.time.Instant
object PolkadotChainSpecific : AbstractPollChainSpecific() {

private val log = LoggerFactory.getLogger(PolkadotChainSpecific::class.java)
override fun parseBlock(data: ByteArray, upstreamId: String): BlockContainer {
override fun parseBlock(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer> {
val response = Global.objectMapper.readValue(data, PolkadotBlockResponse::class.java)

return makeBlock(response.block.header, data, upstreamId)
return api.read(ChainRequest("chain_getBlockHash", ListParams(response.block.header.number)))
.map { makeBlock(it.getResultAsProcessedString(), response.block.header, data, upstreamId) }
}

override fun getFromHeader(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer> {
val header = Global.objectMapper.readValue(data, PolkadotHeader::class.java)

return Mono.just(makeBlock(header, data, upstreamId))
return api.read(ChainRequest("chain_getBlockHash", ListParams(header.number)))
.map { makeBlock(it.getResultAsProcessedString(), header, data, upstreamId) }
}

private fun makeBlock(header: PolkadotHeader, data: ByteArray, upstreamId: String): BlockContainer {
private fun makeBlock(id: String, header: PolkadotHeader, data: ByteArray, upstreamId: String): BlockContainer {
return BlockContainer(
height = header.number.substring(2).toLong(16),
hash = BlockId.from(header.parentHash), // todo
hash = BlockId.from(id),
difficulty = BigInteger.ZERO,
timestamp = Instant.EPOCH,
full = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,22 @@ object StarknetChainSpecific : AbstractPollChainSpecific() {

private val log = LoggerFactory.getLogger(StarknetChainSpecific::class.java)

override fun parseBlock(data: ByteArray, upstreamId: String): BlockContainer {
override fun parseBlock(data: ByteArray, upstreamId: String, api: ChainReader): Mono<BlockContainer> {
val block = Global.objectMapper.readValue(data, StarknetBlock::class.java)

return BlockContainer(
height = block.number,
hash = BlockId.from(block.hash),
difficulty = BigInteger.ZERO,
timestamp = block.timestamp,
full = false,
json = data,
parsed = block,
transactions = emptyList(),
upstreamId = upstreamId,
parentHash = BlockId.from(block.parent),
return Mono.just(
BlockContainer(
height = block.number,
hash = BlockId.from(block.hash),
difficulty = BigInteger.ZERO,
timestamp = block.timestamp,
full = false,
json = data,
parsed = block,
transactions = emptyList(),
upstreamId = upstreamId,
parentHash = BlockId.from(block.parent),
),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package io.emeraldpay.dshackle.upstream.beaconchain

import io.emeraldpay.dshackle.data.BlockContainer
import io.emeraldpay.dshackle.data.BlockId
import io.emeraldpay.dshackle.reader.ChainReader
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import reactor.core.publisher.Mono
import java.math.BigInteger
import java.time.Instant

Expand Down Expand Up @@ -44,7 +48,13 @@ class BeaconChainSpecificTest {
parsed = null,
)

val block = BeaconChainSpecific.parseBlock(header, "upId")
val block = BeaconChainSpecific.parseBlock(
header,
"upId",
object : ChainReader {
override fun read(key: ChainRequest): Mono<ChainResponse> = Mono.empty()
},
).block()!!
assertEquals(expected, block)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package io.emeraldpay.dshackle.upstream.polkadot

import io.emeraldpay.dshackle.data.BlockId
import io.emeraldpay.dshackle.reader.ChainReader
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
import org.assertj.core.api.Assertions
import org.junit.jupiter.api.Test
import reactor.core.publisher.Mono

val example = """
{
Expand Down Expand Up @@ -63,10 +67,16 @@ val healthBadSyncing = """{
class PolkadotChainSpecificTest {
@Test
fun parseResponse() {
val result = PolkadotChainSpecific.parseBlock(example.toByteArray(), "1")
val result = PolkadotChainSpecific.parseBlock(
example.toByteArray(),
"1",
object : ChainReader {
override fun read(key: ChainRequest): Mono<ChainResponse> = Mono.just(ChainResponse("\"0x1\"".toByteArray(), null))
},
).block()!!

Assertions.assertThat(result.height).isEqualTo(17963964)
Assertions.assertThat(result.hash).isEqualTo(BlockId.from("0xb52a9b51fb698a891cf378b990b0b6a5743e52fa5175b44a8a6d4e0b2cfd0a53"))
Assertions.assertThat(result.hash).isEqualTo(BlockId.from("0x1"))
Assertions.assertThat(result.upstreamId).isEqualTo("1")
Assertions.assertThat(result.parentHash).isEqualTo(BlockId.from("0xb52a9b51fb698a891cf378b990b0b6a5743e52fa5175b44a8a6d4e0b2cfd0a53"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package io.emeraldpay.dshackle.upstream.starknet

import io.emeraldpay.dshackle.data.BlockId
import io.emeraldpay.dshackle.reader.ChainReader
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
import org.assertj.core.api.Assertions
import org.junit.jupiter.api.Test
import reactor.core.publisher.Mono

val example = """
{
Expand Down Expand Up @@ -45,21 +49,31 @@ val syncingBad = """
class StarknetChainSpecificTest {
@Test
fun parseResponse() {
val result = StarknetChainSpecific.parseBlock(example.toByteArray(), "1")
val result = StarknetChainSpecific.parseBlock(
example.toByteArray(),
"1",
object : ChainReader {
override fun read(key: ChainRequest): Mono<ChainResponse> = Mono.empty()
},
).block()!!

Assertions.assertThat(result.height).isEqualTo(304789)
Assertions.assertThat(result.hash).isEqualTo(BlockId.from("046fa6638dc7fae06cece980ce4195436a79ef314ca49d99e0cef552d6f13c4e"))
Assertions.assertThat(result.hash)
.isEqualTo(BlockId.from("046fa6638dc7fae06cece980ce4195436a79ef314ca49d99e0cef552d6f13c4e"))
Assertions.assertThat(result.upstreamId).isEqualTo("1")
Assertions.assertThat(result.parentHash).isEqualTo(BlockId.from("07cc1e178c848b0bdfa047a414d9a8bee4f6cb76f25f312f2d42e058ea91d78b"))
Assertions.assertThat(result.parentHash)
.isEqualTo(BlockId.from("07cc1e178c848b0bdfa047a414d9a8bee4f6cb76f25f312f2d42e058ea91d78b"))
}

@Test
fun validateOk() {
Assertions.assertThat(StarknetChainSpecific.validate(syncingGood.toByteArray(), 10, "test")).isEqualTo(UpstreamAvailability.OK)
Assertions.assertThat(StarknetChainSpecific.validate(syncingGood.toByteArray(), 10, "test"))
.isEqualTo(UpstreamAvailability.OK)
}

@Test
fun validateSyncing() {
Assertions.assertThat(StarknetChainSpecific.validate(syncingBad.toByteArray(), 10, "test")).isEqualTo(UpstreamAvailability.SYNCING)
Assertions.assertThat(StarknetChainSpecific.validate(syncingBad.toByteArray(), 10, "test"))
.isEqualTo(UpstreamAvailability.SYNCING)
}
}
Loading