diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt index 33eb6775..ba7ff0fa 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt @@ -62,16 +62,18 @@ class EthereumCallSelector( * @param params JSON-encoded list of parameters for the method */ fun getMatcher(method: String, params: String, head: Head, passthrough: Boolean): Mono { - if (!passthrough && Collections.binarySearch(TAG_METHODS, method) >= 0) { - return blockTagSelector(params, 1, null, head) - } else if (!passthrough && method == "eth_getStorageAt") { - return blockTagSelector(params, 2, null, head) - } else if (method in DefaultEthereumMethods.withFilterIdMethods) { + if (method in DefaultEthereumMethods.withFilterIdMethods) { return sameUpstreamMatcher(params) - } else if (method in GET_BY_HASH_OR_NUMBER_METHODS) { - return blockMethodSelector(method, params, head) - } else if (method == "eth_getLogs") { - return blockTagSelector(params, 0, "toBlock", head) + } else if (!passthrough) { // passthrough indicates we should match only labels + if (Collections.binarySearch(TAG_METHODS, method) >= 0) { + return blockTagSelector(params, 1, null, head) + } else if (method == "eth_getStorageAt") { + return blockTagSelector(params, 2, null, head) + } else if (method in GET_BY_HASH_OR_NUMBER_METHODS) { + return blockMethodSelector(method, params, head) + } else if (method == "eth_getLogs") { + return blockTagSelector(params, 0, "toBlock", head) + } } return Mono.empty() } diff --git a/src/test/groovy/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelectorSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelectorSpec.groovy index fcf585f6..07277b83 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelectorSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelectorSpec.groovy @@ -260,6 +260,32 @@ class EthereumCallSelectorSpec extends Specification { method << ["eth_getTransactionByBlockHashAndIndex", "eth_getBlockByHash"] } + def "No height matcher for getByNumber and getTransactionByBlockNumber methods when passthrough is on"() { + setup: + def cache = Stub(Caches) + def callSelector = new EthereumCallSelector(Stub(Reader), cache) + def head = Stub(Head) + + when: + def act = callSelector.getMatcher( + method, params, head, true + ) + + then: + StepVerifier.create(act) + .expectNext() + .expectComplete() + .verify(Duration.ofSeconds(1)) + + where: + method | params + "eth_getTransactionByBlockNumberAndIndex" | '["0xfbfe3b", false]' + "eth_getTransactionByBlockNumberAndIndex" | '["earliest", false]' + "eth_getTransactionByBlockNumberAndIndex" | '["latest", false]' + "eth_getBlockByNumber" | '["0xfbfe3b", false]' + "eth_getBlockByNumber" | '["earliest", false]' + "eth_getBlockByNumber" | '["latest", false]' + } def "Get height matcher for getByNumber and getTransactionByBlockNumber methods"() { setup: def cache = Stub(Caches) @@ -338,4 +364,26 @@ class EthereumCallSelectorSpec extends Specification { "eth_getLogs" | '[{"toBlock":"latest"}]' | 17654321L "eth_getLogs" | '[{"toBlock":"earliest"}]' | 0L } + + def "No height matcher for getLogs method when passthrough is on"() { + setup: + def cache = Stub(Caches) + def callSelector = new EthereumCallSelector(Stub(Reader), cache) + def head = Stub(Head) + + when: + def act = callSelector.getMatcher(method, param, head, true) + + then: + StepVerifier.create(act) + .expectNext() + .expectComplete() + .verify(Duration.ofSeconds(1)) + + where: + method | param + "eth_getLogs" | '[{"toBlock":"0xfbfe3b"}]' + "eth_getLogs" | '[{"toBlock":"latest"}]' + "eth_getLogs" | '[{"toBlock":"earliest"}]' + } }