From 74e6bfe5146706634899a65684ff6771ebfb99d9 Mon Sep 17 00:00:00 2001 From: a10zn8 Date: Fri, 9 Dec 2022 17:39:12 +0400 Subject: [PATCH] trying to find null in response --- .../emeraldpay/dshackle/proxy/BaseHandler.kt | 2 +- .../dshackle/proxy/WebsocketHandler.kt | 2 +- .../dshackle/reader/CompoundReader.kt | 2 +- .../io/emeraldpay/dshackle/rpc/NativeCall.kt | 39 +++++++++++-------- .../dshackle/proxy/BaseHandlerSpec.groovy | 16 ++++---- .../dshackle/proxy/HttpHandlerSpec.groovy | 4 +- .../proxy/WebsocketHandlerSpec.groovy | 2 +- .../dshackle/proxy/WriteRpcJsonSpec.groovy | 14 +++---- .../dshackle/rpc/NativeCallSpec.groovy | 4 +- 9 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/proxy/BaseHandler.kt b/src/main/kotlin/io/emeraldpay/dshackle/proxy/BaseHandler.kt index 49480fa4..1bd48e74 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/proxy/BaseHandler.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/proxy/BaseHandler.kt @@ -116,7 +116,7 @@ abstract class BaseHandler( // If Proxy is configured to preserve original order it means that a client expect responses at exact same position // as requests even if a request completely failed for a some reason. It's very unlikely situation, but still possible // At this case, if we found a gap in responses, we put a default response with an error - ?: NativeCall.CallResult(id, null, null, NativeCall.CallError(id, "No response", null), null, null) + ?: NativeCall.CallResult(id, null, null, NativeCall.CallError(id, "No response", null), null, null, null) } } .flatMapMany { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/proxy/WebsocketHandler.kt b/src/main/kotlin/io/emeraldpay/dshackle/proxy/WebsocketHandler.kt index 3882d05b..51d097cf 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/proxy/WebsocketHandler.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/proxy/WebsocketHandler.kt @@ -181,7 +181,7 @@ class WebsocketHandler( } Mono.just(response) .map { Global.objectMapper.writeValueAsString(it) } - .doOnNext { eventHandler.onResponse(NativeCall.CallResult.ok(0, null, it.toByteArray(), null, null)) } + .doOnNext { eventHandler.onResponse(NativeCall.CallResult.ok(0, null, it.toByteArray(), null, null, null)) } .doFinally { eventHandler.close() } } else { val eventHandler: AccessHandlerHttp.RequestHandler = eventHandlerFactory.call() diff --git a/src/main/kotlin/io/emeraldpay/dshackle/reader/CompoundReader.kt b/src/main/kotlin/io/emeraldpay/dshackle/reader/CompoundReader.kt index 2d02b07b..f0e712cd 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/reader/CompoundReader.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/reader/CompoundReader.kt @@ -25,7 +25,7 @@ import reactor.core.publisher.Mono * Composition of multiple readers. * Reader returns first value returned by any of the source readers by checking one by one until one of them returns a non-empty result. */ -class CompoundReader( +class CompoundReader ( private vararg val readers: Reader ) : Reader { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt index 73d52cd4..db77f59d 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt @@ -98,7 +98,7 @@ open class NativeCall( val error = it.getError() Mono.just( - CallResult(error.id, 0, null, error, null, null) + CallResult(error.id, 0, null, error, null, null, null) ) } } @@ -119,6 +119,9 @@ open class NativeCall( result.setErrorMessage(error.message).setErrorCode(error.id) } } else { + if (it.result == null || it.result.isEmpty()) { + log.warn("Empty result on building response, method ${it.ctx?.payload?.method}, params ${it.ctx?.payload?.params}") + } result.payload = ByteString.copyFrom(it.result) } if (it.nonce != null && it.signature != null) { @@ -275,9 +278,9 @@ open class NativeCall( .map { validateResult(it, "local", ctx) if (ctx.nonce != null) { - CallResult.ok(ctx.id, ctx.nonce, it, signer.sign(ctx.nonce, it, ctx.upstream.getId()), ctx.upstream.getId()) + CallResult.ok(ctx.id, ctx.nonce, it, signer.sign(ctx.nonce, it, ctx.upstream.getId()), ctx.upstream.getId(), ctx) } else { - CallResult.ok(ctx.id, null, it, null, ctx.upstream.getId()) + CallResult.ok(ctx.id, null, it, null, ctx.upstream.getId(), ctx) } } }.switchIfEmpty( @@ -285,9 +288,9 @@ open class NativeCall( ) .onErrorResume { if (it is CallFailure) { - Mono.just(CallResult.fail(it.id, ctx.nonce, it.reason)) + Mono.just(CallResult.fail(it.id, ctx.nonce, it.reason, ctx)) } else { - Mono.just(CallResult.fail(ctx.id, ctx.nonce, it)) + Mono.just(CallResult.fail(ctx.id, ctx.nonce, it, ctx)) } } } @@ -309,13 +312,13 @@ open class NativeCall( .map { val bytes = ctx.resultDecorator.processResult(it) validateResult(bytes, "remote", ctx) - CallResult.ok(ctx.id, ctx.nonce, bytes, it.signature, ctx.upstream.getId()) + CallResult.ok(ctx.id, ctx.nonce, bytes, it.signature, ctx.upstream.getId(), ctx) } .onErrorResume { t -> val failure = when (t) { - is CallFailure -> CallResult.fail(t.id, ctx.nonce, t.reason) - is JsonRpcException -> CallResult.fail(ctx.id, ctx.nonce, t.error.code, t.error.message) - else -> CallResult.fail(ctx.id, ctx.nonce, t) + is CallFailure -> CallResult.fail(t.id, ctx.nonce, t.reason, ctx) + is JsonRpcException -> CallResult.fail(ctx.id, ctx.nonce, t.error.code, t.error.message, ctx) + else -> CallResult.fail(ctx.id, ctx.nonce, t, ctx) } Mono.just(failure) } @@ -326,7 +329,8 @@ open class NativeCall( ctx.id, ctx.nonce, 1, - errorMessage(attempts, ctx.payload.method) + errorMessage(attempts, ctx.payload.method), + ctx ).also { countFailure(attempts, ctx) } @@ -503,19 +507,20 @@ open class NativeCall( val result: ByteArray?, val error: CallError?, val signature: ResponseSigner.Signature?, - val upstreamId: String? + val upstreamId: String?, + val ctx: ValidCallContext? ) { companion object { - fun ok(id: Int, nonce: Long?, result: ByteArray, signature: ResponseSigner.Signature?, upstreamId: String?): CallResult { - return CallResult(id, nonce, result, null, signature, upstreamId) + fun ok(id: Int, nonce: Long?, result: ByteArray, signature: ResponseSigner.Signature?, upstreamId: String?, ctx: ValidCallContext?): CallResult { + return CallResult(id, nonce, result, null, signature, upstreamId, ctx) } - fun fail(id: Int, nonce: Long?, errorCore: Int, errorMessage: String): CallResult { - return CallResult(id, nonce, null, CallError(errorCore, errorMessage, null), null, null) + fun fail(id: Int, nonce: Long?, errorCore: Int, errorMessage: String, ctx: ValidCallContext?): CallResult { + return CallResult(id, nonce, null, CallError(errorCore, errorMessage, null), null, null, ctx) } - fun fail(id: Int, nonce: Long?, error: Throwable): CallResult { - return CallResult(id, nonce, null, CallError.from(error), null, null) + fun fail(id: Int, nonce: Long?, error: Throwable, ctx: ValidCallContext?): CallResult { + return CallResult(id, nonce, null, CallError.from(error), null, null, ctx) } } diff --git a/src/test/groovy/io/emeraldpay/dshackle/proxy/BaseHandlerSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/proxy/BaseHandlerSpec.groovy index 01d022f7..ae1c22d6 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/proxy/BaseHandlerSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/proxy/BaseHandlerSpec.groovy @@ -62,7 +62,7 @@ class BaseHandlerSpec extends Specification { def call = new ProxyCall(ProxyCall.RpcType.SINGLE) call.items.add(request) call.ids[0] = 5 - def response = new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null) + def response = new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null, null) when: def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, false)) .collectList() @@ -85,7 +85,7 @@ class BaseHandlerSpec extends Specification { def call = new ProxyCall(ProxyCall.RpcType.BATCH) call.items.add(request) call.ids[0] = 5 - def response = new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null) + def response = new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null, null) when: def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, false)) .collectList() @@ -116,8 +116,8 @@ class BaseHandlerSpec extends Specification { call.items.add(request2) call.ids[1] = 6 def response = [ - new NativeCall.CallResult(1, null, '{"foo": 2}'.bytes, null, null, null), - new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null) + new NativeCall.CallResult(1, null, '{"foo": 2}'.bytes, null, null, null, null), + new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null, null) ] when: def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, true)) @@ -149,8 +149,8 @@ class BaseHandlerSpec extends Specification { call.items.add(request2) call.ids[1] = 6 def response = [ - new NativeCall.CallResult(1, null, '{"foo": 2}'.bytes, null, null, null), - new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null) + new NativeCall.CallResult(1, null, '{"foo": 2}'.bytes, null, null, null, null), + new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null, null) ] when: def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, true)) @@ -189,8 +189,8 @@ class BaseHandlerSpec extends Specification { // note there is only 2 responses def response = [ - new NativeCall.CallResult(1, null, '{"foo": 2}'.bytes, null, null, null), - new NativeCall.CallResult(2, null, '{"foo": 3}'.bytes, null, null, null) + new NativeCall.CallResult(1, null, '{"foo": 2}'.bytes, null, null, null, null), + new NativeCall.CallResult(2, null, '{"foo": 3}'.bytes, null, null, null, null) ] when: def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, true)) diff --git a/src/test/groovy/io/emeraldpay/dshackle/proxy/HttpHandlerSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/proxy/HttpHandlerSpec.groovy index 916fb5ac..77a72823 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/proxy/HttpHandlerSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/proxy/HttpHandlerSpec.groovy @@ -43,7 +43,7 @@ class HttpHandlerSpec extends Specification { .setMethod("test_test") .setPayload(ByteString.copyFromUtf8("[]")) .build() - def respItem = new NativeCall.CallResult(1, null, "100".bytes, null, null, null) + def respItem = new NativeCall.CallResult(1, null, "100".bytes, null, null, null, null) def req = BlockchainOuterClass.NativeCallRequest.newBuilder() .setChain(Common.ChainRef.CHAIN_ETHEREUM) .addItems(reqItem) @@ -129,7 +129,7 @@ class HttpHandlerSpec extends Specification { def act = handler.execute(Chain.ETHEREUM, call, new AccessHandlerHttp.NoOpHandler(), false) then: - 1 * nativeCall.nativeCallResult(_) >> Flux.just(new NativeCall.CallResult(1, null, "".bytes, null, null, null)) + 1 * nativeCall.nativeCallResult(_) >> Flux.just(new NativeCall.CallResult(1, null, "".bytes, null, null, null, null)) StepVerifier.create(act) .expectNext("hello") .expectComplete() diff --git a/src/test/groovy/io/emeraldpay/dshackle/proxy/WebsocketHandlerSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/proxy/WebsocketHandlerSpec.groovy index 05b32746..51bf1f16 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/proxy/WebsocketHandlerSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/proxy/WebsocketHandlerSpec.groovy @@ -85,7 +85,7 @@ class WebsocketHandlerSpec extends Specification { def "Respond to a single call"() { setup: - def response = new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, "test") + def response = new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, "test", null) def nativeCall = Mock(NativeCall) { 1 * it.nativeCallResult(_) >> Flux.fromIterable([response]) diff --git a/src/test/groovy/io/emeraldpay/dshackle/proxy/WriteRpcJsonSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/proxy/WriteRpcJsonSpec.groovy index 9b1140e5..d56efb99 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/proxy/WriteRpcJsonSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/proxy/WriteRpcJsonSpec.groovy @@ -85,7 +85,7 @@ class WriteRpcJsonSpec extends Specification { def call = new ProxyCall(ProxyCall.RpcType.SINGLE) call.ids[1] = 105 def data = [ - new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null) + new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null, null) ] when: def act = writer.toJson(call, data[0]) @@ -98,7 +98,7 @@ class WriteRpcJsonSpec extends Specification { def call = new ProxyCall(ProxyCall.RpcType.SINGLE) call.ids[1] = 1 def data = [ - new NativeCall.CallResult(1, null, null, new NativeCall.CallError(1, "Internal Error", null), null, null) + new NativeCall.CallResult(1, null, null, new NativeCall.CallError(1, "Internal Error", null), null, null, null) ] when: def act = writer.toJson(call, data[0]) @@ -111,7 +111,7 @@ class WriteRpcJsonSpec extends Specification { def call = new ProxyCall(ProxyCall.RpcType.SINGLE) call.ids[1] = "aaa" def data = [ - new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null) + new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null, null) ] when: def act = writer.toJson(call, data[0]) @@ -126,9 +126,9 @@ class WriteRpcJsonSpec extends Specification { call.ids[2] = 11 call.ids[3] = 15 def data = [ - new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null), - new NativeCall.CallResult(2, null, null, new NativeCall.CallError(2, "oops", null), null, null), - new NativeCall.CallResult(3, null, '{"hash": "0x2484f459dc"}'.bytes, null, null, null), + new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null, null), + new NativeCall.CallResult(2, null, null, new NativeCall.CallError(2, "oops", null), null, null, null), + new NativeCall.CallResult(3, null, '{"hash": "0x2484f459dc"}'.bytes, null, null, null, null), ] when: def act = Flux.fromIterable(data) @@ -154,7 +154,7 @@ class WriteRpcJsonSpec extends Specification { def call = new ProxyCall(ProxyCall.RpcType.SINGLE) call.ids[1] = 10 def data = [ - new NativeCall.CallResult(1, null, '"0x1"'.bytes, null, null, null), + new NativeCall.CallResult(1, null, '"0x1"'.bytes, null, null, null, null), ] when: def act = Flux.fromIterable(data) diff --git a/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy index 0f039786..9339d98a 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy @@ -193,7 +193,7 @@ class NativeCallSpec extends Specification { when: def resp = nativeCall.buildResponse( - new NativeCall.CallResult(1561, 10, objectMapper.writeValueAsBytes(json), null, null, null) + new NativeCall.CallResult(1561, 10, objectMapper.writeValueAsBytes(json), null, null, null, null) ) then: resp.id == 1561 @@ -208,7 +208,7 @@ class NativeCallSpec extends Specification { when: def resp = nativeCall.buildResponse( - new NativeCall.CallResult(1561, 10, objectMapper.writeValueAsBytes(json), null, new ResponseSigner.Signature("sig1".bytes, "test", 100), "test") + new NativeCall.CallResult(1561, 10, objectMapper.writeValueAsBytes(json), null, new ResponseSigner.Signature("sig1".bytes, "test", 100), "test", null) ) then: resp.id == 1561