You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuweni.apache.org by to...@apache.org on 2022/06/17 17:46:50 UTC
[incubator-tuweni] branch main updated: Make JSONRPC use long numbers to match usage Make JSONRPC requests/responses support string ids instead of numbers
This is an automated email from the ASF dual-hosted git repository.
toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git
The following commit(s) were added to refs/heads/main by this push:
new 3da4a7ac Make JSONRPC use long numbers to match usage Make JSONRPC requests/responses support string ids instead of numbers
new a33dcdf7 Merge pull request #414 from atoulme/jsonrpc-proxy
3da4a7ac is described below
commit 3da4a7ac40fd92c7c59fd1519656c8d955cc8b61
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Thu Jun 16 20:16:37 2022 -0700
Make JSONRPC use long numbers to match usage
Make JSONRPC requests/responses support string ids instead of numbers
---
.../java/org/apache/tuweni/eth/EthJsonModule.java | 36 +++++++++
.../java/org/apache/tuweni/eth/StringOrLong.java | 57 +++++++++++++
.../kotlin/org/apache/tuweni/eth/JSONRPCRequest.kt | 10 ++-
.../org/apache/tuweni/eth/JSONRPCResponse.kt | 18 ++---
.../java/org/apache/tuweni/eth/JsonRpcTest.java | 42 ++++++++++
.../org/apache/tuweni/jsonrpc/app/JSONRPCApp.kt | 5 +-
jsonrpc-app/src/main/resources/logback.xml | 4 +
.../org/apache/tuweni/jsonrpc/JSONRPCClient.kt | 25 ++++--
.../org/apache/tuweni/jsonrpc/JSONRPCServer.kt | 2 +
.../tuweni/jsonrpc/methods/MethodsHandler.kt | 20 ++++-
.../org/apache/tuweni/jsonrpc/methods/Web3.kt | 5 +-
.../org/apache/tuweni/jsonrpc/JSONRPCClientTest.kt | 5 +-
.../org/apache/tuweni/jsonrpc/JSONRPCServerTest.kt | 5 +-
.../tuweni/jsonrpc/methods/MethodsHandlerTest.kt | 94 +++++++++++++---------
.../org/apache/tuweni/jsonrpc/methods/NetTest.kt | 7 +-
.../org/apache/tuweni/stratum/StratumServerApp.kt | 9 ++-
16 files changed, 272 insertions(+), 72 deletions(-)
diff --git a/eth/src/main/java/org/apache/tuweni/eth/EthJsonModule.java b/eth/src/main/java/org/apache/tuweni/eth/EthJsonModule.java
index e701e9f8..476beb39 100644
--- a/eth/src/main/java/org/apache/tuweni/eth/EthJsonModule.java
+++ b/eth/src/main/java/org/apache/tuweni/eth/EthJsonModule.java
@@ -24,6 +24,7 @@ import java.time.Instant;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.SerializerProvider;
@@ -261,6 +262,39 @@ public class EthJsonModule extends SimpleModule {
}
}
+ static class StringOrLongDeserializer extends StdDeserializer<StringOrLong> {
+
+ public StringOrLongDeserializer() {
+ super(StringOrLong.class);
+ }
+
+ @Override
+ public StringOrLong deserialize(JsonParser p, DeserializationContext ctxt) throws IOException,
+ JsonProcessingException {
+ if (p.currentToken().isNumeric()) {
+ return new StringOrLong(p.getLongValue());
+ } else {
+ return new StringOrLong(p.getValueAsString());
+ }
+ }
+ }
+
+ static class StringOrLongSerializer extends StdSerializer<StringOrLong> {
+
+ public StringOrLongSerializer() {
+ super(StringOrLong.class);
+ }
+
+ @Override
+ public void serialize(StringOrLong value, JsonGenerator gen, SerializerProvider provider) throws IOException {
+ if (value.getValueAsString() == null) {
+ gen.writeNumber(value.getValueAsLong());
+ } else {
+ gen.writeString(value.getValueAsString());
+ }
+ }
+ }
+
public EthJsonModule() {
addSerializer(Hash.class, new HashSerializer());
addDeserializer(Hash.class, new HashDeserializer());
@@ -281,5 +315,7 @@ public class EthJsonModule extends SimpleModule {
addDeserializer(Bytes.class, new BytesDeserializer());
addDeserializer(Bytes32.class, new Bytes32Deserializer());
addSerializer(SECP256K1.PublicKey.class, new PublicKeySerializer());
+ addSerializer(StringOrLong.class, new StringOrLongSerializer());
+ addDeserializer(StringOrLong.class, new StringOrLongDeserializer());
}
}
diff --git a/eth/src/main/java/org/apache/tuweni/eth/StringOrLong.java b/eth/src/main/java/org/apache/tuweni/eth/StringOrLong.java
new file mode 100644
index 00000000..43d456b9
--- /dev/null
+++ b/eth/src/main/java/org/apache/tuweni/eth/StringOrLong.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuweni.eth;
+
+import java.util.Objects;
+
+/**
+ * Class representing the identifier of a JSON-RPC request or response.
+ *
+ * The identifier can be a string or a number, but not both at the same time.
+ */
+public class StringOrLong {
+
+ private Long valueAsLong;
+ private String valueAsString;
+
+ public StringOrLong(String value) {
+ this.valueAsString = value;
+ }
+
+ public StringOrLong(Long value) {
+ this.valueAsLong = value;
+ }
+
+ public String getValueAsString() {
+ return valueAsString;
+ }
+
+ public Long getValueAsLong() {
+ return valueAsLong;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof StringOrLong))
+ return false;
+ StringOrLong that = (StringOrLong) o;
+ return Objects.equals(valueAsLong, that.valueAsLong) || Objects.equals(valueAsString, that.valueAsString);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(valueAsLong, valueAsString);
+ }
+}
diff --git a/eth/src/main/kotlin/org/apache/tuweni/eth/JSONRPCRequest.kt b/eth/src/main/kotlin/org/apache/tuweni/eth/JSONRPCRequest.kt
index 20d5804b..20694907 100644
--- a/eth/src/main/kotlin/org/apache/tuweni/eth/JSONRPCRequest.kt
+++ b/eth/src/main/kotlin/org/apache/tuweni/eth/JSONRPCRequest.kt
@@ -19,14 +19,16 @@ package org.apache.tuweni.eth
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
+data class Id(val idAsString: String?, val idAsLong: Long?)
+
/**
* JSONRPCRequest represents a JSON-RPC request to a JSON-RPC service.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-data class JSONRPCRequest(
- @JsonProperty("id") val id: Int,
+data class JSONRPCRequest constructor(
+ @JsonProperty("id") val id: StringOrLong,
@JsonProperty("method") val method: String,
- @JsonProperty("params") val params: Array<String>,
+ @JsonProperty("params") val params: Array<Any>,
@JsonProperty("jsonrpc") val jsonrpc: String = "2.0"
) {
@@ -43,7 +45,7 @@ data class JSONRPCRequest(
*/
fun deserialize(serialized: String): JSONRPCRequest {
val segments = serialized.split("|")
- return JSONRPCRequest(id = 0, method = segments[0], params = segments[1].split(",").toTypedArray())
+ return JSONRPCRequest(id = StringOrLong(0), method = segments[0], params = segments[1].split(",").toTypedArray())
}
}
diff --git a/eth/src/main/kotlin/org/apache/tuweni/eth/JSONRPCResponse.kt b/eth/src/main/kotlin/org/apache/tuweni/eth/JSONRPCResponse.kt
index 203587e2..b94ba922 100644
--- a/eth/src/main/kotlin/org/apache/tuweni/eth/JSONRPCResponse.kt
+++ b/eth/src/main/kotlin/org/apache/tuweni/eth/JSONRPCResponse.kt
@@ -20,14 +20,14 @@ import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
-data class JSONRPCResponse(@JsonProperty("id") val id: Int, @JsonProperty("result") val result: Any? = null, @JsonProperty("error") val error: JSONRPCError? = null, @JsonProperty("jsonrpc") val jsonrpc: String = "2.0")
+data class JSONRPCResponse(@JsonProperty("id") val id: StringOrLong, @JsonProperty("result") val result: Any? = null, @JsonProperty("error") val error: JSONRPCError? = null, @JsonProperty("jsonrpc") val jsonrpc: String = "2.0")
-data class JSONRPCError(@JsonProperty("code") val code: Int, @JsonProperty("message") val message: String)
+data class JSONRPCError(@JsonProperty("code") val code: Long, @JsonProperty("message") val message: String)
-val parseError = JSONRPCResponse(id = 0, error = JSONRPCError(-32700, "Parse error"))
-val invalidRequest = JSONRPCResponse(id = 0, error = JSONRPCError(-32600, "Invalid Request"))
-val methodNotFound = JSONRPCResponse(id = 0, error = JSONRPCError(-32601, "Method not found"))
-val invalidParams = JSONRPCResponse(id = 0, error = JSONRPCError(-32602, "Invalid params"))
-val internalError = JSONRPCResponse(id = 0, error = JSONRPCError(-32603, "Internal error"))
-val tooManyRequests = JSONRPCResponse(id = 0, error = JSONRPCError(code = -32000, message = "Too many requests"))
-val methodNotEnabled = JSONRPCResponse(id = 0, error = JSONRPCError(-32604, "Method not enabled"))
+val parseError = JSONRPCResponse(id = StringOrLong(0), error = JSONRPCError(-32700, "Parse error"))
+val invalidRequest = JSONRPCResponse(id = StringOrLong(0), error = JSONRPCError(-32600, "Invalid Request"))
+val methodNotFound = JSONRPCResponse(id = StringOrLong(0), error = JSONRPCError(-32601, "Method not found"))
+val invalidParams = JSONRPCResponse(id = StringOrLong(0), error = JSONRPCError(-32602, "Invalid params"))
+val internalError = JSONRPCResponse(id = StringOrLong(0), error = JSONRPCError(-32603, "Internal error"))
+val tooManyRequests = JSONRPCResponse(id = StringOrLong(0), error = JSONRPCError(code = -32000, message = "Too many requests"))
+val methodNotEnabled = JSONRPCResponse(id = StringOrLong(0), error = JSONRPCError(-32604, "Method not enabled"))
diff --git a/eth/src/test/java/org/apache/tuweni/eth/JsonRpcTest.java b/eth/src/test/java/org/apache/tuweni/eth/JsonRpcTest.java
new file mode 100644
index 00000000..744dab51
--- /dev/null
+++ b/eth/src/test/java/org/apache/tuweni/eth/JsonRpcTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuweni.eth;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+
+public class JsonRpcTest {
+
+ private static final ObjectMapper mapper = new ObjectMapper();
+ static {
+ mapper.registerModule(new EthJsonModule());
+ }
+
+ @Test
+ void testJsonRpcRequestRoundtrip() throws Exception {
+ JSONRPCRequest req = new JSONRPCRequest(new StringOrLong("3"), "foo_method", new Object[] {"foo", "bar"}, "2.0");
+ String value = mapper.writeValueAsString(req);
+ JSONRPCRequest req2 = mapper.readValue(value, JSONRPCRequest.class);
+ assertEquals(req, req2);
+ }
+
+ @Test
+ void testJsonRpcResponseRoundtrip() throws Exception {
+ JSONRPCResponse resp = new JSONRPCResponse(new StringOrLong("3"), "result", null, "2.0");
+ String value = mapper.writeValueAsString(resp);
+ JSONRPCResponse resp2 = mapper.readValue(value, JSONRPCResponse.class);
+ assertEquals(resp, resp2);
+ }
+}
diff --git a/jsonrpc-app/src/main/kotlin/org/apache/tuweni/jsonrpc/app/JSONRPCApp.kt b/jsonrpc-app/src/main/kotlin/org/apache/tuweni/jsonrpc/app/JSONRPCApp.kt
index d729db13..afb8ea66 100644
--- a/jsonrpc-app/src/main/kotlin/org/apache/tuweni/jsonrpc/app/JSONRPCApp.kt
+++ b/jsonrpc-app/src/main/kotlin/org/apache/tuweni/jsonrpc/app/JSONRPCApp.kt
@@ -31,6 +31,7 @@ import org.apache.tuweni.eth.JSONRPCResponse
import org.apache.tuweni.jsonrpc.JSONRPCClient
import org.apache.tuweni.jsonrpc.JSONRPCServer
import org.apache.tuweni.jsonrpc.methods.CachingHandler
+import org.apache.tuweni.jsonrpc.methods.LoggingHandler
import org.apache.tuweni.jsonrpc.methods.MeteredHandler
import org.apache.tuweni.jsonrpc.methods.MethodAllowListHandler
import org.apache.tuweni.jsonrpc.methods.ThrottlingHandler
@@ -150,7 +151,9 @@ class JSONRPCApplication(
val throttlingHandler = ThrottlingHandler(config.maxConcurrentRequests(), nextHandler)
- val handler = MeteredHandler(successCounter, failureCounter, throttlingHandler::handleRequest)
+ val loggingHandler = LoggingHandler(throttlingHandler::handleRequest, "jsonrpclog")
+
+ val handler = MeteredHandler(successCounter, failureCounter, loggingHandler::handleRequest)
val server = JSONRPCServer(
vertx,
config.port(), config.networkInterface(),
diff --git a/jsonrpc-app/src/main/resources/logback.xml b/jsonrpc-app/src/main/resources/logback.xml
index cb63fd52..89f01051 100644
--- a/jsonrpc-app/src/main/resources/logback.xml
+++ b/jsonrpc-app/src/main/resources/logback.xml
@@ -21,6 +21,10 @@
</encoder>
</appender>
+ <logger level="info" name="jsonrpclog" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
<root level="info">
<appender-ref ref="STDOUT" />
</root>
diff --git a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt
index 147bd8ca..b5318ef1 100644
--- a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt
+++ b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt
@@ -27,13 +27,15 @@ import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import org.apache.tuweni.eth.Address
+import org.apache.tuweni.eth.EthJsonModule
import org.apache.tuweni.eth.JSONRPCRequest
import org.apache.tuweni.eth.JSONRPCResponse
+import org.apache.tuweni.eth.StringOrLong
import org.apache.tuweni.eth.Transaction
import org.apache.tuweni.units.bigints.UInt256
import java.io.Closeable
import java.util.Base64
-import java.util.concurrent.atomic.AtomicInteger
+import java.util.concurrent.atomic.AtomicLong
import kotlin.coroutines.CoroutineContext
val mapper = ObjectMapper()
@@ -51,7 +53,13 @@ class JSONRPCClient(
override val coroutineContext: CoroutineContext = vertx.dispatcher(),
) : Closeable, CoroutineScope {
- val requestCounter = AtomicInteger(1)
+ companion object {
+ private val mapper = ObjectMapper()
+ init {
+ mapper.registerModule(EthJsonModule())
+ }
+ }
+ val requestCounter = AtomicLong(1)
val client = WebClient.create(
vertx,
WebClientOptions().setUserAgent(userAgent).setTryUseCompression(true)
@@ -73,7 +81,8 @@ class JSONRPCClient(
if (response.failed()) {
deferred.completeExceptionally(response.cause())
} else {
- val jsonResponse = response.result().bodyAsJson(JSONRPCResponse::class.java)
+ println(response.result().bodyAsString())
+ val jsonResponse = mapper.readValue(response.result().bodyAsString(), JSONRPCResponse::class.java)
deferred.complete(jsonResponse)
}
}
@@ -89,7 +98,7 @@ class JSONRPCClient(
* @throws ConnectException if it cannot dial the remote client
*/
suspend fun sendRawTransaction(tx: Transaction): String {
- val body = JSONRPCRequest(nextId(), "eth_sendRawTransaction", arrayOf(tx.toBytes().toHexString()))
+ val body = JSONRPCRequest(StringOrLong(nextId()), "eth_sendRawTransaction", arrayOf(tx.toBytes().toHexString()))
val jsonResponse = sendRequest(body).await()
val err = jsonResponse.error
if (err != null) {
@@ -108,7 +117,7 @@ class JSONRPCClient(
* @throws ConnectException if it cannot dial the remote client
*/
suspend fun getBalance_latest(address: Address): UInt256 {
- val body = JSONRPCRequest(nextId(), "eth_getBalance", arrayOf(address.toHexString(), "latest"))
+ val body = JSONRPCRequest(StringOrLong(nextId()), "eth_getBalance", arrayOf(address.toHexString(), "latest"))
val jsonResponse = sendRequest(body).await()
val err = jsonResponse.error
if (err != null) {
@@ -127,7 +136,7 @@ class JSONRPCClient(
* @throws ConnectException if it cannot dial the remote client
*/
suspend fun getTransactionCount_latest(address: Address): UInt256 {
- val body = JSONRPCRequest(nextId(), "eth_getTransactionCount", arrayOf(address.toHexString(), "latest"))
+ val body = JSONRPCRequest(StringOrLong(nextId()), "eth_getTransactionCount", arrayOf(address.toHexString(), "latest"))
val jsonResponse = sendRequest(body).await()
val err = jsonResponse.error
if (err != null) {
@@ -142,9 +151,9 @@ class JSONRPCClient(
client.close()
}
- private fun nextId(): Int {
+ private fun nextId(): Long {
val next = requestCounter.incrementAndGet()
- if (next == Int.MAX_VALUE) {
+ if (next == Long.MAX_VALUE) {
requestCounter.set(1)
}
return next
diff --git a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCServer.kt b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCServer.kt
index 561c6e7b..4bb638c0 100644
--- a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCServer.kt
+++ b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCServer.kt
@@ -48,6 +48,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
+import org.apache.tuweni.eth.EthJsonModule
import org.apache.tuweni.eth.JSONRPCRequest
import org.apache.tuweni.eth.JSONRPCResponse
import org.apache.tuweni.eth.internalError
@@ -79,6 +80,7 @@ class JSONRPCServer(
val mapper = ObjectMapper()
init {
+ mapper.registerModule(EthJsonModule())
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
}
}
diff --git a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandler.kt b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandler.kt
index 2feab0d5..2206f1aa 100644
--- a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandler.kt
+++ b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandler.kt
@@ -26,6 +26,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.apache.tuweni.eth.JSONRPCRequest
import org.apache.tuweni.eth.JSONRPCResponse
+import org.apache.tuweni.eth.StringOrLong
import org.apache.tuweni.eth.methodNotEnabled
import org.apache.tuweni.eth.methodNotFound
import org.apache.tuweni.eth.tooManyRequests
@@ -167,9 +168,9 @@ class CachingPollingHandler(
private fun poll() {
launch {
try {
- var id = 1337
+ var id = 1337L
for (cachedRequest in cachedRequests) {
- val newResponse = delegateHandler(cachedRequest.copy(id = id))
+ val newResponse = delegateHandler(cachedRequest.copy(id = StringOrLong(id)))
id++
if (newResponse.error == null) {
cacheStore.put(cachedRequest, newResponse)
@@ -209,6 +210,21 @@ class CachingPollingHandler(
}
}
+class LoggingHandler(
+ private val delegateHandler: suspend (JSONRPCRequest) -> JSONRPCResponse,
+ loggerName: String,
+) {
+
+ private val logger = LoggerFactory.getLogger(loggerName)
+
+ suspend fun handleRequest(request: JSONRPCRequest): JSONRPCResponse {
+ logger.info(request.toString())
+ val response = delegateHandler.invoke(request)
+ logger.info(response.toString())
+ return response
+ }
+}
+
class ConstantStringResult(val result: String) {
suspend fun handle(request: JSONRPCRequest): JSONRPCResponse {
return JSONRPCResponse(id = request.id, result = result)
diff --git a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/Web3.kt b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/Web3.kt
index aa75ec72..34a920e4 100644
--- a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/Web3.kt
+++ b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/Web3.kt
@@ -31,8 +31,11 @@ suspend fun sha3(request: JSONRPCRequest): JSONRPCResponse {
if (request.params.size != 1) {
return invalidParams.copy(id = request.id)
}
+ if (!(request.params[0] is String)) {
+ return invalidParams.copy(id = request.id)
+ }
try {
- val input = Bytes.fromHexString(request.params[0])
+ val input = Bytes.fromHexString(request.params[0] as String)
return JSONRPCResponse(id = request.id, result = Hash.hash(input).toHexString())
} catch (e: IllegalArgumentException) {
return invalidParams.copy(id = request.id)
diff --git a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClientTest.kt b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClientTest.kt
index a267f59b..a9e9868f 100644
--- a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClientTest.kt
+++ b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClientTest.kt
@@ -27,6 +27,7 @@ import org.apache.tuweni.crypto.SECP256K1
import org.apache.tuweni.eth.Address
import org.apache.tuweni.eth.JSONRPCRequest
import org.apache.tuweni.eth.JSONRPCResponse
+import org.apache.tuweni.eth.StringOrLong
import org.apache.tuweni.eth.Transaction
import org.apache.tuweni.junit.BouncyCastleExtension
import org.apache.tuweni.junit.VertxExtension
@@ -60,7 +61,7 @@ class JSONRPCClientTest {
vertx, port = 0,
methodHandler = {
handler.get().handle(it)
- JSONRPCResponse(3, "")
+ JSONRPCResponse(StringOrLong(3), "")
},
coroutineContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
)
@@ -91,7 +92,7 @@ class JSONRPCClientTest {
)
val sent = CompletableDeferred<String>()
handler.set { request ->
- sent.complete(request.params.get(0))
+ sent.complete(request.params.get(0) as String)
JSONRPCResponse(request.id, "")
}
diff --git a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCServerTest.kt b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCServerTest.kt
index 76f49391..4e497d82 100644
--- a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCServerTest.kt
+++ b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCServerTest.kt
@@ -23,6 +23,7 @@ import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import org.apache.tuweni.concurrent.coroutines.await
import org.apache.tuweni.eth.JSONRPCResponse
+import org.apache.tuweni.eth.StringOrLong
import org.apache.tuweni.io.Base64
import org.apache.tuweni.junit.VertxExtension
import org.apache.tuweni.junit.VertxInstance
@@ -53,7 +54,7 @@ class JSONRPCServerTest {
val server = JSONRPCServer(
vertx, port = 0,
methodHandler = {
- JSONRPCResponse(3, "")
+ JSONRPCResponse(StringOrLong(3), "")
},
coroutineContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
)
@@ -73,7 +74,7 @@ class JSONRPCServerTest {
val server = JSONRPCServer(
vertx, port = 0,
methodHandler = {
- JSONRPCResponse(3, "")
+ JSONRPCResponse(StringOrLong(3), "")
},
useBasicAuthentication = true,
basicAuthenticationPassword = "pass",
diff --git a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandlerTest.kt b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandlerTest.kt
index ef881027..1e1f92b8 100644
--- a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandlerTest.kt
+++ b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandlerTest.kt
@@ -26,6 +26,7 @@ import kotlinx.coroutines.runBlocking
import org.apache.tuweni.eth.JSONRPCError
import org.apache.tuweni.eth.JSONRPCRequest
import org.apache.tuweni.eth.JSONRPCResponse
+import org.apache.tuweni.eth.StringOrLong
import org.apache.tuweni.eth.methodNotFound
import org.apache.tuweni.junit.BouncyCastleExtension
import org.apache.tuweni.kv.MapKeyValueStore
@@ -42,13 +43,22 @@ class MethodsHandlerTest {
@Test
fun testMissingMethod() = runBlocking {
val methodsRouter = MethodsRouter(emptyMap())
- assertEquals(methodNotFound, methodsRouter.handleRequest(JSONRPCRequest(1, "web3_sha3", arrayOf("0xdeadbeef"))))
+ assertEquals(
+ methodNotFound,
+ methodsRouter.handleRequest(JSONRPCRequest(StringOrLong(1), "web3_sha3", arrayOf("0xdeadbeef")))
+ )
}
@Test
fun testRouteMethod() = runBlocking {
val methodsRouter = MethodsRouter(mapOf(Pair("web3_sha3", ::sha3)))
- assertEquals(JSONRPCResponse(1, result = "0xd4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1"), methodsRouter.handleRequest(JSONRPCRequest(1, "web3_sha3", arrayOf("0xdeadbeef"))))
+ assertEquals(
+ JSONRPCResponse(
+ StringOrLong(1),
+ result = "0xd4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1"
+ ),
+ methodsRouter.handleRequest(JSONRPCRequest(StringOrLong(1), "web3_sha3", arrayOf("0xdeadbeef")))
+ )
}
@Test
@@ -66,9 +76,9 @@ class MethodsHandlerTest {
val successCounter = meter.longCounterBuilder("success").build()
val failCounter = meter.longCounterBuilder("fail").build()
val meteredHandler = MeteredHandler(successCounter, failCounter) {
- JSONRPCResponse(1)
+ JSONRPCResponse(StringOrLong(1))
}
- meteredHandler.handleRequest(JSONRPCRequest(1, "foo", emptyArray()))
+ meteredHandler.handleRequest(JSONRPCRequest(StringOrLong(1), "foo", emptyArray()))
Thread.sleep(1200)
var metricValue = 0L
for (metric in exporter.finishedMetricItems) {
@@ -94,9 +104,9 @@ class MethodsHandlerTest {
val successCounter = meter.longCounterBuilder("success").build()
val failCounter = meter.longCounterBuilder("fail").build()
val meteredHandler = MeteredHandler(successCounter, failCounter) {
- JSONRPCResponse(1, error = JSONRPCError(123, "foo"))
+ JSONRPCResponse(StringOrLong(1), error = JSONRPCError(123, "foo"))
}
- meteredHandler.handleRequest(JSONRPCRequest(1, "foo", emptyArray()))
+ meteredHandler.handleRequest(JSONRPCRequest(StringOrLong(1), "foo", emptyArray()))
Thread.sleep(1200)
var metricValue = 0L
for (metric in exporter.finishedMetricItems) {
@@ -112,15 +122,15 @@ class MethodAllowListHandlerTest {
@Test
fun testAllowedMethod() = runBlocking {
- val filter = MethodAllowListHandler(listOf("eth_")) { JSONRPCResponse(1, "foo") }
- val resp = filter.handleRequest(JSONRPCRequest(1, "eth_client", emptyArray()))
+ val filter = MethodAllowListHandler(listOf("eth_")) { JSONRPCResponse(StringOrLong(1), "foo") }
+ val resp = filter.handleRequest(JSONRPCRequest(StringOrLong(1), "eth_client", emptyArray()))
assertNull(resp.error)
}
@Test
fun testForbiddenMethod() = runBlocking {
- val filter = MethodAllowListHandler(listOf("eth_")) { JSONRPCResponse(1, "foo") }
- val resp = filter.handleRequest(JSONRPCRequest(1, "foo_client", emptyArray()))
+ val filter = MethodAllowListHandler(listOf("eth_")) { JSONRPCResponse(StringOrLong(1), "foo") }
+ val resp = filter.handleRequest(JSONRPCRequest(StringOrLong(1), "foo_client", emptyArray()))
assertNotNull(resp.error)
val respContents = resp.error as JSONRPCError
assertEquals(-32604, respContents.code)
@@ -135,34 +145,34 @@ class ThrottlingHandlerTest {
val handler = ThrottlingHandler(4) {
runBlocking {
delay(500)
- JSONRPCResponse(id = 1)
+ JSONRPCResponse(id = StringOrLong(1))
}
}
async {
- val response = handler.handleRequest(JSONRPCRequest(2, "foo", arrayOf()))
- assertEquals(1, response.id)
+ val response = handler.handleRequest(JSONRPCRequest(StringOrLong(2), "foo", arrayOf()))
+ assertEquals(StringOrLong(1), response.id)
}
async {
- val response = handler.handleRequest(JSONRPCRequest(3, "foo", arrayOf()))
- assertEquals(1, response.id)
+ val response = handler.handleRequest(JSONRPCRequest(StringOrLong(3), "foo", arrayOf()))
+ assertEquals(StringOrLong(1), response.id)
}
async {
- val response = handler.handleRequest(JSONRPCRequest(4, "foo", arrayOf()))
- assertEquals(1, response.id)
+ val response = handler.handleRequest(JSONRPCRequest(StringOrLong(4), "foo", arrayOf()))
+ assertEquals(StringOrLong(1), response.id)
}
async {
- val response = handler.handleRequest(JSONRPCRequest(5, "foo", arrayOf()))
- assertEquals(1, response.id)
+ val response = handler.handleRequest(JSONRPCRequest(StringOrLong(5), "foo", arrayOf()))
+ assertEquals(StringOrLong(1), response.id)
}
async {
delay(200)
- val response = handler.handleRequest(JSONRPCRequest(6, "foo", arrayOf()))
+ val response = handler.handleRequest(JSONRPCRequest(StringOrLong(6), "foo", arrayOf()))
assertEquals(-32000, response.error?.code)
}
async {
delay(1000)
- val response = handler.handleRequest(JSONRPCRequest(7, "foo", arrayOf()))
- assertEquals(1, response.id)
+ val response = handler.handleRequest(JSONRPCRequest(StringOrLong(7), "foo", arrayOf()))
+ assertEquals(StringOrLong(1), response.id)
}
}
}
@@ -175,21 +185,26 @@ class CachingHandlerTest {
val kv = MapKeyValueStore.open(map)
val meterSdk = SdkMeterProvider.builder().build()
val meter = meterSdk.get("handler")
- val handler = CachingHandler(listOf("foo"), kv, meter.longCounterBuilder("foo").build(), meter.longCounterBuilder("bar").build()) {
+ val handler = CachingHandler(
+ listOf("foo"),
+ kv,
+ meter.longCounterBuilder("foo").build(),
+ meter.longCounterBuilder("bar").build()
+ ) {
if (it.params.isNotEmpty()) {
- JSONRPCResponse(id = 1, error = JSONRPCError(1234, ""))
+ JSONRPCResponse(id = StringOrLong(1), error = JSONRPCError(1234, ""))
} else {
- JSONRPCResponse(id = 1)
+ JSONRPCResponse(id = StringOrLong(1))
}
}
assertEquals(0, map.size)
- handler.handleRequest(JSONRPCRequest(id = 1, method = "foo", params = arrayOf()))
+ handler.handleRequest(JSONRPCRequest(id = StringOrLong(1), method = "foo", params = arrayOf()))
assertEquals(1, map.size)
- handler.handleRequest(JSONRPCRequest(id = 1, method = "bar", params = arrayOf()))
+ handler.handleRequest(JSONRPCRequest(id = StringOrLong(1), method = "bar", params = arrayOf()))
assertEquals(1, map.size)
- handler.handleRequest(JSONRPCRequest(id = 1, method = "foo", params = arrayOf()))
+ handler.handleRequest(JSONRPCRequest(id = StringOrLong(1), method = "foo", params = arrayOf()))
assertEquals(1, map.size)
- handler.handleRequest(JSONRPCRequest(id = 1, method = "foo", params = arrayOf("bleh")))
+ handler.handleRequest(JSONRPCRequest(id = StringOrLong(1), method = "foo", params = arrayOf("bleh")))
assertEquals(1, map.size)
}
}
@@ -202,22 +217,29 @@ class CachingPollingHandlerTest {
val kv = MapKeyValueStore.open(map)
val meterSdk = SdkMeterProvider.builder().build()
val meter = meterSdk.get("handler")
- val handler = CachingPollingHandler(listOf(JSONRPCRequest(1, "foo", arrayOf())), 1000, kv, meter.longCounterBuilder("foo").build(), meter.longCounterBuilder("bar").build()) {
+ val handler = CachingPollingHandler(
+ listOf(JSONRPCRequest(StringOrLong(1), "foo", arrayOf())),
+ 1000,
+ kv,
+ meter.longCounterBuilder("foo").build(),
+ meter.longCounterBuilder("bar").build()
+ ) {
if (it.params.isNotEmpty()) {
- JSONRPCResponse(id = 1, error = JSONRPCError(1234, ""))
+ JSONRPCResponse(id = StringOrLong(1), error = JSONRPCError(1234, ""))
} else {
- JSONRPCResponse(id = 1)
+ JSONRPCResponse(id = StringOrLong(1))
}
}
delay(500)
assertEquals(1, map.size)
- handler.handleRequest(JSONRPCRequest(id = 1, method = "foo", params = arrayOf()))
+ handler.handleRequest(JSONRPCRequest(id = StringOrLong(1), method = "foo", params = arrayOf()))
assertEquals(1, map.size)
- handler.handleRequest(JSONRPCRequest(id = 1, method = "bar", params = arrayOf()))
+ handler.handleRequest(JSONRPCRequest(id = StringOrLong(1), method = "bar", params = arrayOf()))
assertEquals(1, map.size)
- handler.handleRequest(JSONRPCRequest(id = 1, method = "foo", params = arrayOf()))
+ handler.handleRequest(JSONRPCRequest(id = StringOrLong(1), method = "foo", params = arrayOf()))
assertEquals(1, map.size)
- val errorResp = handler.handleRequest(JSONRPCRequest(id = 1, method = "foo", params = arrayOf("bleh")))
+ val errorResp =
+ handler.handleRequest(JSONRPCRequest(id = StringOrLong(1), method = "foo", params = arrayOf("bleh")))
assertEquals(1, map.size)
assertNotNull(errorResp.error)
}
diff --git a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/NetTest.kt b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/NetTest.kt
index b9421ada..00d51a2a 100644
--- a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/NetTest.kt
+++ b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/NetTest.kt
@@ -18,6 +18,7 @@ package org.apache.tuweni.jsonrpc.methods
import kotlinx.coroutines.runBlocking
import org.apache.tuweni.eth.JSONRPCRequest
+import org.apache.tuweni.eth.StringOrLong
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
@@ -26,8 +27,8 @@ class NetTest {
@Test
fun testNetCheck() = runBlocking {
val net = registerNet("2", true, { 2 })
- assertEquals("2", net["net_version"]?.invoke(JSONRPCRequest(1, "", arrayOf()))?.result)
- assertEquals(true, net["net_listening"]?.invoke(JSONRPCRequest(1, "", arrayOf()))?.result)
- assertEquals("0x2", net["net_peerCount"]?.invoke(JSONRPCRequest(1, "", arrayOf()))?.result)
+ assertEquals("2", net["net_version"]?.invoke(JSONRPCRequest(StringOrLong(1), "", arrayOf()))?.result)
+ assertEquals(true, net["net_listening"]?.invoke(JSONRPCRequest(StringOrLong(1), "", arrayOf()))?.result)
+ assertEquals("0x2", net["net_peerCount"]?.invoke(JSONRPCRequest(StringOrLong(1), "", arrayOf()))?.result)
}
}
diff --git a/stratum/proxy/src/main/kotlin/org/apache/tuweni/stratum/StratumServerApp.kt b/stratum/proxy/src/main/kotlin/org/apache/tuweni/stratum/StratumServerApp.kt
index 8a548e5b..1d15fc3a 100644
--- a/stratum/proxy/src/main/kotlin/org/apache/tuweni/stratum/StratumServerApp.kt
+++ b/stratum/proxy/src/main/kotlin/org/apache/tuweni/stratum/StratumServerApp.kt
@@ -24,12 +24,13 @@ import kotlinx.coroutines.withContext
import org.apache.tuweni.bytes.Bytes
import org.apache.tuweni.bytes.Bytes32
import org.apache.tuweni.eth.JSONRPCRequest
+import org.apache.tuweni.eth.StringOrLong
import org.apache.tuweni.jsonrpc.JSONRPCClient
import org.apache.tuweni.stratum.server.PoWInput
import org.apache.tuweni.stratum.server.StratumServer
import org.apache.tuweni.units.bigints.UInt256
import org.slf4j.LoggerFactory
-import java.util.concurrent.atomic.AtomicInteger
+import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.atomic.AtomicReference
import kotlin.system.exitProcess
@@ -44,7 +45,7 @@ fun main(args: Array<String>) {
val client = JSONRPCClient(vertx, "http://localhost:8545", "")
val port = args[0].toInt()
- val idCounter = AtomicInteger(0)
+ val idCounter = AtomicLong(0)
val seedReference = AtomicReference<Bytes32>()
val server = StratumServer(
vertx, port = port, networkInterface = "0.0.0.0",
@@ -52,7 +53,7 @@ fun main(args: Array<String>) {
logger.info("Got solution $solution")
withContext(client.coroutineContext) {
val req = JSONRPCRequest(
- id = idCounter.incrementAndGet(),
+ id = StringOrLong(idCounter.incrementAndGet()),
method = "eth_submitWork",
params = arrayOf(
Bytes.ofUnsignedLong(solution.nonce).toHexString(),
@@ -79,7 +80,7 @@ fun main(args: Array<String>) {
try {
val response = client.sendRequest(
JSONRPCRequest(
- id = idCounter.incrementAndGet(),
+ id = StringOrLong(idCounter.incrementAndGet()),
method = "eth_getWork",
params = arrayOf()
)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org