Filter and sort upstreams if latest (#476)
This commit is contained in:
@@ -68,16 +68,16 @@ interface RequestReaderFactory {
|
|||||||
class Default : RequestReaderFactory {
|
class Default : RequestReaderFactory {
|
||||||
override fun create(data: ReaderData): RequestReader {
|
override fun create(data: ReaderData): RequestReader {
|
||||||
if (data.quorum is MaximumValueQuorum || data.quorum is BroadcastQuorum) {
|
if (data.quorum is MaximumValueQuorum || data.quorum is BroadcastQuorum) {
|
||||||
return BroadcastReader(data.multistream.getAll(), data.matcher, data.signer, data.quorum, data.tracer)
|
return BroadcastReader(data.multistream.getAll(), data.upstreamFilter.matcher, data.signer, data.quorum, data.tracer)
|
||||||
}
|
}
|
||||||
val apis = data.multistream.getApiSource(data.matcher)
|
val apis = data.multistream.getApiSource(data.upstreamFilter)
|
||||||
return QuorumRequestReader(apis, data.quorum, data.signer, data.tracer)
|
return QuorumRequestReader(apis, data.quorum, data.signer, data.tracer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ReaderData(
|
data class ReaderData(
|
||||||
val multistream: Multistream,
|
val multistream: Multistream,
|
||||||
val matcher: Selector.Matcher,
|
val upstreamFilter: Selector.UpstreamFilter,
|
||||||
val quorum: CallQuorum,
|
val quorum: CallQuorum,
|
||||||
val signer: ResponseSigner?,
|
val signer: ResponseSigner?,
|
||||||
val tracer: Tracer,
|
val tracer: Tracer,
|
||||||
|
|||||||
@@ -331,12 +331,12 @@ open class NativeCall(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val requestMatcher = requestItem.selectorsList
|
val upstreamFilter = requestItem.selectorsList
|
||||||
.takeIf { it.isNotEmpty() }
|
.takeIf { it.isNotEmpty() }
|
||||||
?.run { Mono.just(Selector.convertToMatcher(this, upstream.getHead())) }
|
?.run { Selector.convertToUpstreamFilter(this) }
|
||||||
// for ethereum the actual block needed for the call may be specified in the call parameters
|
// for ethereum the actual block needed for the call may be specified in the call parameters
|
||||||
val callSpecificMatcher: Mono<Selector.Matcher> =
|
val callSpecificMatcher: Mono<Selector.Matcher> =
|
||||||
requestMatcher ?: upstream.callSelector?.getMatcher(method, params, upstream.getHead(), passthrough) ?: Mono.empty()
|
upstreamFilter?.matcher?.let { Mono.just(it) } ?: upstream.callSelector?.getMatcher(method, params, upstream.getHead(), passthrough) ?: Mono.empty()
|
||||||
return callSpecificMatcher.defaultIfEmpty(Selector.empty).map { csm ->
|
return callSpecificMatcher.defaultIfEmpty(Selector.empty).map { csm ->
|
||||||
val matcher = Selector.Builder()
|
val matcher = Selector.Builder()
|
||||||
.withMatcher(csm)
|
.withMatcher(csm)
|
||||||
@@ -363,7 +363,7 @@ open class NativeCall(
|
|||||||
requestItem.id,
|
requestItem.id,
|
||||||
nonce,
|
nonce,
|
||||||
upstream,
|
upstream,
|
||||||
matcher.build(),
|
Selector.UpstreamFilter(upstreamFilter?.sort ?: Selector.Sort.default, matcher.build()),
|
||||||
callQuorum,
|
callQuorum,
|
||||||
parsedCallDetails(requestItem),
|
parsedCallDetails(requestItem),
|
||||||
requestDecorator,
|
requestDecorator,
|
||||||
@@ -433,7 +433,7 @@ open class NativeCall(
|
|||||||
return Mono.error(RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Unsupported method"))
|
return Mono.error(RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Unsupported method"))
|
||||||
}
|
}
|
||||||
val reader = requestReaderFactory.create(
|
val reader = requestReaderFactory.create(
|
||||||
ReaderData(ctx.upstream, ctx.matcher, ctx.callQuorum, signer, tracer),
|
ReaderData(ctx.upstream, ctx.upstreamFilter, ctx.callQuorum, signer, tracer),
|
||||||
)
|
)
|
||||||
val counter = reader.attempts()
|
val counter = reader.attempts()
|
||||||
|
|
||||||
@@ -572,7 +572,7 @@ open class NativeCall(
|
|||||||
val id: Int,
|
val id: Int,
|
||||||
val nonce: Long?,
|
val nonce: Long?,
|
||||||
val upstream: Multistream,
|
val upstream: Multistream,
|
||||||
val matcher: Selector.Matcher,
|
val upstreamFilter: Selector.UpstreamFilter,
|
||||||
val callQuorum: CallQuorum,
|
val callQuorum: CallQuorum,
|
||||||
val payload: T,
|
val payload: T,
|
||||||
val requestDecorator: RequestDecorator,
|
val requestDecorator: RequestDecorator,
|
||||||
@@ -587,13 +587,13 @@ open class NativeCall(
|
|||||||
id: Int,
|
id: Int,
|
||||||
nonce: Long?,
|
nonce: Long?,
|
||||||
upstream: Multistream,
|
upstream: Multistream,
|
||||||
matcher: Selector.Matcher,
|
upstreamFilter: Selector.UpstreamFilter,
|
||||||
callQuorum: CallQuorum,
|
callQuorum: CallQuorum,
|
||||||
payload: T,
|
payload: T,
|
||||||
requestId: String,
|
requestId: String,
|
||||||
requestCount: Int,
|
requestCount: Int,
|
||||||
) : this(
|
) : this(
|
||||||
id, nonce, upstream, matcher, callQuorum, payload,
|
id, nonce, upstream, upstreamFilter, callQuorum, payload,
|
||||||
NoneRequestDecorator(), NoneResultDecorator(), null, false, requestId, requestCount,
|
NoneRequestDecorator(), NoneResultDecorator(), null, false, requestId, requestCount,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -613,13 +613,13 @@ open class NativeCall(
|
|||||||
|
|
||||||
fun <X> withPayload(payload: X): ValidCallContext<X> {
|
fun <X> withPayload(payload: X): ValidCallContext<X> {
|
||||||
return ValidCallContext(
|
return ValidCallContext(
|
||||||
id, nonce, upstream, matcher, callQuorum, payload,
|
id, nonce, upstream, upstreamFilter, callQuorum, payload,
|
||||||
requestDecorator, resultDecorator, forwardedSelector, streamRequest, requestId, requestCount,
|
requestDecorator, resultDecorator, forwardedSelector, streamRequest, requestId, requestCount,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getApis(): ApiSource {
|
fun getApis(): ApiSource {
|
||||||
return upstream.getApiSource(matcher)
|
return upstream.getApiSource(upstreamFilter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class FilteredApis(
|
|||||||
matcher: Selector.Matcher,
|
matcher: Selector.Matcher,
|
||||||
private val pos: Int,
|
private val pos: Int,
|
||||||
private val retries: Int,
|
private val retries: Int,
|
||||||
|
sort: Selector.Sort = Selector.Sort.default,
|
||||||
) : ApiSource {
|
) : ApiSource {
|
||||||
private val internalMatcher: Selector.Matcher
|
private val internalMatcher: Selector.Matcher
|
||||||
|
|
||||||
@@ -69,6 +70,13 @@ class FilteredApis(
|
|||||||
pos: Int,
|
pos: Int,
|
||||||
) : this(chain, allUpstreams, matcher, pos, DEFAULT_RETRY_LIMIT)
|
) : this(chain, allUpstreams, matcher, pos, DEFAULT_RETRY_LIMIT)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
chain: Chain,
|
||||||
|
allUpstreams: List<Upstream>,
|
||||||
|
upstreamFilter: Selector.UpstreamFilter,
|
||||||
|
pos: Int,
|
||||||
|
) : this(chain, allUpstreams, upstreamFilter.matcher, pos, DEFAULT_RETRY_LIMIT, upstreamFilter.sort)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
chain: Chain,
|
chain: Chain,
|
||||||
allUpstreams: List<Upstream>,
|
allUpstreams: List<Upstream>,
|
||||||
@@ -79,12 +87,12 @@ class FilteredApis(
|
|||||||
it.getRole() == UpstreamsConfig.UpstreamRole.PRIMARY
|
it.getRole() == UpstreamsConfig.UpstreamRole.PRIMARY
|
||||||
}.let {
|
}.let {
|
||||||
startFrom(it, pos)
|
startFrom(it, pos)
|
||||||
}
|
}.sortedWith(sort.comparator)
|
||||||
private val secondaryUpstreams: List<Upstream> = allUpstreams.filter {
|
private val secondaryUpstreams: List<Upstream> = allUpstreams.filter {
|
||||||
it.getRole() == UpstreamsConfig.UpstreamRole.SECONDARY
|
it.getRole() == UpstreamsConfig.UpstreamRole.SECONDARY
|
||||||
}.let {
|
}.let {
|
||||||
startFrom(it, pos)
|
startFrom(it, pos)
|
||||||
}
|
}.sortedWith(sort.comparator)
|
||||||
private val standardWithFallback: List<Upstream>
|
private val standardWithFallback: List<Upstream>
|
||||||
|
|
||||||
private val counter: AtomicInteger = AtomicInteger(0)
|
private val counter: AtomicInteger = AtomicInteger(0)
|
||||||
@@ -98,7 +106,7 @@ class FilteredApis(
|
|||||||
it.getRole() == UpstreamsConfig.UpstreamRole.FALLBACK
|
it.getRole() == UpstreamsConfig.UpstreamRole.FALLBACK
|
||||||
}.let {
|
}.let {
|
||||||
startFrom(it, pos)
|
startFrom(it, pos)
|
||||||
}
|
}.sortedWith(sort.comparator)
|
||||||
standardWithFallback = emptyList<Upstream>()
|
standardWithFallback = emptyList<Upstream>()
|
||||||
.plus(primaryUpstreams)
|
.plus(primaryUpstreams)
|
||||||
.plus(secondaryUpstreams)
|
.plus(secondaryUpstreams)
|
||||||
|
|||||||
@@ -206,12 +206,12 @@ abstract class Multistream(
|
|||||||
/**
|
/**
|
||||||
* Get a source for direct APIs
|
* Get a source for direct APIs
|
||||||
*/
|
*/
|
||||||
open fun getApiSource(matcher: Selector.Matcher): ApiSource {
|
open fun getApiSource(upstreamFilter: Selector.UpstreamFilter): ApiSource {
|
||||||
val i = seq++
|
val i = seq++
|
||||||
if (seq >= Int.MAX_VALUE / 2) {
|
if (seq >= Int.MAX_VALUE / 2) {
|
||||||
seq = 0
|
seq = 0
|
||||||
}
|
}
|
||||||
return FilteredApis(chain, getUpstreams(), matcher, i)
|
return FilteredApis(chain, getUpstreams(), upstreamFilter, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,15 +41,19 @@ class Selector {
|
|||||||
val anyLabel = AnyLabelMatcher()
|
val anyLabel = AnyLabelMatcher()
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun convertToMatcher(selectors: List<BlockchainOuterClass.Selector>, head: Head): Matcher {
|
fun convertToUpstreamFilter(selectors: List<BlockchainOuterClass.Selector>): UpstreamFilter {
|
||||||
return selectors
|
val matcher = selectors
|
||||||
.map {
|
.map {
|
||||||
when {
|
when {
|
||||||
it.hasSlotHeightSelector() -> {
|
it.hasSlotHeightSelector() -> {
|
||||||
SlotMatcher(it.slotHeightSelector.slotHeight)
|
SlotMatcher(it.slotHeightSelector.slotHeight)
|
||||||
}
|
}
|
||||||
it.hasHeightSelector() -> {
|
it.hasHeightSelector() -> {
|
||||||
val height = if (it.heightSelector.height == -1L) head.getCurrentHeight() else it.heightSelector.height
|
val height = if (it.heightSelector.height == -1L) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
it.heightSelector.height
|
||||||
|
}
|
||||||
if (height == null) {
|
if (height == null) {
|
||||||
empty
|
empty
|
||||||
} else {
|
} else {
|
||||||
@@ -61,6 +65,10 @@ class Selector {
|
|||||||
}.run {
|
}.run {
|
||||||
MultiMatcher(this)
|
MultiMatcher(this)
|
||||||
}
|
}
|
||||||
|
val sort = selectors.firstOrNull { it.hasHeightSelector() && it.heightSelector.height == -1L }
|
||||||
|
?.let { Sort(compareByDescending { it.getHead().getCurrentHeight() }) }
|
||||||
|
?: Sort.default
|
||||||
|
return UpstreamFilter(sort, matcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -153,6 +161,15 @@ class Selector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class Sort(
|
||||||
|
val comparator: Comparator<Upstream>,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
val default = Sort(compareBy { null })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class Matcher {
|
abstract class Matcher {
|
||||||
fun matches(up: Upstream): Boolean = matchesWithCause(up).matched()
|
fun matches(up: Upstream): Boolean = matchesWithCause(up).matched()
|
||||||
|
|
||||||
@@ -161,6 +178,13 @@ class Selector {
|
|||||||
abstract fun describeInternal(): String
|
abstract fun describeInternal(): String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class UpstreamFilter(
|
||||||
|
val sort: Sort,
|
||||||
|
val matcher: Matcher,
|
||||||
|
) {
|
||||||
|
constructor(matcher: Matcher) : this(Sort.default, matcher)
|
||||||
|
}
|
||||||
|
|
||||||
data class MultiMatcher(
|
data class MultiMatcher(
|
||||||
private val matchers: Collection<Matcher>,
|
private val matchers: Collection<Matcher>,
|
||||||
) : Matcher() {
|
) : Matcher() {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ open class BitcoinMultistream(
|
|||||||
* Finds an API that executed directly on a remote.
|
* Finds an API that executed directly on a remote.
|
||||||
*/
|
*/
|
||||||
open fun getDirectApi(matcher: Selector.Matcher): Mono<ChainReader> {
|
open fun getDirectApi(matcher: Selector.Matcher): Mono<ChainReader> {
|
||||||
val apis = getApiSource(matcher)
|
val apis = getApiSource(Selector.UpstreamFilter(matcher))
|
||||||
apis.request(1)
|
apis.request(1)
|
||||||
return Mono.from(apis)
|
return Mono.from(apis)
|
||||||
.map(Upstream::getIngressReader)
|
.map(Upstream::getIngressReader)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class RemoteUnspentReader(
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun read(key: Address): Mono<List<SimpleUnspent>> {
|
override fun read(key: Address): Mono<List<SimpleUnspent>> {
|
||||||
val apis = upstreams.getApiSource(selector)
|
val apis = upstreams.getApiSource(Selector.UpstreamFilter(selector))
|
||||||
apis.request(1)
|
apis.request(1)
|
||||||
return Mono.empty()
|
return Mono.empty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ class EthereumDirectReader(
|
|||||||
it.create(
|
it.create(
|
||||||
RequestReaderFactory.ReaderData(
|
RequestReaderFactory.ReaderData(
|
||||||
up,
|
up,
|
||||||
requestMatcher,
|
Selector.UpstreamFilter(requestMatcher),
|
||||||
callMethodsFactory.create().createQuorumFor(request.method),
|
callMethodsFactory.create().createQuorumFor(request.method),
|
||||||
null,
|
null,
|
||||||
tracer,
|
tracer,
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
def nativeCall = nativeCall()
|
def nativeCall = nativeCall()
|
||||||
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(
|
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(
|
||||||
1, null, upstream, Selector.empty, new AlwaysQuorum(),
|
1, null, upstream, new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
def nativeCall = nativeCall()
|
def nativeCall = nativeCall()
|
||||||
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(
|
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(
|
||||||
15, null, upstream, Selector.empty, new AlwaysQuorum(),
|
15, null, upstream, new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ class NativeCallSpec extends Specification {
|
|||||||
1 * read(_) >> Mono.just(new RequestReader.Result("\"foo\"".bytes, null, 1, new Upstream.UpstreamSettingsData((byte)1, "test", "v"), null))
|
1 * read(_) >> Mono.just(new RequestReader.Result("\"foo\"".bytes, null, 1, new Upstream.UpstreamSettingsData((byte)1, "test", "v"), null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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()), new Selector.UpstreamFilter(Selector.empty), quorum,
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
@@ -148,7 +148,7 @@ class NativeCallSpec extends Specification {
|
|||||||
1 * read(new ChainRequest("eth_test", new ListParams(), 10)) >> Mono.empty()
|
1 * read(new ChainRequest("eth_test", new ListParams(), 10)) >> Mono.empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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()), new Selector.UpstreamFilter(Selector.empty), quorum,
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
@@ -174,7 +174,7 @@ class NativeCallSpec extends Specification {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def call = new NativeCall.ValidCallContext(12, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
def call = new NativeCall.ValidCallContext(12, 10, TestingCommons.multistream(TestingCommons.api()), new Selector.UpstreamFilter(Selector.empty), quorum,
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
@@ -420,9 +420,9 @@ class NativeCallSpec extends Specification {
|
|||||||
def act = nativeCall.prepareCall(req, multistream)
|
def act = nativeCall.prepareCall(req, multistream)
|
||||||
.collectList().block(Duration.ofSeconds(1)).first()
|
.collectList().block(Duration.ofSeconds(1)).first()
|
||||||
then:
|
then:
|
||||||
act.matcher != null
|
act.upstreamFilter.matcher != null
|
||||||
act.matcher instanceof Selector.MultiMatcher
|
act.upstreamFilter.matcher instanceof Selector.MultiMatcher
|
||||||
with((Selector.MultiMatcher) act.matcher) {
|
with((Selector.MultiMatcher) act.upstreamFilter.matcher) {
|
||||||
it.getMatchers().size() >= 1
|
it.getMatchers().size() >= 1
|
||||||
it.getMatcher(Selector.HeightMatcher) != null
|
it.getMatcher(Selector.HeightMatcher) != null
|
||||||
with(it.getMatcher(Selector.HeightMatcher)) {
|
with(it.getMatcher(Selector.HeightMatcher)) {
|
||||||
@@ -528,7 +528,7 @@ class NativeCallSpec extends Specification {
|
|||||||
def "Parse empty params"() {
|
def "Parse empty params"() {
|
||||||
setup:
|
setup:
|
||||||
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), new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||||
when:
|
when:
|
||||||
def act = nativeCall.parseParams(ctx)
|
def act = nativeCall.parseParams(ctx)
|
||||||
@@ -541,7 +541,7 @@ class NativeCallSpec extends Specification {
|
|||||||
def "Parse none params"() {
|
def "Parse none params"() {
|
||||||
setup:
|
setup:
|
||||||
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), new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||||
when:
|
when:
|
||||||
def act = nativeCall.parseParams(ctx)
|
def act = nativeCall.parseParams(ctx)
|
||||||
@@ -554,7 +554,7 @@ class NativeCallSpec extends Specification {
|
|||||||
def "Parse single param"() {
|
def "Parse single param"() {
|
||||||
setup:
|
setup:
|
||||||
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), new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams(false)), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams(false)), "reqId", 1)
|
||||||
when:
|
when:
|
||||||
def act = nativeCall.parseParams(ctx)
|
def act = nativeCall.parseParams(ctx)
|
||||||
@@ -567,7 +567,7 @@ class NativeCallSpec extends Specification {
|
|||||||
def "Parse multi param"() {
|
def "Parse multi param"() {
|
||||||
setup:
|
setup:
|
||||||
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), new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams(false, 123)), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams(false, 123)), "reqId", 1)
|
||||||
when:
|
when:
|
||||||
def act = nativeCall.parseParams(ctx)
|
def act = nativeCall.parseParams(ctx)
|
||||||
@@ -580,7 +580,7 @@ class NativeCallSpec extends Specification {
|
|||||||
def "Decorate eth_getFilterUpdates params"() {
|
def "Decorate eth_getFilterUpdates params"() {
|
||||||
setup:
|
setup:
|
||||||
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), new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_getFilterUpdates", new ListParams("0xabcd")),
|
new NativeCall.ParsedCallDetails("eth_getFilterUpdates", new ListParams("0xabcd")),
|
||||||
new NativeCall.WithFilterIdDecorator(), new NativeCall.NoneResultDecorator(), null, false, "reqId", 1)
|
new NativeCall.WithFilterIdDecorator(), new NativeCall.NoneResultDecorator(), null, false, "reqId", 1)
|
||||||
when:
|
when:
|
||||||
@@ -612,7 +612,7 @@ class NativeCallSpec extends Specification {
|
|||||||
1 * read(_) >> Mono.just(new RequestReader.Result("\"0xab\"".bytes, null, 1, new Upstream.UpstreamSettingsData((byte) 255, "", ""), null))
|
1 * read(_) >> Mono.just(new RequestReader.Result("\"0xab\"".bytes, null, 1, new Upstream.UpstreamSettingsData((byte) 255, "", ""), null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def call = new NativeCall.ValidCallContext(1, 10, multistream, Selector.empty, quorum,
|
def call = new NativeCall.ValidCallContext(1, 10, multistream, new Selector.UpstreamFilter(Selector.empty), quorum,
|
||||||
new NativeCall.ParsedCallDetails("eth_getFilterChanges", new ListParams()),
|
new NativeCall.ParsedCallDetails("eth_getFilterChanges", new ListParams()),
|
||||||
new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator(), null, false, "reqId", 1)
|
new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator(), null, false, "reqId", 1)
|
||||||
|
|
||||||
@@ -645,7 +645,7 @@ class NativeCallSpec extends Specification {
|
|||||||
1 * read(_) >> Mono.just(new RequestReader.Result("\"0xab\"".bytes, null, 1, new Upstream.UpstreamSettingsData((byte) 1, "", ""), null))
|
1 * read(_) >> Mono.just(new RequestReader.Result("\"0xab\"".bytes, null, 1, new Upstream.UpstreamSettingsData((byte) 1, "", ""), null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def call = new NativeCall.ValidCallContext(1, 10, multistream, Selector.empty, quorum,
|
def call = new NativeCall.ValidCallContext(1, 10, multistream, new Selector.UpstreamFilter(Selector.empty), quorum,
|
||||||
new NativeCall.ParsedCallDetails("eth_getFilterChanges", new ListParams()),
|
new NativeCall.ParsedCallDetails("eth_getFilterChanges", new ListParams()),
|
||||||
new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator(), null, false, "reqId", 1)
|
new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator(), null, false, "reqId", 1)
|
||||||
|
|
||||||
@@ -667,7 +667,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(10, null,
|
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(10, null,
|
||||||
upstream,
|
upstream,
|
||||||
Selector.empty, new AlwaysQuorum(),
|
new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||||
when:
|
when:
|
||||||
nativeCall.fetch(ctx)
|
nativeCall.fetch(ctx)
|
||||||
@@ -684,7 +684,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(10, null,
|
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(10, null,
|
||||||
upstream,
|
upstream,
|
||||||
Selector.empty, new AlwaysQuorum(),
|
new Selector.UpstreamFilter(Selector.empty), new AlwaysQuorum(),
|
||||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||||
when:
|
when:
|
||||||
def act = nativeCall.fetch(ctx)
|
def act = nativeCall.fetch(ctx)
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class FilteredApisSpec extends Specification {
|
|||||||
it.setStatus(UpstreamAvailability.OK)
|
it.setStatus(UpstreamAvailability.OK)
|
||||||
}
|
}
|
||||||
when:
|
when:
|
||||||
def iter = new FilteredApis(Chain.ETHEREUM__MAINNET, upstreams, matcher, 0, 0)
|
def iter = new FilteredApis(Chain.ETHEREUM__MAINNET, upstreams, matcher, 0, 0, Selector.Sort.default)
|
||||||
iter.request(10)
|
iter.request(10)
|
||||||
then:
|
then:
|
||||||
StepVerifier.create(iter)
|
StepVerifier.create(iter)
|
||||||
@@ -97,7 +97,7 @@ class FilteredApisSpec extends Specification {
|
|||||||
.verify(Duration.ofSeconds(1))
|
.verify(Duration.ofSeconds(1))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
iter = new FilteredApis(Chain.ETHEREUM__MAINNET, upstreams, matcher, 1, 0)
|
iter = new FilteredApis(Chain.ETHEREUM__MAINNET, upstreams, matcher, 1, 0, Selector.Sort.default)
|
||||||
iter.request(10)
|
iter.request(10)
|
||||||
then:
|
then:
|
||||||
StepVerifier.create(iter)
|
StepVerifier.create(iter)
|
||||||
@@ -108,7 +108,7 @@ class FilteredApisSpec extends Specification {
|
|||||||
.verify(Duration.ofSeconds(1))
|
.verify(Duration.ofSeconds(1))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
iter = new FilteredApis(Chain.ETHEREUM__MAINNET, upstreams, matcher, 1, 2)
|
iter = new FilteredApis(Chain.ETHEREUM__MAINNET, upstreams, matcher, 1, 2, Selector.Sort.default)
|
||||||
iter.request(10)
|
iter.request(10)
|
||||||
then:
|
then:
|
||||||
StepVerifier.create(iter)
|
StepVerifier.create(iter)
|
||||||
@@ -134,7 +134,7 @@ class FilteredApisSpec extends Specification {
|
|||||||
TestingCommons.upstream(it)
|
TestingCommons.upstream(it)
|
||||||
}
|
}
|
||||||
when:
|
when:
|
||||||
def act = new FilteredApis(Chain.ETHEREUM__MAINNET, ups, Selector.empty, 2, 0)
|
def act = new FilteredApis(Chain.ETHEREUM__MAINNET, ups, Selector.empty, 2, 0, Selector.Sort.default)
|
||||||
act.request(10)
|
act.request(10)
|
||||||
then:
|
then:
|
||||||
StepVerifier.create(act)
|
StepVerifier.create(act)
|
||||||
@@ -153,7 +153,7 @@ class FilteredApisSpec extends Specification {
|
|||||||
TestingCommons.upstream(it)
|
TestingCommons.upstream(it)
|
||||||
}
|
}
|
||||||
when:
|
when:
|
||||||
def act = new FilteredApis(Chain.ETHEREUM__MAINNET, ups, Selector.empty, 2, 0)
|
def act = new FilteredApis(Chain.ETHEREUM__MAINNET, ups, Selector.empty, 2, 0, Selector.Sort.default)
|
||||||
act.request(3)
|
act.request(3)
|
||||||
then:
|
then:
|
||||||
StepVerifier.create(act)
|
StepVerifier.create(act)
|
||||||
@@ -212,7 +212,7 @@ class FilteredApisSpec extends Specification {
|
|||||||
when:
|
when:
|
||||||
def act = new FilteredApis(Chain.ETHEREUM__MAINNET,
|
def act = new FilteredApis(Chain.ETHEREUM__MAINNET,
|
||||||
[] + fallback + standard,
|
[] + fallback + standard,
|
||||||
Selector.empty, 0, 1)
|
Selector.empty, 0, 1, Selector.Sort.default)
|
||||||
act.request(10)
|
act.request(10)
|
||||||
then:
|
then:
|
||||||
StepVerifier.create(act)
|
StepVerifier.create(act)
|
||||||
@@ -248,7 +248,7 @@ class FilteredApisSpec extends Specification {
|
|||||||
when:
|
when:
|
||||||
def act = new FilteredApis(Chain.ETHEREUM__MAINNET,
|
def act = new FilteredApis(Chain.ETHEREUM__MAINNET,
|
||||||
[] + fallback + standard + secondary,
|
[] + fallback + standard + secondary,
|
||||||
Selector.empty, 0, 2)
|
Selector.empty, 0, 2, Selector.Sort.default)
|
||||||
act.request(11)
|
act.request(11)
|
||||||
then:
|
then:
|
||||||
StepVerifier.create(act)
|
StepVerifier.create(act)
|
||||||
@@ -285,7 +285,7 @@ class FilteredApisSpec extends Specification {
|
|||||||
when:
|
when:
|
||||||
def act = new FilteredApis(Chain.ETHEREUM__MAINNET,
|
def act = new FilteredApis(Chain.ETHEREUM__MAINNET,
|
||||||
[] + lagging + ok,
|
[] + lagging + ok,
|
||||||
Selector.empty, 0, 1)
|
Selector.empty, 0, 1, Selector.Sort.default)
|
||||||
act.request(4)
|
act.request(4)
|
||||||
then:
|
then:
|
||||||
StepVerifier.create(act)
|
StepVerifier.create(act)
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ class SelectorSpec extends Specification {
|
|||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
when:
|
when:
|
||||||
def act = Selector.convertToMatcher(List.of(slotHeightSelector), Stub(Head))
|
def act = Selector.convertToUpstreamFilter(List.of(slotHeightSelector))
|
||||||
then:
|
then:
|
||||||
act == new Selector.MultiMatcher(List.of(new Selector.SlotMatcher(10000)))
|
act.matcher == new Selector.MultiMatcher(List.of(new Selector.SlotMatcher(10000)))
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Convert height selector"() {
|
def "Convert height selector"() {
|
||||||
@@ -57,16 +57,13 @@ class SelectorSpec extends Specification {
|
|||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
when:
|
when:
|
||||||
def act = Selector.convertToMatcher(List.of(heightSelector), Stub(Head))
|
def act = Selector.convertToUpstreamFilter(List.of(heightSelector))
|
||||||
then:
|
then:
|
||||||
act == new Selector.MultiMatcher(List.of(new Selector.HeightMatcher(10000)))
|
act.matcher == new Selector.MultiMatcher(List.of(new Selector.HeightMatcher(10000)))
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Convert height selector with latest"() {
|
def "Convert height selector with latest"() {
|
||||||
setup:
|
setup:
|
||||||
def head = Mock(Head) {
|
|
||||||
1 * getCurrentHeight() >> 15000
|
|
||||||
}
|
|
||||||
def heightSelector = BlockchainOuterClass.Selector.newBuilder()
|
def heightSelector = BlockchainOuterClass.Selector.newBuilder()
|
||||||
.setHeightSelector(
|
.setHeightSelector(
|
||||||
BlockchainOuterClass.HeightSelector.newBuilder()
|
BlockchainOuterClass.HeightSelector.newBuilder()
|
||||||
@@ -75,9 +72,10 @@ class SelectorSpec extends Specification {
|
|||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
when:
|
when:
|
||||||
def act = Selector.convertToMatcher(List.of(heightSelector), head)
|
def act = Selector.convertToUpstreamFilter(List.of(heightSelector))
|
||||||
then:
|
then:
|
||||||
act == new Selector.MultiMatcher(List.of(new Selector.HeightMatcher(15000)))
|
act.matcher == new Selector.MultiMatcher(List.of(Selector.empty))
|
||||||
|
act.sort != Selector.Sort.default
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Convert LABEL match"() {
|
def "Convert LABEL match"() {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class RequestReaderFactoryTest {
|
|||||||
Arguments.of(
|
Arguments.of(
|
||||||
RequestReaderFactory.ReaderData(
|
RequestReaderFactory.ReaderData(
|
||||||
ms,
|
ms,
|
||||||
Selector.empty,
|
Selector.UpstreamFilter(Selector.empty),
|
||||||
MaximumValueQuorum(),
|
MaximumValueQuorum(),
|
||||||
null,
|
null,
|
||||||
tracer,
|
tracer,
|
||||||
@@ -43,7 +43,7 @@ class RequestReaderFactoryTest {
|
|||||||
Arguments.of(
|
Arguments.of(
|
||||||
RequestReaderFactory.ReaderData(
|
RequestReaderFactory.ReaderData(
|
||||||
ms,
|
ms,
|
||||||
Selector.empty,
|
Selector.UpstreamFilter(Selector.empty),
|
||||||
BroadcastQuorum(),
|
BroadcastQuorum(),
|
||||||
null,
|
null,
|
||||||
tracer,
|
tracer,
|
||||||
|
|||||||
Reference in New Issue
Block a user