From 1d738800147d07c1bbece5b7b62944b1c46d0e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Kope=C4=87?= Date: Tue, 20 Oct 2020 12:27:40 +0200 Subject: [PATCH 1/2] [ETCM-139] Report precise information on rpc when account data is missing --- .../CheckpointingJsonMethodsImplicits.scala | 2 +- .../jsonrpc/EthJsonMethodsImplicits.scala | 2 +- .../io/iohk/ethereum/jsonrpc/EthService.scala | 76 +++++++++---------- .../jsonrpc/IeleJsonMethodsImplicits.scala | 2 +- .../jsonrpc/JsonMethodsImplicits.scala | 6 +- .../ethereum/jsonrpc/JsonRpcController.scala | 10 ++- .../iohk/ethereum/jsonrpc/JsonRpcError.scala | 27 ++++++- .../ethereum/jsonrpc/PersonalService.scala | 4 +- .../jsonrpc/QAJsonMethodsImplicits.scala | 2 +- .../io/iohk/ethereum/jsonrpc/QAService.scala | 2 +- .../jsonrpc/TestJsonMethodsImplicits.scala | 2 +- .../server/http/JsonRpcHttpServer.scala | 2 +- .../jsonrpc/CheckpointingJRCSpec.scala | 2 +- .../ethereum/jsonrpc/EthServiceSpec.scala | 13 ++++ .../jsonrpc/JsonRpcControllerEthSpec.scala | 20 +++++ .../jsonrpc/JsonRpcControllerSpec.scala | 4 +- .../jsonrpc/PersonalServiceSpec.scala | 2 +- .../iohk/ethereum/jsonrpc/QAServiceSpec.scala | 2 +- .../io/iohk/ethereum/jsonrpc/QaJRCSpec.scala | 12 +-- 19 files changed, 123 insertions(+), 69 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala index bf470d14bb..bd69f1faef 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala @@ -4,7 +4,7 @@ import akka.util.ByteString import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.jsonrpc.CheckpointingService._ import io.iohk.ethereum.jsonrpc.JsonRpcController.Codec -import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.JsonSerializers.QuantitiesSerializer import org.json4s.JsonAST._ import org.json4s.{Extraction, JsonAST} diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala index 2c5a82ce48..e45a8577b2 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala @@ -4,7 +4,7 @@ import akka.util.ByteString import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonDecoder, JsonEncoder} -import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.PersonalService.{SendTransactionRequest, SendTransactionResponse, SignRequest} import org.json4s.{Extraction, JsonAST} import org.json4s.JsonAST.{JArray, JBool, JString, JValue, _} diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala index e658d0749c..8907d3d474 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala @@ -19,6 +19,7 @@ import io.iohk.ethereum.jsonrpc.FilterManager.{FilterChanges, FilterLogs, LogFil import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonRpcConfig import io.iohk.ethereum.keystore.KeyStore import io.iohk.ethereum.ledger.{InMemoryWorldStateProxy, Ledger, StxLedger} +import io.iohk.ethereum.mpt.MerklePatriciaTrie.MissingNodeException import io.iohk.ethereum.ommers.OmmersPool import io.iohk.ethereum.rlp import io.iohk.ethereum.rlp.RLPImplicitConversions._ @@ -234,7 +235,7 @@ class EthService( private[this] def ifEthash[Req, Res](req: Req)(f: Req => Res): ServiceResponse[Res] = { @inline def F[A](x: A): Future[A] = Future.successful(x) - consensus.ifEthash[ServiceResponse[Res]](_ => F(Right(f(req))))(F(Left(JsonRpcErrors.ConsensusIsNotEthash))) + consensus.ifEthash[ServiceResponse[Res]](_ => F(Right(f(req))))(F(Left(JsonRpcError.ConsensusIsNotEthash))) } def protocolVersion(req: ProtocolVersionRequest): ServiceResponse[ProtocolVersionResponse] = @@ -565,7 +566,7 @@ class EthService( ) } response - })(Future.successful(Left(JsonRpcErrors.ConsensusIsNotEthash))) + })(Future.successful(Left(JsonRpcError.ConsensusIsNotEthash))) private def getOmmersFromPool(parentBlockHash: ByteString): Future[OmmersPool.Ommers] = consensus.ifEthash(ethash => { @@ -610,7 +611,7 @@ class EthService( Right(SubmitWorkResponse(false)) } } - })(Future.successful(Left(JsonRpcErrors.ConsensusIsNotEthash))) + })(Future.successful(Left(JsonRpcError.ConsensusIsNotEthash))) /** * Implements the eth_syncing method that returns syncing information if the node is syncing. @@ -649,10 +650,10 @@ class EthService( pendingTransactionsManager ! PendingTransactionsManager.AddOrOverrideTransaction(signedTransaction) Future.successful(Right(SendRawTransactionResponse(signedTransaction.hash))) } else { - Future.successful(Left(JsonRpcErrors.InvalidRequest)) + Future.successful(Left(JsonRpcError.InvalidRequest)) } case Failure(_) => - Future.successful(Left(JsonRpcErrors.InvalidRequest)) + Future.successful(Left(JsonRpcError.InvalidRequest)) } } @@ -669,7 +670,7 @@ class EthService( val dataEither = (tx.function, tx.contractCode) match { case (Some(function), None) => Right(rlp.encode(RLPList(function, args))) case (None, Some(contractCode)) => Right(rlp.encode(RLPList(contractCode, args))) - case _ => Left(JsonRpcErrors.InvalidParams("Iele transaction should contain either functionName or contractCode")) + case _ => Left(JsonRpcError.InvalidParams("Iele transaction should contain either functionName or contractCode")) } dataEither match { @@ -722,7 +723,7 @@ class EthService( Right(GetUncleCountByBlockHashResponse(blockBody.uncleNodesList.size)) case None => Left( - JsonRpcErrors.InvalidParams(s"Block with hash ${Hex.toHexString(req.blockHash.toArray[Byte])} not found") + JsonRpcError.InvalidParams(s"Block with hash ${Hex.toHexString(req.blockHash.toArray[Byte])} not found") ) } } @@ -786,31 +787,22 @@ class EthService( .flatMap(_ => Right(None)) } - def getBalance(req: GetBalanceRequest): ServiceResponse[GetBalanceResponse] = { - Future { - withAccount(req.address, req.block) { account => - GetBalanceResponse(account.balance) - } + def getBalance(req: GetBalanceRequest): ServiceResponse[GetBalanceResponse] = + withAccount(req.address, req.block) { account => + GetBalanceResponse(account.balance) } - } - def getStorageAt(req: GetStorageAtRequest): ServiceResponse[GetStorageAtResponse] = { - Future { - withAccount(req.address, req.block) { account => - GetStorageAtResponse( - blockchain.getAccountStorageAt(account.storageRoot, req.position, blockchainConfig.ethCompatibleStorage) - ) - } + def getStorageAt(req: GetStorageAtRequest): ServiceResponse[GetStorageAtResponse] = + withAccount(req.address, req.block) { account => + GetStorageAtResponse( + blockchain.getAccountStorageAt(account.storageRoot, req.position, blockchainConfig.ethCompatibleStorage) + ) } - } - def getTransactionCount(req: GetTransactionCountRequest): ServiceResponse[GetTransactionCountResponse] = { - Future { - withAccount(req.address, req.block) { account => - GetTransactionCountResponse(account.nonce) - } + def getTransactionCount(req: GetTransactionCountRequest): ServiceResponse[GetTransactionCountResponse] = + withAccount(req.address, req.block) { account => + GetTransactionCountResponse(account.nonce) } - } def newFilter(req: NewFilterRequest): ServiceResponse[NewFilterResponse] = { implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) @@ -875,20 +867,25 @@ class EthService( } } - private def withAccount[T](address: Address, blockParam: BlockParam)(f: Account => T): Either[JsonRpcError, T] = { - resolveBlock(blockParam).map { case ResolvedBlock(block, _) => - f( - blockchain.getAccount(address, block.header.number).getOrElse(Account.empty(blockchainConfig.accountStartNonce)) - ) + private def withAccount[T](address: Address, blockParam: BlockParam)(makeResponse: Account => T): ServiceResponse[T] = + Future { + resolveBlock(blockParam) + .map { case ResolvedBlock(block, _) => + blockchain + .getAccount(address, block.header.number) + .getOrElse(Account.empty(blockchainConfig.accountStartNonce)) + } + .map(makeResponse) + }.recover { case _: MissingNodeException => + Left(JsonRpcError.NodeNotFound) } - } private def resolveBlock(blockParam: BlockParam): Either[JsonRpcError, ResolvedBlock] = { def getBlock(number: BigInt): Either[JsonRpcError, Block] = { blockchain .getBlockByNumber(number) .map(Right.apply) - .getOrElse(Left(JsonRpcErrors.InvalidParams(s"Block $number not found"))) + .getOrElse(Left(JsonRpcError.InvalidParams(s"Block $number not found"))) } blockParam match { @@ -941,7 +938,7 @@ class EthService( if (numBlocksToSearch > jsonRpcConfig.accountTransactionsMaxBlocks) { Future.successful( Left( - JsonRpcErrors.InvalidParams( + JsonRpcError.InvalidParams( s"""Maximum number of blocks to search is ${jsonRpcConfig.accountTransactionsMaxBlocks}, requested: $numBlocksToSearch. |See: 'network.rpc.account-transactions-max-blocks' config.""".stripMargin ) @@ -975,13 +972,10 @@ class EthService( } } - def getStorageRoot(req: GetStorageRootRequest): ServiceResponse[GetStorageRootResponse] = { - Future { - withAccount(req.address, req.block) { account => - GetStorageRootResponse(account.storageRoot) - } + def getStorageRoot(req: GetStorageRootRequest): ServiceResponse[GetStorageRootResponse] = + withAccount(req.address, req.block) { account => + GetStorageRootResponse(account.storageRoot) } - } /** * Returns the transactions that are pending in the transaction pool and have a from address that is one of the accounts this node manages. diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala index 4fd8054fbb..926a420b08 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala @@ -3,7 +3,7 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.JsonRpcController.{JsonDecoder, JsonEncoder} -import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.PersonalService.{InvalidAddress, SendIeleTransactionRequest} import org.json4s.JsonAST.{JArray, JObject, JString, JValue} diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala index d335f0837b..16ad83f41b 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala @@ -8,7 +8,7 @@ import io.iohk.ethereum.domain.Address import io.iohk.ethereum.jsonrpc.EthService.BlockParam import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonDecoder, JsonEncoder} -import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.JsonSerializers.{ AddressJsonSerializer, OptionNoneToJNullSerializer, @@ -141,7 +141,7 @@ trait JsonMethodsImplicits { extractQuantity(other) .map(BlockParam.WithNumber) .left - .map(_ => JsonRpcErrors.InvalidParams(s"Invalid default block param: $other")) + .map(_ => JsonRpcError.InvalidParams(s"Invalid default block param: $other")) } } @@ -152,7 +152,7 @@ trait JsonMethodsImplicits { object JsonMethodsImplicits extends JsonMethodsImplicits { - import JsonRpcErrors._ + import JsonRpcError._ implicit val web3_sha3 = new JsonDecoder[Sha3Request] with JsonEncoder[Sha3Response] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, Sha3Request] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala index 3416009656..cafb1fdef2 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala @@ -10,7 +10,7 @@ import org.json4s.JsonAST.{JArray, JValue} import org.json4s.JsonDSL._ import com.typesafe.config.{Config => TypesafeConfig} import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} -import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.QAService.{ GenerateCheckpointRequest, GenerateCheckpointResponse, @@ -47,6 +47,12 @@ object JsonRpcController { trait JsonEncoder[T] { def encodeJson(t: T): JValue } + object JsonEncoder { + def apply[T](implicit encoder: JsonEncoder[T]): JsonEncoder[T] = encoder + + implicit def listEncoder[T](implicit itemEncoder: JsonEncoder[T]): JsonEncoder[List[T]] = list => + JArray(list.map(itemEncoder.encodeJson)) + } trait Codec[Req, Res] extends JsonDecoder[Req] with JsonEncoder[Res] object Codec { @@ -126,7 +132,7 @@ class JsonRpcController( import TestJsonMethodsImplicits._ import IeleJsonMethodsImplicits._ import JsonMethodsImplicits._ - import JsonRpcErrors._ + import JsonRpcError._ import DebugJsonMethodsImplicits._ import QAJsonMethodsImplicits._ import CheckpointingJsonMethodsImplicits._ diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala index a0f1ee38f9..5551353b18 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala @@ -1,13 +1,17 @@ package io.iohk.ethereum.jsonrpc import io.iohk.ethereum.consensus.Protocol -import org.json4s.JsonAST.JValue +import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonEncoder +import org.json4s.{JInt, JString, JObject, JValue} case class JsonRpcError(code: Int, message: String, data: Option[JValue]) // scalastyle:off magic.number // scalastyle:off public.methods.have.type -object JsonRpcErrors { +object JsonRpcError { + def apply[T: JsonEncoder](code: Int, message: String, data: T): JsonRpcError = + JsonRpcError(code, message, Some(JsonEncoder[T].encodeJson(data))) + val ParseError = JsonRpcError(-32700, "An error occurred on the server while parsing the JSON text", None) val InvalidRequest = JsonRpcError(-32600, "The JSON sent is not a valid Request object", None) val MethodNotFound = JsonRpcError(-32601, "The method does not exist / is not available", None) @@ -16,9 +20,26 @@ object JsonRpcErrors { def LogicError(msg: String) = JsonRpcError(-32000, msg, None) val AccountLocked = LogicError("account is locked or unknown") - // We use the recommendation from https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal + // We use the recommendation from https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal // // Note Error Code "2", "Action not allowed" could be a candidate here, but the description they provide // probably does not match this use-case. final val ConsensusIsNotEthash = JsonRpcError(200, s"The consensus algorithm is not ${Protocol.Names.Ethash}", None) + + def executionError(reasons: List[EthCustomError]): JsonRpcError = JsonRpcError(3, "Execution error", reasons) + val NodeNotFound = executionError(List(EthCustomError.DoesntExist("State node"))) + + // Custom errors based on proposal https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal + sealed abstract class EthCustomError private (val code: Int, val message: String) + object EthCustomError { + implicit val ethCustomErrorEncoder: JsonEncoder[EthCustomError] = err => + JObject("code" -> JInt(err.code), "message" -> JString(err.message)) + + case class DoesntExist(what: String) extends EthCustomError(100, s"${what} doesn't exist") + case object RequiresEther extends EthCustomError(101, "Requires ether") + case object GasTooLow extends EthCustomError(102, "Gas too low") + case object GasLimitExceeded extends EthCustomError(103, "Gas limit exceeded") + case object Rejected extends EthCustomError(104, "Rejected") + case object EtherTooLow extends EthCustomError(105, "Ether too low") + } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index a449f23090..447f7ae51c 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -11,7 +11,7 @@ import io.iohk.ethereum.db.storage.AppStateStorage import io.iohk.ethereum.domain.{Account, Address, Blockchain} import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.keystore.{KeyStore, Wallet} -import io.iohk.ethereum.jsonrpc.JsonRpcErrors._ +import io.iohk.ethereum.jsonrpc.JsonRpcError._ import io.iohk.ethereum.rlp.RLPList import io.iohk.ethereum.transactions.PendingTransactionsManager import io.iohk.ethereum.transactions.PendingTransactionsManager.{AddOrOverrideTransaction, PendingTransactionsResponse} @@ -178,7 +178,7 @@ class PersonalService( val dataEither = (tx.function, tx.contractCode) match { case (Some(function), None) => Right(rlp.encode(RLPList(function, args))) case (None, Some(contractCode)) => Right(rlp.encode(RLPList(contractCode, args))) - case _ => Left(JsonRpcErrors.InvalidParams("Iele transaction should contain either functionName or contractCode")) + case _ => Left(JsonRpcError.InvalidParams("Iele transaction should contain either functionName or contractCode")) } dataEither match { diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala index e4aa77e4b4..8df1ce4c23 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala @@ -3,7 +3,7 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonEncoder} -import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.QAService._ import org.json4s.Extraction import org.json4s.JsonAST._ diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala index abc538c6dc..65f00f404a 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala @@ -39,7 +39,7 @@ class QAService( .map(_ |> (MineBlocksResponse(_)) |> (_.asRight)) .recover { case t: Throwable => log.info("Unable to mine requested blocks", t) - Left(JsonRpcErrors.InternalError) + Left(JsonRpcError.InternalError) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestJsonMethodsImplicits.scala index ca422878c5..1329c6f39c 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestJsonMethodsImplicits.scala @@ -2,7 +2,7 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString import io.iohk.ethereum.jsonrpc.JsonRpcController.{JsonDecoder, JsonEncoder} -import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.TestService._ import org.json4s.JsonAST._ import org.json4s.JsonDSL._ diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala index 6b1a65192a..21fbed7422 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala @@ -37,7 +37,7 @@ trait JsonRpcHttpServer extends Json4sSupport { .newBuilder() .handle { case _: MalformedRequestContentRejection => - complete((StatusCodes.BadRequest, JsonRpcResponse("2.0", None, Some(JsonRpcErrors.ParseError), JInt(0)))) + complete((StatusCodes.BadRequest, JsonRpcResponse("2.0", None, Some(JsonRpcError.ParseError), JInt(0)))) case _: CorsRejection => complete(StatusCodes.Forbidden) } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingJRCSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingJRCSpec.scala index fab2ec379d..d14ff64f0a 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingJRCSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingJRCSpec.scala @@ -4,7 +4,7 @@ import io.iohk.ethereum.checkpointing.CheckpointingTestHelpers import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.jsonrpc.CheckpointingService._ import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonRpcConfig -import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.nodebuilder.SecureRandomBuilder import io.iohk.ethereum.utils.{ByteStringUtils, Config} import io.iohk.ethereum.{Fixtures, NormalPatience, crypto} diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index e969352a30..d0dbcec11a 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -899,6 +899,19 @@ class EthServiceSpec response.futureValue shouldEqual Right(GetBalanceResponse(123)) } + it should "handle MissingNodeException when getting balance" in new TestSetup { + val address = Address(ByteString(Hex.decode("abbb6bebfa05aa13e908eaa492bd7a8343760477"))) + + val newBlockHeader = blockToRequest.header + val newblock = blockToRequest.copy(header = newBlockHeader) + blockchain.storeBlock(newblock).commit() + blockchain.saveBestKnownBlocks(newblock.header.number) + + val response = ethService.getBalance(GetBalanceRequest(address, BlockParam.Latest)) + + response.futureValue shouldEqual Left(JsonRpcError.NodeNotFound) + } + it should "handle getStorageAt request" in new TestSetup { import io.iohk.ethereum.rlp.UInt256RLPImplicits._ diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index 0b603a6ea0..ce16e60846 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -489,6 +489,26 @@ class JsonRpcControllerEthSpec response should haveStringResult("0x11") } + it should "return error with custom error in data in eth_balance" in new JsonRpcControllerFixture { + val mockEthService = mock[EthService] + override val jsonRpcController = newJsonRpcController(mockEthService) + + (mockEthService.getBalance _) + .expects(*) + .returning(Future.successful(Left(JsonRpcError.NodeNotFound))) + + val request: JsonRpcRequest = newJsonRpcRequest( + "eth_getBalance", + List( + JString(s"0x7B9Bc474667Db2fFE5b08d000F1Acc285B2Ae47D"), + JString(s"latest") + ) + ) + + val response = jsonRpcController.handleRequest(request).futureValue + response should haveError(JsonRpcError.NodeNotFound) + } + it should "eth_getStorageAt" in new JsonRpcControllerFixture { val mockEthService = mock[EthService] override val jsonRpcController = newJsonRpcController(mockEthService) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala index 8869f1c5ba..5514fd3c85 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala @@ -55,7 +55,7 @@ class JsonRpcControllerSpec val response = jsonRpcController.handleRequest(rpcRequest).futureValue - response should haveError(JsonRpcErrors.InvalidParams("Invalid method parameters")) + response should haveError(JsonRpcError.InvalidParams("Invalid method parameters")) } it should "handle clientVersion request" in new JsonRpcControllerFixture { @@ -108,7 +108,7 @@ class JsonRpcControllerSpec val ethRpcRequest = newJsonRpcRequest("eth_protocolVersion") val ethResponse = jsonRpcController.handleRequest(ethRpcRequest).futureValue - ethResponse should haveError(JsonRpcErrors.MethodNotFound) + ethResponse should haveError(JsonRpcError.MethodNotFound) val web3RpcRequest = newJsonRpcRequest("web3_clientVersion") val web3Response = jsonRpcController.handleRequest(web3RpcRequest).futureValue diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala index a673ea0387..a6c17a2591 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala @@ -9,7 +9,7 @@ import com.miguno.akka.testing.VirtualTime import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.db.storage.AppStateStorage import io.iohk.ethereum.domain.{UInt256, _} -import io.iohk.ethereum.jsonrpc.JsonRpcErrors._ +import io.iohk.ethereum.jsonrpc.JsonRpcError._ import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.keystore.KeyStore.{DecryptionFailed, IOError} import io.iohk.ethereum.keystore.{KeyStore, Wallet} diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala index 43bd8d363a..8f299187f5 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala @@ -44,7 +44,7 @@ class QAServiceSpec .returning(Future.failed(new ClassCastException("error"))) .atLeastOnce() - qaService.mineBlocks(mineBlocksReq).map(_ shouldBe Left(JsonRpcErrors.InternalError)) + qaService.mineBlocks(mineBlocksReq).map(_ shouldBe Left(JsonRpcError.InternalError)) } it should "generate checkpoint for block with given blockHash and send it to sync" in customTestCaseF( diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala index 46a0478dd2..2ad2e9a12d 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala @@ -75,7 +75,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).futureValue - response should haveError(JsonRpcErrors.InternalError) + response should haveError(JsonRpcError.InternalError) } } @@ -134,7 +134,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP val response: JsonRpcResponse = jsonRpcController.handleRequest(req).futureValue - response should haveError(JsonRpcErrors.InvalidParams()) + response should haveError(JsonRpcError.InvalidParams()) } "private keys are not valid" in new TestSetup { @@ -154,7 +154,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP jsonRpcController.handleRequest(req).futureValue response should haveError( - JsonRpcErrors.InvalidParams("Unable to parse private key, expected byte data but got: JInt(1)") + JsonRpcError.InvalidParams("Unable to parse private key, expected byte data but got: JInt(1)") ) } @@ -174,7 +174,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP val response: JsonRpcResponse = jsonRpcController.handleRequest(req).futureValue - response should haveError(JsonRpcErrors.InvalidParams()) + response should haveError(JsonRpcError.InvalidParams()) } } @@ -187,7 +187,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP val response: JsonRpcResponse = jsonRpcController.handleRequest(generateCheckpointRpcRequest).futureValue - response should haveError(JsonRpcErrors.InternalError) + response should haveError(JsonRpcError.InternalError) } } @@ -220,7 +220,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP val response: JsonRpcResponse = jsonRpcController.handleRequest(getFederationMembersInfoRpcRequest).futureValue - response should haveError(JsonRpcErrors.InternalError) + response should haveError(JsonRpcError.InternalError) } } } From 75c74ceb1c7e4c280f9fec1f8a02df8162cd1f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Kope=C4=87?= Date: Tue, 20 Oct 2020 16:17:33 +0200 Subject: [PATCH 2/2] [ETCM-139] Fix json rpc error serialization, json4s - thank you for being so unhelpful there --- build.sbt | 10 +- .../CheckpointingJsonMethodsImplicits.scala | 12 +-- .../jsonrpc/DebugJsonMethodsImplicits.scala | 8 +- .../jsonrpc/EthJsonMethodsImplicits.scala | 97 ++++++++++--------- .../jsonrpc/IeleJsonMethodsImplicits.scala | 6 +- .../jsonrpc/JsonMethodsImplicits.scala | 44 ++++----- .../ethereum/jsonrpc/JsonRpcController.scala | 67 +++---------- .../iohk/ethereum/jsonrpc/JsonRpcError.scala | 10 +- .../jsonrpc/QAJsonMethodsImplicits.scala | 19 ++-- .../jsonrpc/TestJsonMethodsImplicits.scala | 14 +-- .../jsonrpc/serialization/JsonEncoder.scala | 25 +++++ .../serialization/JsonMethodCodec.scala | 14 +++ .../serialization/JsonMethodDecoder.scala | 18 ++++ .../{ => serialization}/JsonSerializers.scala | 16 ++- .../server/http/JsonRpcHttpServer.scala | 10 +- .../jsonrpc/server/ipc/JsonRpcIpcServer.scala | 5 +- .../jsonrpc/JsonRpcControllerEthSpec.scala | 2 +- .../JsonRpcControllerEthTransactionSpec.scala | 2 +- .../JsonRpcControllerPersonalSpec.scala | 2 +- .../jsonrpc/JsonRpcControllerSpec.scala | 2 +- 20 files changed, 213 insertions(+), 170 deletions(-) create mode 100644 src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonEncoder.scala create mode 100644 src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonMethodCodec.scala create mode 100644 src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonMethodDecoder.scala rename src/main/scala/io/iohk/ethereum/jsonrpc/{ => serialization}/JsonSerializers.scala (67%) diff --git a/build.sbt b/build.sbt index 045c0e099d..3247fd4bc4 100644 --- a/build.sbt +++ b/build.sbt @@ -68,8 +68,12 @@ val root = { libraryDependencies ++= dep ) .settings(executableScriptName := name.value) - .settings(inConfig(Integration)(Defaults.testSettings - ++ org.scalafmt.sbt.ScalafmtPlugin.scalafmtConfigSettings :+ (Test / parallelExecution := false)): _*) + .settings( + inConfig(Integration)( + Defaults.testSettings + ++ org.scalafmt.sbt.ScalafmtPlugin.scalafmtConfigSettings :+ (Test / parallelExecution := false) + ): _* + ) .settings(inConfig(Benchmark)(Defaults.testSettings :+ (Test / parallelExecution := false)): _*) .settings(inConfig(Evm)(Defaults.testSettings :+ (Test / parallelExecution := false)): _*) .settings(inConfig(Ets)(Defaults.testSettings :+ (Test / parallelExecution := false)): _*) @@ -161,7 +165,7 @@ addCommandAlias( |;scalafmtAll |;scalastyle |;test:scalastyle - |;test + |;testQuick |;it:test |""".stripMargin ) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala index bd69f1faef..376ee5493b 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala @@ -3,16 +3,16 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.jsonrpc.CheckpointingService._ -import io.iohk.ethereum.jsonrpc.JsonRpcController.Codec import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams -import io.iohk.ethereum.jsonrpc.JsonSerializers.QuantitiesSerializer +import io.iohk.ethereum.jsonrpc.serialization.JsonMethodCodec +import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.QuantitiesSerializer import org.json4s.JsonAST._ import org.json4s.{Extraction, JsonAST} object CheckpointingJsonMethodsImplicits extends JsonMethodsImplicits { - implicit val checkpointing_getLatestBlock: Codec[GetLatestBlockRequest, GetLatestBlockResponse] = - new Codec[GetLatestBlockRequest, GetLatestBlockResponse] { + implicit val checkpointing_getLatestBlock: JsonMethodCodec[GetLatestBlockRequest, GetLatestBlockResponse] = + new JsonMethodCodec[GetLatestBlockRequest, GetLatestBlockResponse] { override def decodeJson( params: Option[JsonAST.JArray] ): Either[JsonRpcError, GetLatestBlockRequest] = @@ -30,8 +30,8 @@ object CheckpointingJsonMethodsImplicits extends JsonMethodsImplicits { Extraction.decompose(resp)(formats - QuantitiesSerializer) } - implicit val checkpointing_pushCheckpoint: Codec[PushCheckpointRequest, PushCheckpointResponse] = - new Codec[PushCheckpointRequest, PushCheckpointResponse] { + implicit val checkpointing_pushCheckpoint: JsonMethodCodec[PushCheckpointRequest, PushCheckpointResponse] = + new JsonMethodCodec[PushCheckpointRequest, PushCheckpointResponse] { override def decodeJson( params: Option[JsonAST.JArray] ): Either[JsonRpcError, PushCheckpointRequest] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugJsonMethodsImplicits.scala index 5380935f94..ca4714c008 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugJsonMethodsImplicits.scala @@ -1,14 +1,14 @@ package io.iohk.ethereum.jsonrpc import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} -import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonEncoder} -import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder +import io.iohk.ethereum.jsonrpc.serialization.JsonMethodDecoder.NoParamsMethodDecoder +import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodCodec} import org.json4s.JsonAST.{JArray, JString, JValue} object DebugJsonMethodsImplicits extends JsonMethodsImplicits { - implicit val debug_listPeersInfo: Codec[ListPeersInfoRequest, ListPeersInfoResponse] = - new NoParamsDecoder(ListPeersInfoRequest()) with JsonEncoder[ListPeersInfoResponse] { + implicit val debug_listPeersInfo: JsonMethodCodec[ListPeersInfoRequest, ListPeersInfoResponse] = + new NoParamsMethodDecoder(ListPeersInfoRequest()) with JsonEncoder[ListPeersInfoResponse] { def encodeJson(t: ListPeersInfoResponse): JValue = JArray(t.peers.map(a => JString(a.toString))) } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala index e45a8577b2..7abe35c10a 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala @@ -2,32 +2,33 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString import io.iohk.ethereum.jsonrpc.EthService._ -import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder -import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonDecoder, JsonEncoder} import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.PersonalService.{SendTransactionRequest, SendTransactionResponse, SignRequest} -import org.json4s.{Extraction, JsonAST} +import io.iohk.ethereum.jsonrpc.serialization.JsonMethodDecoder.NoParamsMethodDecoder +import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodCodec, JsonMethodDecoder} import org.json4s.JsonAST.{JArray, JBool, JString, JValue, _} import org.json4s.JsonDSL._ +import org.json4s.{Extraction, JsonAST} // scalastyle:off number.of.methods object EthJsonMethodsImplicits extends JsonMethodsImplicits { - implicit val eth_protocolVersion = new NoParamsDecoder(ProtocolVersionRequest()) + implicit val eth_protocolVersion = new NoParamsMethodDecoder(ProtocolVersionRequest()) with JsonEncoder[ProtocolVersionResponse] { def encodeJson(t: ProtocolVersionResponse): JValue = t.value } - implicit val eth_chainId = new NoParamsDecoder(ChainIdRequest()) with JsonEncoder[ChainIdResponse] { + implicit val eth_chainId = new NoParamsMethodDecoder(ChainIdRequest()) with JsonEncoder[ChainIdResponse] { def encodeJson(t: ChainIdResponse) = encodeAsHex(t.value) } - implicit val eth_blockNumber = new NoParamsDecoder(BestBlockNumberRequest()) + implicit val eth_blockNumber = new NoParamsMethodDecoder(BestBlockNumberRequest()) with JsonEncoder[BestBlockNumberResponse] { override def encodeJson(t: BestBlockNumberResponse): JValue = Extraction.decompose(t.bestBlockNumber) } - implicit val eth_submitHashrate = new JsonDecoder[SubmitHashRateRequest] with JsonEncoder[SubmitHashRateResponse] { + implicit val eth_submitHashrate = new JsonMethodDecoder[SubmitHashRateRequest] + with JsonEncoder[SubmitHashRateResponse] { override def decodeJson(params: Option[JsonAST.JArray]): Either[JsonRpcError, SubmitHashRateRequest] = params match { case Some(JArray(hashRate :: JString(id) :: Nil)) => @@ -43,25 +44,25 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { override def encodeJson(t: SubmitHashRateResponse): JValue = JBool(t.success) } - implicit val eth_gasPrice = new NoParamsDecoder(GetGasPriceRequest()) with JsonEncoder[GetGasPriceResponse] { + implicit val eth_gasPrice = new NoParamsMethodDecoder(GetGasPriceRequest()) with JsonEncoder[GetGasPriceResponse] { override def encodeJson(t: GetGasPriceResponse): JValue = encodeAsHex(t.price) } - implicit val eth_mining = new NoParamsDecoder(GetMiningRequest()) with JsonEncoder[GetMiningResponse] { + implicit val eth_mining = new NoParamsMethodDecoder(GetMiningRequest()) with JsonEncoder[GetMiningResponse] { override def encodeJson(t: GetMiningResponse): JValue = JBool(t.isMining) } - implicit val eth_hashrate = new NoParamsDecoder(GetHashRateRequest()) with JsonEncoder[GetHashRateResponse] { + implicit val eth_hashrate = new NoParamsMethodDecoder(GetHashRateRequest()) with JsonEncoder[GetHashRateResponse] { override def encodeJson(t: GetHashRateResponse): JsonAST.JValue = encodeAsHex(t.hashRate) } - implicit val eth_coinbase = new NoParamsDecoder(GetCoinbaseRequest()) with JsonEncoder[GetCoinbaseResponse] { + implicit val eth_coinbase = new NoParamsMethodDecoder(GetCoinbaseRequest()) with JsonEncoder[GetCoinbaseResponse] { override def encodeJson(t: GetCoinbaseResponse): JsonAST.JValue = { encodeAsHex(t.address.bytes) } } - implicit val eth_getWork = new NoParamsDecoder(GetWorkRequest()) with JsonEncoder[GetWorkResponse] { + implicit val eth_getWork = new NoParamsMethodDecoder(GetWorkRequest()) with JsonEncoder[GetWorkResponse] { override def encodeJson(t: GetWorkResponse): JsonAST.JValue = { val powHeaderHash = encodeAsHex(t.powHeaderHash) val dagSeed = encodeAsHex(t.dagSeed) @@ -70,7 +71,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } } - implicit val eth_submitWork = new JsonDecoder[SubmitWorkRequest] with JsonEncoder[SubmitWorkResponse] { + implicit val eth_submitWork = new JsonMethodDecoder[SubmitWorkRequest] with JsonEncoder[SubmitWorkResponse] { override def decodeJson(params: Option[JsonAST.JArray]): Either[JsonRpcError, SubmitWorkRequest] = params match { case Some(JArray(JString(nonce) :: JString(powHeaderHash) :: JString(mixHash) :: Nil)) => for { @@ -85,7 +86,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { override def encodeJson(t: SubmitWorkResponse): JValue = JBool(t.success) } - implicit val eth_getBlockTransactionCountByHash = new JsonDecoder[TxCountByBlockHashRequest] + implicit val eth_getBlockTransactionCountByHash = new JsonMethodDecoder[TxCountByBlockHashRequest] with JsonEncoder[TxCountByBlockHashResponse] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, TxCountByBlockHashRequest] = params match { @@ -98,7 +99,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { Extraction.decompose(t.txsQuantity.map(BigInt(_))) } - implicit val eth_getBlockByHash = new JsonDecoder[BlockByBlockHashRequest] + implicit val eth_getBlockByHash = new JsonMethodDecoder[BlockByBlockHashRequest] with JsonEncoder[BlockByBlockHashResponse] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, BlockByBlockHashRequest] = { params match { @@ -112,7 +113,8 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { Extraction.decompose(t.blockResponse) } - implicit val eth_getBlockByNumber = new JsonDecoder[BlockByNumberRequest] with JsonEncoder[BlockByNumberResponse] { + implicit val eth_getBlockByNumber = new JsonMethodDecoder[BlockByNumberRequest] + with JsonEncoder[BlockByNumberResponse] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, BlockByNumberRequest] = { params match { case Some(JArray(blockStr :: JBool(fullTxs) :: Nil)) => @@ -125,7 +127,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { Extraction.decompose(t.blockResponse) } - implicit val eth_pendingTransactions = new NoParamsDecoder(EthPendingTransactionsRequest()) + implicit val eth_pendingTransactions = new NoParamsMethodDecoder(EthPendingTransactionsRequest()) with JsonEncoder[EthPendingTransactionsResponse] { override def encodeJson(t: EthPendingTransactionsResponse): JValue = @@ -135,7 +137,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } implicit val eth_getTransactionByHash = - new JsonDecoder[GetTransactionByHashRequest] with JsonEncoder[GetTransactionByHashResponse] { + new JsonMethodDecoder[GetTransactionByHashRequest] with JsonEncoder[GetTransactionByHashResponse] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetTransactionByHashRequest] = params match { case Some(JArray(JString(txHash) :: Nil)) => @@ -150,7 +152,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } implicit val eth_getTransactionReceipt = - new JsonDecoder[GetTransactionReceiptRequest] with JsonEncoder[GetTransactionReceiptResponse] { + new JsonMethodDecoder[GetTransactionReceiptRequest] with JsonEncoder[GetTransactionReceiptResponse] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetTransactionReceiptRequest] = params match { case Some(JArray(JString(txHash) :: Nil)) => @@ -171,7 +173,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } implicit val GetTransactionByBlockHashAndIndexRequestDecoder = - new JsonDecoder[GetTransactionByBlockHashAndIndexRequest] { + new JsonMethodDecoder[GetTransactionByBlockHashAndIndexRequest] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetTransactionByBlockHashAndIndexRequest] = params match { case Some(JArray(JString(blockHash) :: transactionIndex :: Nil)) => @@ -190,7 +192,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } implicit val GetTransactionByBlockNumberAndIndexRequestDecoder = - new JsonDecoder[GetTransactionByBlockNumberAndIndexRequest] { + new JsonMethodDecoder[GetTransactionByBlockNumberAndIndexRequest] { override def decodeJson( params: Option[JArray] ): Either[JsonRpcError, GetTransactionByBlockNumberAndIndexRequest] = @@ -210,7 +212,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { t.transactionResponse.map(RawTransactionCodec.asRawTransaction _ andThen encodeAsHex) } - implicit val eth_getUncleByBlockHashAndIndex = new JsonDecoder[UncleByBlockHashAndIndexRequest] + implicit val eth_getUncleByBlockHashAndIndex = new JsonMethodDecoder[UncleByBlockHashAndIndexRequest] with JsonEncoder[UncleByBlockHashAndIndexResponse] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, UncleByBlockHashAndIndexRequest] = params match { @@ -231,7 +233,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } } - implicit val eth_getUncleByBlockNumberAndIndex = new JsonDecoder[UncleByBlockNumberAndIndexRequest] + implicit val eth_getUncleByBlockNumberAndIndex = new JsonMethodDecoder[UncleByBlockNumberAndIndexRequest] with JsonEncoder[UncleByBlockNumberAndIndexResponse] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, UncleByBlockNumberAndIndexRequest] = params match { @@ -252,14 +254,14 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } } - implicit val eth_syncing = new NoParamsDecoder(SyncingRequest()) with JsonEncoder[SyncingResponse] { + implicit val eth_syncing = new NoParamsMethodDecoder(SyncingRequest()) with JsonEncoder[SyncingResponse] { def encodeJson(t: SyncingResponse): JValue = t.syncStatus match { case Some(syncStatus) => Extraction.decompose(syncStatus) case None => false } } - implicit val eth_sendRawTransaction = new JsonDecoder[SendRawTransactionRequest] + implicit val eth_sendRawTransaction = new JsonMethodDecoder[SendRawTransactionRequest] with JsonEncoder[SendRawTransactionResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, SendRawTransactionRequest] = params match { @@ -273,7 +275,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { def encodeJson(t: SendRawTransactionResponse): JValue = encodeAsHex(t.transactionHash) } - implicit val eth_sendTransaction = new Codec[SendTransactionRequest, SendTransactionResponse] { + implicit val eth_sendTransaction = new JsonMethodCodec[SendTransactionRequest, SendTransactionResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, SendTransactionRequest] = params match { case Some(JArray(JObject(tx) :: _)) => @@ -286,7 +288,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { encodeAsHex(t.txHash) } - implicit val eth_call = new JsonDecoder[CallRequest] with JsonEncoder[CallResponse] { + implicit val eth_call = new JsonMethodDecoder[CallRequest] with JsonEncoder[CallResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, CallRequest] = params match { case Some(JArray((txObj: JObject) :: (blockValue: JValue) :: Nil)) => @@ -300,7 +302,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { def encodeJson(t: CallResponse): JValue = encodeAsHex(t.returnData) } - implicit val eth_estimateGas = new JsonDecoder[CallRequest] with JsonEncoder[EstimateGasResponse] { + implicit val eth_estimateGas = new JsonMethodDecoder[CallRequest] with JsonEncoder[EstimateGasResponse] { override def encodeJson(t: EstimateGasResponse): JValue = encodeAsHex(t.gas) override def decodeJson(params: Option[JArray]): Either[JsonRpcError, CallRequest] = @@ -313,7 +315,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } - implicit val eth_getCode = new JsonDecoder[GetCodeRequest] with JsonEncoder[GetCodeResponse] { + implicit val eth_getCode = new JsonMethodDecoder[GetCodeRequest] with JsonEncoder[GetCodeResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetCodeRequest] = params match { case Some(JArray((address: JString) :: (blockValue: JValue) :: Nil)) => @@ -327,7 +329,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { def encodeJson(t: GetCodeResponse): JValue = encodeAsHex(t.result) } - implicit val eth_getUncleCountByBlockNumber = new JsonDecoder[GetUncleCountByBlockNumberRequest] + implicit val eth_getUncleCountByBlockNumber = new JsonMethodDecoder[GetUncleCountByBlockNumberRequest] with JsonEncoder[GetUncleCountByBlockNumberResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetUncleCountByBlockNumberRequest] = params match { @@ -341,7 +343,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { def encodeJson(t: GetUncleCountByBlockNumberResponse): JValue = encodeAsHex(t.result) } - implicit val eth_getUncleCountByBlockHash = new JsonDecoder[GetUncleCountByBlockHashRequest] + implicit val eth_getUncleCountByBlockHash = new JsonMethodDecoder[GetUncleCountByBlockHashRequest] with JsonEncoder[GetUncleCountByBlockHashResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetUncleCountByBlockHashRequest] = params match { @@ -355,7 +357,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { def encodeJson(t: GetUncleCountByBlockHashResponse): JValue = encodeAsHex(t.result) } - implicit val eth_getBlockTransactionCountByNumber = new JsonDecoder[GetBlockTransactionCountByNumberRequest] + implicit val eth_getBlockTransactionCountByNumber = new JsonMethodDecoder[GetBlockTransactionCountByNumberRequest] with JsonEncoder[GetBlockTransactionCountByNumberResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetBlockTransactionCountByNumberRequest] = params match { @@ -369,7 +371,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { def encodeJson(t: GetBlockTransactionCountByNumberResponse): JValue = encodeAsHex(t.result) } - implicit val eth_getBalance = new JsonDecoder[GetBalanceRequest] with JsonEncoder[GetBalanceResponse] { + implicit val eth_getBalance = new JsonMethodDecoder[GetBalanceRequest] with JsonEncoder[GetBalanceResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetBalanceRequest] = params match { case Some(JArray((addressStr: JString) :: (blockValue: JValue) :: Nil)) => @@ -377,13 +379,14 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { address <- extractAddress(addressStr) block <- extractBlockParam(blockValue) } yield GetBalanceRequest(address, block) - case _ => Left(InvalidParams()) + case other => + Left(InvalidParams()) } def encodeJson(t: GetBalanceResponse): JValue = encodeAsHex(t.value) } - implicit val eth_getStorageAt = new JsonDecoder[GetStorageAtRequest] with JsonEncoder[GetStorageAtResponse] { + implicit val eth_getStorageAt = new JsonMethodDecoder[GetStorageAtRequest] with JsonEncoder[GetStorageAtResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetStorageAtRequest] = params match { case Some(JArray((addressStr: JString) :: (positionStr: JString) :: (blockValue: JValue) :: Nil)) => @@ -398,7 +401,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { def encodeJson(t: GetStorageAtResponse): JValue = encodeAsHex(t.value) } - implicit val eth_getTransactionCount = new JsonDecoder[GetTransactionCountRequest] + implicit val eth_getTransactionCount = new JsonMethodDecoder[GetTransactionCountRequest] with JsonEncoder[GetTransactionCountResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetTransactionCountRequest] = params match { @@ -417,7 +420,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { def encodeJson(t: NewFilterResponse): JValue = encodeAsHex(t.filterId) } - implicit val eth_newFilter = new JsonDecoder[NewFilterRequest] { + implicit val eth_newFilter = new JsonMethodDecoder[NewFilterRequest] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, NewFilterRequest] = params match { case Some(JArray((filterObj: JObject) :: Nil)) => @@ -428,11 +431,12 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } } - implicit val eth_newBlockFilter = new NoParamsDecoder(NewBlockFilterRequest()) {} + implicit val eth_newBlockFilter = new NoParamsMethodDecoder(NewBlockFilterRequest()) {} - implicit val eth_newPendingTransactionFilter = new NoParamsDecoder(NewPendingTransactionFilterRequest()) {} + implicit val eth_newPendingTransactionFilter = new NoParamsMethodDecoder(NewPendingTransactionFilterRequest()) {} - implicit val eth_uninstallFilter = new JsonDecoder[UninstallFilterRequest] with JsonEncoder[UninstallFilterResponse] { + implicit val eth_uninstallFilter = new JsonMethodDecoder[UninstallFilterRequest] + with JsonEncoder[UninstallFilterResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, UninstallFilterRequest] = params match { case Some(JArray((rawFilterId: JValue) :: Nil)) => @@ -444,7 +448,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { override def encodeJson(t: UninstallFilterResponse): JValue = JBool(t.success) } - implicit val eth_getFilterChanges = new JsonDecoder[GetFilterChangesRequest] + implicit val eth_getFilterChanges = new JsonMethodDecoder[GetFilterChangesRequest] with JsonEncoder[GetFilterChangesResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetFilterChangesRequest] = params match { @@ -462,7 +466,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } } - implicit val eth_getFilterLogs = new JsonDecoder[GetFilterLogsRequest] with JsonEncoder[GetFilterLogsResponse] { + implicit val eth_getFilterLogs = new JsonMethodDecoder[GetFilterLogsRequest] with JsonEncoder[GetFilterLogsResponse] { import FilterManager._ def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetFilterLogsRequest] = @@ -482,7 +486,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } } - implicit val eth_getLogs = new JsonDecoder[GetLogsRequest] with JsonEncoder[GetLogsResponse] { + implicit val eth_getLogs = new JsonMethodDecoder[GetLogsRequest] with JsonEncoder[GetLogsResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetLogsRequest] = params match { case Some(JArray((filterObj: JObject) :: Nil)) => @@ -537,7 +541,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } yield Filter(fromBlock = fromBlock, toBlock = toBlock, address = address, topics = topics) } - implicit val eth_sign = new JsonDecoder[SignRequest] { + implicit val eth_sign = new JsonMethodDecoder[SignRequest] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, SignRequest] = params match { case Some(JArray(JString(addr) :: JString(message) :: _)) => @@ -572,7 +576,7 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { } implicit val daedalus_getAccountTransactions = - new JsonDecoder[GetAccountTransactionsRequest] with JsonEncoder[GetAccountTransactionsResponse] { + new JsonMethodDecoder[GetAccountTransactionsRequest] with JsonEncoder[GetAccountTransactionsResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetAccountTransactionsRequest] = params match { case Some(JArray(JString(addrJson) :: fromBlockJson :: toBlockJson :: Nil)) => @@ -588,7 +592,8 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { JObject("transactions" -> JArray(t.transactions.map(Extraction.decompose).toList)) } - implicit val eth_getStorageRoot = new JsonDecoder[GetStorageRootRequest] with JsonEncoder[GetStorageRootResponse] { + implicit val eth_getStorageRoot = new JsonMethodDecoder[GetStorageRootRequest] + with JsonEncoder[GetStorageRootResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetStorageRootRequest] = params match { case Some(JArray((addressStr: JString) :: (blockValue: JValue) :: Nil)) => diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala index 926a420b08..dbaa81fb7e 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala @@ -2,9 +2,9 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString import io.iohk.ethereum.jsonrpc.EthService._ -import io.iohk.ethereum.jsonrpc.JsonRpcController.{JsonDecoder, JsonEncoder} import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.PersonalService.{InvalidAddress, SendIeleTransactionRequest} +import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodDecoder} import org.json4s.JsonAST.{JArray, JObject, JString, JValue} object IeleJsonMethodsImplicits extends JsonMethodsImplicits { @@ -34,7 +34,7 @@ object IeleJsonMethodsImplicits extends JsonMethodsImplicits { ) } - implicit val iele_call = new JsonDecoder[IeleCallRequest] with JsonEncoder[IeleCallResponse] { + implicit val iele_call = new JsonMethodDecoder[IeleCallRequest] with JsonEncoder[IeleCallResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, IeleCallRequest] = params match { case Some(JArray((txObj: JObject) :: (blockValue: JValue) :: Nil)) => @@ -93,7 +93,7 @@ object IeleJsonMethodsImplicits extends JsonMethodsImplicits { } yield IeleTransactionRequest(from, to, value, gas, gasPrice, nonce, function, arguments, contractCode) } - implicit val iele_sendTransaction = new JsonDecoder[SendIeleTransactionRequest] { + implicit val iele_sendTransaction = new JsonMethodDecoder[SendIeleTransactionRequest] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, SendIeleTransactionRequest] = params match { case Some(JArray(JObject(tx) :: _)) => diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala index 16ad83f41b..bafb3ddd2b 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala @@ -6,30 +6,21 @@ import akka.util.ByteString import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.domain.Address import io.iohk.ethereum.jsonrpc.EthService.BlockParam -import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder -import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonDecoder, JsonEncoder} import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams -import io.iohk.ethereum.jsonrpc.JsonSerializers.{ - AddressJsonSerializer, - OptionNoneToJNullSerializer, - QuantitiesSerializer, - UnformattedDataJsonSerializer -} import io.iohk.ethereum.jsonrpc.NetService._ import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.jsonrpc.Web3Service.{ClientVersionRequest, ClientVersionResponse, Sha3Request, Sha3Response} +import io.iohk.ethereum.jsonrpc.serialization.JsonMethodDecoder.NoParamsMethodDecoder +import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodCodec, JsonMethodDecoder, JsonSerializers} import io.iohk.ethereum.utils.BigIntExtensionMethods.BigIntAsUnsigned +import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ import org.json4s.JsonDSL._ -import org.json4s.{DefaultFormats, Formats} -import org.bouncycastle.util.encoders.Hex import scala.util.Try trait JsonMethodsImplicits { - - implicit val formats: Formats = DefaultFormats.preservingEmptyValues + OptionNoneToJNullSerializer + - QuantitiesSerializer + UnformattedDataJsonSerializer + AddressJsonSerializer + implicit val formats = JsonSerializers.formats protected def encodeAsHex(input: ByteString): JString = JString(s"0x${Hex.toHexString(input.toArray[Byte])}") @@ -154,7 +145,7 @@ object JsonMethodsImplicits extends JsonMethodsImplicits { import JsonRpcError._ - implicit val web3_sha3 = new JsonDecoder[Sha3Request] with JsonEncoder[Sha3Response] { + implicit val web3_sha3 = new JsonMethodDecoder[Sha3Request] with JsonEncoder[Sha3Response] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, Sha3Request] = params match { case Some(JArray((input: JString) :: Nil)) => extractBytes(input).map(Sha3Request) @@ -164,24 +155,25 @@ object JsonMethodsImplicits extends JsonMethodsImplicits { override def encodeJson(t: Sha3Response): JValue = encodeAsHex(t.data) } - implicit val web3_clientVersion = new NoParamsDecoder(ClientVersionRequest()) + implicit val web3_clientVersion = new NoParamsMethodDecoder(ClientVersionRequest()) with JsonEncoder[ClientVersionResponse] { override def encodeJson(t: ClientVersionResponse): JValue = t.value } - implicit val net_version = new NoParamsDecoder(VersionRequest()) with JsonEncoder[VersionResponse] { + implicit val net_version = new NoParamsMethodDecoder(VersionRequest()) with JsonEncoder[VersionResponse] { override def encodeJson(t: VersionResponse): JValue = t.value } - implicit val net_listening = new NoParamsDecoder(ListeningRequest()) with JsonEncoder[ListeningResponse] { + implicit val net_listening = new NoParamsMethodDecoder(ListeningRequest()) with JsonEncoder[ListeningResponse] { override def encodeJson(t: ListeningResponse): JValue = t.value } - implicit val net_peerCount = new NoParamsDecoder(PeerCountRequest()) with JsonEncoder[PeerCountResponse] { + implicit val net_peerCount = new NoParamsMethodDecoder(PeerCountRequest()) with JsonEncoder[PeerCountResponse] { override def encodeJson(t: PeerCountResponse): JValue = encodeAsHex(t.value) } - implicit val personal_importRawKey = new JsonDecoder[ImportRawKeyRequest] with JsonEncoder[ImportRawKeyResponse] { + implicit val personal_importRawKey = new JsonMethodDecoder[ImportRawKeyRequest] + with JsonEncoder[ImportRawKeyResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, ImportRawKeyRequest] = params match { case Some(JArray(JString(key) :: JString(passphrase) :: _)) => @@ -194,7 +186,7 @@ object JsonMethodsImplicits extends JsonMethodsImplicits { JString(t.address.toString) } - implicit val personal_newAccount = new JsonDecoder[NewAccountRequest] with JsonEncoder[NewAccountResponse] { + implicit val personal_newAccount = new JsonMethodDecoder[NewAccountRequest] with JsonEncoder[NewAccountResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, NewAccountRequest] = params match { case Some(JArray(JString(passphrase) :: _)) => @@ -207,14 +199,14 @@ object JsonMethodsImplicits extends JsonMethodsImplicits { JString(t.address.toString) } - implicit val personal_listAccounts = new NoParamsDecoder(ListAccountsRequest()) + implicit val personal_listAccounts = new NoParamsMethodDecoder(ListAccountsRequest()) with JsonEncoder[ListAccountsResponse] { def encodeJson(t: ListAccountsResponse): JValue = JArray(t.addresses.map(a => JString(a.toString))) } implicit val personal_sendTransaction = - new Codec[SendTransactionWithPassphraseRequest, SendTransactionWithPassphraseResponse] { + new JsonMethodCodec[SendTransactionWithPassphraseRequest, SendTransactionWithPassphraseResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, SendTransactionWithPassphraseRequest] = params match { case Some(JArray(JObject(tx) :: JString(passphrase) :: _)) => @@ -227,7 +219,7 @@ object JsonMethodsImplicits extends JsonMethodsImplicits { encodeAsHex(t.txHash) } - implicit val personal_sign = new Codec[SignRequest, SignResponse] { + implicit val personal_sign = new JsonMethodCodec[SignRequest, SignResponse] { override def encodeJson(t: SignResponse): JValue = { import t.signature._ encodeAsHex(ByteString(r.toUnsignedByteArray ++ s.toUnsignedByteArray :+ v)) @@ -245,7 +237,7 @@ object JsonMethodsImplicits extends JsonMethodsImplicits { } } - implicit val personal_ecRecover = new Codec[EcRecoverRequest, EcRecoverResponse] { + implicit val personal_ecRecover = new JsonMethodCodec[EcRecoverRequest, EcRecoverResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, EcRecoverRequest] = params match { @@ -274,7 +266,7 @@ object JsonMethodsImplicits extends JsonMethodsImplicits { encodeAsHex(t.address.bytes) } - implicit val personal_unlockAccount = new Codec[UnlockAccountRequest, UnlockAccountResponse] { + implicit val personal_unlockAccount = new JsonMethodCodec[UnlockAccountRequest, UnlockAccountResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, UnlockAccountRequest] = { params match { case Some(JArray(JString(addr) :: JString(passphrase) :: JNull :: _)) => @@ -295,7 +287,7 @@ object JsonMethodsImplicits extends JsonMethodsImplicits { JBool(t.result) } - implicit val personal_lockAccount = new Codec[LockAccountRequest, LockAccountResponse] { + implicit val personal_lockAccount = new JsonMethodCodec[LockAccountRequest, LockAccountResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, LockAccountRequest] = { params match { case Some(JArray(JString(addr) :: _)) => diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala index cafb1fdef2..86520735d5 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala @@ -1,16 +1,14 @@ package io.iohk.ethereum.jsonrpc +import java.util.concurrent.TimeUnit + +import com.typesafe.config.{Config => TypesafeConfig} +import io.iohk.ethereum.jsonrpc.CheckpointingService._ +import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonRpcConfig import io.iohk.ethereum.jsonrpc.NetService._ import io.iohk.ethereum.jsonrpc.PersonalService._ -import io.iohk.ethereum.jsonrpc.Web3Service._ -import io.iohk.ethereum.utils.Logger -import org.json4s.JsonAST.{JArray, JValue} -import org.json4s.JsonDSL._ -import com.typesafe.config.{Config => TypesafeConfig} -import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} -import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.QAService.{ GenerateCheckpointRequest, GenerateCheckpointResponse, @@ -18,54 +16,19 @@ import io.iohk.ethereum.jsonrpc.QAService.{ GetFederationMembersInfoResponse } import io.iohk.ethereum.jsonrpc.TestService._ +import io.iohk.ethereum.jsonrpc.Web3Service._ +import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodDecoder} import io.iohk.ethereum.jsonrpc.server.http.JsonRpcHttpServer.JsonRpcHttpServerConfig import io.iohk.ethereum.jsonrpc.server.ipc.JsonRpcIpcServer.JsonRpcIpcServerConfig -import java.util.concurrent.TimeUnit - -import io.iohk.ethereum.jsonrpc.CheckpointingService._ +import io.iohk.ethereum.utils.Logger +import org.json4s.JsonDSL._ -import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration import scala.util.{Failure, Success} object JsonRpcController { - - trait JsonDecoder[T] { - def decodeJson(params: Option[JArray]): Either[JsonRpcError, T] - } - object JsonDecoder { - abstract class NoParamsDecoder[T](request: => T) extends JsonDecoder[T] { - def decodeJson(params: Option[JArray]): Either[JsonRpcError, T] = - params match { - case None | Some(JArray(Nil)) => Right(request) - case _ => Left(InvalidParams(s"No parameters expected")) - } - } - } - - trait JsonEncoder[T] { - def encodeJson(t: T): JValue - } - object JsonEncoder { - def apply[T](implicit encoder: JsonEncoder[T]): JsonEncoder[T] = encoder - - implicit def listEncoder[T](implicit itemEncoder: JsonEncoder[T]): JsonEncoder[List[T]] = list => - JArray(list.map(itemEncoder.encodeJson)) - } - - trait Codec[Req, Res] extends JsonDecoder[Req] with JsonEncoder[Res] - object Codec { - import scala.language.implicitConversions - - implicit def decoderWithEncoderIntoCodec[Req, Res]( - decEnc: JsonDecoder[Req] with JsonEncoder[Res] - ): Codec[Req, Res] = new Codec[Req, Res] { - def decodeJson(params: Option[JArray]) = decEnc.decodeJson(params) - def encodeJson(t: Res) = decEnc.encodeJson(t) - } - } - trait JsonRpcConfig { def apis: Seq[String] def accountTransactionsMaxBlocks: Int @@ -127,15 +90,15 @@ class JsonRpcController( config: JsonRpcConfig ) extends Logger { - import JsonRpcController._ + import CheckpointingJsonMethodsImplicits._ + import DebugJsonMethodsImplicits._ import EthJsonMethodsImplicits._ - import TestJsonMethodsImplicits._ import IeleJsonMethodsImplicits._ import JsonMethodsImplicits._ + import JsonRpcController._ import JsonRpcError._ - import DebugJsonMethodsImplicits._ import QAJsonMethodsImplicits._ - import CheckpointingJsonMethodsImplicits._ + import TestJsonMethodsImplicits._ lazy val apisHandleFns: Map[String, PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]]] = Map( Apis.Eth -> handleEthRequest, @@ -415,7 +378,7 @@ class JsonRpcController( private def handle[Req, Res]( fn: Req => Future[Either[JsonRpcError, Res]], rpcReq: JsonRpcRequest - )(implicit dec: JsonDecoder[Req], enc: JsonEncoder[Res]): Future[JsonRpcResponse] = { + )(implicit dec: JsonMethodDecoder[Req], enc: JsonEncoder[Res]): Future[JsonRpcResponse] = { dec.decodeJson(rpcReq.params) match { case Right(req) => fn(req) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala index 5551353b18..8a18abff10 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala @@ -1,8 +1,8 @@ package io.iohk.ethereum.jsonrpc import io.iohk.ethereum.consensus.Protocol -import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonEncoder -import org.json4s.{JInt, JString, JObject, JValue} +import io.iohk.ethereum.jsonrpc.serialization.JsonEncoder +import org.json4s.{JInt, JObject, JString, JValue} case class JsonRpcError(code: Int, message: String, data: Option[JValue]) @@ -12,6 +12,12 @@ object JsonRpcError { def apply[T: JsonEncoder](code: Int, message: String, data: T): JsonRpcError = JsonRpcError(code, message, Some(JsonEncoder[T].encodeJson(data))) + implicit val jsonRpcErrorEncoder: JsonEncoder[JsonRpcError] = err => + JObject( + List("code" -> JsonEncoder.encode(err.code), "message" -> JsonEncoder.encode(err.message)) ++ + err.data.map("data" -> _) + ) + val ParseError = JsonRpcError(-32700, "An error occurred on the server while parsing the JSON text", None) val InvalidRequest = JsonRpcError(-32600, "The JSON sent is not a valid Request object", None) val MethodNotFound = JsonRpcError(-32601, "The method does not exist / is not available", None) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala index 8df1ce4c23..da7f5a836c 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala @@ -1,16 +1,16 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString -import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder -import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonEncoder} import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams -import io.iohk.ethereum.jsonrpc.QAService._ +import io.iohk.ethereum.jsonrpc.QAService.{MineBlocksRequest, MineBlocksResponse, _} +import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodCodec} +import io.iohk.ethereum.jsonrpc.serialization.JsonMethodDecoder.NoParamsMethodDecoder import org.json4s.Extraction import org.json4s.JsonAST._ object QAJsonMethodsImplicits extends JsonMethodsImplicits { - implicit val qa_mineBlocks: Codec[MineBlocksRequest, MineBlocksResponse] = - new Codec[MineBlocksRequest, MineBlocksResponse] { + implicit val qa_mineBlocks: JsonMethodCodec[MineBlocksRequest, MineBlocksResponse] = + new JsonMethodCodec[MineBlocksRequest, MineBlocksResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, MineBlocksRequest] = { params match { case Some(JArray(JInt(numBlocks) :: JBool(withTransactions) :: Nil)) => @@ -33,8 +33,8 @@ object QAJsonMethodsImplicits extends JsonMethodsImplicits { ) } - implicit val qa_generateCheckpoint: Codec[GenerateCheckpointRequest, GenerateCheckpointResponse] = - new Codec[GenerateCheckpointRequest, GenerateCheckpointResponse] { + implicit val qa_generateCheckpoint: JsonMethodCodec[GenerateCheckpointRequest, GenerateCheckpointResponse] = + new JsonMethodCodec[GenerateCheckpointRequest, GenerateCheckpointResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, GenerateCheckpointRequest] = { params match { case Some(JArray((keys: JArray) :: JString(hash) :: Nil)) => @@ -60,8 +60,9 @@ object QAJsonMethodsImplicits extends JsonMethodsImplicits { } } - implicit val qa_getFederationMembersInfo: Codec[GetFederationMembersInfoRequest, GetFederationMembersInfoResponse] = - new NoParamsDecoder(GetFederationMembersInfoRequest()) with JsonEncoder[GetFederationMembersInfoResponse] { + implicit val qa_getFederationMembersInfo + : JsonMethodCodec[GetFederationMembersInfoRequest, GetFederationMembersInfoResponse] = + new NoParamsMethodDecoder(GetFederationMembersInfoRequest()) with JsonEncoder[GetFederationMembersInfoResponse] { def encodeJson(t: GetFederationMembersInfoResponse): JValue = Extraction.decompose(t) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestJsonMethodsImplicits.scala index 1329c6f39c..edaf42e515 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestJsonMethodsImplicits.scala @@ -1,9 +1,9 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString -import io.iohk.ethereum.jsonrpc.JsonRpcController.{JsonDecoder, JsonEncoder} import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams import io.iohk.ethereum.jsonrpc.TestService._ +import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodDecoder} import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.bouncycastle.util.encoders.Hex @@ -12,7 +12,8 @@ import scala.util.Try object TestJsonMethodsImplicits extends JsonMethodsImplicits { - implicit val test_setChainParams = new JsonDecoder[SetChainParamsRequest] with JsonEncoder[SetChainParamsResponse] { + implicit val test_setChainParams = new JsonMethodDecoder[SetChainParamsRequest] + with JsonEncoder[SetChainParamsResponse] { private def extractAccounts(accountsJson: JValue): Either[JsonRpcError, Map[ByteString, AccountConfig]] = { val accounts = accountsJson.asInstanceOf[JObject].values.collect { case (key, accObj: Map[_, _]) => val rawWei = accObj.asInstanceOf[Map[String, Any]]("wei").asInstanceOf[String] @@ -73,7 +74,7 @@ object TestJsonMethodsImplicits extends JsonMethodsImplicits { override def encodeJson(t: SetChainParamsResponse): JValue = true } - implicit val test_mineBlocks = new JsonDecoder[MineBlocksRequest] with JsonEncoder[MineBlocksResponse] { + implicit val test_mineBlocks = new JsonMethodDecoder[MineBlocksRequest] with JsonEncoder[MineBlocksResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, MineBlocksRequest] = params match { case Some(JArray(JInt(numBlocks) :: Nil)) => @@ -84,7 +85,7 @@ object TestJsonMethodsImplicits extends JsonMethodsImplicits { override def encodeJson(t: MineBlocksResponse): JValue = true } - implicit val test_modifyTimestamp = new JsonDecoder[ModifyTimestampRequest] + implicit val test_modifyTimestamp = new JsonMethodDecoder[ModifyTimestampRequest] with JsonEncoder[ModifyTimestampResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, ModifyTimestampRequest] = params match { @@ -96,7 +97,8 @@ object TestJsonMethodsImplicits extends JsonMethodsImplicits { override def encodeJson(t: ModifyTimestampResponse): JValue = true } - implicit val test_rewindToBlock = new JsonDecoder[RewindToBlockRequest] with JsonEncoder[RewindToBlockResponse] { + implicit val test_rewindToBlock = new JsonMethodDecoder[RewindToBlockRequest] + with JsonEncoder[RewindToBlockResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, RewindToBlockRequest] = params match { case Some(JArray(JInt(blockNum) :: Nil)) => @@ -107,7 +109,7 @@ object TestJsonMethodsImplicits extends JsonMethodsImplicits { override def encodeJson(t: RewindToBlockResponse): JValue = true } - implicit val miner_setEtherbase = new JsonDecoder[SetEtherbaseRequest] with JsonEncoder[SetEtherbaseResponse] { + implicit val miner_setEtherbase = new JsonMethodDecoder[SetEtherbaseRequest] with JsonEncoder[SetEtherbaseResponse] { def decodeJson(params: Option[JArray]): Either[JsonRpcError, SetEtherbaseRequest] = params match { case Some(JArray((addressStr: JString) :: Nil)) => diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonEncoder.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonEncoder.scala new file mode 100644 index 0000000000..056a53f04c --- /dev/null +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonEncoder.scala @@ -0,0 +1,25 @@ +package io.iohk.ethereum.jsonrpc.serialization + +import org.json4s.{JArray, JBool, JInt, JNull, JString, JValue} + +trait JsonEncoder[T] { + def encodeJson(t: T): JValue +} +object JsonEncoder { + def apply[T](implicit encoder: JsonEncoder[T]): JsonEncoder[T] = encoder + + def encode[T](value: T)(implicit encoder: JsonEncoder[T]): JValue = encoder.encodeJson(value) + + implicit val stringEncoder: JsonEncoder[String] = JString(_) + implicit val intEncoder: JsonEncoder[Int] = JInt(_) + implicit val booleanEncoder: JsonEncoder[Boolean] = JBool(_) + implicit val jvalueEncoder: JsonEncoder[JValue] = identity + + implicit def listEncoder[T](implicit itemEncoder: JsonEncoder[T]): JsonEncoder[List[T]] = list => + JArray(list.map(itemEncoder.encodeJson)) + + def optionToNullEncoder[T](implicit valueEncoder: JsonEncoder[T]): JsonEncoder[Option[T]] = { + case Some(value) => valueEncoder.encodeJson(value) + case None => JNull + } +} diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonMethodCodec.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonMethodCodec.scala new file mode 100644 index 0000000000..820588039f --- /dev/null +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonMethodCodec.scala @@ -0,0 +1,14 @@ +package io.iohk.ethereum.jsonrpc.serialization +import org.json4s.JArray + +trait JsonMethodCodec[Req, Res] extends JsonMethodDecoder[Req] with JsonEncoder[Res] +object JsonMethodCodec { + import scala.language.implicitConversions + + implicit def decoderWithEncoderIntoCodec[Req, Res]( + decEnc: JsonMethodDecoder[Req] with JsonEncoder[Res] + ): JsonMethodCodec[Req, Res] = new JsonMethodCodec[Req, Res] { + def decodeJson(params: Option[JArray]) = decEnc.decodeJson(params) + def encodeJson(t: Res) = decEnc.encodeJson(t) + } +} diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonMethodDecoder.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonMethodDecoder.scala new file mode 100644 index 0000000000..c24c03e605 --- /dev/null +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonMethodDecoder.scala @@ -0,0 +1,18 @@ +package io.iohk.ethereum.jsonrpc.serialization + +import io.iohk.ethereum.jsonrpc.JsonRpcError +import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams +import org.json4s.JsonAST.JArray + +trait JsonMethodDecoder[T] { + def decodeJson(params: Option[JArray]): Either[JsonRpcError, T] +} +object JsonMethodDecoder { + abstract class NoParamsMethodDecoder[T](request: => T) extends JsonMethodDecoder[T] { + def decodeJson(params: Option[JArray]): Either[JsonRpcError, T] = + params match { + case None | Some(JArray(Nil)) => Right(request) + case _ => Left(InvalidParams(s"No parameters expected")) + } + } +} diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonSerializers.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonSerializers.scala similarity index 67% rename from src/main/scala/io/iohk/ethereum/jsonrpc/JsonSerializers.scala rename to src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonSerializers.scala index d3655178d4..e9ca9ce9dd 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonSerializers.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/serialization/JsonSerializers.scala @@ -1,12 +1,14 @@ -package io.iohk.ethereum.jsonrpc +package io.iohk.ethereum.jsonrpc.serialization import akka.util.ByteString import io.iohk.ethereum.domain.Address -import org.json4s.JsonAST.{JNull, JString} -import org.json4s.CustomSerializer +import io.iohk.ethereum.jsonrpc.JsonRpcError import org.bouncycastle.util.encoders.Hex +import org.json4s.{CustomSerializer, DefaultFormats, Formats, JNull, JString} object JsonSerializers { + implicit val formats: Formats = + DefaultFormats + UnformattedDataJsonSerializer + QuantitiesSerializer + OptionNoneToJNullSerializer + AddressJsonSerializer object UnformattedDataJsonSerializer extends CustomSerializer[ByteString](_ => @@ -45,4 +47,12 @@ object JsonSerializers { ) ) + object RpcErrorJsonSerializer + extends CustomSerializer[JsonRpcError](_ => + ( + { PartialFunction.empty }, + { case err: JsonRpcError => JsonEncoder.encode(err) } + ) + ) + } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala index 21fbed7422..7bb3a7489c 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala @@ -1,5 +1,7 @@ package io.iohk.ethereum.jsonrpc.server.http +import java.security.SecureRandom + import akka.actor.ActorSystem import akka.http.scaladsl.model._ import akka.http.scaladsl.server.Directives._ @@ -10,10 +12,10 @@ import ch.megard.akka.http.cors.scaladsl.model.HttpOriginMatcher import ch.megard.akka.http.cors.scaladsl.settings.CorsSettings import de.heikoseeberger.akkahttpjson4s.Json4sSupport import io.iohk.ethereum.jsonrpc._ +import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers import io.iohk.ethereum.utils.{ConfigUtils, Logger} -import java.security.SecureRandom -import org.json4s.JsonAST.JInt -import org.json4s.{DefaultFormats, native} +import org.json4s.{DefaultFormats, JInt, native} + import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future import scala.util.Try @@ -24,7 +26,7 @@ trait JsonRpcHttpServer extends Json4sSupport { implicit val serialization = native.Serialization - implicit val formats = DefaultFormats + implicit val formats = DefaultFormats + JsonSerializers.RpcErrorJsonSerializer def corsAllowedOrigins: HttpOriginMatcher diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/server/ipc/JsonRpcIpcServer.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/server/ipc/JsonRpcIpcServer.scala index 1f56896717..ab3e3911c7 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/server/ipc/JsonRpcIpcServer.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/server/ipc/JsonRpcIpcServer.scala @@ -4,13 +4,14 @@ import java.io.{BufferedReader, File, InputStreamReader} import java.net.{ServerSocket, Socket} import akka.actor.ActorSystem +import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers import io.iohk.ethereum.jsonrpc.server.ipc.JsonRpcIpcServer.JsonRpcIpcServerConfig import io.iohk.ethereum.jsonrpc.{JsonRpcController, JsonRpcRequest} import io.iohk.ethereum.utils.Logger import org.json4s.JsonAST.JValue import org.json4s.native.JsonMethods._ import org.json4s.native.Serialization -import org.json4s.{DefaultFormats, native} +import org.json4s.native import org.scalasbt.ipcsocket.UnixDomainServerSocket import scala.annotation.tailrec @@ -54,7 +55,7 @@ class JsonRpcIpcServer(jsonRpcController: JsonRpcController, config: JsonRpcIpcS class ClientThread(jsonRpcController: JsonRpcController, clientSocket: Socket) extends Thread { implicit private val serialization = native.Serialization - implicit private val formats = DefaultFormats + implicit private val formats = JsonSerializers.formats private val out = clientSocket.getOutputStream private val in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream)) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index ce16e60846..702198883c 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -12,7 +12,7 @@ import io.iohk.ethereum.crypto.kec256 import io.iohk.ethereum.domain._ import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.FilterManager.LogFilterLogs -import io.iohk.ethereum.jsonrpc.JsonSerializers.{ +import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.{ OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala index 284a145cee..6cabb5c596 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala @@ -7,7 +7,7 @@ import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.domain._ import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.FilterManager.TxLog -import io.iohk.ethereum.jsonrpc.JsonSerializers.{ +import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.{ OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala index dc55e4af02..cffe8eab26 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala @@ -7,7 +7,7 @@ import akka.testkit.TestKit import akka.util.ByteString import io.iohk.ethereum.{LongPatience, WithActorSystemShutDown} import io.iohk.ethereum.domain._ -import io.iohk.ethereum.jsonrpc.JsonSerializers.{ +import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.{ OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala index 5514fd3c85..84315bb106 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala @@ -5,7 +5,7 @@ import akka.testkit.TestKit import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonRpcConfig -import io.iohk.ethereum.jsonrpc.JsonSerializers.{ +import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.{ OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer