diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt index e999a150..40a180b0 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt @@ -30,6 +30,7 @@ import io.emeraldpay.dshackle.quorum.QuorumRpcReader import io.emeraldpay.dshackle.startup.ConfiguredUpstreams import io.emeraldpay.dshackle.startup.UpstreamChangeEvent import io.emeraldpay.dshackle.upstream.* +import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods import io.emeraldpay.dshackle.upstream.calls.EthereumCallSelector import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream @@ -255,13 +256,13 @@ open class NativeCall( } private fun getRequestDecorator(method: String): RequestDecorator = - if (method == "eth_getFilterChanges" || method == "eth_uninstallFilter") - GetFilterUpdatesDecorator() + if (method in DefaultEthereumMethods.withFilterIdMethods) + WithFilterIdDecorator() else NoneRequestDecorator() private fun getResultDecorator(method: String): ResultDecorator = - if (CreateFilterDecorator.createFilterMethods.contains(method)) CreateFilterDecorator() else NoneResultDecorator() + if (method in DefaultEthereumMethods.newFilterMethods) CreateFilterDecorator() else NoneResultDecorator() fun fetch(ctx: ValidCallContext): Mono { return ctx.upstream.getRoutedApi(ctx.matcher) @@ -381,11 +382,6 @@ open class NativeCall( companion object { const val quoteCode = '"'.code.toByte() - val createFilterMethods = listOf( - "eth_newFilter", - "eth_newBlockFilter", - "eth_newPendingTransactionFilter" - ) } override fun processResult(result: QuorumRpcReader.Result): ByteArray { val bytes = result.value @@ -406,7 +402,7 @@ open class NativeCall( override fun processRequest(request: List): List = request } - open class GetFilterUpdatesDecorator : RequestDecorator { + open class WithFilterIdDecorator : RequestDecorator { override fun processRequest(request: List): List { val filterId = request.first().toString() val sanitized = filterId.substring(0, filterId.lastIndex - 1) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt index 29994819..d2c3b9fb 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt @@ -35,6 +35,20 @@ class DefaultEthereumMethods( private val version = "\"EmeraldDshackle/${Global.version}\"" + companion object { + val withFilterIdMethods = listOf( + "eth_getFilterChanges", + "eth_getFilterLogs", + "eth_uninstallFilter" + ) + + val newFilterMethods = listOf( + "eth_newFilter", + "eth_newBlockFilter", + "eth_newPendingTransactionFilter", + ) + } + private val anyResponseMethods = listOf( "eth_gasPrice", "eth_call", @@ -70,13 +84,7 @@ class DefaultEthereumMethods( "eth_feeHistory" ) - private val filterMethods = listOf( - "eth_getFilterChanges", - "eth_newFilter", - "eth_newBlockFilter", - "eth_newPendingTransactionFilter", - "eth_uninstallFilter" - ) + private val filterMethods = withFilterIdMethods + newFilterMethods private val allowedMethods = anyResponseMethods + firstValueMethods + specialMethods + headVerifiedMethods + filterMethods 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 abf684de..edca897e 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt @@ -57,7 +57,7 @@ class EthereumCallSelector( return blockTagSelector(params, 1, head) } else if (method == "eth_getStorageAt") { return blockTagSelector(params, 2, head) - } else if (method == "eth_getFilterChanges" || method == "eth_uninstallFilter") { + } else if (method in DefaultEthereumMethods.withFilterIdMethods) { return sameUpstreamMatcher(params) } return Mono.empty() diff --git a/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy index 28fa74cd..2bff6234 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy @@ -452,7 +452,7 @@ class NativeCallSpec extends Specification { .collectList().block(Duration.ofSeconds(1)).first() then: act instanceof NativeCall.ValidCallContext - act.requestDecorator instanceof NativeCall.GetFilterUpdatesDecorator + act.requestDecorator instanceof NativeCall.WithFilterIdDecorator } def "Prepare call adds decorator for eth_uninstallFilter"() { @@ -483,7 +483,7 @@ class NativeCallSpec extends Specification { .collectList().block(Duration.ofSeconds(1)).first() then: act instanceof NativeCall.ValidCallContext - act.requestDecorator instanceof NativeCall.GetFilterUpdatesDecorator + act.requestDecorator instanceof NativeCall.WithFilterIdDecorator } def "Parse empty params"() { @@ -543,7 +543,7 @@ class NativeCallSpec extends Specification { def nativeCall = nativeCall() def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(), new NativeCall.RawCallDetails("eth_getFilterUpdates", '["0xabcd"]'), - new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.NoneResultDecorator()) + new NativeCall.WithFilterIdDecorator(), new NativeCall.NoneResultDecorator()) when: def act = nativeCall.parseParams(ctx) then: @@ -564,7 +564,7 @@ class NativeCallSpec extends Specification { } def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum, new NativeCall.ParsedCallDetails("eth_getFilterChanges", []), - new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.CreateFilterDecorator()) + new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator()) when: def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1)) @@ -586,7 +586,7 @@ class NativeCallSpec extends Specification { } def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum, new NativeCall.ParsedCallDetails("eth_getFilterChanges", []), - new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.CreateFilterDecorator()) + new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator()) when: def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))