diff --git a/src/main/java/io/emeraldpay/dshackle/upstream/ethereum/json/BlockJson.java b/src/main/java/io/emeraldpay/dshackle/upstream/ethereum/json/BlockJson.java index fe1d25a7..2463d8e0 100644 --- a/src/main/java/io/emeraldpay/dshackle/upstream/ethereum/json/BlockJson.java +++ b/src/main/java/io/emeraldpay/dshackle/upstream/ethereum/json/BlockJson.java @@ -21,8 +21,6 @@ import java.util.Objects; @JsonSerialize(using = BlockJsonSerializer.class) public class BlockJson implements Serializable { - //TODO nonce or sealFields - /** * the block number. null when its pending block. */ @@ -240,11 +238,11 @@ public class BlockJson implements Serializable { } public HexData getExtraData() { - if (extraData != null) { - return extraData; - } else { - return HexData.empty(); - } + return Objects.requireNonNullElseGet(extraData, HexData::empty); + } + + public boolean checkExtraData() { + return extraData != null; } public void setExtraData(HexData extraData) { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/ThrottledLogger.kt b/src/main/kotlin/io/emeraldpay/dshackle/ThrottledLogger.kt new file mode 100644 index 00000000..88dda0bb --- /dev/null +++ b/src/main/kotlin/io/emeraldpay/dshackle/ThrottledLogger.kt @@ -0,0 +1,25 @@ +package io.emeraldpay.dshackle + +import com.github.benmanes.caffeine.cache.Caffeine +import org.slf4j.Logger +import java.time.Duration + +class ThrottledLogger { + companion object { + + private val cache = Caffeine.newBuilder() + .expireAfterWrite(Duration.ofMinutes(1)) + .build() + + fun log(log: Logger, msg: String) { + log(log, msg, msg) + } + + fun log(log: Logger, category: String, msg: String) { + if (cache.getIfPresent(category) == null) { + log.warn(msg) + cache.put(category, true) + } + } + } +} diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumDirectReader.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumDirectReader.kt index 279a0ce0..9ccaeca9 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumDirectReader.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumDirectReader.kt @@ -3,6 +3,7 @@ package io.emeraldpay.dshackle.upstream.ethereum import com.fasterxml.jackson.databind.ObjectMapper import io.emeraldpay.dshackle.Defaults import io.emeraldpay.dshackle.Global +import io.emeraldpay.dshackle.ThrottledLogger import io.emeraldpay.dshackle.cache.Caches import io.emeraldpay.dshackle.cache.CurrentBlockCache import io.emeraldpay.dshackle.data.BlockContainer @@ -160,6 +161,9 @@ class EthereumDirectReader( .retryWhen(Retry.fixedDelay(3, Duration.ofMillis(200))) .flatMap { result -> val block = objectMapper.readValue(result.data, BlockJson::class.java) as BlockJson? + if (block?.checkExtraData() == false) { + ThrottledLogger.log(log, "${up.getId()} recieved block with empty extradata from direct reader") + } if (block == null) { Mono.empty() } else { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumWsHead.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumWsHead.kt index 81d05a7b..54896dad 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumWsHead.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumWsHead.kt @@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream.ethereum import io.emeraldpay.dshackle.Global import io.emeraldpay.dshackle.SilentException +import io.emeraldpay.dshackle.ThrottledLogger import io.emeraldpay.dshackle.data.BlockContainer import io.emeraldpay.dshackle.reader.JsonRpcReader import io.emeraldpay.dshackle.reader.Reader @@ -89,7 +90,11 @@ class EthereumWsHead( fun listenNewHeads(): Flux { return subscribe() .map { - Global.objectMapper.readValue(it, BlockJson::class.java) as BlockJson + val block = Global.objectMapper.readValue(it, BlockJson::class.java) as BlockJson + if (!block.checkExtraData() && skipEnhance) { + ThrottledLogger.log(log, "$upstreamId recieved block with empty extradata through ws subscription") + } + return@map block } .flatMap { block -> // newHeads returns incomplete blocks, i.e. without some fields and without transaction hashes, @@ -115,7 +120,13 @@ class EthereumWsHead( } } .flatMap(JsonRpcResponse::requireResult) - .map { BlockContainer.fromEthereumJson(it, upstreamId) } + .map { + val parsedBlock = BlockContainer.fromEthereumJson(it, upstreamId) + if (parsedBlock.parsed is BlockJson<*> && !parsedBlock.parsed.checkExtraData() && !skipEnhance) { + ThrottledLogger.log(log, "$upstreamId recieved block with empty extradata from block enrichment") + } + return@map parsedBlock + } } }, headScheduler