Merge pull request #74 from p2p-org/debug-null-nativecall-result
trying to find null in response
This commit is contained in:
@@ -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
|
// 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
|
// 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
|
// 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 {
|
.flatMapMany {
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ class WebsocketHandler(
|
|||||||
}
|
}
|
||||||
Mono.just(response)
|
Mono.just(response)
|
||||||
.map { Global.objectMapper.writeValueAsString(it) }
|
.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() }
|
.doFinally { eventHandler.close() }
|
||||||
} else {
|
} else {
|
||||||
val eventHandler: AccessHandlerHttp.RequestHandler = eventHandlerFactory.call()
|
val eventHandler: AccessHandlerHttp.RequestHandler = eventHandlerFactory.call()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import reactor.core.publisher.Mono
|
|||||||
* Composition of multiple readers.
|
* 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.
|
* 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<K, D>(
|
class CompoundReader<K, D> (
|
||||||
private vararg val readers: Reader<K, D>
|
private vararg val readers: Reader<K, D>
|
||||||
) : Reader<K, D> {
|
) : Reader<K, D> {
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ open class NativeCall(
|
|||||||
val error = it.getError()
|
val error = it.getError()
|
||||||
|
|
||||||
Mono.just(
|
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)
|
result.setErrorMessage(error.message).setErrorCode(error.id)
|
||||||
}
|
}
|
||||||
} else {
|
} 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)
|
result.payload = ByteString.copyFrom(it.result)
|
||||||
}
|
}
|
||||||
if (it.nonce != null && it.signature != null) {
|
if (it.nonce != null && it.signature != null) {
|
||||||
@@ -275,9 +278,9 @@ open class NativeCall(
|
|||||||
.map {
|
.map {
|
||||||
validateResult(it, "local", ctx)
|
validateResult(it, "local", ctx)
|
||||||
if (ctx.nonce != null) {
|
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 {
|
} else {
|
||||||
CallResult.ok(ctx.id, null, it, null, ctx.upstream.getId())
|
CallResult.ok(ctx.id, null, it, null, ctx.upstream.getId(), ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.switchIfEmpty(
|
}.switchIfEmpty(
|
||||||
@@ -285,9 +288,9 @@ open class NativeCall(
|
|||||||
)
|
)
|
||||||
.onErrorResume {
|
.onErrorResume {
|
||||||
if (it is CallFailure) {
|
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 {
|
} 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 {
|
.map {
|
||||||
val bytes = ctx.resultDecorator.processResult(it)
|
val bytes = ctx.resultDecorator.processResult(it)
|
||||||
validateResult(bytes, "remote", ctx)
|
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 ->
|
.onErrorResume { t ->
|
||||||
val failure = when (t) {
|
val failure = when (t) {
|
||||||
is CallFailure -> CallResult.fail(t.id, ctx.nonce, t.reason)
|
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)
|
is JsonRpcException -> CallResult.fail(ctx.id, ctx.nonce, t.error.code, t.error.message, ctx)
|
||||||
else -> CallResult.fail(ctx.id, ctx.nonce, t)
|
else -> CallResult.fail(ctx.id, ctx.nonce, t, ctx)
|
||||||
}
|
}
|
||||||
Mono.just(failure)
|
Mono.just(failure)
|
||||||
}
|
}
|
||||||
@@ -326,7 +329,8 @@ open class NativeCall(
|
|||||||
ctx.id,
|
ctx.id,
|
||||||
ctx.nonce,
|
ctx.nonce,
|
||||||
1,
|
1,
|
||||||
errorMessage(attempts, ctx.payload.method)
|
errorMessage(attempts, ctx.payload.method),
|
||||||
|
ctx
|
||||||
).also {
|
).also {
|
||||||
countFailure(attempts, ctx)
|
countFailure(attempts, ctx)
|
||||||
}
|
}
|
||||||
@@ -503,19 +507,20 @@ open class NativeCall(
|
|||||||
val result: ByteArray?,
|
val result: ByteArray?,
|
||||||
val error: CallError?,
|
val error: CallError?,
|
||||||
val signature: ResponseSigner.Signature?,
|
val signature: ResponseSigner.Signature?,
|
||||||
val upstreamId: String?
|
val upstreamId: String?,
|
||||||
|
val ctx: ValidCallContext<ParsedCallDetails>?
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
fun ok(id: Int, nonce: Long?, result: ByteArray, signature: ResponseSigner.Signature?, upstreamId: String?): CallResult {
|
fun ok(id: Int, nonce: Long?, result: ByteArray, signature: ResponseSigner.Signature?, upstreamId: String?, ctx: ValidCallContext<ParsedCallDetails>?): CallResult {
|
||||||
return CallResult(id, nonce, result, null, signature, upstreamId)
|
return CallResult(id, nonce, result, null, signature, upstreamId, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fail(id: Int, nonce: Long?, errorCore: Int, errorMessage: String): CallResult {
|
fun fail(id: Int, nonce: Long?, errorCore: Int, errorMessage: String, ctx: ValidCallContext<ParsedCallDetails>?): CallResult {
|
||||||
return CallResult(id, nonce, null, CallError(errorCore, errorMessage, null), null, null)
|
return CallResult(id, nonce, null, CallError(errorCore, errorMessage, null), null, null, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fail(id: Int, nonce: Long?, error: Throwable): CallResult {
|
fun fail(id: Int, nonce: Long?, error: Throwable, ctx: ValidCallContext<ParsedCallDetails>?): CallResult {
|
||||||
return CallResult(id, nonce, null, CallError.from(error), null, null)
|
return CallResult(id, nonce, null, CallError.from(error), null, null, ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class BaseHandlerSpec extends Specification {
|
|||||||
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
||||||
call.items.add(request)
|
call.items.add(request)
|
||||||
call.ids[0] = 5
|
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:
|
when:
|
||||||
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, false))
|
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, false))
|
||||||
.collectList()
|
.collectList()
|
||||||
@@ -85,7 +85,7 @@ class BaseHandlerSpec extends Specification {
|
|||||||
def call = new ProxyCall(ProxyCall.RpcType.BATCH)
|
def call = new ProxyCall(ProxyCall.RpcType.BATCH)
|
||||||
call.items.add(request)
|
call.items.add(request)
|
||||||
call.ids[0] = 5
|
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:
|
when:
|
||||||
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, false))
|
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, false))
|
||||||
.collectList()
|
.collectList()
|
||||||
@@ -116,8 +116,8 @@ class BaseHandlerSpec extends Specification {
|
|||||||
call.items.add(request2)
|
call.items.add(request2)
|
||||||
call.ids[1] = 6
|
call.ids[1] = 6
|
||||||
def response = [
|
def response = [
|
||||||
new NativeCall.CallResult(1, null, '{"foo": 2}'.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)
|
new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null, null)
|
||||||
]
|
]
|
||||||
when:
|
when:
|
||||||
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, true))
|
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, true))
|
||||||
@@ -149,8 +149,8 @@ class BaseHandlerSpec extends Specification {
|
|||||||
call.items.add(request2)
|
call.items.add(request2)
|
||||||
call.ids[1] = 6
|
call.ids[1] = 6
|
||||||
def response = [
|
def response = [
|
||||||
new NativeCall.CallResult(1, null, '{"foo": 2}'.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)
|
new NativeCall.CallResult(0, null, '{"foo": 1}'.bytes, null, null, null, null)
|
||||||
]
|
]
|
||||||
when:
|
when:
|
||||||
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, true))
|
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
|
// note there is only 2 responses
|
||||||
def response = [
|
def response = [
|
||||||
new NativeCall.CallResult(1, null, '{"foo": 2}'.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)
|
new NativeCall.CallResult(2, null, '{"foo": 3}'.bytes, null, null, null, null)
|
||||||
]
|
]
|
||||||
when:
|
when:
|
||||||
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, true))
|
def act = Flux.from(handler.execute(Chain.ETHEREUM, call, requestHandler, true))
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class HttpHandlerSpec extends Specification {
|
|||||||
.setMethod("test_test")
|
.setMethod("test_test")
|
||||||
.setPayload(ByteString.copyFromUtf8("[]"))
|
.setPayload(ByteString.copyFromUtf8("[]"))
|
||||||
.build()
|
.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()
|
def req = BlockchainOuterClass.NativeCallRequest.newBuilder()
|
||||||
.setChain(Common.ChainRef.CHAIN_ETHEREUM)
|
.setChain(Common.ChainRef.CHAIN_ETHEREUM)
|
||||||
.addItems(reqItem)
|
.addItems(reqItem)
|
||||||
@@ -129,7 +129,7 @@ class HttpHandlerSpec extends Specification {
|
|||||||
def act = handler.execute(Chain.ETHEREUM, call, new AccessHandlerHttp.NoOpHandler(), false)
|
def act = handler.execute(Chain.ETHEREUM, call, new AccessHandlerHttp.NoOpHandler(), false)
|
||||||
|
|
||||||
then:
|
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)
|
StepVerifier.create(act)
|
||||||
.expectNext("hello")
|
.expectNext("hello")
|
||||||
.expectComplete()
|
.expectComplete()
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class WebsocketHandlerSpec extends Specification {
|
|||||||
|
|
||||||
def "Respond to a single call"() {
|
def "Respond to a single call"() {
|
||||||
setup:
|
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) {
|
def nativeCall = Mock(NativeCall) {
|
||||||
1 * it.nativeCallResult(_) >> Flux.fromIterable([response])
|
1 * it.nativeCallResult(_) >> Flux.fromIterable([response])
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class WriteRpcJsonSpec extends Specification {
|
|||||||
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
||||||
call.ids[1] = 105
|
call.ids[1] = 105
|
||||||
def data = [
|
def data = [
|
||||||
new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null)
|
new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null, null)
|
||||||
]
|
]
|
||||||
when:
|
when:
|
||||||
def act = writer.toJson(call, data[0])
|
def act = writer.toJson(call, data[0])
|
||||||
@@ -98,7 +98,7 @@ class WriteRpcJsonSpec extends Specification {
|
|||||||
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
||||||
call.ids[1] = 1
|
call.ids[1] = 1
|
||||||
def data = [
|
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:
|
when:
|
||||||
def act = writer.toJson(call, data[0])
|
def act = writer.toJson(call, data[0])
|
||||||
@@ -111,7 +111,7 @@ class WriteRpcJsonSpec extends Specification {
|
|||||||
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
||||||
call.ids[1] = "aaa"
|
call.ids[1] = "aaa"
|
||||||
def data = [
|
def data = [
|
||||||
new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null)
|
new NativeCall.CallResult(1, null, '"0x98dbb1"'.bytes, null, null, null, null)
|
||||||
]
|
]
|
||||||
when:
|
when:
|
||||||
def act = writer.toJson(call, data[0])
|
def act = writer.toJson(call, data[0])
|
||||||
@@ -126,9 +126,9 @@ class WriteRpcJsonSpec extends Specification {
|
|||||||
call.ids[2] = 11
|
call.ids[2] = 11
|
||||||
call.ids[3] = 15
|
call.ids[3] = 15
|
||||||
def data = [
|
def data = [
|
||||||
new NativeCall.CallResult(1, null, '"0x98dbb1"'.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),
|
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),
|
new NativeCall.CallResult(3, null, '{"hash": "0x2484f459dc"}'.bytes, null, null, null, null),
|
||||||
]
|
]
|
||||||
when:
|
when:
|
||||||
def act = Flux.fromIterable(data)
|
def act = Flux.fromIterable(data)
|
||||||
@@ -154,7 +154,7 @@ class WriteRpcJsonSpec extends Specification {
|
|||||||
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)
|
||||||
call.ids[1] = 10
|
call.ids[1] = 10
|
||||||
def data = [
|
def data = [
|
||||||
new NativeCall.CallResult(1, null, '"0x1"'.bytes, null, null, null),
|
new NativeCall.CallResult(1, null, '"0x1"'.bytes, null, null, null, null),
|
||||||
]
|
]
|
||||||
when:
|
when:
|
||||||
def act = Flux.fromIterable(data)
|
def act = Flux.fromIterable(data)
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
when:
|
when:
|
||||||
def resp = nativeCall.buildResponse(
|
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:
|
then:
|
||||||
resp.id == 1561
|
resp.id == 1561
|
||||||
@@ -208,7 +208,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
when:
|
when:
|
||||||
def resp = nativeCall.buildResponse(
|
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:
|
then:
|
||||||
resp.id == 1561
|
resp.id == 1561
|
||||||
|
|||||||
Reference in New Issue
Block a user