Merge pull request #44 from p2p-org/add_eth_getFilterLogs

add eth_getFilterLogs support
This commit is contained in:
MaxFomenkov
2022-11-28 18:29:07 +04:00
committed by GitHub
4 changed files with 26 additions and 22 deletions

View File

@@ -30,6 +30,7 @@ import io.emeraldpay.dshackle.quorum.QuorumRpcReader
import io.emeraldpay.dshackle.startup.ConfiguredUpstreams import io.emeraldpay.dshackle.startup.ConfiguredUpstreams
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
import io.emeraldpay.dshackle.upstream.* import io.emeraldpay.dshackle.upstream.*
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
import io.emeraldpay.dshackle.upstream.calls.EthereumCallSelector import io.emeraldpay.dshackle.upstream.calls.EthereumCallSelector
import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
@@ -255,13 +256,13 @@ open class NativeCall(
} }
private fun getRequestDecorator(method: String): RequestDecorator = private fun getRequestDecorator(method: String): RequestDecorator =
if (method == "eth_getFilterChanges" || method == "eth_uninstallFilter") if (method in DefaultEthereumMethods.withFilterIdMethods)
GetFilterUpdatesDecorator() WithFilterIdDecorator()
else else
NoneRequestDecorator() NoneRequestDecorator()
private fun getResultDecorator(method: String): ResultDecorator = 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<ParsedCallDetails>): Mono<CallResult> { fun fetch(ctx: ValidCallContext<ParsedCallDetails>): Mono<CallResult> {
return ctx.upstream.getRoutedApi(ctx.matcher) return ctx.upstream.getRoutedApi(ctx.matcher)
@@ -381,11 +382,6 @@ open class NativeCall(
companion object { companion object {
const val quoteCode = '"'.code.toByte() const val quoteCode = '"'.code.toByte()
val createFilterMethods = listOf(
"eth_newFilter",
"eth_newBlockFilter",
"eth_newPendingTransactionFilter"
)
} }
override fun processResult(result: QuorumRpcReader.Result): ByteArray { override fun processResult(result: QuorumRpcReader.Result): ByteArray {
val bytes = result.value val bytes = result.value
@@ -406,7 +402,7 @@ open class NativeCall(
override fun processRequest(request: List<Any>): List<Any> = request override fun processRequest(request: List<Any>): List<Any> = request
} }
open class GetFilterUpdatesDecorator : RequestDecorator { open class WithFilterIdDecorator : RequestDecorator {
override fun processRequest(request: List<Any>): List<Any> { override fun processRequest(request: List<Any>): List<Any> {
val filterId = request.first().toString() val filterId = request.first().toString()
val sanitized = filterId.substring(0, filterId.lastIndex - 1) val sanitized = filterId.substring(0, filterId.lastIndex - 1)

View File

@@ -35,6 +35,20 @@ class DefaultEthereumMethods(
private val version = "\"EmeraldDshackle/${Global.version}\"" 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( private val anyResponseMethods = listOf(
"eth_gasPrice", "eth_gasPrice",
"eth_call", "eth_call",
@@ -70,13 +84,7 @@ class DefaultEthereumMethods(
"eth_feeHistory" "eth_feeHistory"
) )
private val filterMethods = listOf( private val filterMethods = withFilterIdMethods + newFilterMethods
"eth_getFilterChanges",
"eth_newFilter",
"eth_newBlockFilter",
"eth_newPendingTransactionFilter",
"eth_uninstallFilter"
)
private val allowedMethods = anyResponseMethods + firstValueMethods + specialMethods + headVerifiedMethods + filterMethods private val allowedMethods = anyResponseMethods + firstValueMethods + specialMethods + headVerifiedMethods + filterMethods

View File

@@ -57,7 +57,7 @@ class EthereumCallSelector(
return blockTagSelector(params, 1, head) return blockTagSelector(params, 1, head)
} else if (method == "eth_getStorageAt") { } else if (method == "eth_getStorageAt") {
return blockTagSelector(params, 2, head) return blockTagSelector(params, 2, head)
} else if (method == "eth_getFilterChanges" || method == "eth_uninstallFilter") { } else if (method in DefaultEthereumMethods.withFilterIdMethods) {
return sameUpstreamMatcher(params) return sameUpstreamMatcher(params)
} }
return Mono.empty() return Mono.empty()

View File

@@ -452,7 +452,7 @@ class NativeCallSpec extends Specification {
.collectList().block(Duration.ofSeconds(1)).first() .collectList().block(Duration.ofSeconds(1)).first()
then: then:
act instanceof NativeCall.ValidCallContext act instanceof NativeCall.ValidCallContext
act.requestDecorator instanceof NativeCall.GetFilterUpdatesDecorator act.requestDecorator instanceof NativeCall.WithFilterIdDecorator
} }
def "Prepare call adds decorator for eth_uninstallFilter"() { def "Prepare call adds decorator for eth_uninstallFilter"() {
@@ -483,7 +483,7 @@ class NativeCallSpec extends Specification {
.collectList().block(Duration.ofSeconds(1)).first() .collectList().block(Duration.ofSeconds(1)).first()
then: then:
act instanceof NativeCall.ValidCallContext act instanceof NativeCall.ValidCallContext
act.requestDecorator instanceof NativeCall.GetFilterUpdatesDecorator act.requestDecorator instanceof NativeCall.WithFilterIdDecorator
} }
def "Parse empty params"() { def "Parse empty params"() {
@@ -543,7 +543,7 @@ class NativeCallSpec extends Specification {
def nativeCall = nativeCall() def nativeCall = nativeCall()
def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(), def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(),
new NativeCall.RawCallDetails("eth_getFilterUpdates", '["0xabcd"]'), new NativeCall.RawCallDetails("eth_getFilterUpdates", '["0xabcd"]'),
new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.NoneResultDecorator()) new NativeCall.WithFilterIdDecorator(), new NativeCall.NoneResultDecorator())
when: when:
def act = nativeCall.parseParams(ctx) def act = nativeCall.parseParams(ctx)
then: then:
@@ -564,7 +564,7 @@ class NativeCallSpec extends Specification {
} }
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum, def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
new NativeCall.ParsedCallDetails("eth_getFilterChanges", []), new NativeCall.ParsedCallDetails("eth_getFilterChanges", []),
new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.CreateFilterDecorator()) new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator())
when: when:
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1)) 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, def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
new NativeCall.ParsedCallDetails("eth_getFilterChanges", []), new NativeCall.ParsedCallDetails("eth_getFilterChanges", []),
new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.CreateFilterDecorator()) new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator())
when: when:
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1)) def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))