From 4dc52091e3c27fc477c5d69ca8354fd31983698c Mon Sep 17 00:00:00 2001 From: KirillPamPam Date: Mon, 27 Nov 2023 14:54:28 +0400 Subject: [PATCH] Height matcher to proxy (#340) --- emerald-grpc | 2 +- .../io/emeraldpay/dshackle/rpc/NativeCall.kt | 5 ++- .../emeraldpay/dshackle/upstream/Selector.kt | 20 ++++++++++++ .../dshackle/upstream/SelectorSpec.groovy | 32 +++++++++++++++++-- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/emerald-grpc b/emerald-grpc index e6153279a..e6fcfa6f8 160000 --- a/emerald-grpc +++ b/emerald-grpc @@ -1 +1 @@ -Subproject commit e6153279a531807157639db258d7590ef83faace +Subproject commit e6fcfa6f811afc445c4a8966ed7cfebcbf678d4a diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt index 3a8891703..cc2bf9de5 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt @@ -285,9 +285,12 @@ open class NativeCall( ), ) } + val requestMatcher = requestItem.selectorsList + .takeIf { it.isNotEmpty() } + ?.run { Mono.just(Selector.convertToMatcher(this, upstream.getHead())) } // for ethereum the actual block needed for the call may be specified in the call parameters val callSpecificMatcher: Mono = - upstream.callSelector?.getMatcher(method, params, upstream.getHead(), passthrough) ?: Mono.empty() + requestMatcher ?: upstream.callSelector?.getMatcher(method, params, upstream.getHead(), passthrough) ?: Mono.empty() return callSpecificMatcher.defaultIfEmpty(Selector.empty).map { csm -> val matcher = Selector.Builder() .withMatcher(csm) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Selector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Selector.kt index d05426bd9..006a31c53 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Selector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Selector.kt @@ -39,6 +39,26 @@ class Selector { @JvmStatic val anyLabel = AnyLabelMatcher() + @JvmStatic + fun convertToMatcher(selectors: List, head: Head): Matcher { + return selectors + .map { + when { + it.hasHeightSelector() -> { + val height = if (it.heightSelector.height == -1L) head.getCurrentHeight() else it.heightSelector.height + if (height == null) { + empty + } else { + HeightMatcher(height) + } + } + else -> empty + } + }.run { + MultiMatcher(this) + } + } + @JvmStatic fun convertToMatcher(req: BlockchainOuterClass.Selector?): LabelSelectorMatcher { return when { diff --git a/src/test/groovy/io/emeraldpay/dshackle/upstream/SelectorSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/upstream/SelectorSpec.groovy index 34516c3dc..f0b1dbc9d 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/upstream/SelectorSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/upstream/SelectorSpec.groovy @@ -32,11 +32,37 @@ class SelectorSpec extends Specification { private BlockchainOuterClass.Selector selectLabel2Selector = BlockchainOuterClass.Selector.newBuilder() .setLabelSelector(selectLabel2).build() - def "Convert nothing"() { + def "Convert height selector"() { + setup: + def heightSelector = BlockchainOuterClass.Selector.newBuilder() + .setHeightSelector( + BlockchainOuterClass.HeightSelector.newBuilder() + .setHeight(10000) + .build() + ) + .build() + when: + def act = Selector.convertToMatcher(List.of(heightSelector), Stub(Head)) + then: + act == new Selector.MultiMatcher(List.of(new Selector.HeightMatcher(10000))) + } + + def "Convert height selector with latest"() { + setup: + def head = Mock(Head) { + 1 * getCurrentHeight() >> 15000 + } + def heightSelector = BlockchainOuterClass.Selector.newBuilder() + .setHeightSelector( + BlockchainOuterClass.HeightSelector.newBuilder() + .setHeight(-1) + .build() + ) + .build() when: - def act = Selector.convertToMatcher(null) + def act = Selector.convertToMatcher(List.of(heightSelector), head) then: - act.class == Selector.AnyLabelMatcher + act == new Selector.MultiMatcher(List.of(new Selector.HeightMatcher(15000))) } def "Convert LABEL match"() {