From bbe4fe58c2a8fb1af8bf2a559924ff3fa656498f Mon Sep 17 00:00:00 2001 From: a10zn8 Date: Wed, 31 Jul 2024 18:17:04 +0300 Subject: [PATCH] make additional request for blockhash in polkadot --- .../beaconchain/BeaconChainSpecific.kt | 26 ++++++++++--------- .../upstream/cosmos/CosmosChainSpecific.kt | 26 ++++++++++--------- .../ethereum/EthereumChainSpecific.kt | 6 ++--- .../upstream/generic/AbstractChainSpecific.kt | 6 ++--- .../upstream/near/NearChainSpecific.kt | 26 ++++++++++--------- .../polkadot/PolkadotChainSpecific.kt | 14 +++++----- .../starknet/StarknetChainSpecific.kt | 26 ++++++++++--------- .../beaconchain/BeaconChainSpecificTest.kt | 12 ++++++++- .../polkadot/PolkadotChainSpecificTest.kt | 14 ++++++++-- .../starknet/StarknetChainSpecificTest.kt | 24 +++++++++++++---- 10 files changed, 111 insertions(+), 69 deletions(-) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainSpecific.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainSpecific.kt index f9065b099..25d3c8a86 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainSpecific.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainSpecific.kt @@ -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 { val blockHeader = Global.objectMapper.readValue(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), + ), ) } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/cosmos/CosmosChainSpecific.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/cosmos/CosmosChainSpecific.kt index e1094ab9c..6054f3372 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/cosmos/CosmosChainSpecific.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/cosmos/CosmosChainSpecific.kt @@ -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 { 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), + ), ) } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumChainSpecific.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumChainSpecific.kt index 5604c3007..58053f027 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumChainSpecific.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumChainSpecific.kt @@ -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 { + return Mono.just(BlockContainer.fromEthereumJson(data, upstreamId)) } override fun getFromHeader(data: ByteArray, upstreamId: String, api: ChainReader): Mono { - return Mono.just(parseBlock(data, upstreamId)) + return parseBlock(data, upstreamId, api) } override fun latestBlockRequest() = diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/generic/AbstractChainSpecific.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/generic/AbstractChainSpecific.kt index bc37f5e08..693df7a68 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/generic/AbstractChainSpecific.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/generic/AbstractChainSpecific.kt @@ -121,12 +121,12 @@ abstract class AbstractChainSpecific : ChainSpecific { abstract class AbstractPollChainSpecific : AbstractChainSpecific() { override fun getLatestBlock(api: ChainReader, upstreamId: String): Mono { - 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 } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/near/NearChainSpecific.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/near/NearChainSpecific.kt index f1f4c7760..9bb1a7fd2 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/near/NearChainSpecific.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/near/NearChainSpecific.kt @@ -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 { 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), + ), ) } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/polkadot/PolkadotChainSpecific.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/polkadot/PolkadotChainSpecific.kt index 720758b65..25fdfd65b 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/polkadot/PolkadotChainSpecific.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/polkadot/PolkadotChainSpecific.kt @@ -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 { 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 { 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, diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetChainSpecific.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetChainSpecific.kt index 69da6f7cf..3d75f92b2 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetChainSpecific.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetChainSpecific.kt @@ -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 { 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), + ), ) } diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainSpecificTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainSpecificTest.kt index 528bd59d6..319ac4e60 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainSpecificTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainSpecificTest.kt @@ -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 = Mono.empty() + }, + ).block()!! assertEquals(expected, block) } } diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/polkadot/PolkadotChainSpecificTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/polkadot/PolkadotChainSpecificTest.kt index b52b467c2..11f7adabc 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/polkadot/PolkadotChainSpecificTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/polkadot/PolkadotChainSpecificTest.kt @@ -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 = 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")) } diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetChainSpecificTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetChainSpecificTest.kt index 2d30c321f..a6ea1875b 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetChainSpecificTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetChainSpecificTest.kt @@ -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 = 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) } }