Skip to content

Commit

Permalink
problem: full block returns transactions in different order
Browse files Browse the repository at this point in the history
fix: #82
  • Loading branch information
splix committed Mar 27, 2021
1 parent 3aa54cc commit b40b208
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class EthereumFullBlocksReader(
val blockSplit = splitByTransactions(block.json!!)

val transactions = Flux.fromIterable(block.transactions)
.flatMap { txes.read(it) }
.flatMapSequential { txes.read(it) }
.collectList()

return@flatMap transactions.flatMap { transactionsData ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,19 @@ import io.emeraldpay.dshackle.cache.TxMemCache
import io.emeraldpay.dshackle.data.BlockContainer
import io.emeraldpay.dshackle.data.BlockId
import io.emeraldpay.dshackle.data.TxContainer
import io.emeraldpay.dshackle.data.TxId
import io.emeraldpay.dshackle.reader.Reader
import io.infinitape.etherjar.domain.BlockHash
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 reactor.core.publisher.Mono
import spock.lang.Specification

import java.nio.ByteBuffer
import java.time.Duration
import java.time.Instant

class EthereumFullBlocksReaderSpec extends Specification {
Expand Down Expand Up @@ -111,6 +114,21 @@ class EthereumFullBlocksReaderSpec extends Specification {
it
}

// all transaction2
def block4 = new BlockJson().with {
it.number = 103
it.hash = BlockHash.from(hash3)
it.totalDifficulty = BigInteger.ONE
it.timestamp = Instant.now()
it.transactions = [
new TransactionRefJson(tx1.hash),
new TransactionRefJson(tx2.hash),
new TransactionRefJson(tx3.hash),
new TransactionRefJson(tx4.hash)
]
it
}


def "Read transactions and return full block"() {
setup:
Expand Down Expand Up @@ -178,6 +196,34 @@ class EthereumFullBlocksReaderSpec extends Specification {
}
}

def "Produce block with original order of transactions"() {
setup:
def txes = Mock(Reader) {
1 * it.read(TxId.from(tx1.hash)) >> Mono.just(TxContainer.from(tx1)).delayElement(Duration.ofMillis(50))
1 * it.read(TxId.from(tx2.hash)) >> Mono.just(TxContainer.from(tx2)).delayElement(Duration.ofMillis(40))
1 * it.read(TxId.from(tx3.hash)) >> Mono.just(TxContainer.from(tx3)).delayElement(Duration.ofMillis(30))
1 * it.read(TxId.from(tx4.hash)) >> Mono.just(TxContainer.from(tx4)).delayElement(Duration.ofMillis(20))
}
def blocks = new BlocksMemCache()
blocks.add(BlockContainer.from(block4))

def full = new EthereumFullBlocksReader(blocks, txes)

when:
def act = full.read(BlockId.from(block4.hash)).block()
act = objectMapper.readValue(act.json, BlockJson)
def transactions = act.transactions

then:
transactions.size() == 4
transactions[0] instanceof TransactionJson
transactions[1] instanceof TransactionJson
transactions[0].hash == TransactionId.from(hash1)
transactions[1].hash == TransactionId.from(hash2)
transactions[2].hash == TransactionId.from(hash3)
transactions[3].hash == TransactionId.from(hash4)
}

def "Read block without transactions"() {
setup:
def txes = new TxMemCache()
Expand Down
9 changes: 8 additions & 1 deletion testing/dshackle/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,12 @@
.Run from project root directory:
[source,bash]
----
./gradlew run --args="--configPath=./testing/dshackle/dshackle.yaml"
./gradlew run --args="--configPath=./testing/dshackle/dshackle-mock.yaml"
----

or

[source,bash]
----
./gradlew run --args="--configPath=./testing/dshackle/dshackle-real.yaml"
----
File renamed without changes.
29 changes: 29 additions & 0 deletions testing/dshackle/dshackle-real.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: v1
port: 12448

tls:
enabled: false

cluster:
upstreams:
- id: eth-1
chain: ethereum
connection:
ethereum:
rpc:
url: "${DSHACKLE_TEST_ETH1_RPC}"
ws:
url: "${DSHACKLE_TEST_ETH1_WS}"
origin: "${DSHACKLE_TEST_ETH1_WSORIGIN}"

cache:
redis:
enabled: false

proxy:
port: 18081
tls:
enabled: false
routes:
- id: eth
blockchain: ethereum
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,20 @@ class ProxyClient {
this.objectMapper = new ObjectMapper()
}

static ProxyClient ethereumMock() {
return forPrefix(18080, "eth")
}

static ProxyClient ethereumReal() {
return forPrefix(18081, "eth")
}

static ProxyClient forPrefix(String prefix) {
return new ProxyClient("http://127.0.0.1:18080/$prefix")
return forPrefix(18080, prefix)
}

static ProxyClient forPrefix(int port, String prefix) {
return new ProxyClient("http://127.0.0.1:$port/$prefix")
}

static ProxyClient forOriginal(int port) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.emeraldpay.dshackle.testing.trial.proxy

import io.emeraldpay.dshackle.testing.trial.Debugger
import io.emeraldpay.dshackle.testing.trial.ProxyClient
import spock.lang.Specification
import spock.lang.Timeout

class GetBlockRealSpec extends Specification {

def client = ProxyClient.ethereumReal()

def setup() {
Debugger.enabled = false
}

def cleanup() {
Debugger.enabled = true
}

@Timeout(15)
def "Correct order for transactions on #height"() {
expect:
def results = [
(client.execute("eth_getBlockByNumber", ["0x" + Integer.toString(height, 16), false]).result["transactions"] as List<String>),
(client.execute("eth_getBlockByNumber", ["0x" + Integer.toString(height, 16), true]).result["transactions"] as List<Map<String, Object>>)
.collect { it.hash }
]

println(results[0])
println(results[1])

results[0] == results[1]

where:
height << (10_000_000..10_000_500)

}
}

0 comments on commit b40b208

Please sign in to comment.