Merge pull request #543 from apache/jsonrpc_ethgetBlockByNumber
Support eth_getBlockByNumber from JSONRPC client
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 7c9e205..4f221fd 100644
--- a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt
+++ b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClient.kt
@@ -68,7 +68,7 @@
val authorizationHeader = "Basic " + Base64.getEncoder()
.encode((basicAuthenticationUsername + ":" + basicAuthenticationPassword).toByteArray())
- suspend fun sendRequest(request: JSONRPCRequest): Deferred<JSONRPCResponse> {
+ fun sendRequest(request: JSONRPCRequest): Deferred<JSONRPCResponse> {
val deferred = CompletableDeferred<JSONRPCResponse>()
val httpRequest = client.postAbs(endpointUrl)
.putHeader("Content-Type", "application/json")
@@ -81,7 +81,6 @@
if (response.failed()) {
deferred.completeExceptionally(response.cause())
} else {
- println(response.result().bodyAsString())
val jsonResponse = mapper.readValue(response.result().bodyAsString(), JSONRPCResponse::class.java)
deferred.complete(jsonResponse)
}
@@ -151,6 +150,28 @@
}
}
+ /**
+ * Gets block data by block number
+ * @param blockNumber the block number
+ * @param includeTransactions whether to include transactions detail
+ * @return the whole block information as a JSON document.
+ */
+ suspend fun getBlockByBlockNumber(blockNumber: Int, includeTransactions: Boolean): Map<*, *> {
+ val body = JSONRPCRequest(
+ StringOrLong(nextId()),
+ "eth_getBlockByNumber",
+ arrayOf(blockNumber, includeTransactions)
+ )
+ val jsonResponse = sendRequest(body).await()
+ val err = jsonResponse.error
+ if (err != null) {
+ val errorMessage = "Code ${err.code}: ${err.message}"
+ throw ClientRequestException(errorMessage)
+ } else {
+ return jsonResponse.result as Map<*, *>
+ }
+ }
+
override fun close() {
client.close()
}
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 8c54b1e..de81773 100644
--- a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClientTest.kt
+++ b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/JSONRPCClientTest.kt
@@ -16,7 +16,6 @@
*/
package org.apache.tuweni.jsonrpc
-import io.vertx.core.Handler
import io.vertx.core.Vertx
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.asCoroutineDispatcher
@@ -27,7 +26,6 @@
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
@@ -50,7 +48,7 @@
class JSONRPCClientTest {
companion object {
- val handler = AtomicReference<Handler<JSONRPCRequest>>()
+ val handler = AtomicReference<(JSONRPCRequest) -> JSONRPCResponse>()
var server: JSONRPCServer? = null
@JvmStatic
@@ -64,8 +62,7 @@
vertx,
port = 0,
methodHandler = {
- handler.get().handle(it)
- JSONRPCResponse(StringOrLong(3), "")
+ handler.get()(it)
},
coroutineContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
)
@@ -119,4 +116,21 @@
}
}
}
+
+ @Test
+ fun testGetBlockByNumber(@VertxInstance vertx: Vertx) {
+ JSONRPCClient(vertx, "http://localhost:" + server!!.port()).use {
+ val sent = CompletableDeferred<Any>()
+ handler.set { request ->
+ sent.complete(request.params.get(0))
+ JSONRPCResponse(request.id, mapOf(Pair("foo", "bar")))
+ }
+
+ runBlocking {
+ val block = it.getBlockByBlockNumber(32, true)
+ assertEquals(block["foo"], "bar")
+ sent.await()
+ }
+ }
+ }
}