@@ -62,4 +62,9 @@ class EthereumHeadMock implements Head {
|
||||
void onBeforeBlock(@NotNull Runnable handler) {
|
||||
handlers.add(handler)
|
||||
}
|
||||
|
||||
@Override
|
||||
Long getCurrentHeight() {
|
||||
return latest?.height
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import io.emeraldpay.dshackle.FileResolver
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.cache.CachesFactory
|
||||
import io.emeraldpay.dshackle.config.CacheConfig
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
import io.emeraldpay.dshackle.data.BlockId
|
||||
import io.emeraldpay.dshackle.reader.EmptyReader
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
import io.emeraldpay.dshackle.upstream.Multistream
|
||||
@@ -30,12 +32,17 @@ import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import io.infinitape.etherjar.domain.BlockHash
|
||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||
|
||||
import java.time.Instant
|
||||
|
||||
class TestingCommons {
|
||||
|
||||
static EthereumApiMock api() {
|
||||
return new EthereumApiMock()
|
||||
}
|
||||
|
||||
static EthereumUpstreamMock upstream(Reader<JsonRpcRequest, JsonRpcResponse> api) {
|
||||
return new EthereumUpstreamMock(Chain.ETHEREUM, api)
|
||||
}
|
||||
@@ -69,4 +76,15 @@ class TestingCommons {
|
||||
static FileResolver fileResolver() {
|
||||
return new FileResolver(new File("src/test/resources"))
|
||||
}
|
||||
|
||||
static BlockContainer blockForEthereum(Long height) {
|
||||
BlockJson block = new BlockJson().tap {
|
||||
setNumber(height)
|
||||
setHash(BlockHash.from("0xc4b01774e426325b50f0c709753ec7cf1f1774439d587dfb91f2a4eeb8179cde"))
|
||||
setTotalDifficulty(BigInteger.ONE)
|
||||
setTimestamp(Instant.now())
|
||||
}
|
||||
return BlockContainer.from(block)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.reader.EmptyReader
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
import io.emeraldpay.dshackle.upstream.EmptyHead
|
||||
import io.emeraldpay.dshackle.upstream.Head
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||
import org.apache.commons.collections4.functors.ConstantFactory
|
||||
import reactor.core.publisher.Mono
|
||||
import spock.lang.Specification
|
||||
|
||||
import java.time.Duration
|
||||
@@ -21,11 +28,92 @@ class NativeCallRouterSpec extends Specification {
|
||||
Caches.default(),
|
||||
ConstantFactory.constantFactory(new DefaultEthereumMethods(Chain.ETHEREUM))
|
||||
),
|
||||
methods
|
||||
methods,
|
||||
new EmptyHead()
|
||||
)
|
||||
when:
|
||||
def act = router.read(new JsonRpcRequest("eth_coinbase", [])).block(Duration.ofSeconds(1))
|
||||
then:
|
||||
act.resultAsProcessedString == "0x0000000000000000000000000000000000000000"
|
||||
}
|
||||
|
||||
def "getBlockByNumber with latest uses latest id"() {
|
||||
setup:
|
||||
def head = Mock(Head) {
|
||||
1 * getCurrentHeight() >> 101L
|
||||
}
|
||||
def reader = Mock(EthereumReader) {
|
||||
_ * blocksByIdAsCont() >> new EmptyReader<>()
|
||||
_ * txByHashAsCont() >> new EmptyReader<>()
|
||||
1 * blocksByHeightAsCont() >> Mock(Reader) {
|
||||
1 * read(101L) >> Mono.just(TestingCommons.blockForEthereum(101L))
|
||||
}
|
||||
}
|
||||
def methods = new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
def router = new NativeCallRouter(reader, methods, head)
|
||||
|
||||
when:
|
||||
def act = router.getBlockByNumber(["latest", false])
|
||||
|
||||
then:
|
||||
act != null
|
||||
with(act.block()) {
|
||||
it.length > 0
|
||||
with(Global.objectMapper.readValue(it, BlockJson)) {
|
||||
number == 101
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "getBlockByNumber with earliest uses 0 block"() {
|
||||
setup:
|
||||
def head = Stub(Head) {}
|
||||
def reader = Mock(EthereumReader) {
|
||||
_ * blocksByIdAsCont() >> new EmptyReader<>()
|
||||
_ * txByHashAsCont() >> new EmptyReader<>()
|
||||
1 * blocksByHeightAsCont() >> Mock(Reader) {
|
||||
1 * read(0L) >> Mono.just(TestingCommons.blockForEthereum(0L))
|
||||
}
|
||||
}
|
||||
def methods = new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
def router = new NativeCallRouter(reader, methods, head)
|
||||
|
||||
when:
|
||||
def act = router.getBlockByNumber(["earliest", false])
|
||||
|
||||
then:
|
||||
act != null
|
||||
with(act.block()) {
|
||||
it.length > 0
|
||||
with(Global.objectMapper.readValue(it, BlockJson)) {
|
||||
number == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "getBlockByNumber fetches the block"() {
|
||||
setup:
|
||||
def head = Stub(Head) {}
|
||||
def reader = Mock(EthereumReader) {
|
||||
_ * blocksByIdAsCont() >> new EmptyReader<>()
|
||||
_ * txByHashAsCont() >> new EmptyReader<>()
|
||||
1 * blocksByHeightAsCont() >> Mock(Reader) {
|
||||
1 * read(74735L) >> Mono.just(TestingCommons.blockForEthereum(74735L))
|
||||
}
|
||||
}
|
||||
def methods = new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
def router = new NativeCallRouter(reader, methods, head)
|
||||
|
||||
when:
|
||||
def act = router.getBlockByNumber(["0x123ef", false])
|
||||
|
||||
then:
|
||||
act != null
|
||||
with(act.block()) {
|
||||
it.length > 0
|
||||
with(Global.objectMapper.readValue(it, BlockJson)) {
|
||||
number == 74735
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user