diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/UpstreamRpcMethodsDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/UpstreamRpcMethodsDetector.kt index 5b6c3981..215f3faf 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/UpstreamRpcMethodsDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/UpstreamRpcMethodsDetector.kt @@ -18,10 +18,16 @@ abstract class UpstreamRpcMethodsDetector( listOf( "method ([A-Za-z0-9_]+) does not exist/is not available", "([A-Za-z0-9_]+) found but the containing module is disabled", - "Method not found", + "[Mm]ethod not found", "The method ([A-Za-z0-9_]+) is not available", ).map { s -> s.toRegex() } + private val availableRegexps = + listOf( + "missing value for required argument ([0-9]+)", + "Invalid params", + ).map { s -> s.toRegex() } + open fun detectRpcMethods(): Mono> = detectByMagicMethod().switchIfEmpty(detectByMethod()) protected fun detectByMethod(): Mono> = @@ -38,9 +44,15 @@ abstract class UpstreamRpcMethodsDetector( method to true } .onErrorResume { err -> - val notAvailableError = + val methodAvailableError = + availableRegexps.any { s -> s.containsMatchIn(err.message ?: "") } + val methodNotAvailableError = notAvailableRegexps.any { s -> s.containsMatchIn(err.message ?: "") } - if (notAvailableError) { + + if (methodAvailableError) { + log.error("$method failed with ${err.message}, detect as true") + Mono.just(method to true) + } else if (methodNotAvailableError) { log.error("$method failed with ${err.message}, detect as false") Mono.just(method to false) } else { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/BasicEthUpstreamRpcMethodsDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/BasicEthUpstreamRpcMethodsDetector.kt index acc3a525..bf81b4ed 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/BasicEthUpstreamRpcMethodsDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/BasicEthUpstreamRpcMethodsDetector.kt @@ -34,6 +34,7 @@ class BasicEthUpstreamRpcMethodsDetector( setOf( "eth_getBlockReceipts" to ListParams("latest"), "trace_callMany" to ListParams(listOf(listOf())), + "eth_simulateV1" to ListParams(listOf(listOf())), ) private fun parseRpcModules(data: ByteArray): Map { diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/ethereum/BasicEthUpstreamRpcMethodsDetectorTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/ethereum/BasicEthUpstreamRpcMethodsDetectorTest.kt index 3951ceca..f183b22e 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/ethereum/BasicEthUpstreamRpcMethodsDetectorTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/ethereum/BasicEthUpstreamRpcMethodsDetectorTest.kt @@ -48,6 +48,15 @@ class BasicEthUpstreamRpcMethodsDetectorTest { null, ), ) + on { + read(ChainRequest("eth_simulateV1", ListParams(listOf(listOf())))) + } doReturn + Mono.just( + ChainResponse( + "[]".toByteArray(), + null, + ), + ) } val upstream = @@ -97,6 +106,15 @@ class BasicEthUpstreamRpcMethodsDetectorTest { null, ), ) + on { + read(ChainRequest("eth_simulateV1", ListParams(listOf(listOf())))) + } doReturn + Mono.just( + ChainResponse( + "[]".toByteArray(), + null, + ), + ) } val upstream = @@ -108,7 +126,7 @@ class BasicEthUpstreamRpcMethodsDetectorTest { val detector = BasicEthUpstreamRpcMethodsDetector(upstream, config) Assertions.assertThat(detector.detectRpcMethods().block()).apply { isNotNull() - hasSize(2) + hasSize(3) containsEntry("eth_getBlockReceipts", true) containsEntry("trace_callMany", true) } @@ -147,6 +165,15 @@ class BasicEthUpstreamRpcMethodsDetectorTest { null, ), ) + on { + read(ChainRequest("eth_simulateV1", ListParams(listOf(listOf())))) + } doReturn + Mono.just( + ChainResponse( + null, + ChainCallError(32602, "missing value for required argument 0"), + ), + ) } val upstream = @@ -168,6 +195,7 @@ class BasicEthUpstreamRpcMethodsDetectorTest { containsEntry("eth_getBlockByNumber", false) containsEntry("eth_getBlockReceipts", true) containsEntry("debug_traceBlock", true) + containsEntry("eth_simulateV1", true) } } }