Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -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)): _*)
Expand Down Expand Up @@ -161,7 +165,7 @@ addCommandAlias(
|;scalafmtAll
|;scalastyle
|;test:scalastyle
|;test
|;testQuick
|;it:test
|""".stripMargin
)
Original file line number Diff line number Diff line change
Expand Up @@ -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.JsonRpcErrors.InvalidParams
import io.iohk.ethereum.jsonrpc.JsonSerializers.QuantitiesSerializer
import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams
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] =
Expand All @@ -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] =
Expand Down
Original file line number Diff line number Diff line change
@@ -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)))
}
Expand Down

Large diffs are not rendered by default.

76 changes: 35 additions & 41 deletions src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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._
Expand Down Expand Up @@ -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] =
Expand Down Expand Up @@ -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 => {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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))
}
}

Expand All @@ -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 {
Expand Down Expand Up @@ -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")
)
}
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we could get MissingNodeException?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly during fast-sync.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could happen during regular one if state node is lost along the way, but it's much less probable while during fast-sync it is sure that such error happens.

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 {
Expand Down Expand Up @@ -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
)
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.JsonRpcErrors.InvalidParams
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 {
Expand Down Expand Up @@ -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)) =>
Expand Down Expand Up @@ -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) :: _)) =>
Expand Down
Loading