diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumFullBlocksReader.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumFullBlocksReader.kt index 3d5d466e..6d3815a6 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumFullBlocksReader.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumFullBlocksReader.kt @@ -81,7 +81,7 @@ class EthereumFullBlocksReader( } else { joinWithTransactions(blockSplit.t1, blockSplit.t2, Flux.fromIterable(transactionsData).map { it.json!! }) .reduce(ByteBuffer.allocate(block.json.size * 4), accumulate) - .map { it.flip().array() } + .map(this@EthereumFullBlocksReader::extractContent) .map { json -> BlockContainer(block.height, block.hash, block.difficulty, block.timestamp, true, @@ -95,6 +95,13 @@ class EthereumFullBlocksReader( } } + fun extractContent(it: ByteBuffer): ByteArray { + val pos = it.position() + val result = ByteArray(pos) + it.flip().get(result, 0, pos) + return result + } + fun splitByTransactions(json: ByteArray): Tuple2 { //TODO find a lib that implements Knuth-Morris-Pratt Pattern Matching Algorithm for byte arrays // and reimplement without making a string copy from bytes diff --git a/src/test/groovy/io/emeraldpay/dshackle/upstream/ethereum/EthereumFullBlocksReaderSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/upstream/ethereum/EthereumFullBlocksReaderSpec.groovy index 3c50485f..c68f8bf0 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/upstream/ethereum/EthereumFullBlocksReaderSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/upstream/ethereum/EthereumFullBlocksReaderSpec.groovy @@ -15,7 +15,6 @@ */ package io.emeraldpay.dshackle.upstream.ethereum -import com.fasterxml.jackson.core.PrettyPrinter import com.fasterxml.jackson.core.util.DefaultPrettyPrinter import com.fasterxml.jackson.databind.ObjectMapper import io.emeraldpay.dshackle.Global @@ -32,8 +31,10 @@ import io.infinitape.etherjar.domain.TransactionId import io.infinitape.etherjar.rpc.json.BlockJson import io.infinitape.etherjar.rpc.json.TransactionJson import io.infinitape.etherjar.rpc.json.TransactionRefJson +import org.apache.commons.codec.binary.Hex import spock.lang.Specification +import java.nio.ByteBuffer import java.time.Instant class EthereumFullBlocksReaderSpec extends Specification { @@ -374,4 +375,42 @@ class EthereumFullBlocksReaderSpec extends Specification { new String(act.getT1()).endsWith('"transactions":[') new String(act.getT2()) == ']}' } + + def "Extract from buffer without trailing zeroes"() { + setup: + def reader = new EthereumFullBlocksReader(Stub(Reader), Stub(Reader)) + when: + def buffer = ByteBuffer.allocate(8) + buffer.put(1 as byte) + buffer.put(2 as byte) + def act = reader.extractContent(buffer) + then: + act.size() == 2 + Hex.encodeHexString(act) == "0102" + + when: + buffer = ByteBuffer.allocate(8) + buffer.put(1 as byte) + buffer.put(2 as byte) + buffer.put(3 as byte) + act = reader.extractContent(buffer) + then: + act.size() == 3 + Hex.encodeHexString(act) == "010203" + + when: + buffer = ByteBuffer.allocate(8) + buffer.put(1 as byte) + buffer.put(2 as byte) + buffer.put(3 as byte) + buffer.put(4 as byte) + buffer.put(5 as byte) + buffer.put(6 as byte) + buffer.put(7 as byte) + buffer.put(8 as byte) + act = reader.extractContent(buffer) + then: + act.size() == 8 + Hex.encodeHexString(act) == "0102030405060708" + } }