Add height matcher for some methods (#218)
This commit is contained in:
@@ -95,10 +95,9 @@ open class NativeCall(
|
|||||||
fun onUpstreamChangeEvent(event: UpstreamChangeEvent) {
|
fun onUpstreamChangeEvent(event: UpstreamChangeEvent) {
|
||||||
casting[BlockchainType.from(event.chain)]?.let { cast ->
|
casting[BlockchainType.from(event.chain)]?.let { cast ->
|
||||||
multistreamHolder.getUpstream(event.chain).let { up ->
|
multistreamHolder.getUpstream(event.chain).let { up ->
|
||||||
val reader = up.cast(cast).getReader()
|
|
||||||
ethereumCallSelectors.putIfAbsent(
|
ethereumCallSelectors.putIfAbsent(
|
||||||
event.chain,
|
event.chain,
|
||||||
EthereumCallSelector(reader.heightByHash(), up.caches)
|
EthereumCallSelector(up.caches)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,12 @@ package io.emeraldpay.dshackle.upstream.calls
|
|||||||
import io.emeraldpay.dshackle.Global
|
import io.emeraldpay.dshackle.Global
|
||||||
import io.emeraldpay.dshackle.cache.Caches
|
import io.emeraldpay.dshackle.cache.Caches
|
||||||
import io.emeraldpay.dshackle.data.BlockId
|
import io.emeraldpay.dshackle.data.BlockId
|
||||||
import io.emeraldpay.dshackle.reader.Reader
|
|
||||||
import io.emeraldpay.dshackle.upstream.Head
|
import io.emeraldpay.dshackle.upstream.Head
|
||||||
import io.emeraldpay.dshackle.upstream.Selector
|
import io.emeraldpay.dshackle.upstream.Selector
|
||||||
import io.emeraldpay.etherjar.hex.HexQuantity
|
import io.emeraldpay.etherjar.hex.HexQuantity
|
||||||
import org.bouncycastle.util.encoders.DecoderException
|
import org.bouncycastle.util.encoders.DecoderException
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import java.util.Collections
|
|
||||||
import java.util.Objects
|
import java.util.Objects
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,7 +31,6 @@ import java.util.Objects
|
|||||||
* The implementation is specific for Ethereum.
|
* The implementation is specific for Ethereum.
|
||||||
*/
|
*/
|
||||||
class EthereumCallSelector(
|
class EthereumCallSelector(
|
||||||
private val heightReader: Reader<BlockId, Long>,
|
|
||||||
private val caches: Caches
|
private val caches: Caches
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -41,17 +38,25 @@ class EthereumCallSelector(
|
|||||||
private val log = LoggerFactory.getLogger(EthereumCallSelector::class.java)
|
private val log = LoggerFactory.getLogger(EthereumCallSelector::class.java)
|
||||||
|
|
||||||
// ref https://eth.wiki/json-rpc/API#the-default-block-parameter
|
// ref https://eth.wiki/json-rpc/API#the-default-block-parameter
|
||||||
private val TAG_METHODS = listOf(
|
private val TAG_METHODS = setOf(
|
||||||
"eth_getBalance",
|
"eth_getBalance",
|
||||||
"eth_getCode",
|
"eth_getCode",
|
||||||
"eth_getTransactionCount",
|
"eth_getTransactionCount",
|
||||||
// no "eth_getStorageAt" because it has different structure, and therefore separate logic
|
// no "eth_getStorageAt" because it has different structure, and therefore separate logic
|
||||||
"eth_call"
|
"eth_call",
|
||||||
).sorted()
|
"eth_getRootHash",
|
||||||
|
"bor_getRootHash"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val FILTER_OBJECT_METHODS = setOf(
|
||||||
|
"eth_newFilter", "eth_getLogs"
|
||||||
|
)
|
||||||
|
|
||||||
private val GET_BY_HASH_OR_NUMBER_METHODS = setOf(
|
private val GET_BY_HASH_OR_NUMBER_METHODS = setOf(
|
||||||
"eth_getBlockByHash", "eth_getBlockByNumber",
|
"eth_getBlockByHash", "eth_getBlockByNumber", "bor_getSignersAtHash",
|
||||||
"eth_getTransactionByBlockHashAndIndex", "eth_getTransactionByBlockNumberAndIndex"
|
"eth_getTransactionByBlockHashAndIndex", "eth_getTransactionByBlockNumberAndIndex",
|
||||||
|
"eth_getBlockTransactionCountByNumber", "bor_getAuthor", "eth_getUncleCountByBlockNumber",
|
||||||
|
"eth_getUncleByBlockNumberAndIndex"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,14 +70,19 @@ class EthereumCallSelector(
|
|||||||
if (method in DefaultEthereumMethods.withFilterIdMethods) {
|
if (method in DefaultEthereumMethods.withFilterIdMethods) {
|
||||||
return sameUpstreamMatcher(params)
|
return sameUpstreamMatcher(params)
|
||||||
} else if (!passthrough) { // passthrough indicates we should match only labels
|
} else if (!passthrough) { // passthrough indicates we should match only labels
|
||||||
if (Collections.binarySearch(TAG_METHODS, method) >= 0) {
|
when (method) {
|
||||||
return blockTagSelector(params, 1, null, head)
|
in TAG_METHODS -> {
|
||||||
} else if (method == "eth_getStorageAt") {
|
return blockTagSelector(params, 1, null, head)
|
||||||
return blockTagSelector(params, 2, null, head)
|
}
|
||||||
} else if (method in GET_BY_HASH_OR_NUMBER_METHODS) {
|
"eth_getStorageAt" -> {
|
||||||
return blockMethodSelector(method, params, head)
|
return blockTagSelector(params, 2, null, head)
|
||||||
} else if (method == "eth_getLogs") {
|
}
|
||||||
return blockTagSelector(params, 0, "toBlock", head)
|
in GET_BY_HASH_OR_NUMBER_METHODS -> {
|
||||||
|
return blockTagSelector(params, 0, null, head)
|
||||||
|
}
|
||||||
|
in FILTER_OBJECT_METHODS -> {
|
||||||
|
return blockTagSelector(params, 0, "toBlock", head)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Mono.empty()
|
return Mono.empty()
|
||||||
@@ -91,6 +101,7 @@ class EthereumCallSelector(
|
|||||||
val nodeId = hashHex.toInt(16)
|
val nodeId = hashHex.toInt(16)
|
||||||
return Mono.just(Selector.SameNodeMatcher(nodeId.toByte()))
|
return Mono.just(Selector.SameNodeMatcher(nodeId.toByte()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun blockTagSelector(params: String, pos: Int, paramName: String?, head: Head): Mono<Selector.Matcher> {
|
private fun blockTagSelector(params: String, pos: Int, paramName: String?, head: Head): Mono<Selector.Matcher> {
|
||||||
val list = objectMapper.readerFor(Any::class.java).readValues<Any>(params).readAll()
|
val list = objectMapper.readerFor(Any::class.java).readValues<Any>(params).readAll()
|
||||||
if (list.size < pos + 1) {
|
if (list.size < pos + 1) {
|
||||||
@@ -131,9 +142,9 @@ class EthereumCallSelector(
|
|||||||
val minHeight: Long? = when (tag) {
|
val minHeight: Long? = when (tag) {
|
||||||
"latest" -> head.getCurrentHeight()
|
"latest" -> head.getCurrentHeight()
|
||||||
"earliest" -> 0L // for earliest it doesn't nothing, we expect to have 0 block
|
"earliest" -> 0L // for earliest it doesn't nothing, we expect to have 0 block
|
||||||
else -> if (tag.startsWith("0x")) {
|
else -> if (tag.startsWith("0x") || tag.toLongOrNull() != null) {
|
||||||
return if (tag.length == 66) { // 32-byte hash is represented as 0x + 64 characters
|
return if (tag.length == 66) { // 32-byte hash is represented as 0x + 64 characters
|
||||||
blockByHash(tag, head)
|
blockByHash(tag)
|
||||||
} else {
|
} else {
|
||||||
blockByHeight(tag)
|
blockByHeight(tag)
|
||||||
}
|
}
|
||||||
@@ -148,21 +159,8 @@ class EthereumCallSelector(
|
|||||||
Mono.empty()
|
Mono.empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun blockMethodSelector(method: String, params: String, head: Head): Mono<Selector.Matcher> {
|
|
||||||
val list = objectMapper.readerFor(Any::class.java).readValues<Any>(params).readAll()
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
return Mono.empty()
|
|
||||||
}
|
|
||||||
val hashOrNumber = Objects.toString(list[0])
|
|
||||||
|
|
||||||
return when (method) {
|
private fun blockByHash(blockHash: String): Mono<Selector.Matcher> {
|
||||||
"eth_getTransactionByBlockHashAndIndex", "eth_getBlockByHash" -> blockByHashFromCache(hashOrNumber)
|
|
||||||
"eth_getTransactionByBlockNumberAndIndex", "eth_getBlockByNumber" -> blockSelectorByTag(hashOrNumber, head)
|
|
||||||
else -> Mono.empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun blockByHashFromCache(blockHash: String): Mono<Selector.Matcher> {
|
|
||||||
return try {
|
return try {
|
||||||
caches.getLastHeightByHash()
|
caches.getLastHeightByHash()
|
||||||
.read(BlockId.from(blockHash))
|
.read(BlockId.from(blockHash))
|
||||||
@@ -176,22 +174,16 @@ class EthereumCallSelector(
|
|||||||
|
|
||||||
private fun blockByHeight(blockNumber: String): Mono<Selector.Matcher> {
|
private fun blockByHeight(blockNumber: String): Mono<Selector.Matcher> {
|
||||||
return try {
|
return try {
|
||||||
Mono.just(Selector.HeightMatcher(HexQuantity.from(blockNumber).value.longValueExact()))
|
val height =
|
||||||
|
if (blockNumber.startsWith("0x")) {
|
||||||
|
HexQuantity.from(blockNumber).value.longValueExact()
|
||||||
|
} else {
|
||||||
|
blockNumber.toLong()
|
||||||
|
}
|
||||||
|
Mono.just(Selector.HeightMatcher(height))
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
log.warn("Invalid blockNumber: $blockNumber")
|
log.warn("Invalid blockNumber: $blockNumber")
|
||||||
Mono.empty<Selector.Matcher>()
|
Mono.empty()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun blockByHash(blockHash: String, head: Head): Mono<Selector.Matcher> {
|
|
||||||
return try {
|
|
||||||
val blockId = BlockId.from(blockHash)
|
|
||||||
heightReader.read(blockId)
|
|
||||||
.switchIfEmpty(Mono.justOrEmpty(head.getCurrentHeight()))
|
|
||||||
.map { Selector.HeightMatcher(it) }
|
|
||||||
} catch (t: Throwable) {
|
|
||||||
log.warn("Invalid blockHash: $blockHash")
|
|
||||||
Mono.empty<Selector.Matcher>()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package io.emeraldpay.dshackle.upstream.calls
|
package io.emeraldpay.dshackle.upstream.calls
|
||||||
|
|
||||||
|
|
||||||
import io.emeraldpay.dshackle.cache.Caches
|
import io.emeraldpay.dshackle.cache.Caches
|
||||||
import io.emeraldpay.dshackle.cache.HeightByHashMemCache
|
import io.emeraldpay.dshackle.cache.HeightByHashMemCache
|
||||||
import io.emeraldpay.dshackle.data.BlockId
|
import io.emeraldpay.dshackle.data.BlockId
|
||||||
import io.emeraldpay.dshackle.reader.Reader
|
|
||||||
import io.emeraldpay.dshackle.upstream.Head
|
import io.emeraldpay.dshackle.upstream.Head
|
||||||
import io.emeraldpay.dshackle.upstream.Selector
|
import io.emeraldpay.dshackle.upstream.Selector
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
@@ -32,7 +30,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get height matcher for latest balance"() {
|
def "Get height matcher for latest balance"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
1 * getCurrentHeight() >> 100
|
1 * getCurrentHeight() >> 100
|
||||||
}
|
}
|
||||||
@@ -44,7 +42,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get height matcher for latest call"() {
|
def "Get height matcher for latest call"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
1 * getCurrentHeight() >> 100
|
1 * getCurrentHeight() >> 100
|
||||||
}
|
}
|
||||||
@@ -56,7 +54,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get height matcher for latest storageAt"() {
|
def "Get height matcher for latest storageAt"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
1 * getCurrentHeight() >> 100
|
1 * getCurrentHeight() >> 100
|
||||||
}
|
}
|
||||||
@@ -68,7 +66,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get height matcher for balance on block"() {
|
def "Get height matcher for balance on block"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
_ * getCurrentHeight() >> 100
|
_ * getCurrentHeight() >> 100
|
||||||
}
|
}
|
||||||
@@ -80,10 +78,12 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get height matcher for balance on block referred by hash"() {
|
def "Get height matcher for balance on block referred by hash"() {
|
||||||
setup:
|
setup:
|
||||||
def heights = Mock(Reader) {
|
def cache = Mock(Caches) { caches ->
|
||||||
1 * it.read(BlockId.from("0xc90f1c8c125a4d5b90742f16947bdb1d10516f173fd7fc51223d10499de2a812")) >> Mono.just(8606722L)
|
1 * caches.getLastHeightByHash() >> Mock(HeightByHashMemCache) { memCache ->
|
||||||
|
1 * memCache.read(BlockId.from("0xc90f1c8c125a4d5b90742f16947bdb1d10516f173fd7fc51223d10499de2a812")) >> Mono.just(8606722L)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(heights, Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
_ * getCurrentHeight() >> 9128116
|
_ * getCurrentHeight() >> 9128116
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "No matcher for invalid height"() {
|
def "No matcher for invalid height"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
_ * getCurrentHeight() >> 100
|
_ * getCurrentHeight() >> 100
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "No matcher for negative height"() {
|
def "No matcher for negative height"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
_ * getCurrentHeight() >> 100
|
_ * getCurrentHeight() >> 100
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "No matcher for negative long"() {
|
def "No matcher for negative long"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
_ * getCurrentHeight() >> 100
|
_ * getCurrentHeight() >> 100
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "No matcher for pending balance"() {
|
def "No matcher for pending balance"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
_ * getCurrentHeight() >> 100
|
_ * getCurrentHeight() >> 100
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get height matcher with EIP-1898"() {
|
def "Get height matcher with EIP-1898"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader), Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Stub(Head)
|
def head = Stub(Head)
|
||||||
when:
|
when:
|
||||||
def act = callSelector.getMatcher("eth_call", '["0x0000", {"blockNumber": "0x100"}]', head, false).block()
|
def act = callSelector.getMatcher("eth_call", '["0x0000", {"blockNumber": "0x100"}]', head, false).block()
|
||||||
@@ -155,10 +155,12 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get hash matcher with EIP-1898"() {
|
def "Get hash matcher with EIP-1898"() {
|
||||||
setup:
|
setup:
|
||||||
def heights = Mock(Reader) {
|
def cache = Mock(Caches) { caches ->
|
||||||
1 * it.read(BlockId.from("0xa6af163aab691919c595e2a466f0a7b01f1dff8cfd9631dee811df57064c2d32")) >> Mono.just(12079192L)
|
1 * caches.getLastHeightByHash() >> Mock(HeightByHashMemCache) { memCache ->
|
||||||
|
1 * memCache.read(BlockId.from("0xa6af163aab691919c595e2a466f0a7b01f1dff8cfd9631dee811df57064c2d32")) >> Mono.just(12079192L)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(heights, Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Stub(Head)
|
def head = Stub(Head)
|
||||||
when:
|
when:
|
||||||
def act = callSelector.getMatcher("eth_call",
|
def act = callSelector.getMatcher("eth_call",
|
||||||
@@ -170,10 +172,12 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get empty matcher for block tag with passthrough arg"() {
|
def "Get empty matcher for block tag with passthrough arg"() {
|
||||||
setup:
|
setup:
|
||||||
def heights = Mock(Reader) {
|
def cache = Mock(Caches) { caches ->
|
||||||
0 * it.read(BlockId.from("0xa6af163aab691919c595e2a466f0a7b01f1dff8cfd9631dee811df57064c2d32")) >> Mono.just(12079192L)
|
0 * caches.getLastHeightByHash() >> Mock(HeightByHashMemCache) { memCache ->
|
||||||
|
0 * memCache.read(BlockId.from("0xa6af163aab691919c595e2a466f0a7b01f1dff8cfd9631dee811df57064c2d32")) >> Mono.just(12079192L)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(heights, Stub(Caches))
|
EthereumCallSelector callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Stub(Head)
|
def head = Stub(Head)
|
||||||
when:
|
when:
|
||||||
def act = callSelector.getMatcher("eth_call",
|
def act = callSelector.getMatcher("eth_call",
|
||||||
@@ -183,26 +187,9 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
act == null
|
act == null
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Match head if hash matcher for unknown hash"() {
|
|
||||||
setup:
|
|
||||||
def heights = Mock(Reader) {
|
|
||||||
1 * it.read(BlockId.from("0xa6af163aab691919c595e2a466f0a7b01f1dff8cfd9631dee811df57064c2d32")) >> Mono.empty()
|
|
||||||
}
|
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(heights, Stub(Caches))
|
|
||||||
def head = Mock(Head) {
|
|
||||||
1 * it.getCurrentHeight() >> 100
|
|
||||||
}
|
|
||||||
when:
|
|
||||||
def act = callSelector.getMatcher("eth_call",
|
|
||||||
'["0x0000", {"blockHash": "0xa6af163aab691919c595e2a466f0a7b01f1dff8cfd9631dee811df57064c2d32"}]', head, false)
|
|
||||||
.block()
|
|
||||||
then:
|
|
||||||
act == new Selector.HeightMatcher(100)
|
|
||||||
}
|
|
||||||
|
|
||||||
def "Get same matcher for getFilterChanges method"() {
|
def "Get same matcher for getFilterChanges method"() {
|
||||||
setup:
|
setup:
|
||||||
def callSelector = new EthereumCallSelector(Mock(Reader), Stub(Caches))
|
def callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head)
|
def head = Mock(Head)
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
@@ -219,7 +206,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
|
|
||||||
def "Get empty matcher for getFilterChanges method without params"() {
|
def "Get empty matcher for getFilterChanges method without params"() {
|
||||||
setup:
|
setup:
|
||||||
def callSelector = new EthereumCallSelector(Mock(Reader), Stub(Caches))
|
def callSelector = new EthereumCallSelector(Stub(Caches))
|
||||||
def head = Mock(Head)
|
def head = Mock(Head)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
@@ -238,7 +225,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
1 * memCache.read(BlockId.from(hash)) >> Mono.just(blockHeight)
|
1 * memCache.read(BlockId.from(hash)) >> Mono.just(blockHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def callSelector = new EthereumCallSelector(Stub(Reader), cache)
|
def callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Stub(Head)
|
def head = Stub(Head)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
@@ -254,13 +241,13 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
.verify(Duration.ofSeconds(1))
|
.verify(Duration.ofSeconds(1))
|
||||||
|
|
||||||
where:
|
where:
|
||||||
method << ["eth_getTransactionByBlockHashAndIndex", "eth_getBlockByHash"]
|
method << ["eth_getTransactionByBlockHashAndIndex", "eth_getBlockByHash", "bor_getSignersAtHash"]
|
||||||
}
|
}
|
||||||
|
|
||||||
def "No height matcher for getByNumber and getTransactionByBlockNumber methods when passthrough is on"() {
|
def "No height matcher for getByNumber and getTransactionByBlockNumber methods when passthrough is on"() {
|
||||||
setup:
|
setup:
|
||||||
def cache = Stub(Caches)
|
def cache = Stub(Caches)
|
||||||
def callSelector = new EthereumCallSelector(Stub(Reader), cache)
|
def callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Stub(Head)
|
def head = Stub(Head)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
@@ -283,10 +270,11 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
"eth_getBlockByNumber" | '["earliest", false]'
|
"eth_getBlockByNumber" | '["earliest", false]'
|
||||||
"eth_getBlockByNumber" | '["latest", false]'
|
"eth_getBlockByNumber" | '["latest", false]'
|
||||||
}
|
}
|
||||||
def "Get height matcher for getByNumber and getTransactionByBlockNumber methods"() {
|
|
||||||
|
def "Get height matcher for byNumber methods"() {
|
||||||
setup:
|
setup:
|
||||||
def cache = Stub(Caches)
|
def cache = Stub(Caches)
|
||||||
def callSelector = new EthereumCallSelector(Stub(Reader), cache)
|
def callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
_ * getCurrentHeight() >> 17654321L
|
_ * getCurrentHeight() >> 17654321L
|
||||||
}
|
}
|
||||||
@@ -310,6 +298,18 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
"eth_getBlockByNumber" | '["0xfbfe3b", false]' | 16514619L
|
"eth_getBlockByNumber" | '["0xfbfe3b", false]' | 16514619L
|
||||||
"eth_getBlockByNumber" | '["earliest", false]' | 0L
|
"eth_getBlockByNumber" | '["earliest", false]' | 0L
|
||||||
"eth_getBlockByNumber" | '["latest", false]' | 17654321L
|
"eth_getBlockByNumber" | '["latest", false]' | 17654321L
|
||||||
|
"eth_getBlockTransactionCountByNumber" | '["latest"]' | 17654321L
|
||||||
|
"eth_getBlockTransactionCountByNumber" | '["0xfbfe3b"]' | 16514619L
|
||||||
|
"eth_getBlockTransactionCountByNumber" | '["earliest"]' | 0L
|
||||||
|
"eth_getUncleCountByBlockNumber" | '["latest"]' | 17654321L
|
||||||
|
"eth_getUncleCountByBlockNumber" | '["0xfbfe3b"]' | 16514619L
|
||||||
|
"eth_getUncleCountByBlockNumber" | '["earliest"]' | 0L
|
||||||
|
"eth_getUncleCountByBlockNumber" | '["latest"]' | 17654321L
|
||||||
|
"eth_getUncleCountByBlockNumber" | '["0xfbfe3b"]' | 16514619L
|
||||||
|
"eth_getUncleCountByBlockNumber" | '["earliest"]' | 0L
|
||||||
|
"eth_getUncleByBlockNumberAndIndex" | '["latest"]' | 17654321L
|
||||||
|
"eth_getUncleByBlockNumberAndIndex" | '["0xfbfe3b"]' | 16514619L
|
||||||
|
"eth_getUncleByBlockNumberAndIndex" | '["earliest"]' | 0L
|
||||||
}
|
}
|
||||||
|
|
||||||
def "No height matcher for getByHash method"() {
|
def "No height matcher for getByHash method"() {
|
||||||
@@ -320,7 +320,7 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
1 * memCache.read(BlockId.from(hash)) >> resultFromCache
|
1 * memCache.read(BlockId.from(hash)) >> resultFromCache
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def callSelector = new EthereumCallSelector(Stub(Reader), cache)
|
def callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Stub(Head)
|
def head = Stub(Head)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
@@ -339,10 +339,10 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
resultFromCache << [Mono.empty(), Mono.error(new RuntimeException())]
|
resultFromCache << [Mono.empty(), Mono.error(new RuntimeException())]
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Get height matcher for getLogs method"() {
|
def "Get height matcher for getLogs and eth_newFilter method"() {
|
||||||
setup:
|
setup:
|
||||||
def cache = Stub(Caches)
|
def cache = Stub(Caches)
|
||||||
def callSelector = new EthereumCallSelector(Stub(Reader), cache)
|
def callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Mock(Head) {
|
def head = Mock(Head) {
|
||||||
_ * getCurrentHeight() >> 17654321L
|
_ * getCurrentHeight() >> 17654321L
|
||||||
}
|
}
|
||||||
@@ -361,12 +361,15 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
"eth_getLogs" | '[{"toBlock":"0xfbfe3b"}]' | 16514619L
|
"eth_getLogs" | '[{"toBlock":"0xfbfe3b"}]' | 16514619L
|
||||||
"eth_getLogs" | '[{"toBlock":"latest"}]' | 17654321L
|
"eth_getLogs" | '[{"toBlock":"latest"}]' | 17654321L
|
||||||
"eth_getLogs" | '[{"toBlock":"earliest"}]' | 0L
|
"eth_getLogs" | '[{"toBlock":"earliest"}]' | 0L
|
||||||
|
"eth_newFilter" | '[{"toBlock":"0xfbfe2b", "toBlock":"0xfbfe3b"}]' | 16514619L
|
||||||
|
"eth_newFilter" | '[{"toBlock":"0xfbfe3b", "toBlock":"latest"}]' | 17654321L
|
||||||
|
"eth_newFilter" | '[{"toBlock":"0xfbfe3b", "toBlock":"earliest"}]' | 0L
|
||||||
}
|
}
|
||||||
|
|
||||||
def "No height matcher for getLogs method when passthrough is on"() {
|
def "No height matcher for getLogs and eth_newFilter method when passthrough is on"() {
|
||||||
setup:
|
setup:
|
||||||
def cache = Stub(Caches)
|
def cache = Stub(Caches)
|
||||||
def callSelector = new EthereumCallSelector(Stub(Reader), cache)
|
def callSelector = new EthereumCallSelector(cache)
|
||||||
def head = Stub(Head)
|
def head = Stub(Head)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
@@ -383,5 +386,33 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
"eth_getLogs" | '[{"toBlock":"0xfbfe3b"}]'
|
"eth_getLogs" | '[{"toBlock":"0xfbfe3b"}]'
|
||||||
"eth_getLogs" | '[{"toBlock":"latest"}]'
|
"eth_getLogs" | '[{"toBlock":"latest"}]'
|
||||||
"eth_getLogs" | '[{"toBlock":"earliest"}]'
|
"eth_getLogs" | '[{"toBlock":"earliest"}]'
|
||||||
|
"eth_newFilter" | '[{"toBlock":"0xfbfe2b", "toBlock":"0xfbfe3b"}]'
|
||||||
|
"eth_newFilter" | '[{"toBlock":"0xfbfe3b", "toBlock":"latest"}]'
|
||||||
|
"eth_newFilter" | '[{"toBlock":"0xfbfe3b", "toBlock":"earliest"}]'
|
||||||
|
}
|
||||||
|
|
||||||
|
def "Get height matcher for bor method"() {
|
||||||
|
setup:
|
||||||
|
def cache = Stub(Caches)
|
||||||
|
def callSelector = new EthereumCallSelector(cache)
|
||||||
|
def head = Mock(Head) {
|
||||||
|
_ * getCurrentHeight() >> 17654321L
|
||||||
|
}
|
||||||
|
|
||||||
|
when:
|
||||||
|
def act = callSelector.getMatcher(method, param, head, false)
|
||||||
|
|
||||||
|
then:
|
||||||
|
StepVerifier.create(act)
|
||||||
|
.expectNext(new Selector.HeightMatcher(height))
|
||||||
|
.expectComplete()
|
||||||
|
.verify(Duration.ofSeconds(1))
|
||||||
|
|
||||||
|
where:
|
||||||
|
method | param | height
|
||||||
|
"eth_getRootHash" | '[1023, 1200]' | 1200L
|
||||||
|
"bor_getRootHash" | '[1000, 1400]' | 1400L
|
||||||
|
"bor_getAuthor" | '["latest"]' | 17654321L
|
||||||
|
"bor_getAuthor" | '["0xfbfe3b"]' | 16514619L
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user