problem: quorum is not applied for internal reads
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.cache.CurrentBlockCache
|
||||
import io.emeraldpay.dshackle.quorum.QuorumReaderFactory
|
||||
import io.emeraldpay.dshackle.quorum.QuorumRpcReader
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
import io.emeraldpay.dshackle.upstream.ApiSource
|
||||
import io.emeraldpay.dshackle.upstream.Multistream
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import io.infinitape.etherjar.domain.Address
|
||||
import io.infinitape.etherjar.domain.BlockHash
|
||||
import io.infinitape.etherjar.domain.TransactionId
|
||||
import io.infinitape.etherjar.domain.Wei
|
||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||
import io.infinitape.etherjar.rpc.json.TransactionJson
|
||||
import org.apache.commons.collections4.Factory
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.test.StepVerifier
|
||||
import spock.lang.Specification
|
||||
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
class EthereumDirectReaderSpec extends Specification {
|
||||
|
||||
String hash1 = "0x40d15edaff9acdabd2a1c96fd5f683b3300aad34e7015f34def3c56ba8a7ffb5"
|
||||
String address1 = "0xe0aadb0a012dbcdc529c4c743d3e0385a0b54d3d"
|
||||
|
||||
def "Reads block by hash"() {
|
||||
setup:
|
||||
def json = new BlockJson().tap {
|
||||
number = 100
|
||||
hash = BlockHash.from(hash1)
|
||||
timestamp = Instant.now()
|
||||
totalDifficulty = BigInteger.ONE
|
||||
transactions = []
|
||||
}
|
||||
def up = Mock(Multistream) {
|
||||
1 * getApiSource(_) >> Stub(ApiSource)
|
||||
}
|
||||
def calls = Mock(Factory) {
|
||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
}
|
||||
EthereumDirectReader reader = new EthereumDirectReader(
|
||||
up, Caches.default(), new CurrentBlockCache(), calls
|
||||
)
|
||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||
1 * create(_, _) >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> Mono.just(
|
||||
new QuorumRpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(json), 1
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
when:
|
||||
def act = reader.blockReader.read(BlockHash.from(hash1))
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
.expectNextMatches { block ->
|
||||
block.hash.toHexWithPrefix() == hash1
|
||||
}
|
||||
.expectComplete()
|
||||
.verify(Duration.ofSeconds(1))
|
||||
}
|
||||
|
||||
def "Reads block by height"() {
|
||||
setup:
|
||||
def json = new BlockJson().tap {
|
||||
number = 100
|
||||
hash = BlockHash.from(hash1)
|
||||
timestamp = Instant.now()
|
||||
totalDifficulty = BigInteger.ONE
|
||||
transactions = []
|
||||
}
|
||||
def up = Mock(Multistream) {
|
||||
1 * getApiSource(_) >> Stub(ApiSource)
|
||||
}
|
||||
def calls = Mock(Factory) {
|
||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
}
|
||||
EthereumDirectReader reader = new EthereumDirectReader(
|
||||
up, Caches.default(), new CurrentBlockCache(), calls
|
||||
)
|
||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||
1 * create(_, _) >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >> Mono.just(
|
||||
new QuorumRpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(json), 1
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
when:
|
||||
def act = reader.blockByHeightReader.read(100)
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
.expectNextMatches { block ->
|
||||
block.hash.toHexWithPrefix() == hash1
|
||||
}
|
||||
.expectComplete()
|
||||
.verify(Duration.ofSeconds(1))
|
||||
}
|
||||
|
||||
def "Reads tx"() {
|
||||
setup:
|
||||
def json = new TransactionJson().tap {
|
||||
hash = TransactionId.from(hash1)
|
||||
blockNumber = 100
|
||||
blockHash = BlockHash.from(hash1)
|
||||
}
|
||||
def up = Mock(Multistream) {
|
||||
1 * getApiSource(_) >> Stub(ApiSource)
|
||||
}
|
||||
def calls = Mock(Factory) {
|
||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
}
|
||||
EthereumDirectReader reader = new EthereumDirectReader(
|
||||
up, Caches.default(), new CurrentBlockCache(), calls
|
||||
)
|
||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||
1 * create(_, _) >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionByHash", [hash1])) >> Mono.just(
|
||||
new QuorumRpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(json), 1
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
when:
|
||||
def act = reader.txReader.read(TransactionId.from(hash1))
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
.expectNextMatches { block ->
|
||||
block.hash.toHexWithPrefix() == hash1
|
||||
}
|
||||
.expectComplete()
|
||||
.verify(Duration.ofSeconds(1))
|
||||
}
|
||||
|
||||
def "Reads balance"() {
|
||||
setup:
|
||||
def up = Mock(Multistream) {
|
||||
1 * getApiSource(_) >> Stub(ApiSource)
|
||||
}
|
||||
def calls = Mock(Factory) {
|
||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
}
|
||||
EthereumDirectReader reader = new EthereumDirectReader(
|
||||
up, Caches.default(), new CurrentBlockCache(), calls
|
||||
)
|
||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||
1 * create(_, _) >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", [address1, "latest"])) >> Mono.just(
|
||||
new QuorumRpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes("0x100"), 1
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
when:
|
||||
def act = reader.balanceReader.read(Address.from(address1))
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
.expectNext(Wei.from("0x100"))
|
||||
.expectComplete()
|
||||
.verify(Duration.ofSeconds(1))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,8 @@ import io.emeraldpay.dshackle.data.TxContainer
|
||||
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
import io.emeraldpay.dshackle.upstream.Multistream
|
||||
import io.emeraldpay.dshackle.upstream.calls.CallMethods
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import io.infinitape.etherjar.domain.Address
|
||||
import io.infinitape.etherjar.domain.BlockHash
|
||||
@@ -32,6 +34,8 @@ import io.infinitape.etherjar.domain.Wei
|
||||
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.collections4.Factory
|
||||
import org.apache.commons.collections4.functors.ConstantFactory
|
||||
import reactor.core.publisher.Mono
|
||||
import spock.lang.Specification
|
||||
|
||||
@@ -54,6 +58,7 @@ class EthereumReaderSpec extends Specification {
|
||||
json.blockHash = blockJson.hash
|
||||
json.blockNumber = blockJson.number
|
||||
}
|
||||
Factory<CallMethods> calls = ConstantFactory.constantFactory(new DefaultEthereumMethods(Chain.ETHEREUM))
|
||||
|
||||
def "Block by Id reads from cache"() {
|
||||
setup:
|
||||
@@ -63,7 +68,7 @@ class EthereumReaderSpec extends Specification {
|
||||
def caches = Caches.newBuilder()
|
||||
.setBlockByHash(memCache)
|
||||
.build()
|
||||
def reader = new EthereumReader(Stub(Multistream), caches)
|
||||
def reader = new EthereumReader(Stub(Multistream), caches, calls)
|
||||
|
||||
when:
|
||||
def act = reader.blocksById().read(blockId).block()
|
||||
@@ -84,7 +89,7 @@ class EthereumReaderSpec extends Specification {
|
||||
api.answer("eth_getBlockByHash", ["0xf85b826fdf98ee0f48f7db001be00472e63ceb056846f4ecac5f0c32878b8ab2", false], blockJson)
|
||||
|
||||
def upstream = TestingCommons.aggregatedUpstream(api)
|
||||
def reader = new EthereumReader(upstream, caches)
|
||||
def reader = new EthereumReader(upstream, caches, calls)
|
||||
|
||||
when:
|
||||
def act = reader.blocksById().read(blockId).block()
|
||||
@@ -105,7 +110,7 @@ class EthereumReaderSpec extends Specification {
|
||||
api.answer("eth_getBlockByHash", ["0xf85b826fdf98ee0f48f7db001be00472e63ceb056846f4ecac5f0c32878b8ab2", false], blockJson)
|
||||
|
||||
def upstream = TestingCommons.aggregatedUpstream(api)
|
||||
def reader = new EthereumReader(upstream, caches)
|
||||
def reader = new EthereumReader(upstream, caches, calls)
|
||||
|
||||
when:
|
||||
def act = reader.blocksById().read(blockId).block()
|
||||
@@ -122,7 +127,7 @@ class EthereumReaderSpec extends Specification {
|
||||
def caches = Caches.newBuilder()
|
||||
.setBlockByHash(memCache)
|
||||
.build()
|
||||
def reader = new EthereumReader(Stub(Multistream), caches)
|
||||
def reader = new EthereumReader(Stub(Multistream), caches, calls)
|
||||
|
||||
when:
|
||||
def act = reader.blocksByHash().read(blockJson.hash).block()
|
||||
@@ -142,7 +147,7 @@ class EthereumReaderSpec extends Specification {
|
||||
def api = TestingCommons.api()
|
||||
api.answer("eth_getBlockByHash", ["0xf85b826fdf98ee0f48f7db001be00472e63ceb056846f4ecac5f0c32878b8ab2", false], blockJson)
|
||||
def upstream = TestingCommons.aggregatedUpstream(api)
|
||||
def reader = new EthereumReader(upstream, caches)
|
||||
def reader = new EthereumReader(upstream, caches, calls)
|
||||
|
||||
when:
|
||||
def act = reader.blocksByHash().read(blockJson.hash).block()
|
||||
@@ -159,7 +164,7 @@ class EthereumReaderSpec extends Specification {
|
||||
def caches = Caches.newBuilder()
|
||||
.setTxByHash(memCache)
|
||||
.build()
|
||||
def reader = new EthereumReader(Stub(Multistream), caches)
|
||||
def reader = new EthereumReader(Stub(Multistream), caches, calls)
|
||||
|
||||
when:
|
||||
def act = reader.txByHash().read(txJson.hash).block()
|
||||
@@ -180,7 +185,7 @@ class EthereumReaderSpec extends Specification {
|
||||
def api = TestingCommons.api()
|
||||
api.answer("eth_getTransactionByHash", [txJson.hash.toHex()], txJson)
|
||||
def upstream = TestingCommons.aggregatedUpstream(api)
|
||||
def reader = new EthereumReader(upstream, caches)
|
||||
def reader = new EthereumReader(upstream, caches, calls)
|
||||
|
||||
when:
|
||||
def act = reader.txByHash().read(txJson.hash).block()
|
||||
@@ -196,7 +201,7 @@ class EthereumReaderSpec extends Specification {
|
||||
api.answerOnce("eth_getBalance", ["0x70b91ff87a902b53dc6e2f6bda8bb9b330ccd30c", "latest"], "0xff")
|
||||
EthereumUpstreamMock upstream = new EthereumUpstreamMock(Chain.ETHEREUM, api)
|
||||
def upstreams = TestingCommons.aggregatedUpstream(upstream)
|
||||
def reader = new EthereumReader(upstreams, Caches.default())
|
||||
def reader = new EthereumReader(upstreams, Caches.default(), calls)
|
||||
reader.start()
|
||||
|
||||
when:
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.emeraldpay.dshackle.test.TestingCommons
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import org.apache.commons.collections4.functors.ConstantFactory
|
||||
import spock.lang.Specification
|
||||
|
||||
import java.time.Duration
|
||||
@@ -17,7 +18,8 @@ class NativeCallRouterSpec extends Specification {
|
||||
def router = new NativeCallRouter(
|
||||
new EthereumReader(
|
||||
TestingCommons.aggregatedUpstream(TestingCommons.api()),
|
||||
Caches.default()
|
||||
Caches.default(),
|
||||
ConstantFactory.constantFactory(new DefaultEthereumMethods(Chain.ETHEREUM))
|
||||
),
|
||||
methods
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user