make additional request for blockhash in polkadot (#537)
This commit is contained in:
@@ -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),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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() =
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = """
|
||||
{
|
||||
@@ -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"))
|
||||
}
|
||||
|
||||
@@ -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 = """
|
||||
{
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user