Skip to content

Commit c02157d

Browse files
authored
Etcm 139 incomplete data errors during fast sync (#748)
1 parent c340728 commit c02157d

28 files changed

+327
-230
lines changed

build.sbt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,12 @@ val root = {
6868
libraryDependencies ++= dep
6969
)
7070
.settings(executableScriptName := name.value)
71-
.settings(inConfig(Integration)(Defaults.testSettings
72-
++ org.scalafmt.sbt.ScalafmtPlugin.scalafmtConfigSettings :+ (Test / parallelExecution := false)): _*)
71+
.settings(
72+
inConfig(Integration)(
73+
Defaults.testSettings
74+
++ org.scalafmt.sbt.ScalafmtPlugin.scalafmtConfigSettings :+ (Test / parallelExecution := false)
75+
): _*
76+
)
7377
.settings(inConfig(Benchmark)(Defaults.testSettings :+ (Test / parallelExecution := false)): _*)
7478
.settings(inConfig(Evm)(Defaults.testSettings :+ (Test / parallelExecution := false)): _*)
7579
.settings(inConfig(Ets)(Defaults.testSettings :+ (Test / parallelExecution := false)): _*)
@@ -161,7 +165,7 @@ addCommandAlias(
161165
|;scalafmtAll
162166
|;scalastyle
163167
|;test:scalastyle
164-
|;test
168+
|;testQuick
165169
|;it:test
166170
|""".stripMargin
167171
)

src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingJsonMethodsImplicits.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ package io.iohk.ethereum.jsonrpc
33
import akka.util.ByteString
44
import io.iohk.ethereum.crypto.ECDSASignature
55
import io.iohk.ethereum.jsonrpc.CheckpointingService._
6-
import io.iohk.ethereum.jsonrpc.JsonRpcController.Codec
7-
import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams
8-
import io.iohk.ethereum.jsonrpc.JsonSerializers.QuantitiesSerializer
6+
import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams
7+
import io.iohk.ethereum.jsonrpc.serialization.JsonMethodCodec
8+
import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.QuantitiesSerializer
99
import org.json4s.JsonAST._
1010
import org.json4s.{Extraction, JsonAST}
1111

1212
object CheckpointingJsonMethodsImplicits extends JsonMethodsImplicits {
1313

14-
implicit val checkpointing_getLatestBlock: Codec[GetLatestBlockRequest, GetLatestBlockResponse] =
15-
new Codec[GetLatestBlockRequest, GetLatestBlockResponse] {
14+
implicit val checkpointing_getLatestBlock: JsonMethodCodec[GetLatestBlockRequest, GetLatestBlockResponse] =
15+
new JsonMethodCodec[GetLatestBlockRequest, GetLatestBlockResponse] {
1616
override def decodeJson(
1717
params: Option[JsonAST.JArray]
1818
): Either[JsonRpcError, GetLatestBlockRequest] =
@@ -30,8 +30,8 @@ object CheckpointingJsonMethodsImplicits extends JsonMethodsImplicits {
3030
Extraction.decompose(resp)(formats - QuantitiesSerializer)
3131
}
3232

33-
implicit val checkpointing_pushCheckpoint: Codec[PushCheckpointRequest, PushCheckpointResponse] =
34-
new Codec[PushCheckpointRequest, PushCheckpointResponse] {
33+
implicit val checkpointing_pushCheckpoint: JsonMethodCodec[PushCheckpointRequest, PushCheckpointResponse] =
34+
new JsonMethodCodec[PushCheckpointRequest, PushCheckpointResponse] {
3535
override def decodeJson(
3636
params: Option[JsonAST.JArray]
3737
): Either[JsonRpcError, PushCheckpointRequest] =

src/main/scala/io/iohk/ethereum/jsonrpc/DebugJsonMethodsImplicits.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package io.iohk.ethereum.jsonrpc
22

33
import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse}
4-
import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonEncoder}
5-
import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder
4+
import io.iohk.ethereum.jsonrpc.serialization.JsonMethodDecoder.NoParamsMethodDecoder
5+
import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodCodec}
66
import org.json4s.JsonAST.{JArray, JString, JValue}
77

88
object DebugJsonMethodsImplicits extends JsonMethodsImplicits {
99

10-
implicit val debug_listPeersInfo: Codec[ListPeersInfoRequest, ListPeersInfoResponse] =
11-
new NoParamsDecoder(ListPeersInfoRequest()) with JsonEncoder[ListPeersInfoResponse] {
10+
implicit val debug_listPeersInfo: JsonMethodCodec[ListPeersInfoRequest, ListPeersInfoResponse] =
11+
new NoParamsMethodDecoder(ListPeersInfoRequest()) with JsonEncoder[ListPeersInfoResponse] {
1212
def encodeJson(t: ListPeersInfoResponse): JValue =
1313
JArray(t.peers.map(a => JString(a.toString)))
1414
}

src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala

Lines changed: 52 additions & 47 deletions
Large diffs are not rendered by default.

src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import io.iohk.ethereum.jsonrpc.FilterManager.{FilterChanges, FilterLogs, LogFil
1919
import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonRpcConfig
2020
import io.iohk.ethereum.keystore.KeyStore
2121
import io.iohk.ethereum.ledger.{InMemoryWorldStateProxy, Ledger, StxLedger}
22+
import io.iohk.ethereum.mpt.MerklePatriciaTrie.MissingNodeException
2223
import io.iohk.ethereum.ommers.OmmersPool
2324
import io.iohk.ethereum.rlp
2425
import io.iohk.ethereum.rlp.RLPImplicitConversions._
@@ -234,7 +235,7 @@ class EthService(
234235

235236
private[this] def ifEthash[Req, Res](req: Req)(f: Req => Res): ServiceResponse[Res] = {
236237
@inline def F[A](x: A): Future[A] = Future.successful(x)
237-
consensus.ifEthash[ServiceResponse[Res]](_ => F(Right(f(req))))(F(Left(JsonRpcErrors.ConsensusIsNotEthash)))
238+
consensus.ifEthash[ServiceResponse[Res]](_ => F(Right(f(req))))(F(Left(JsonRpcError.ConsensusIsNotEthash)))
238239
}
239240

240241
def protocolVersion(req: ProtocolVersionRequest): ServiceResponse[ProtocolVersionResponse] =
@@ -565,7 +566,7 @@ class EthService(
565566
)
566567
}
567568
response
568-
})(Future.successful(Left(JsonRpcErrors.ConsensusIsNotEthash)))
569+
})(Future.successful(Left(JsonRpcError.ConsensusIsNotEthash)))
569570

570571
private def getOmmersFromPool(parentBlockHash: ByteString): Future[OmmersPool.Ommers] =
571572
consensus.ifEthash(ethash => {
@@ -610,7 +611,7 @@ class EthService(
610611
Right(SubmitWorkResponse(false))
611612
}
612613
}
613-
})(Future.successful(Left(JsonRpcErrors.ConsensusIsNotEthash)))
614+
})(Future.successful(Left(JsonRpcError.ConsensusIsNotEthash)))
614615

615616
/**
616617
* Implements the eth_syncing method that returns syncing information if the node is syncing.
@@ -649,10 +650,10 @@ class EthService(
649650
pendingTransactionsManager ! PendingTransactionsManager.AddOrOverrideTransaction(signedTransaction)
650651
Future.successful(Right(SendRawTransactionResponse(signedTransaction.hash)))
651652
} else {
652-
Future.successful(Left(JsonRpcErrors.InvalidRequest))
653+
Future.successful(Left(JsonRpcError.InvalidRequest))
653654
}
654655
case Failure(_) =>
655-
Future.successful(Left(JsonRpcErrors.InvalidRequest))
656+
Future.successful(Left(JsonRpcError.InvalidRequest))
656657
}
657658
}
658659

@@ -669,7 +670,7 @@ class EthService(
669670
val dataEither = (tx.function, tx.contractCode) match {
670671
case (Some(function), None) => Right(rlp.encode(RLPList(function, args)))
671672
case (None, Some(contractCode)) => Right(rlp.encode(RLPList(contractCode, args)))
672-
case _ => Left(JsonRpcErrors.InvalidParams("Iele transaction should contain either functionName or contractCode"))
673+
case _ => Left(JsonRpcError.InvalidParams("Iele transaction should contain either functionName or contractCode"))
673674
}
674675

675676
dataEither match {
@@ -722,7 +723,7 @@ class EthService(
722723
Right(GetUncleCountByBlockHashResponse(blockBody.uncleNodesList.size))
723724
case None =>
724725
Left(
725-
JsonRpcErrors.InvalidParams(s"Block with hash ${Hex.toHexString(req.blockHash.toArray[Byte])} not found")
726+
JsonRpcError.InvalidParams(s"Block with hash ${Hex.toHexString(req.blockHash.toArray[Byte])} not found")
726727
)
727728
}
728729
}
@@ -786,31 +787,22 @@ class EthService(
786787
.flatMap(_ => Right(None))
787788
}
788789

789-
def getBalance(req: GetBalanceRequest): ServiceResponse[GetBalanceResponse] = {
790-
Future {
791-
withAccount(req.address, req.block) { account =>
792-
GetBalanceResponse(account.balance)
793-
}
790+
def getBalance(req: GetBalanceRequest): ServiceResponse[GetBalanceResponse] =
791+
withAccount(req.address, req.block) { account =>
792+
GetBalanceResponse(account.balance)
794793
}
795-
}
796794

797-
def getStorageAt(req: GetStorageAtRequest): ServiceResponse[GetStorageAtResponse] = {
798-
Future {
799-
withAccount(req.address, req.block) { account =>
800-
GetStorageAtResponse(
801-
blockchain.getAccountStorageAt(account.storageRoot, req.position, blockchainConfig.ethCompatibleStorage)
802-
)
803-
}
795+
def getStorageAt(req: GetStorageAtRequest): ServiceResponse[GetStorageAtResponse] =
796+
withAccount(req.address, req.block) { account =>
797+
GetStorageAtResponse(
798+
blockchain.getAccountStorageAt(account.storageRoot, req.position, blockchainConfig.ethCompatibleStorage)
799+
)
804800
}
805-
}
806801

807-
def getTransactionCount(req: GetTransactionCountRequest): ServiceResponse[GetTransactionCountResponse] = {
808-
Future {
809-
withAccount(req.address, req.block) { account =>
810-
GetTransactionCountResponse(account.nonce)
811-
}
802+
def getTransactionCount(req: GetTransactionCountRequest): ServiceResponse[GetTransactionCountResponse] =
803+
withAccount(req.address, req.block) { account =>
804+
GetTransactionCountResponse(account.nonce)
812805
}
813-
}
814806

815807
def newFilter(req: NewFilterRequest): ServiceResponse[NewFilterResponse] = {
816808
implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout)
@@ -875,20 +867,25 @@ class EthService(
875867
}
876868
}
877869

878-
private def withAccount[T](address: Address, blockParam: BlockParam)(f: Account => T): Either[JsonRpcError, T] = {
879-
resolveBlock(blockParam).map { case ResolvedBlock(block, _) =>
880-
f(
881-
blockchain.getAccount(address, block.header.number).getOrElse(Account.empty(blockchainConfig.accountStartNonce))
882-
)
870+
private def withAccount[T](address: Address, blockParam: BlockParam)(makeResponse: Account => T): ServiceResponse[T] =
871+
Future {
872+
resolveBlock(blockParam)
873+
.map { case ResolvedBlock(block, _) =>
874+
blockchain
875+
.getAccount(address, block.header.number)
876+
.getOrElse(Account.empty(blockchainConfig.accountStartNonce))
877+
}
878+
.map(makeResponse)
879+
}.recover { case _: MissingNodeException =>
880+
Left(JsonRpcError.NodeNotFound)
883881
}
884-
}
885882

886883
private def resolveBlock(blockParam: BlockParam): Either[JsonRpcError, ResolvedBlock] = {
887884
def getBlock(number: BigInt): Either[JsonRpcError, Block] = {
888885
blockchain
889886
.getBlockByNumber(number)
890887
.map(Right.apply)
891-
.getOrElse(Left(JsonRpcErrors.InvalidParams(s"Block $number not found")))
888+
.getOrElse(Left(JsonRpcError.InvalidParams(s"Block $number not found")))
892889
}
893890

894891
blockParam match {
@@ -941,7 +938,7 @@ class EthService(
941938
if (numBlocksToSearch > jsonRpcConfig.accountTransactionsMaxBlocks) {
942939
Future.successful(
943940
Left(
944-
JsonRpcErrors.InvalidParams(
941+
JsonRpcError.InvalidParams(
945942
s"""Maximum number of blocks to search is ${jsonRpcConfig.accountTransactionsMaxBlocks}, requested: $numBlocksToSearch.
946943
|See: 'network.rpc.account-transactions-max-blocks' config.""".stripMargin
947944
)
@@ -975,13 +972,10 @@ class EthService(
975972
}
976973
}
977974

978-
def getStorageRoot(req: GetStorageRootRequest): ServiceResponse[GetStorageRootResponse] = {
979-
Future {
980-
withAccount(req.address, req.block) { account =>
981-
GetStorageRootResponse(account.storageRoot)
982-
}
975+
def getStorageRoot(req: GetStorageRootRequest): ServiceResponse[GetStorageRootResponse] =
976+
withAccount(req.address, req.block) { account =>
977+
GetStorageRootResponse(account.storageRoot)
983978
}
984-
}
985979

986980
/**
987981
* Returns the transactions that are pending in the transaction pool and have a from address that is one of the accounts this node manages.

src/main/scala/io/iohk/ethereum/jsonrpc/IeleJsonMethodsImplicits.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package io.iohk.ethereum.jsonrpc
22

33
import akka.util.ByteString
44
import io.iohk.ethereum.jsonrpc.EthService._
5-
import io.iohk.ethereum.jsonrpc.JsonRpcController.{JsonDecoder, JsonEncoder}
6-
import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams
5+
import io.iohk.ethereum.jsonrpc.JsonRpcError.InvalidParams
76
import io.iohk.ethereum.jsonrpc.PersonalService.{InvalidAddress, SendIeleTransactionRequest}
7+
import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodDecoder}
88
import org.json4s.JsonAST.{JArray, JObject, JString, JValue}
99

1010
object IeleJsonMethodsImplicits extends JsonMethodsImplicits {
@@ -34,7 +34,7 @@ object IeleJsonMethodsImplicits extends JsonMethodsImplicits {
3434
)
3535
}
3636

37-
implicit val iele_call = new JsonDecoder[IeleCallRequest] with JsonEncoder[IeleCallResponse] {
37+
implicit val iele_call = new JsonMethodDecoder[IeleCallRequest] with JsonEncoder[IeleCallResponse] {
3838
def decodeJson(params: Option[JArray]): Either[JsonRpcError, IeleCallRequest] =
3939
params match {
4040
case Some(JArray((txObj: JObject) :: (blockValue: JValue) :: Nil)) =>
@@ -93,7 +93,7 @@ object IeleJsonMethodsImplicits extends JsonMethodsImplicits {
9393
} yield IeleTransactionRequest(from, to, value, gas, gasPrice, nonce, function, arguments, contractCode)
9494
}
9595

96-
implicit val iele_sendTransaction = new JsonDecoder[SendIeleTransactionRequest] {
96+
implicit val iele_sendTransaction = new JsonMethodDecoder[SendIeleTransactionRequest] {
9797
def decodeJson(params: Option[JArray]): Either[JsonRpcError, SendIeleTransactionRequest] =
9898
params match {
9999
case Some(JArray(JObject(tx) :: _)) =>

0 commit comments

Comments
 (0)