@@ -26,7 +26,6 @@ import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
import io.netty.buffer.ByteBuf
|
||||
import io.netty.buffer.Unpooled
|
||||
import io.netty.handler.ssl.SslContextBuilder
|
||||
import org.reactivestreams.Publisher
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.http.HttpHeaders
|
||||
@@ -37,7 +36,6 @@ import reactor.netty.http.server.HttpServer
|
||||
import reactor.netty.http.server.HttpServerRequest
|
||||
import reactor.netty.http.server.HttpServerResponse
|
||||
import reactor.netty.http.server.HttpServerRoutes
|
||||
import java.io.File
|
||||
import java.util.function.BiFunction
|
||||
|
||||
/**
|
||||
@@ -100,8 +98,8 @@ class ProxyServer(
|
||||
.flatMapMany { call -> execute(chain, call) }
|
||||
.onErrorResume(RpcException::class.java) { err ->
|
||||
val id = err.details?.let {
|
||||
if (it is JsonRpcResponse.Id) it else JsonRpcResponse.IntId(-1)
|
||||
} ?: JsonRpcResponse.IntId(-1)
|
||||
if (it is JsonRpcResponse.Id) it else JsonRpcResponse.NumberId(-1)
|
||||
} ?: JsonRpcResponse.NumberId(-1)
|
||||
|
||||
val json = JsonRpcResponse.error(err.code, err.rpcMessage, id)
|
||||
Mono.just(Global.objectMapper.writeValueAsString(json))
|
||||
|
||||
@@ -58,7 +58,7 @@ class QuorumRpcReader(
|
||||
val defaultResult: Mono<Result> = Mono.just(quorum).flatMap { q ->
|
||||
if (q.isFailed()) {
|
||||
Mono.error<Result>(
|
||||
q.getError()?.asException(JsonRpcResponse.IntId(1))
|
||||
q.getError()?.asException(JsonRpcResponse.NumberId(1))
|
||||
?: RpcException(-32000, "Unknown Upstream error")
|
||||
)
|
||||
} else {
|
||||
|
||||
@@ -211,7 +211,7 @@ open class NativeCall(
|
||||
companion object {
|
||||
fun from(t: Throwable): CallError {
|
||||
return when (t) {
|
||||
is JsonRpcException -> CallError(t.id.asInt(), t.error.message, t.error)
|
||||
is JsonRpcException -> CallError(t.id.asNumber().toInt(), t.error.message, t.error)
|
||||
is RpcException -> CallError(t.code, t.rpcMessage, null)
|
||||
is CallFailure -> CallError(t.id, t.reason.message ?: "Upstream Error", null)
|
||||
else -> CallError(1, t.message ?: "Upstream Error", null)
|
||||
|
||||
@@ -31,7 +31,7 @@ class JsonRpcError(val code: Int, val message: String, val details: Any?) {
|
||||
}
|
||||
|
||||
fun asException(id: JsonRpcResponse.Id?): JsonRpcException {
|
||||
return JsonRpcException(id ?: JsonRpcResponse.IntId(-1), this)
|
||||
return JsonRpcException(id ?: JsonRpcResponse.NumberId(-1), this)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
||||
@@ -22,7 +22,7 @@ class JsonRpcException(
|
||||
val error: JsonRpcError
|
||||
) : Exception(error.message) {
|
||||
|
||||
constructor(id: Int, message: String) : this(JsonRpcResponse.IntId(id), JsonRpcError(-32005, message))
|
||||
constructor(id: Int, message: String) : this(JsonRpcResponse.NumberId(id), JsonRpcError(-32005, message))
|
||||
|
||||
companion object {
|
||||
fun from(err: RpcException): JsonRpcException {
|
||||
@@ -30,9 +30,9 @@ class JsonRpcException(
|
||||
if (it is JsonRpcResponse.Id) {
|
||||
it
|
||||
} else {
|
||||
JsonRpcResponse.IntId(-3)
|
||||
JsonRpcResponse.NumberId(-3)
|
||||
}
|
||||
} ?: JsonRpcResponse.IntId(-4)
|
||||
} ?: JsonRpcResponse.NumberId(-4)
|
||||
return JsonRpcException(
|
||||
id, JsonRpcError.from(err)
|
||||
)
|
||||
|
||||
@@ -88,7 +88,7 @@ class JsonRpcHttpClient(
|
||||
|
||||
return response.response { header, bytes ->
|
||||
if (header.status().code() != 200) {
|
||||
Mono.error(JsonRpcException(JsonRpcResponse.IntId(-2),
|
||||
Mono.error(JsonRpcException(JsonRpcResponse.NumberId(-2),
|
||||
JsonRpcError(RpcResponseError.CODE_UPSTREAM_INVALID_RESPONSE, "HTTP Code: ${header.status().code()}"))
|
||||
)
|
||||
} else {
|
||||
@@ -105,7 +105,7 @@ class JsonRpcHttpClient(
|
||||
.onErrorResume { t ->
|
||||
val err = when (t) {
|
||||
is RpcException -> JsonRpcResponse.error(t.code, t.rpcMessage)
|
||||
is JsonRpcException -> JsonRpcResponse.error(t.error, JsonRpcResponse.IntId(1))
|
||||
is JsonRpcException -> JsonRpcResponse.error(t.error, JsonRpcResponse.NumberId(1))
|
||||
else -> JsonRpcResponse.error(1, t.message ?: t.javaClass.name)
|
||||
}
|
||||
Mono.just(err)
|
||||
|
||||
@@ -26,7 +26,7 @@ class JsonRpcResponse(
|
||||
val id: Id
|
||||
) {
|
||||
|
||||
constructor(result: ByteArray?, error: JsonRpcError?) : this(result, error, IntId(0))
|
||||
constructor(result: ByteArray?, error: JsonRpcError?) : this(result, error, NumberId(0))
|
||||
|
||||
companion object {
|
||||
private val NULL_VALUE = "null".toByteArray()
|
||||
@@ -129,29 +129,31 @@ class JsonRpcResponse(
|
||||
* JSON RPC wrapper. Makes sure that the id is either Int or String
|
||||
*/
|
||||
interface Id {
|
||||
fun asInt(): Int
|
||||
fun asNumber(): Long
|
||||
fun asString(): String
|
||||
fun isInt(): Boolean
|
||||
fun isNumber(): Boolean
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun from(id: Any): Id {
|
||||
if (id is Int) {
|
||||
return IntId(id)
|
||||
return NumberId(id)
|
||||
}
|
||||
if (id is Number) {
|
||||
return IntId(id.toInt())
|
||||
return NumberId(id.toLong())
|
||||
}
|
||||
if (id is String) {
|
||||
return StringId(id)
|
||||
}
|
||||
throw IllegalArgumentException("Id must be Int or String")
|
||||
throw IllegalArgumentException("Id must be Number or String")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IntId(val id: Int) : Id {
|
||||
override fun asInt(): Int {
|
||||
class NumberId(val id: Long) : Id {
|
||||
constructor(id: Int) : this(id.toLong())
|
||||
|
||||
override fun asNumber(): Long {
|
||||
return id
|
||||
}
|
||||
|
||||
@@ -159,13 +161,13 @@ class JsonRpcResponse(
|
||||
throw IllegalStateException("Not string")
|
||||
}
|
||||
|
||||
override fun isInt(): Boolean {
|
||||
override fun isNumber(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is IntId) return false
|
||||
if (other !is NumberId) return false
|
||||
|
||||
if (id != other.id) return false
|
||||
|
||||
@@ -173,20 +175,20 @@ class JsonRpcResponse(
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id
|
||||
return id.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
class StringId(val id: String) : Id {
|
||||
override fun asInt(): Int {
|
||||
throw IllegalStateException("Not int")
|
||||
override fun asNumber(): Long {
|
||||
throw IllegalStateException("Not a number")
|
||||
}
|
||||
|
||||
override fun asString(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun isInt(): Boolean {
|
||||
override fun isNumber(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -209,8 +211,8 @@ class JsonRpcResponse(
|
||||
override fun serialize(value: JsonRpcResponse, gen: JsonGenerator, serializers: SerializerProvider) {
|
||||
gen.writeStartObject()
|
||||
gen.writeStringField("jsonrpc", "2.0")
|
||||
if (value.id.isInt()) {
|
||||
gen.writeNumberField("id", value.id.asInt())
|
||||
if (value.id.isNumber()) {
|
||||
gen.writeNumberField("id", value.id.asNumber())
|
||||
} else {
|
||||
gen.writeStringField("id", value.id.asString())
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class ProxyServerSpec extends Specification {
|
||||
def "Return error on invalid request"() {
|
||||
setup:
|
||||
ReadRpcJson read = Mock(ReadRpcJson) {
|
||||
1 * apply(_) >> { throw new RpcException(-32123, "test", new JsonRpcResponse.IntId(4)) }
|
||||
1 * apply(_) >> { throw new RpcException(-32123, "test", new JsonRpcResponse.NumberId(4)) }
|
||||
}
|
||||
def server = new ProxyServer(
|
||||
Stub(ProxyConfig),
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package io.emeraldpay.dshackle.proxy
|
||||
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
import spock.lang.Specification
|
||||
@@ -192,7 +192,7 @@ class ReadRpcJsonSpec extends Specification {
|
||||
def t = thrown(RpcException)
|
||||
t.code == -32600
|
||||
t.rpcMessage.toLowerCase() == "jsonrpc version is not set"
|
||||
t.details == new JsonRpcResponse.IntId(2)
|
||||
t.details == new JsonRpcResponse.NumberId(2)
|
||||
}
|
||||
|
||||
def "Error if jsonrpc version is invalid"() {
|
||||
@@ -202,7 +202,7 @@ class ReadRpcJsonSpec extends Specification {
|
||||
def t = thrown(RpcException)
|
||||
t.code == -32600
|
||||
t.rpcMessage.toLowerCase() == "unsupported json rpc version: 3.0"
|
||||
t.details == new JsonRpcResponse.IntId(2)
|
||||
t.details == new JsonRpcResponse.NumberId(2)
|
||||
}
|
||||
|
||||
def "Error if method is not set"() {
|
||||
@@ -212,7 +212,7 @@ class ReadRpcJsonSpec extends Specification {
|
||||
def t = thrown(RpcException)
|
||||
t.code == -32600
|
||||
t.rpcMessage.toLowerCase() == "method is not set"
|
||||
t.details == new JsonRpcResponse.IntId(2)
|
||||
t.details == new JsonRpcResponse.NumberId(2)
|
||||
}
|
||||
|
||||
def "Error if params is not array"() {
|
||||
@@ -222,6 +222,6 @@ class ReadRpcJsonSpec extends Specification {
|
||||
def t = thrown(RpcException)
|
||||
t.code == -32600
|
||||
t.rpcMessage.toLowerCase() == "params must be an array"
|
||||
t.details == new JsonRpcResponse.IntId(2)
|
||||
t.details == new JsonRpcResponse.NumberId(2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class JsonRpcResponseSpec extends Specification {
|
||||
|
||||
def "Serialize int id and null result"() {
|
||||
setup:
|
||||
def json = new JsonRpcResponse("null".bytes, null, new JsonRpcResponse.IntId(1))
|
||||
def json = new JsonRpcResponse("null".bytes, null, new JsonRpcResponse.NumberId(1))
|
||||
when:
|
||||
def act = objectMapper.writeValueAsString(json)
|
||||
then:
|
||||
@@ -72,7 +72,7 @@ class JsonRpcResponseSpec extends Specification {
|
||||
|
||||
def "Serialize int id and string result"() {
|
||||
setup:
|
||||
def json = new JsonRpcResponse('"Hello World"'.bytes, null, new JsonRpcResponse.IntId(10))
|
||||
def json = new JsonRpcResponse('"Hello World"'.bytes, null, new JsonRpcResponse.NumberId(10))
|
||||
when:
|
||||
def act = objectMapper.writeValueAsString(json)
|
||||
then:
|
||||
@@ -81,7 +81,7 @@ class JsonRpcResponseSpec extends Specification {
|
||||
|
||||
def "Serialize int id and object result"() {
|
||||
setup:
|
||||
def json = new JsonRpcResponse('{"foo": "Hello World", "bar": 1}'.bytes, null, new JsonRpcResponse.IntId(101))
|
||||
def json = new JsonRpcResponse('{"foo": "Hello World", "bar": 1}'.bytes, null, new JsonRpcResponse.NumberId(101))
|
||||
when:
|
||||
def act = objectMapper.writeValueAsString(json)
|
||||
then:
|
||||
@@ -90,7 +90,7 @@ class JsonRpcResponseSpec extends Specification {
|
||||
|
||||
def "Serialize int id and error"() {
|
||||
setup:
|
||||
def json = new JsonRpcResponse(null, new JsonRpcError(-32041, "Oooops"), new JsonRpcResponse.IntId(101))
|
||||
def json = new JsonRpcResponse(null, new JsonRpcError(-32041, "Oooops"), new JsonRpcResponse.NumberId(101))
|
||||
when:
|
||||
def act = objectMapper.writeValueAsString(json)
|
||||
then:
|
||||
|
||||
Reference in New Issue
Block a user