solution: cache requested transactions
This commit is contained in:
145
src/test/groovy/io/emeraldpay/dshackle/cache/CachesSpec.groovy
vendored
Normal file
145
src/test/groovy/io/emeraldpay/dshackle/cache/CachesSpec.groovy
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
package io.emeraldpay.dshackle.cache
|
||||
|
||||
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 spock.lang.Specification
|
||||
|
||||
class CachesSpec extends Specification {
|
||||
|
||||
String hash1 = "0xd3f34def3c56ba4e701540d15edaff9acd2a1c968a7ff83b3300ab5dfd5f6aab"
|
||||
String hash2 = "0x4aabdaff9acd2f30d15e00ab5dfd5f6c56ba4ea1c968a7ff8d3f34de70153b33"
|
||||
|
||||
|
||||
def "Evict txes if block updated"() {
|
||||
setup:
|
||||
TxMemCache txCache = Mock()
|
||||
HeightCache heightCache = Mock()
|
||||
BlocksMemCache blocksCache = Mock()
|
||||
def caches = Caches.newBuilder()
|
||||
.setTxByHash(txCache)
|
||||
.setBlockByHeight(heightCache)
|
||||
.setBlockByHash(blocksCache)
|
||||
.build()
|
||||
|
||||
def block1 = new BlockJson()
|
||||
block1.number = 100
|
||||
block1.hash = BlockHash.from(hash1)
|
||||
|
||||
def block2 = new BlockJson()
|
||||
block2.number = 100
|
||||
block2.hash = BlockHash.from(hash2)
|
||||
|
||||
when:
|
||||
caches.cache(Caches.Tag.LATEST, block1)
|
||||
then:
|
||||
1 * blocksCache.add(block1)
|
||||
1 * heightCache.add(block1) >> null
|
||||
|
||||
when:
|
||||
caches.cache(Caches.Tag.LATEST, block2)
|
||||
then:
|
||||
1 * blocksCache.add(block2)
|
||||
1 * heightCache.add(block2) >> block1.hash
|
||||
1 * blocksCache.get(block1.hash) >> block1
|
||||
1 * txCache.evict(block1)
|
||||
}
|
||||
|
||||
def "Evict txes if block updated - when block not cached"() {
|
||||
setup:
|
||||
TxMemCache txCache = Mock()
|
||||
HeightCache heightCache = Mock()
|
||||
BlocksMemCache blocksCache = Mock()
|
||||
def caches = Caches.newBuilder()
|
||||
.setTxByHash(txCache)
|
||||
.setBlockByHeight(heightCache)
|
||||
.setBlockByHash(blocksCache)
|
||||
.build()
|
||||
|
||||
def block1 = new BlockJson()
|
||||
block1.number = 100
|
||||
block1.hash = BlockHash.from(hash1)
|
||||
|
||||
def block2 = new BlockJson()
|
||||
block2.number = 100
|
||||
block2.hash = BlockHash.from(hash2)
|
||||
|
||||
when:
|
||||
caches.cache(Caches.Tag.LATEST, block1)
|
||||
then:
|
||||
1 * blocksCache.add(block1)
|
||||
1 * heightCache.add(block1) >> null
|
||||
|
||||
when:
|
||||
caches.cache(Caches.Tag.LATEST, block2)
|
||||
then:
|
||||
1 * blocksCache.add(block2)
|
||||
1 * heightCache.add(block2) >> block1.hash
|
||||
1 * blocksCache.get(block1.hash) >> null
|
||||
1 * txCache.evict(block1.hash)
|
||||
}
|
||||
|
||||
def "Do not cache txes of a requested block if it's just id"() {
|
||||
setup:
|
||||
TxMemCache txCache = Mock()
|
||||
HeightCache heightCache = Mock()
|
||||
BlocksMemCache blocksCache = Mock()
|
||||
def caches = Caches.newBuilder()
|
||||
.setTxByHash(txCache)
|
||||
.setBlockByHeight(heightCache)
|
||||
.setBlockByHash(blocksCache)
|
||||
.build()
|
||||
|
||||
def block = new BlockJson()
|
||||
block.number = 100
|
||||
block.hash = BlockHash.from(hash1)
|
||||
block.transactions = [
|
||||
new TransactionRefJson(TransactionId.from(hash1)),
|
||||
new TransactionRefJson(TransactionId.from(hash2)),
|
||||
]
|
||||
|
||||
when:
|
||||
caches.cache(Caches.Tag.REQUESTED, block)
|
||||
then:
|
||||
0 * txCache.add(_)
|
||||
}
|
||||
|
||||
def "Cache txes of a requested block"() {
|
||||
setup:
|
||||
TxMemCache txCache = Mock()
|
||||
HeightCache heightCache = Mock()
|
||||
BlocksMemCache blocksCache = Mock()
|
||||
def caches = Caches.newBuilder()
|
||||
.setTxByHash(txCache)
|
||||
.setBlockByHeight(heightCache)
|
||||
.setBlockByHash(blocksCache)
|
||||
.build()
|
||||
|
||||
def tx1 = new TransactionJson().with {
|
||||
hash = TransactionId.from(hash1)
|
||||
blockHash = BlockHash.from(hash1)
|
||||
blockNumber = 100
|
||||
it
|
||||
}
|
||||
def tx2 = new TransactionJson().with {
|
||||
hash = TransactionId.from(hash2)
|
||||
blockHash = BlockHash.from(hash1)
|
||||
blockNumber = 100
|
||||
it
|
||||
}
|
||||
|
||||
|
||||
def block = new BlockJson()
|
||||
block.number = 100
|
||||
block.hash = BlockHash.from(hash1)
|
||||
block.transactions = [tx1, tx2]
|
||||
|
||||
when:
|
||||
caches.cache(Caches.Tag.REQUESTED, block)
|
||||
then:
|
||||
1 * txCache.add(tx1)
|
||||
1 * txCache.add(tx2)
|
||||
}
|
||||
}
|
||||
131
src/test/groovy/io/emeraldpay/dshackle/cache/TxMemCacheSpec.groovy
vendored
Normal file
131
src/test/groovy/io/emeraldpay/dshackle/cache/TxMemCacheSpec.groovy
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
package io.emeraldpay.dshackle.cache
|
||||
|
||||
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 spock.lang.Specification
|
||||
|
||||
class TxMemCacheSpec extends Specification {
|
||||
|
||||
String hash1 = "0xd3f34def3c56ba4e701540d15edaff9acd2a1c968a7ff83b3300ab5dfd5f6aab"
|
||||
String hash2 = "0x4aabdaff9acd2f30d15e00ab5dfd5f6c56ba4ea1c968a7ff8d3f34de70153b33"
|
||||
String hash3 = "0x40d15edaff9acdabd2a1c96fd5f683b3300aad34e7015f34def3c56ba8a7ffb5"
|
||||
String hash4 = "0xa4e7a75dfd5f6a83b3304dc56bfa0abfd3fef01540d15edafc9683f9acd2a13b"
|
||||
|
||||
def "Add and read"() {
|
||||
setup:
|
||||
def cache = new TxMemCache()
|
||||
def tx = new TransactionJson()
|
||||
tx.hash = TransactionId.from(hash1)
|
||||
tx.blockHash = BlockHash.from(hash1)
|
||||
tx.blockNumber = 100
|
||||
|
||||
when:
|
||||
cache.add(tx)
|
||||
def act = cache.read(TransactionId.from(hash1)).block()
|
||||
then:
|
||||
act == tx
|
||||
}
|
||||
|
||||
def "Keeps only configured amount"() {
|
||||
setup:
|
||||
def cache = new TxMemCache(3)
|
||||
|
||||
when:
|
||||
[hash1, hash2, hash3, hash4].eachWithIndex{ String hash, int i ->
|
||||
def tx = new TransactionJson()
|
||||
tx.blockNumber = 100 + i
|
||||
tx.blockHash = BlockHash.from(hash)
|
||||
tx.hash = TransactionId.from(hash)
|
||||
cache.add(tx)
|
||||
}
|
||||
|
||||
def act1 = cache.read(TransactionId.from(hash1)).block()
|
||||
def act2 = cache.read(TransactionId.from(hash2)).block()
|
||||
def act3 = cache.read(TransactionId.from(hash3)).block()
|
||||
def act4 = cache.read(TransactionId.from(hash4)).block()
|
||||
then:
|
||||
act2.hash.toHex() == hash2
|
||||
act3.hash.toHex() == hash3
|
||||
act4.hash.toHex() == hash4
|
||||
act1 == null
|
||||
}
|
||||
|
||||
def "Evict all by block hash"() {
|
||||
setup:
|
||||
def cache = new TxMemCache()
|
||||
|
||||
when:
|
||||
[hash1, hash2].eachWithIndex{ String hash, int i ->
|
||||
def tx = new TransactionJson()
|
||||
tx.blockNumber = 100
|
||||
tx.blockHash = BlockHash.from(hash1)
|
||||
tx.hash = TransactionId.from(hash)
|
||||
cache.add(tx)
|
||||
}
|
||||
[hash3, hash4].eachWithIndex{ String hash, int i ->
|
||||
def tx = new TransactionJson()
|
||||
tx.blockNumber = 101
|
||||
tx.blockHash = BlockHash.from(hash2)
|
||||
tx.hash = TransactionId.from(hash)
|
||||
cache.add(tx)
|
||||
}
|
||||
|
||||
cache.evict(BlockHash.from(hash1))
|
||||
|
||||
def act1 = cache.read(TransactionId.from(hash1)).block()
|
||||
def act2 = cache.read(TransactionId.from(hash2)).block()
|
||||
def act3 = cache.read(TransactionId.from(hash3)).block()
|
||||
def act4 = cache.read(TransactionId.from(hash4)).block()
|
||||
|
||||
then:
|
||||
act1 == null
|
||||
act2 == null
|
||||
act3.hash.toHex() == hash3
|
||||
act4.hash.toHex() == hash4
|
||||
}
|
||||
|
||||
def "Evict all by block data"() {
|
||||
setup:
|
||||
def cache = new TxMemCache()
|
||||
|
||||
when:
|
||||
[hash1, hash2].eachWithIndex{ String hash, int i ->
|
||||
def tx = new TransactionJson()
|
||||
tx.blockNumber = 100
|
||||
tx.blockHash = BlockHash.from(hash1)
|
||||
tx.hash = TransactionId.from(hash)
|
||||
cache.add(tx)
|
||||
}
|
||||
[hash3, hash4].eachWithIndex{ String hash, int i ->
|
||||
def tx = new TransactionJson()
|
||||
tx.blockNumber = 100
|
||||
tx.blockHash = BlockHash.from(hash2)
|
||||
tx.hash = TransactionId.from(hash)
|
||||
cache.add(tx)
|
||||
}
|
||||
|
||||
def block = new BlockJson<TransactionRefJson>()
|
||||
block.hash = BlockHash.from(hash1)
|
||||
block.number = 100
|
||||
block.transactions = [
|
||||
new TransactionRefJson(TransactionId.from(hash1)),
|
||||
new TransactionRefJson(TransactionId.from(hash2)),
|
||||
]
|
||||
|
||||
cache.evict(block)
|
||||
|
||||
def act1 = cache.read(TransactionId.from(hash1)).block()
|
||||
def act2 = cache.read(TransactionId.from(hash2)).block()
|
||||
def act3 = cache.read(TransactionId.from(hash3)).block()
|
||||
def act4 = cache.read(TransactionId.from(hash4)).block()
|
||||
|
||||
then:
|
||||
act1 == null
|
||||
act2 == null
|
||||
act3.hash.toHex() == hash3
|
||||
act4.hash.toHex() == hash4
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ class EthereumApiMock extends DirectEthereumApi {
|
||||
private ObjectMapper objectMapper
|
||||
|
||||
EthereumApiMock(@NotNull ReactorRpcClient rpcClient, @NotNull ObjectMapper objectMapper, @NotNull Chain chain) {
|
||||
super(rpcClient, objectMapper, new DirectCallMethods())
|
||||
super(rpcClient, null, objectMapper, new DirectCallMethods())
|
||||
this.objectMapper = objectMapper
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class EthereumApiStub extends DirectEthereumApi {
|
||||
}
|
||||
|
||||
EthereumApiStub(String id) {
|
||||
super(rpcClient, objectMapper, new DirectCallMethods())
|
||||
super(rpcClient, null, objectMapper, new DirectCallMethods())
|
||||
this.id = id
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.Version
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.upstream.AggregatedUpstream
|
||||
import io.emeraldpay.dshackle.upstream.CallMethods
|
||||
import io.emeraldpay.dshackle.upstream.ChainUpstreams
|
||||
@@ -73,6 +74,6 @@ class TestingCommons {
|
||||
}
|
||||
|
||||
static AggregatedUpstream aggregatedUpstream(EthereumUpstream up) {
|
||||
return new ChainUpstreams(Chain.ETHEREUM, [up], objectMapper())
|
||||
return new ChainUpstreams(Chain.ETHEREUM, [up], Caches.default(), objectMapper())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package io.emeraldpay.dshackle.test
|
||||
|
||||
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.upstream.AggregatedUpstream
|
||||
import io.emeraldpay.dshackle.upstream.ChainUpstreams
|
||||
import io.emeraldpay.dshackle.upstream.QuorumBasedMethods
|
||||
@@ -40,7 +40,7 @@ class UpstreamsMock implements Upstreams {
|
||||
|
||||
AggregatedUpstream addUpstream(@NotNull Chain chain, @NotNull Upstream up) {
|
||||
if (!upstreams.containsKey(chain)) {
|
||||
upstreams[chain] = new ChainUpstreams(chain, [up], TestingCommons.objectMapper())
|
||||
upstreams[chain] = new ChainUpstreams(chain, [up], Caches.default(), TestingCommons.objectMapper())
|
||||
} else {
|
||||
upstreams[chain].addUpstream(up)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package io.emeraldpay.dshackle.upstream
|
||||
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.quorum.AlwaysQuorum
|
||||
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
@@ -28,7 +29,7 @@ class AggregatedUpstreamSpec extends Specification {
|
||||
setup:
|
||||
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, Stub(DirectEthereumApi), new DirectCallMethods(["eth_test1", "eth_test2"]))
|
||||
def up2 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, Stub(DirectEthereumApi), new DirectCallMethods(["eth_test2", "eth_test3"]))
|
||||
def aggr = new ChainUpstreams(Chain.ETHEREUM, [up1, up2], TestingCommons.objectMapper())
|
||||
def aggr = new ChainUpstreams(Chain.ETHEREUM, [up1, up2], Caches.default(), TestingCommons.objectMapper())
|
||||
when:
|
||||
aggr.onUpstreamsUpdated()
|
||||
def act = aggr.getMethods()
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.emeraldpay.dshackle.upstream
|
||||
|
||||
import io.emeraldpay.dshackle.cache.BlockByHeight
|
||||
import io.emeraldpay.dshackle.cache.BlocksMemCache
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.cache.HeightCache
|
||||
import io.emeraldpay.dshackle.reader.EmptyReader
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
@@ -23,8 +24,7 @@ class CachingEthereumApiSpec extends Specification {
|
||||
def head = Mock(EthereumHead.class)
|
||||
def api = new CachingEthereumApi(
|
||||
TestingCommons.objectMapper(),
|
||||
new EmptyReader<BlockHash, BlockJson<TransactionRefJson>>(),
|
||||
new EmptyReader<>(),
|
||||
Caches.default(),
|
||||
head
|
||||
)
|
||||
1 * head.getFlux() >> Flux.just(new BlockJson<TransactionRefJson>(number: 100))
|
||||
@@ -43,8 +43,7 @@ class CachingEthereumApiSpec extends Specification {
|
||||
def head = Mock(EthereumHead.class)
|
||||
def api = new CachingEthereumApi(
|
||||
TestingCommons.objectMapper(),
|
||||
new EmptyReader<BlockHash, BlockJson<TransactionRefJson>>(),
|
||||
new EmptyReader<>(),
|
||||
Caches.default(),
|
||||
head
|
||||
)
|
||||
when:
|
||||
@@ -62,8 +61,7 @@ class CachingEthereumApiSpec extends Specification {
|
||||
def head = Mock(EthereumHead.class)
|
||||
def api = new CachingEthereumApi(
|
||||
TestingCommons.objectMapper(),
|
||||
cache,
|
||||
new EmptyReader<>(),
|
||||
Caches.newBuilder().setBlockByHash(cache).build(),
|
||||
head
|
||||
)
|
||||
cache.add(new BlockJson<TransactionRefJson>(number: 100, hash: BlockHash.from("0x5b4590a9905fa1c9cc273f32e6dc63b4c512f0ee14edc6fa41c26b416a7b5d58")))
|
||||
@@ -85,8 +83,7 @@ class CachingEthereumApiSpec extends Specification {
|
||||
def head = Mock(EthereumHead.class)
|
||||
def api = new CachingEthereumApi(
|
||||
TestingCommons.objectMapper(),
|
||||
blocksCache,
|
||||
new BlockByHeight(heightCache, blocksCache),
|
||||
Caches.newBuilder().setBlockByHash(blocksCache).setBlockByHeight(heightCache).build(),
|
||||
head
|
||||
)
|
||||
def block = new BlockJson<TransactionRefJson>(number: 100, hash: BlockHash.from("0x5b4590a9905fa1c9cc273f32e6dc63b4c512f0ee14edc6fa41c26b416a7b5d58"))
|
||||
|
||||
@@ -47,7 +47,7 @@ class FilteredApisSpec extends Specification {
|
||||
new EthereumUpstream(
|
||||
"test",
|
||||
Chain.ETHEREUM,
|
||||
new DirectEthereumApi(rpcClient, objectMapper, ethereumTargets),
|
||||
new DirectEthereumApi(rpcClient, null, objectMapper, ethereumTargets),
|
||||
(EthereumWs) null,
|
||||
new UpstreamsConfig.Options(),
|
||||
new NodeDetailsList.NodeDetails(1, UpstreamsConfig.Labels.fromMap(it)),
|
||||
|
||||
@@ -20,6 +20,8 @@ import io.emeraldpay.dshackle.upstream.DirectCallMethods
|
||||
import io.infinitape.etherjar.rpc.ReactorRpcClient
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
import io.infinitape.etherjar.rpc.RpcResponseError
|
||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||
import io.infinitape.etherjar.rpc.json.TransactionJson
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.test.StepVerifier
|
||||
import spock.lang.Specification
|
||||
@@ -28,7 +30,7 @@ import java.time.Duration
|
||||
|
||||
class DirectEthereumApiSpec extends Specification {
|
||||
|
||||
DirectEthereumApi api = new DirectEthereumApi(Stub(ReactorRpcClient), TestingCommons.objectMapper(), new DirectCallMethods())
|
||||
DirectEthereumApi api = new DirectEthereumApi(Stub(ReactorRpcClient), null, TestingCommons.objectMapper(), new DirectCallMethods())
|
||||
|
||||
def "Process successful result"() {
|
||||
setup:
|
||||
@@ -89,4 +91,110 @@ class DirectEthereumApiSpec extends Specification {
|
||||
.verify(Duration.ofSeconds(1))
|
||||
|
||||
}
|
||||
|
||||
def "Typed mapping for block request"() {
|
||||
when:
|
||||
def act = api.callMapping("eth_getBlockByHash", ["0xacf5611707048efc39cabed483e420672ca1ed070f248ef6202c99994dbc6061", false])
|
||||
then:
|
||||
act.jsonType == BlockJson
|
||||
act.resultType == BlockJson
|
||||
}
|
||||
|
||||
def "Typed mapping for block request with txes"() {
|
||||
when:
|
||||
def act = api.callMapping("eth_getBlockByHash", ["0xacf5611707048efc39cabed483e420672ca1ed070f248ef6202c99994dbc6061", true])
|
||||
then:
|
||||
act.jsonType == BlockJson
|
||||
act.resultType == BlockJson
|
||||
}
|
||||
|
||||
def "Typed mapping for block by height request"() {
|
||||
when:
|
||||
def act = api.callMapping("eth_getBlockByNumber", ["0x135", false])
|
||||
then:
|
||||
act.jsonType == BlockJson
|
||||
act.resultType == BlockJson
|
||||
}
|
||||
|
||||
def "Typed mapping for block by height request with txes"() {
|
||||
when:
|
||||
def act = api.callMapping("eth_getBlockByNumber", ["0xacf5", true])
|
||||
then:
|
||||
act.jsonType == BlockJson
|
||||
act.resultType == BlockJson
|
||||
}
|
||||
|
||||
def "Typed mapping for tx request"() {
|
||||
when:
|
||||
def act = api.callMapping("eth_getTransactionByHash", ["0xacf5611707048efc39cabed483e420672ca1ed070f248ef6202c99994dbc6061"])
|
||||
then:
|
||||
act.jsonType == TransactionJson
|
||||
act.resultType == TransactionJson
|
||||
}
|
||||
|
||||
def "Errors for mapping of invalid tx request"() {
|
||||
when:
|
||||
api.callMapping("eth_getTransactionByHash", ["0xacf5611707048efc39cabed483e420672ca1ed070f248ef6"])
|
||||
then:
|
||||
def t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
|
||||
when:
|
||||
api.callMapping("eth_getTransactionByHash", ["0xacf5611707048efc39cabed483e420672ca1ed070f248ef6202c99994dbc6061", true])
|
||||
then:
|
||||
t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
|
||||
when:
|
||||
api.callMapping("eth_getTransactionByHash", [])
|
||||
then:
|
||||
t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
}
|
||||
|
||||
def "Errors for mapping of invalid block request"() {
|
||||
when:
|
||||
api.callMapping("eth_getBlockByHash", ["0xacf5611707048efc39cabed483e420672ca1ed070f248ef6202c99994dbc6061"])
|
||||
then:
|
||||
def t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
|
||||
when:
|
||||
api.callMapping("eth_getBlockByHash", ["0xacf5611707048efc39cabed48f6202c99994dbc6061", true])
|
||||
then:
|
||||
t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
|
||||
when:
|
||||
api.callMapping("eth_getBlockByHash", [])
|
||||
then:
|
||||
t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
}
|
||||
|
||||
def "Errors for mapping of invalid block by number request"() {
|
||||
when:
|
||||
api.callMapping("eth_getBlockByNumber", ["0xacf5611707048efc3248ef6202c99994dbc6061"])
|
||||
then:
|
||||
def t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
|
||||
when:
|
||||
api.callMapping("eth_getBlockByNumber", ["0x", true])
|
||||
then:
|
||||
t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
|
||||
when:
|
||||
api.callMapping("eth_getBlockByNumber", ["-0x23", true])
|
||||
then:
|
||||
t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
|
||||
when:
|
||||
api.callMapping("eth_getBlockByNumber", [])
|
||||
then:
|
||||
t = thrown(RpcException)
|
||||
t.code == RpcResponseError.CODE_INVALID_METHOD_PARAMS
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user