From fe0b8953df52c4770638963e8486ce9448661f4c Mon Sep 17 00:00:00 2001 From: lemastero Date: Thu, 22 Oct 2020 01:32:05 +0200 Subject: [PATCH 01/33] [ETCM-269] port Future to monix Task --- .../ethereum/healthcheck/Healthcheck.scala | 25 +-- .../jsonrpc/CheckpointingService.scala | 24 +-- .../iohk/ethereum/jsonrpc/DebugService.scala | 28 +-- .../io/iohk/ethereum/jsonrpc/EthService.scala | 159 ++++++++++-------- .../ethereum/jsonrpc/JsonRpcController.scala | 101 +++++------ .../jsonrpc/JsonRpcHealthChecker.scala | 25 +-- .../io/iohk/ethereum/jsonrpc/NetService.scala | 22 ++- .../jsonrpc/NodeJsonRpcHealthChecker.scala | 6 +- .../ethereum/jsonrpc/PersonalService.scala | 68 ++++---- .../io/iohk/ethereum/jsonrpc/QAService.scala | 23 +-- .../iohk/ethereum/jsonrpc/TestService.scala | 32 ++-- .../iohk/ethereum/jsonrpc/Web3Service.scala | 8 +- .../io/iohk/ethereum/jsonrpc/package.scala | 4 +- .../server/http/JsonRpcHttpServer.scala | 13 +- .../jsonrpc/server/ipc/JsonRpcIpcServer.scala | 4 +- .../ethereum/jsonrpc/EthServiceSpec.scala | 125 +++++++------- 16 files changed, 356 insertions(+), 311 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/healthcheck/Healthcheck.scala b/src/main/scala/io/iohk/ethereum/healthcheck/Healthcheck.scala index 4d02188b5a..dfe85e4574 100644 --- a/src/main/scala/io/iohk/ethereum/healthcheck/Healthcheck.scala +++ b/src/main/scala/io/iohk/ethereum/healthcheck/Healthcheck.scala @@ -1,7 +1,8 @@ package io.iohk.ethereum.healthcheck -import scala.concurrent.{ExecutionContext, Future} -import scala.util.{Failure, Success} +import monix.eval.Task + +import scala.concurrent.ExecutionContext /** * Represents a health check, runs it and interprets the outcome. @@ -18,20 +19,20 @@ import scala.util.{Failure, Success} */ case class Healthcheck[Error, Result]( description: String, - f: () => Future[Either[Error, Result]], + f: () => Task[Either[Error, Result]], mapResultToError: Result => Option[String] = (_: Result) => None, mapErrorToError: Error => Option[String] = (error: Error) => Some(String.valueOf(error)), mapExceptionToError: Throwable => Option[String] = (t: Throwable) => Some(String.valueOf(t)) ) { - def apply()(implicit ec: ExecutionContext): Future[HealthcheckResult] = { - f().transform { - case Success(Left(error)) => - Success(HealthcheckResult(description, mapErrorToError(error))) - case Success(Right(result)) => - Success(HealthcheckResult(description, mapResultToError(result))) - case Failure(t) => - Success(HealthcheckResult(description, mapExceptionToError(t))) - } + def apply()(implicit ec: ExecutionContext): Task[HealthcheckResult] = { + f() + .map { + case Left(error) => + HealthcheckResult(description, mapErrorToError(error)) + case Right(result) => + HealthcheckResult(description, mapResultToError(result)) + } + .onErrorHandle(t => HealthcheckResult(description, mapExceptionToError(t))) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala index 7c4780ffbb..1c2af54ebe 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala @@ -6,9 +6,7 @@ import io.iohk.ethereum.blockchain.sync.regular.RegularSync.NewCheckpoint import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.domain.Blockchain import io.iohk.ethereum.utils.Logger -import monix.execution.Scheduler.Implicits.global - -import scala.concurrent.Future +import monix.eval.Task class CheckpointingService( blockchain: Blockchain, @@ -21,23 +19,27 @@ class CheckpointingService( lazy val bestBlockNum = blockchain.getBestBlockNumber() lazy val blockToReturnNum = bestBlockNum - bestBlockNum % req.checkpointingInterval - Future { + Task { blockchain.getBlockByNumber(blockToReturnNum) }.flatMap { case Some(b) => val resp = GetLatestBlockResponse(b.hash, b.number) - Future.successful(Right(resp)) + Task.now(Right(resp)) case None => - log.error( - s"Failed to retrieve block for checkpointing: block at number $blockToReturnNum was unavailable " + - s"even though best block number was $bestBlockNum (re-org occurred?)" - ) - getLatestBlock(req) // this can fail only during a re-org, so we just try again + Task + .now( + log.error( + s"Failed to retrieve block for checkpointing: block at number $blockToReturnNum was unavailable " + + s"even though best block number was $bestBlockNum (re-org occurred?)" + ) + ) + .flatMap(_ => getLatestBlock(req) // this can fail only during a re-org, so we just try again + ) } } - def pushCheckpoint(req: PushCheckpointRequest): ServiceResponse[PushCheckpointResponse] = Future { + def pushCheckpoint(req: PushCheckpointRequest): ServiceResponse[PushCheckpointResponse] = Task { syncController ! NewCheckpoint(req.hash, req.signatures) Right(PushCheckpointResponse()) } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala index 4130d2a7f9..ae6b96d74a 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala @@ -7,9 +7,9 @@ import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInf import io.iohk.ethereum.network.EtcPeerManagerActor.{PeerInfo, PeerInfoResponse} import io.iohk.ethereum.network.PeerManagerActor.Peers import io.iohk.ethereum.network.{EtcPeerManagerActor, Peer, PeerActor, PeerId, PeerManagerActor} +import monix.eval.Task import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future import scala.concurrent.duration._ object DebugService { @@ -24,26 +24,30 @@ class DebugService(peerManager: ActorRef, etcPeerManager: ActorRef) { def listPeersInfo(getPeersInfoRequest: ListPeersInfoRequest): ServiceResponse[ListPeersInfoResponse] = { val result = for { ids <- getPeerIds - peers <- Future.traverse(ids)(getPeerInfo) + peers <- Task.traverse(ids)(getPeerInfo) } yield ListPeersInfoResponse(peers.flatten) - result.map(Right(_)) + Task.from(result.map(Right(_))) } - private def getPeerIds: Future[List[PeerId]] = { + private def getPeerIds: Task[List[PeerId]] = { implicit val timeout: Timeout = Timeout(5.seconds) - (peerManager ? PeerManagerActor.GetPeers) - .mapTo[Peers] - .recover { case _ => Peers(Map.empty[Peer, PeerActor.Status]) } - .map(_.peers.keySet.map(_.id).toList) + Task.fromFuture( + (peerManager ? PeerManagerActor.GetPeers) + .mapTo[Peers] + .recover { case _ => Peers(Map.empty[Peer, PeerActor.Status]) } + .map(_.peers.keySet.map(_.id).toList) + ) } - private def getPeerInfo(peer: PeerId): Future[Option[PeerInfo]] = { + private def getPeerInfo(peer: PeerId): Task[Option[PeerInfo]] = { implicit val timeout: Timeout = Timeout(5.seconds) - (etcPeerManager ? EtcPeerManagerActor.PeerInfoRequest(peer)) - .mapTo[PeerInfoResponse] - .collect { case PeerInfoResponse(info) => info } + Task.fromFuture { + (etcPeerManager ? EtcPeerManagerActor.PeerInfoRequest(peer)) + .mapTo[PeerInfoResponse] + .collect { case PeerInfoResponse(info) => info } + } } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala index ea6b3b584f..737fa94a01 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala @@ -4,8 +4,7 @@ import java.time.Duration import java.util.Date import java.util.concurrent.atomic.AtomicReference -import akka.actor.ActorRef -import akka.pattern.ask +import akka.actor.{Actor, ActorRef} import akka.util.{ByteString, Timeout} import io.iohk.ethereum.blockchain.sync.regular.RegularSync import io.iohk.ethereum.consensus.ConsensusConfig @@ -26,14 +25,24 @@ import io.iohk.ethereum.rlp.UInt256RLPImplicits._ import io.iohk.ethereum.transactions.PendingTransactionsManager import io.iohk.ethereum.transactions.PendingTransactionsManager.{PendingTransaction, PendingTransactionsResponse} import io.iohk.ethereum.utils._ +import monix.eval.Task import org.bouncycastle.util.encoders.Hex +import AkkaTaskOps._ +import io.iohk.ethereum.jsonrpc.{FilterManager => FM} -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration import scala.language.existentials import scala.util.{Failure, Success, Try} +object AkkaTaskOps { self: ActorRef => + implicit class TaskActorOps(to: ActorRef) { + import akka.pattern.ask + + def askFor[A](message: Any)(implicit timeout: Timeout, sender: ActorRef = Actor.noSender): Task[A] = + Task.fromFuture(to ? message).map(_.asInstanceOf[A]) + } +} + // scalastyle:off number.of.methods number.of.types file.size.limit object EthService { @@ -225,22 +234,22 @@ class EthService( private[this] def consensusConfig: ConsensusConfig = fullConsensusConfig.generic private[this] def ifEthash[Req, Res](req: Req)(f: Req => Res): ServiceResponse[Res] = { - @inline def F[A](x: A): Future[A] = Future.successful(x) + @inline def F[A](x: A): Task[A] = Task.now(x) consensus.ifEthash[ServiceResponse[Res]](_ => F(Right(f(req))))(F(Left(JsonRpcErrors.ConsensusIsNotEthash))) } def protocolVersion(req: ProtocolVersionRequest): ServiceResponse[ProtocolVersionResponse] = - Future.successful(Right(ProtocolVersionResponse(f"0x$protocolVersion%x"))) + Task.now(Right(ProtocolVersionResponse(f"0x$protocolVersion%x"))) def chainId(req: ChainIdRequest): ServiceResponse[ChainIdResponse] = - Future.successful(Right(ChainIdResponse(blockchainConfig.chainId))) + Task.now(Right(ChainIdResponse(blockchainConfig.chainId))) /** * eth_blockNumber that returns the number of most recent block. * * @return Current block number the client is on. */ - def bestBlockNumber(req: BestBlockNumberRequest): ServiceResponse[BestBlockNumberResponse] = Future { + def bestBlockNumber(req: BestBlockNumberRequest): ServiceResponse[BestBlockNumberResponse] = Task { Right(BestBlockNumberResponse(blockchain.getBestBlockNumber())) } @@ -251,7 +260,7 @@ class EthService( * @return the number of txs that the block has or None if the client doesn't have the block requested */ def getBlockTransactionCountByHash(request: TxCountByBlockHashRequest): ServiceResponse[TxCountByBlockHashResponse] = - Future { + Task { val txsCount = blockchain.getBlockBodyByHash(request.blockHash).map(_.transactionList.size) Right(TxCountByBlockHashResponse(txsCount)) } @@ -262,7 +271,7 @@ class EthService( * @param request with the hash of the block requested * @return the block requested or None if the client doesn't have the block */ - def getByBlockHash(request: BlockByBlockHashRequest): ServiceResponse[BlockByBlockHashResponse] = Future { + def getByBlockHash(request: BlockByBlockHashRequest): ServiceResponse[BlockByBlockHashResponse] = Task { val BlockByBlockHashRequest(blockHash, fullTxs) = request val blockOpt = blockchain.getBlockByHash(blockHash) val totalDifficulty = blockchain.getTotalDifficultyByHash(blockHash) @@ -277,7 +286,7 @@ class EthService( * @param request with the block requested (by it's number or by tag) * @return the block requested or None if the client doesn't have the block */ - def getBlockByNumber(request: BlockByNumberRequest): ServiceResponse[BlockByNumberResponse] = Future { + def getBlockByNumber(request: BlockByNumberRequest): ServiceResponse[BlockByNumberResponse] = Task { val BlockByNumberRequest(blockParam, fullTxs) = request val blockResponseOpt = resolveBlock(blockParam).toOption.map { case ResolvedBlock(block, pending) => val totalDifficulty = blockchain.getTotalDifficultyByHash(block.header.hash) @@ -313,8 +322,8 @@ class EthService( eventualMaybeData.map(txResponse => Right(GetTransactionByHashResponse(txResponse.map(TransactionResponse(_))))) } - def getTransactionDataByHash(txHash: ByteString): Future[Option[TransactionData]] = { - val maybeTxPendingResponse: Future[Option[TransactionData]] = getTransactionsFromPool.map { + def getTransactionDataByHash(txHash: ByteString): Task[Option[TransactionData]] = { + val maybeTxPendingResponse: Task[Option[TransactionData]] = getTransactionsFromPool().map { _.pendingTransactions.map(_.stx.tx).find(_.hash == txHash).map(TransactionData(_)) } @@ -330,7 +339,7 @@ class EthService( } def getTransactionReceipt(req: GetTransactionReceiptRequest): ServiceResponse[GetTransactionReceiptResponse] = - Future { + Task { val result: Option[TransactionReceiptResponse] = for { TransactionLocation(blockHash, txIndex) <- blockchain.getTransactionLocation(req.txHash) Block(header, body) <- blockchain.getBlockByHash(blockHash) @@ -400,7 +409,7 @@ class EthService( .map(asRawTransactionResponse) private def getTransactionByBlockHashAndIndex(blockHash: ByteString, transactionIndex: BigInt) = - Future { + Task { for { blockWithTx <- blockchain.getBlockByHash(blockHash) blockTxs = blockWithTx.body.transactionList if transactionIndex >= 0 && transactionIndex < blockTxs.size @@ -416,7 +425,7 @@ class EthService( */ def getUncleByBlockHashAndIndex( request: UncleByBlockHashAndIndexRequest - ): ServiceResponse[UncleByBlockHashAndIndexResponse] = Future { + ): ServiceResponse[UncleByBlockHashAndIndexResponse] = Task { val UncleByBlockHashAndIndexRequest(blockHash, uncleIndex) = request val uncleHeaderOpt = blockchain .getBlockBodyByHash(blockHash) @@ -443,7 +452,7 @@ class EthService( */ def getUncleByBlockNumberAndIndex( request: UncleByBlockNumberAndIndexRequest - ): ServiceResponse[UncleByBlockNumberAndIndexResponse] = Future { + ): ServiceResponse[UncleByBlockNumberAndIndexResponse] = Task { val UncleByBlockNumberAndIndexRequest(blockParam, uncleIndex) = request val uncleBlockResponseOpt = resolveBlock(blockParam).toOption .flatMap { case ResolvedBlock(block, pending) => @@ -481,7 +490,7 @@ class EthService( val blockDifference = 30 val bestBlock = blockchain.getBestBlockNumber() - Future { + Task { val gasPrice = ((bestBlock - blockDifference) to bestBlock) .flatMap(blockchain.getBlockByNumber) .flatMap(_.body.transactionList) @@ -539,7 +548,7 @@ class EthService( import io.iohk.ethereum.consensus.ethash.EthashUtils.{epoch, seed} val bestBlock = blockchain.getBestBlock() - getOmmersFromPool(bestBlock.hash).zip(getTransactionsFromPool).map { case (ommers, pendingTxs) => + Task.parZip2(getOmmersFromPool(bestBlock.hash), getTransactionsFromPool()).map { case (ommers, pendingTxs) => val blockGenerator = ethash.blockGenerator blockGenerator.generateBlock( bestBlock, @@ -560,40 +569,40 @@ class EthService( Left(JsonRpcErrors.InternalError) } } - })(Future.successful(Left(JsonRpcErrors.ConsensusIsNotEthash))) + })(Task.now(Left(JsonRpcErrors.ConsensusIsNotEthash))) - private def getOmmersFromPool(parentBlockHash: ByteString): Future[OmmersPool.Ommers] = + private def getOmmersFromPool(parentBlockHash: ByteString): Task[OmmersPool.Ommers] = consensus.ifEthash(ethash => { val miningConfig = ethash.config.specific implicit val timeout: Timeout = Timeout(miningConfig.ommerPoolQueryTimeout) - (ommersPool ? OmmersPool.GetOmmers(parentBlockHash)) - .mapTo[OmmersPool.Ommers] - .recover { case ex => + ommersPool + .askFor[OmmersPool.Ommers](OmmersPool.GetOmmers(parentBlockHash)) + .onErrorHandle { ex => log.error("failed to get ommer, mining block with empty ommers list", ex) OmmersPool.Ommers(Nil) } - })(Future.successful(OmmersPool.Ommers(Nil))) // NOTE If not Ethash consensus, ommers do not make sense, so => Nil + })(Task.now(OmmersPool.Ommers(Nil))) // NOTE If not Ethash consensus, ommers do not make sense, so => Nil // TODO This seems to be re-implemented in TransactionPicker, probably move to a better place? Also generalize the error message. - private[jsonrpc] def getTransactionsFromPool(): Future[PendingTransactionsResponse] = { + private[jsonrpc] def getTransactionsFromPool(): Task[PendingTransactionsResponse] = { implicit val timeout: Timeout = Timeout(getTransactionFromPoolTimeout) - (pendingTransactionsManager ? PendingTransactionsManager.GetPendingTransactions) - .mapTo[PendingTransactionsResponse] - .recover { case ex => + pendingTransactionsManager + .askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) + .onErrorHandle { ex => log.error("failed to get transactions, mining block with empty transactions list", ex) PendingTransactionsResponse(Nil) } } def getCoinbase(req: GetCoinbaseRequest): ServiceResponse[GetCoinbaseResponse] = - Future.successful(Right(GetCoinbaseResponse(consensusConfig.coinbase))) + Task.now(Right(GetCoinbaseResponse(consensusConfig.coinbase))) def submitWork(req: SubmitWorkRequest): ServiceResponse[SubmitWorkResponse] = consensus.ifEthash[ServiceResponse[SubmitWorkResponse]](ethash => { reportActive() - Future { + Task { ethash.blockGenerator.getPrepared(req.powHeaderHash) match { case Some(pendingBlock) if blockchain.getBestBlockNumber() <= pendingBlock.block.header.number => import pendingBlock._ @@ -605,14 +614,14 @@ class EthService( Right(SubmitWorkResponse(false)) } } - })(Future.successful(Left(JsonRpcErrors.ConsensusIsNotEthash))) + })(Task.now(Left(JsonRpcErrors.ConsensusIsNotEthash))) /** * Implements the eth_syncing method that returns syncing information if the node is syncing. * * @return The syncing status if the node is syncing or None if not */ - def syncing(req: SyncingRequest): ServiceResponse[SyncingResponse] = Future { + def syncing(req: SyncingRequest): ServiceResponse[SyncingResponse] = Task { val currentBlock = blockchain.getBestBlockNumber() val highestBlock = appStateStorage.getEstimatedHighestBlock() @@ -638,17 +647,17 @@ class EthService( case Success(signedTransaction) => if (SignedTransaction.getSender(signedTransaction).isDefined) { pendingTransactionsManager ! PendingTransactionsManager.AddOrOverrideTransaction(signedTransaction) - Future.successful(Right(SendRawTransactionResponse(signedTransaction.hash))) + Task.now(Right(SendRawTransactionResponse(signedTransaction.hash))) } else { - Future.successful(Left(JsonRpcErrors.InvalidRequest)) + Task.now(Left(JsonRpcErrors.InvalidRequest)) } case Failure(_) => - Future.successful(Left(JsonRpcErrors.InvalidRequest)) + Task.now(Left(JsonRpcErrors.InvalidRequest)) } } def call(req: CallRequest): ServiceResponse[CallResponse] = { - Future { + Task { doCall(req)(stxLedger.simulateTransaction).map(r => CallResponse(r.vmReturnData)) } } @@ -669,18 +678,18 @@ class EthService( .map(_.right.map { callResponse => IeleCallResponse(rlp.decode[Seq[ByteString]](callResponse.returnData.toArray[Byte])(seqEncDec[ByteString])) }) - case Left(error) => Future.successful(Left(error)) + case Left(error) => Task.now(Left(error)) } } def estimateGas(req: CallRequest): ServiceResponse[EstimateGasResponse] = { - Future { + Task { doCall(req)(stxLedger.binarySearchGasEstimation).map(gasUsed => EstimateGasResponse(gasUsed)) } } def getCode(req: GetCodeRequest): ServiceResponse[GetCodeResponse] = { - Future { + Task { resolveBlock(req.block).map { case ResolvedBlock(block, _) => val world = blockchain.getWorldStateProxy( block.header.number, @@ -697,7 +706,7 @@ class EthService( def getUncleCountByBlockNumber( req: GetUncleCountByBlockNumberRequest ): ServiceResponse[GetUncleCountByBlockNumberResponse] = { - Future { + Task { resolveBlock(req.block).map { case ResolvedBlock(block, _) => GetUncleCountByBlockNumberResponse(block.body.uncleNodesList.size) } @@ -707,7 +716,7 @@ class EthService( def getUncleCountByBlockHash( req: GetUncleCountByBlockHashRequest ): ServiceResponse[GetUncleCountByBlockHashResponse] = { - Future { + Task { blockchain.getBlockBodyByHash(req.blockHash) match { case Some(blockBody) => Right(GetUncleCountByBlockHashResponse(blockBody.uncleNodesList.size)) @@ -722,7 +731,7 @@ class EthService( def getBlockTransactionCountByNumber( req: GetBlockTransactionCountByNumberRequest ): ServiceResponse[GetBlockTransactionCountByNumberResponse] = { - Future { + Task { resolveBlock(req.block).map { case ResolvedBlock(block, _) => GetBlockTransactionCountByNumberResponse(block.body.transactionList.size) } @@ -738,7 +747,7 @@ class EthService( */ def getTransactionByBlockNumberAndIndex( req: GetTransactionByBlockNumberAndIndexRequest - ): ServiceResponse[GetTransactionByBlockNumberAndIndexResponse] = Future { + ): ServiceResponse[GetTransactionByBlockNumberAndIndexResponse] = Task { getTransactionDataByBlockNumberAndIndex(req.block, req.transactionIndex) .map(_.map(TransactionResponse(_))) .map(GetTransactionByBlockNumberAndIndexResponse) @@ -753,7 +762,7 @@ class EthService( */ def getRawTransactionByBlockNumberAndIndex( req: GetTransactionByBlockNumberAndIndexRequest - ): ServiceResponse[RawTransactionResponse] = Future { + ): ServiceResponse[RawTransactionResponse] = Task { getTransactionDataByBlockNumberAndIndex(req.block, req.transactionIndex) .map(x => x.map(_.stx)) .map(RawTransactionResponse) @@ -778,7 +787,7 @@ class EthService( } def getBalance(req: GetBalanceRequest): ServiceResponse[GetBalanceResponse] = { - Future { + Task { withAccount(req.address, req.block) { account => GetBalanceResponse(account.balance) } @@ -786,7 +795,7 @@ class EthService( } def getStorageAt(req: GetStorageAtRequest): ServiceResponse[GetStorageAtResponse] = { - Future { + Task { withAccount(req.address, req.block) { account => GetStorageAtResponse( blockchain.getAccountStorageAt(account.storageRoot, req.position, blockchainConfig.ethCompatibleStorage) @@ -796,7 +805,7 @@ class EthService( } def getTransactionCount(req: GetTransactionCountRequest): ServiceResponse[GetTransactionCountResponse] = { - Future { + Task { withAccount(req.address, req.block) { account => GetTransactionCountResponse(account.nonce) } @@ -807,8 +816,8 @@ class EthService( implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) import req.filter._ - (filterManager ? FilterManager.NewLogFilter(fromBlock, toBlock, address, topics)) - .mapTo[FilterManager.NewFilterResponse] + filterManager + .askFor[FM.NewFilterResponse](FM.NewLogFilter(fromBlock, toBlock, address, topics)) .map { resp => Right(NewFilterResponse(resp.id)) } @@ -816,51 +825,57 @@ class EthService( def newBlockFilter(req: NewBlockFilterRequest): ServiceResponse[NewFilterResponse] = { implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) - - (filterManager ? FilterManager.NewBlockFilter).mapTo[FilterManager.NewFilterResponse].map { resp => - Right(NewFilterResponse(resp.id)) - } + filterManager + .askFor[FM.NewFilterResponse](FM.NewBlockFilter) + .map { resp => + Right(NewFilterResponse(resp.id)) + } } def newPendingTransactionFilter(req: NewPendingTransactionFilterRequest): ServiceResponse[NewFilterResponse] = { implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) - - (filterManager ? FilterManager.NewPendingTransactionFilter).mapTo[FilterManager.NewFilterResponse].map { resp => - Right(NewFilterResponse(resp.id)) - } + filterManager + .askFor[FM.NewFilterResponse](FM.NewPendingTransactionFilter) + .map { resp => + Right(NewFilterResponse(resp.id)) + } } def uninstallFilter(req: UninstallFilterRequest): ServiceResponse[UninstallFilterResponse] = { implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) - (filterManager ? FilterManager.UninstallFilter(req.filterId)).map { _ => - Right(UninstallFilterResponse(success = true)) - } + filterManager + .askFor(FM.UninstallFilter(req.filterId)) + .map { _: Any => + Right(UninstallFilterResponse(success = true)) + } } def getFilterChanges(req: GetFilterChangesRequest): ServiceResponse[GetFilterChangesResponse] = { implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) - (filterManager ? FilterManager.GetFilterChanges(req.filterId)).mapTo[FilterManager.FilterChanges].map { - filterChanges => + filterManager + .askFor[FM.FilterChanges](FM.GetFilterChanges(req.filterId)) + .map { filterChanges => Right(GetFilterChangesResponse(filterChanges)) - } + } } def getFilterLogs(req: GetFilterLogsRequest): ServiceResponse[GetFilterLogsResponse] = { implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) - - (filterManager ? FilterManager.GetFilterLogs(req.filterId)).mapTo[FilterManager.FilterLogs].map { filterLogs => - Right(GetFilterLogsResponse(filterLogs)) - } + filterManager + .askFor[FilterManager.FilterLogs](FM.GetFilterLogs(req.filterId)) + .map { filterLogs => + Right(GetFilterLogsResponse(filterLogs)) + } } def getLogs(req: GetLogsRequest): ServiceResponse[GetLogsResponse] = { implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) import req.filter._ - (filterManager ? FilterManager.GetLogs(fromBlock, toBlock, address, topics)) - .mapTo[FilterManager.LogFilterLogs] + filterManager + .askFor[FM.LogFilterLogs](FM.GetLogs(fromBlock, toBlock, address, topics)) .map { filterLogs => Right(GetLogsResponse(filterLogs)) } @@ -930,7 +945,7 @@ class EthService( ): ServiceResponse[GetAccountTransactionsResponse] = { val numBlocksToSearch = request.toBlock - request.fromBlock if (numBlocksToSearch > jsonRpcConfig.accountTransactionsMaxBlocks) { - Future.successful( + Task.now( Left( JsonRpcErrors.InvalidParams( s"""Maximum number of blocks to search is ${jsonRpcConfig.accountTransactionsMaxBlocks}, requested: $numBlocksToSearch. @@ -967,7 +982,7 @@ class EthService( } def getStorageRoot(req: GetStorageRootRequest): ServiceResponse[GetStorageRootResponse] = { - Future { + Task { withAccount(req.address, req.block) { account => GetStorageRootResponse(account.storageRoot) } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala index 3416009656..dce2d32232 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala @@ -1,16 +1,16 @@ package io.iohk.ethereum.jsonrpc +import java.util.concurrent.TimeUnit + +import cats.syntax.all._ +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.JsonRpcErrors.InvalidParams 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.JsonRpcErrors.InvalidParams import io.iohk.ethereum.jsonrpc.QAService.{ GenerateCheckpointRequest, GenerateCheckpointResponse, @@ -18,16 +18,15 @@ import io.iohk.ethereum.jsonrpc.QAService.{ GetFederationMembersInfoResponse } import io.iohk.ethereum.jsonrpc.TestService._ +import io.iohk.ethereum.jsonrpc.Web3Service._ 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 monix.eval.Task +import org.json4s.JsonAST.{JArray, JValue} +import org.json4s.JsonDSL._ -import scala.concurrent.Future -import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration.FiniteDuration -import scala.util.{Failure, Success} object JsonRpcController { @@ -121,17 +120,17 @@ class JsonRpcController( config: JsonRpcConfig ) extends Logger { - import JsonRpcController._ + import CheckpointingJsonMethodsImplicits._ + import DebugJsonMethodsImplicits._ import EthJsonMethodsImplicits._ - import TestJsonMethodsImplicits._ import IeleJsonMethodsImplicits._ import JsonMethodsImplicits._ + import JsonRpcController._ import JsonRpcErrors._ - import DebugJsonMethodsImplicits._ import QAJsonMethodsImplicits._ - import CheckpointingJsonMethodsImplicits._ + import TestJsonMethodsImplicits._ - lazy val apisHandleFns: Map[String, PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]]] = Map( + lazy val apisHandleFns: Map[String, PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]]] = Map( Apis.Eth -> handleEthRequest, Apis.Web3 -> handleWeb3Request, Apis.Net -> handleNetRequest, @@ -147,14 +146,14 @@ class JsonRpcController( private def enabledApis: Seq[String] = config.apis :+ Apis.Rpc // RPC enabled by default - private def handleWeb3Request: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleWeb3Request: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "web3_sha3", _, _) => handle[Sha3Request, Sha3Response](web3Service.sha3, req) case req @ JsonRpcRequest(_, "web3_clientVersion", _, _) => handle[ClientVersionRequest, ClientVersionResponse](web3Service.clientVersion, req) } - private def handleNetRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleNetRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "net_version", _, _) => handle[VersionRequest, VersionResponse](netService.version, req) case req @ JsonRpcRequest(_, "net_listening", _, _) => @@ -165,7 +164,7 @@ class JsonRpcController( // scalastyle:off cyclomatic.complexity // scalastyle:off method.length - private def handleEthRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleEthRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "eth_protocolVersion", _, _) => handle[ProtocolVersionRequest, ProtocolVersionResponse](ethService.protocolVersion, req) case req @ JsonRpcRequest(_, "eth_chainId", _, _) => @@ -287,19 +286,19 @@ class JsonRpcController( handle[EthPendingTransactionsRequest, EthPendingTransactionsResponse](ethService.ethPendingTransactions, req) } - private def handleDebugRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleDebugRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "debug_listPeersInfo", _, _) => handle[ListPeersInfoRequest, ListPeersInfoResponse](debugService.listPeersInfo, req) } - private def handleTestRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleTestRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { testServiceOpt match { case Some(testService) => handleTestRequest(testService) case None => PartialFunction.empty } } - private def handleTestRequest(testService: TestService): PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleTestRequest(testService: TestService): PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "test_setChainParams", _, _) => handle[SetChainParamsRequest, SetChainParamsResponse](testService.setChainParams, req) case req @ JsonRpcRequest(_, "test_mineBlocks", _, _) => @@ -312,14 +311,14 @@ class JsonRpcController( handle[SetEtherbaseRequest, SetEtherbaseResponse](testService.setEtherbase, req) } - private def handleIeleRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleIeleRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "iele_sendTransaction", _, _) => handle[SendIeleTransactionRequest, SendTransactionResponse](personalService.sendIeleTransaction, req) case req @ JsonRpcRequest(_, "iele_call", _, _) => handle[IeleCallRequest, IeleCallResponse](ethService.ieleCall, req) } - private def handlePersonalRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handlePersonalRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "personal_importRawKey", _, _) => handle[ImportRawKeyRequest, ImportRawKeyResponse](personalService.importRawKey, req) @@ -348,12 +347,12 @@ class JsonRpcController( handle[EcRecoverRequest, EcRecoverResponse](personalService.ecRecover, req) } - private def handleDaedalusRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleDaedalusRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "daedalus_getAccountTransactions", _, _) => handle[GetAccountTransactionsRequest, GetAccountTransactionsResponse](ethService.getAccountTransactions, req) } - private def handleQARequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleQARequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "qa_mineBlocks", _, _) => handle[QAService.MineBlocksRequest, QAService.MineBlocksResponse](qaService.mineBlocks, req) @@ -364,7 +363,7 @@ class JsonRpcController( handle[GetFederationMembersInfoRequest, GetFederationMembersInfoResponse](qaService.getFederationMembersInfo, req) } - private def handleCheckpointingRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleCheckpointingRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "checkpointing_getLatestBlock", _, _) => handle[GetLatestBlockRequest, GetLatestBlockResponse](checkpointingService.getLatestBlock, req) @@ -372,44 +371,48 @@ class JsonRpcController( handle[PushCheckpointRequest, PushCheckpointResponse](checkpointingService.pushCheckpoint, req) } - private def handleRpcRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { + private def handleRpcRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "rpc_modules", _, _) => val result = enabledApis.map { _ -> "1.0" }.toMap - Future.successful(JsonRpcResponse("2.0", Some(result), None, req.id)) + Task(JsonRpcResponse("2.0", Some(result), None, req.id)) } - def handleRequest(request: JsonRpcRequest): Future[JsonRpcResponse] = { + def handleRequest(request: JsonRpcRequest): Task[JsonRpcResponse] = { val startTimeNanos = System.nanoTime() - val notFoundFn: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { case _ => + val notFoundFn: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case _ => JsonRpcControllerMetrics.NotFoundMethodsCounter.increment() - Future.successful(errorResponse(request, MethodNotFound)) + Task(errorResponse(request, MethodNotFound)) } - val handleFn: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = + val handleFn: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = enabledApis.foldLeft(notFoundFn)((fn, api) => apisHandleFns.getOrElse(api, PartialFunction.empty) orElse fn) - handleFn(request).andThen { - case Success(JsonRpcResponse(_, _, Some(JsonRpcError(_, _, _)), _)) => - JsonRpcControllerMetrics.MethodsErrorCounter.increment() - - case Success(JsonRpcResponse(_, _, None, _)) => - JsonRpcControllerMetrics.MethodsSuccessCounter.increment() + handleFn(request) + .flatTap { + case JsonRpcResponse(_, _, Some(JsonRpcError(_, _, _)), _) => + Task(JsonRpcControllerMetrics.MethodsErrorCounter.increment()) - val endTimeNanos = System.nanoTime() - val dtNanos = endTimeNanos - startTimeNanos - JsonRpcControllerMetrics.MethodsTimer.record(dtNanos, TimeUnit.NANOSECONDS) + case JsonRpcResponse(_, _, None, _) => + Task { + JsonRpcControllerMetrics.MethodsSuccessCounter.increment() - case Failure(t) => + val endTimeNanos = System.nanoTime() + val dtNanos = endTimeNanos - startTimeNanos + JsonRpcControllerMetrics.MethodsTimer.record(dtNanos, TimeUnit.NANOSECONDS) + } + } + .onErrorRecoverWith { case t: Throwable => JsonRpcControllerMetrics.MethodsExceptionCounter.increment() log.error("Error serving request", t) - } + Task.raiseError(t) + } } private def handle[Req, Res]( - fn: Req => Future[Either[JsonRpcError, Res]], + fn: Req => Task[Either[JsonRpcError, Res]], rpcReq: JsonRpcRequest - )(implicit dec: JsonDecoder[Req], enc: JsonEncoder[Res]): Future[JsonRpcResponse] = { + )(implicit dec: JsonDecoder[Req], enc: JsonEncoder[Res]): Task[JsonRpcResponse] = { dec.decodeJson(rpcReq.params) match { case Right(req) => fn(req) @@ -422,7 +425,7 @@ class JsonRpcController( errorResponse(rpcReq, InternalError) } case Left(error) => - Future.successful(errorResponse(rpcReq, error)) + Task(errorResponse(rpcReq, error)) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcHealthChecker.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcHealthChecker.scala index f66369cd45..e35161f21f 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcHealthChecker.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcHealthChecker.scala @@ -1,21 +1,22 @@ package io.iohk.ethereum.jsonrpc import io.iohk.ethereum.healthcheck.HealthcheckResponse - -import scala.concurrent.Future -import scala.util.{Failure, Success} -import scala.concurrent.ExecutionContext.Implicits.global +import monix.eval.Task trait JsonRpcHealthChecker { - def healthCheck(): Future[HealthcheckResponse] + def healthCheck(): Task[HealthcheckResponse] - def handleResponse(responseF: Future[HealthcheckResponse]): Future[HealthcheckResponse] = { - responseF.andThen { - case Success(response) if (!response.isOK) => - JsonRpcControllerMetrics.HealhcheckErrorCounter.increment() - case Failure(t) => + def handleResponse(responseF: Task[HealthcheckResponse]): Task[HealthcheckResponse] = { + responseF + .map { + case response if (!response.isOK) => + JsonRpcControllerMetrics.HealhcheckErrorCounter.increment() + response + case response => response + } + .onErrorHandleWith { t => JsonRpcControllerMetrics.HealhcheckErrorCounter.increment() - } + Task.raiseError(t) + } } - } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala index 96fd57238b..05f11abf50 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala @@ -1,15 +1,16 @@ package io.iohk.ethereum.jsonrpc +import java.util.concurrent.atomic.AtomicReference + import akka.actor.ActorRef import akka.util.Timeout import io.iohk.ethereum.jsonrpc.NetService.NetServiceConfig import io.iohk.ethereum.network.PeerManagerActor import io.iohk.ethereum.utils.ServerStatus.{Listening, NotListening} import io.iohk.ethereum.utils.{Config, NodeStatus} -import java.util.concurrent.atomic.AtomicReference -import scala.concurrent.Future +import monix.eval.Task + import scala.concurrent.duration._ -import scala.concurrent.ExecutionContext.Implicits.global object NetService { case class VersionRequest() @@ -35,10 +36,10 @@ class NetService(nodeStatusHolder: AtomicReference[NodeStatus], peerManager: Act import NetService._ def version(req: VersionRequest): ServiceResponse[VersionResponse] = - Future.successful(Right(VersionResponse(Config.Network.peer.networkId.toString))) + Task.now(Right(VersionResponse(Config.Network.peer.networkId.toString))) def listening(req: ListeningRequest): ServiceResponse[ListeningResponse] = { - Future.successful { + Task.now { Right( nodeStatusHolder.get().serverStatus match { case _: Listening => ListeningResponse(true) @@ -50,11 +51,14 @@ class NetService(nodeStatusHolder: AtomicReference[NodeStatus], peerManager: Act def peerCount(req: PeerCountRequest): ServiceResponse[PeerCountResponse] = { import akka.pattern.ask - implicit val timeout = Timeout(config.peerManagerTimeout) + implicit val timeout: Timeout = Timeout(config.peerManagerTimeout) - (peerManager ? PeerManagerActor.GetPeers) - .mapTo[PeerManagerActor.Peers] + Task + .fromFuture( + (peerManager ? PeerManagerActor.GetPeers) + .mapTo[PeerManagerActor.Peers] + ) .map { peers => Right(PeerCountResponse(peers.handshaked.size)) } + .timeout(timeout.duration) } - } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/NodeJsonRpcHealthChecker.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/NodeJsonRpcHealthChecker.scala index b90edd7df8..d04c87ac50 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/NodeJsonRpcHealthChecker.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/NodeJsonRpcHealthChecker.scala @@ -3,9 +3,9 @@ package io.iohk.ethereum.jsonrpc import io.iohk.ethereum.healthcheck.HealthcheckResponse import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.NetService._ +import monix.eval.Task import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future class NodeJsonRpcHealthChecker( netService: NetService, @@ -29,7 +29,7 @@ class NodeJsonRpcHealthChecker( () => ethService.getBlockByNumber(BlockByNumberRequest(BlockParam.Pending, true)) ) - override def healthCheck(): Future[HealthcheckResponse] = { + override def healthCheck(): Task[HealthcheckResponse] = { val listeningF = listeningHC() val peerCountF = peerCountHC() val earliestBlockF = earliestBlockHC() @@ -37,7 +37,7 @@ class NodeJsonRpcHealthChecker( val pendingBlockF = pendingBlockHC() val allChecksF = List(listeningF, peerCountF, earliestBlockF, latestBlockF, pendingBlockF) - val responseF = Future.sequence(allChecksF).map(HealthcheckResponse) + val responseF = Task.sequence(allChecksF).map(HealthcheckResponse) handleResponse(responseF) } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index a449f23090..98bda124de 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -5,6 +5,7 @@ import java.time.Duration import akka.actor.ActorRef import akka.pattern.ask import akka.util.{ByteString, Timeout} +import cats.syntax.either._ import io.iohk.ethereum.crypto import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.db.storage.AppStateStorage @@ -19,10 +20,7 @@ import io.iohk.ethereum.utils.{BlockchainConfig, TxPoolConfig} import io.iohk.ethereum.rlp import io.iohk.ethereum.rlp.RLPImplicits._ import io.iohk.ethereum.rlp.RLPImplicitConversions._ - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future -import scala.util.Try +import monix.eval.Task object PersonalService { @@ -77,14 +75,14 @@ class PersonalService( private val unlockedWallets: ExpiringMap[Address, Wallet] = ExpiringMap.empty(Duration.ofSeconds(defaultUnlockTime)) - def importRawKey(req: ImportRawKeyRequest): ServiceResponse[ImportRawKeyResponse] = Future { + def importRawKey(req: ImportRawKeyRequest): ServiceResponse[ImportRawKeyResponse] = Task { for { prvKey <- Right(req.prvKey).filterOrElse(_.length == PrivateKeyLength, InvalidKey) addr <- keyStore.importPrivateKey(prvKey, req.passphrase).left.map(handleError) } yield ImportRawKeyResponse(addr) } - def newAccount(req: NewAccountRequest): ServiceResponse[NewAccountResponse] = Future { + def newAccount(req: NewAccountRequest): ServiceResponse[NewAccountResponse] = Task { keyStore .newAccount(req.passphrase) .map(NewAccountResponse.apply) @@ -92,7 +90,7 @@ class PersonalService( .map(handleError) } - def listAccounts(request: ListAccountsRequest): ServiceResponse[ListAccountsResponse] = Future { + def listAccounts(request: ListAccountsRequest): ServiceResponse[ListAccountsResponse] = Task { keyStore .listAccounts() .map(ListAccountsResponse.apply) @@ -100,7 +98,7 @@ class PersonalService( .map(handleError) } - def unlockAccount(request: UnlockAccountRequest): ServiceResponse[UnlockAccountResponse] = Future { + def unlockAccount(request: UnlockAccountRequest): ServiceResponse[UnlockAccountResponse] = Task { keyStore .unlockAccount(request.address, request.passphrase) .left @@ -117,12 +115,12 @@ class PersonalService( } } - def lockAccount(request: LockAccountRequest): ServiceResponse[LockAccountResponse] = Future.successful { + def lockAccount(request: LockAccountRequest): ServiceResponse[LockAccountResponse] = Task.now { unlockedWallets.remove(request.address) Right(LockAccountResponse(true)) } - def sign(request: SignRequest): ServiceResponse[SignResponse] = Future { + def sign(request: SignRequest): ServiceResponse[SignResponse] = Task { import request._ val accountWallet = { @@ -136,7 +134,7 @@ class PersonalService( } } - def ecRecover(req: EcRecoverRequest): ServiceResponse[EcRecoverResponse] = Future { + def ecRecover(req: EcRecoverRequest): ServiceResponse[EcRecoverResponse] = Task { import req._ signature .publicKey(getMessageToSign(message)) @@ -149,25 +147,25 @@ class PersonalService( def sendTransaction( request: SendTransactionWithPassphraseRequest ): ServiceResponse[SendTransactionWithPassphraseResponse] = { - val maybeWalletUnlocked = Future { + val maybeWalletUnlocked = Task { keyStore.unlockAccount(request.tx.from, request.passphrase).left.map(handleError) } maybeWalletUnlocked.flatMap { case Right(wallet) => val futureTxHash = sendTransaction(request.tx, wallet) futureTxHash.map(txHash => Right(SendTransactionWithPassphraseResponse(txHash))) - case Left(err) => Future.successful(Left(err)) + case Left(err) => Task.now(Left(err)) } } def sendTransaction(request: SendTransactionRequest): ServiceResponse[SendTransactionResponse] = { unlockedWallets.get(request.tx.from) match { case Some(wallet) => - val futureTxHash = sendTransaction(request.tx, wallet) - futureTxHash.map(txHash => Right(SendTransactionResponse(txHash))) + val txHashAction = sendTransaction(request.tx, wallet) + txHashAction.map(txHash => Right(SendTransactionResponse(txHash))) case None => - Future.successful(Left(AccountLocked)) + Task.now(Left(AccountLocked)) } } @@ -189,35 +187,37 @@ class PersonalService( ) ) case Left(error) => - Future.successful(Left(error)) + Task.now(Left(error)) } } - private def sendTransaction(request: TransactionRequest, wallet: Wallet): Future[ByteString] = { + private def sendTransaction(request: TransactionRequest, wallet: Wallet): Task[ByteString] = { implicit val timeout = Timeout(txPoolConfig.pendingTxManagerQueryTimeout) val pendingTxsFuture = - (txPool ? PendingTransactionsManager.GetPendingTransactions).mapTo[PendingTransactionsResponse] - val latestPendingTxNonceFuture: Future[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => + Task.fromFuture((txPool ? PendingTransactionsManager.GetPendingTransactions).mapTo[PendingTransactionsResponse]) + val latestPendingTxNonceAction: Task[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => val senderTxsNonces = pendingTxs.pendingTransactions .collect { case ptx if ptx.stx.senderAddress == wallet.address => ptx.stx.tx.tx.nonce } - Try(senderTxsNonces.max).toOption + Either.catchNonFatal(senderTxsNonces.max).toOption } - latestPendingTxNonceFuture.map { maybeLatestPendingTxNonce => - val maybeCurrentNonce = getCurrentAccount(request.from).map(_.nonce.toBigInt) - val maybeNextTxNonce = maybeLatestPendingTxNonce.map(_ + 1) orElse maybeCurrentNonce - val tx = request.toTransaction(maybeNextTxNonce.getOrElse(blockchainConfig.accountStartNonce)) - - val stx = if (blockchain.getBestBlockNumber() >= blockchainConfig.eip155BlockNumber) { - wallet.signTx(tx, Some(blockchainConfig.chainId)) - } else { - wallet.signTx(tx, None) - } + latestPendingTxNonceAction + .map { maybeLatestPendingTxNonce => + val maybeCurrentNonce = getCurrentAccount(request.from).map(_.nonce.toBigInt) + val maybeNextTxNonce = maybeLatestPendingTxNonce.map(_ + 1) orElse maybeCurrentNonce + val tx = request.toTransaction(maybeNextTxNonce.getOrElse(blockchainConfig.accountStartNonce)) - txPool ! AddOrOverrideTransaction(stx.tx) + val stx = if (blockchain.getBestBlockNumber() >= blockchainConfig.eip155BlockNumber) { + wallet.signTx(tx, Some(blockchainConfig.chainId)) + } else { + wallet.signTx(tx, None) + } - stx.tx.hash - } + txPool ! AddOrOverrideTransaction(stx.tx) + + stx.tx.hash + } + .timeout(timeout.duration) } private def getCurrentAccount(address: Address): Option[Account] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala index abc538c6dc..5250394c88 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala @@ -15,11 +15,10 @@ import io.iohk.ethereum.domain.{Blockchain, Checkpoint} import io.iohk.ethereum.jsonrpc.QAService.MineBlocksResponse.MinerResponseType import io.iohk.ethereum.jsonrpc.QAService._ import io.iohk.ethereum.utils.{BlockchainConfig, Logger} +import monix.eval.Task import monix.execution.Scheduler.Implicits.global import mouse.all._ -import scala.concurrent.Future - class QAService( consensus: Consensus, blockchain: Blockchain, @@ -34,19 +33,21 @@ class QAService( * @return nothing */ def mineBlocks(req: MineBlocksRequest): ServiceResponse[MineBlocksResponse] = { - consensus - .sendMiner(MineBlocks(req.numBlocks, req.withTransactions, req.parentBlock)) - .map(_ |> (MineBlocksResponse(_)) |> (_.asRight)) - .recover { case t: Throwable => - log.info("Unable to mine requested blocks", t) - Left(JsonRpcErrors.InternalError) - } + Task.fromFuture( + consensus + .sendMiner(MineBlocks(req.numBlocks, req.withTransactions, req.parentBlock)) + .map(_ |> (MineBlocksResponse(_)) |> (_.asRight)) + .recover { case t: Throwable => + log.info("Unable to mine requested blocks", t) + Left(JsonRpcErrors.InternalError) + } + ) } def generateCheckpoint( req: GenerateCheckpointRequest ): ServiceResponse[GenerateCheckpointResponse] = { - Future { + Task { val hash = req.blockHash.getOrElse(blockchain.getBestBlock().hash) val checkpoint = generateCheckpoint(hash, req.privateKeys) syncController ! NewCheckpoint(hash, checkpoint.signatures) @@ -65,7 +66,7 @@ class QAService( def getFederationMembersInfo( req: GetFederationMembersInfoRequest ): ServiceResponse[GetFederationMembersInfoResponse] = { - Future { + Task.now { Right(GetFederationMembersInfoResponse(blockchainConfig.checkpointPubKeys.toList)) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala index 0230b81c57..87106adcd1 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala @@ -10,10 +10,10 @@ import io.iohk.ethereum.testmode.{TestLedgerWrapper, TestmodeConsensus} import io.iohk.ethereum.transactions.PendingTransactionsManager import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransactionsResponse import io.iohk.ethereum.utils.Logger +import monix.eval.Task import org.bouncycastle.util.encoders.Hex import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future import scala.concurrent.duration._ import scala.util.Try @@ -105,11 +105,11 @@ class TestService( // update test ledger with new config testLedgerWrapper.blockchainConfig = newBlockchainConfig - Future.successful(Right(SetChainParamsResponse())) + Task.now(Right(SetChainParamsResponse())) } def mineBlocks(request: MineBlocksRequest): ServiceResponse[MineBlocksResponse] = { - def mineBlock(): Future[Unit] = { + def mineBlock(): Task[Unit] = { getBlockForMining(blockchain.getBestBlock()).map { blockForMining => val res = testLedgerWrapper.ledger.importBlock(blockForMining.block) log.info("Block mining result: " + res) @@ -118,8 +118,8 @@ class TestService( } } - def doNTimesF(n: Int)(fn: () => Future[Unit]): Future[Unit] = fn().flatMap { res => - if (n <= 1) Future.successful(res) + def doNTimesF(n: Int)(fn: () => Task[Unit]): Task[Unit] = fn().flatMap { res => + if (n <= 1) Task.now(res) else doNTimesF(n - 1)(fn) } @@ -128,7 +128,7 @@ class TestService( def modifyTimestamp(request: ModifyTimestampRequest): ServiceResponse[ModifyTimestampResponse] = { consensus.blockTimestamp = request.timestamp - Future.successful(Right(ModifyTimestampResponse())) + Task.now(Right(ModifyTimestampResponse())) } def rewindToBlock(request: RewindToBlockRequest): ServiceResponse[RewindToBlockResponse] = { @@ -136,19 +136,22 @@ class TestService( (blockchain.getBestBlockNumber() until request.blockNum by -1).foreach { n => blockchain.removeBlock(blockchain.getBlockHeaderByNumber(n).get.hash, withState = false) } - Future.successful(Right(RewindToBlockResponse())) + Task.now(Right(RewindToBlockResponse())) } def setEtherbase(req: SetEtherbaseRequest): ServiceResponse[SetEtherbaseResponse] = { etherbase = req.etherbase - Future.successful(Right(SetEtherbaseResponse())) + Task.now(Right(SetEtherbaseResponse())) } - private def getBlockForMining(parentBlock: Block): Future[PendingBlock] = { + private def getBlockForMining(parentBlock: Block): Task[PendingBlock] = { implicit val timeout = Timeout(5.seconds) - (pendingTransactionsManager ? PendingTransactionsManager.GetPendingTransactions) - .mapTo[PendingTransactionsResponse] - .recover { case _ => PendingTransactionsResponse(Nil) } + Task + .fromFuture( + (pendingTransactionsManager ? PendingTransactionsManager.GetPendingTransactions) + .mapTo[PendingTransactionsResponse] + ) + .onErrorRecover { case _ => PendingTransactionsResponse(Nil) } .flatMap { pendingTxs => consensus.blockGenerator.generateBlock( parentBlock, @@ -156,9 +159,10 @@ class TestService( etherbase, Nil ) match { - case Right(pb) => Future.successful(pb) - case Left(err) => Future.failed(new RuntimeException(s"Error while generating block for mining: $err")) + case Right(pb) => Task.now(pb) + case Left(err) => Task.raiseError(new RuntimeException(s"Error while generating block for mining: $err")) } } + .timeout(timeout.duration) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/Web3Service.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/Web3Service.scala index 797caeb16f..56e4e26319 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/Web3Service.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/Web3Service.scala @@ -3,8 +3,7 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString import io.iohk.ethereum.crypto import io.iohk.ethereum.utils.Config - -import scala.concurrent.Future +import monix.eval.Task object Web3Service { case class Sha3Request(data: ByteString) @@ -18,11 +17,10 @@ class Web3Service { import Web3Service._ def sha3(req: Sha3Request): ServiceResponse[Sha3Response] = { - Future.successful(Right(Sha3Response(crypto.kec256(req.data)))) + Task(Right(Sha3Response(crypto.kec256(req.data)))) } def clientVersion(req: ClientVersionRequest): ServiceResponse[ClientVersionResponse] = { - Future.successful(Right(ClientVersionResponse(Config.clientVersion))) + Task(Right(ClientVersionResponse(Config.clientVersion))) } - } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/package.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/package.scala index 6565d5b16c..af59df8f71 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/package.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/package.scala @@ -1,7 +1,7 @@ package io.iohk.ethereum -import scala.concurrent.Future +import monix.eval.Task package object jsonrpc { - type ServiceResponse[T] = Future[Either[JsonRpcError, T]] + type ServiceResponse[T] = Task[Either[JsonRpcError, T]] } 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..a4c766057e 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 @@ -12,10 +12,11 @@ import de.heikoseeberger.akkahttpjson4s.Json4sSupport import io.iohk.ethereum.jsonrpc._ import io.iohk.ethereum.utils.{ConfigUtils, Logger} import java.security.SecureRandom +import monix.eval.Task +import monix.execution.Scheduler.Implicits.{global => MonixGlobal} import org.json4s.JsonAST.JInt import org.json4s.{DefaultFormats, native} -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future + import scala.util.Try trait JsonRpcHttpServer extends Json4sSupport { @@ -79,11 +80,15 @@ trait JsonRpcHttpServer extends Json4sSupport { } private def handleRequest(request: JsonRpcRequest) = { - complete(jsonRpcController.handleRequest(request)) + complete(jsonRpcController.handleRequest(request).runToFuture(MonixGlobal)) } private def handleBatchRequest(requests: Seq[JsonRpcRequest]) = { - complete(Future.sequence(requests.map(request => jsonRpcController.handleRequest(request)))) + complete { + Task + .traverse(requests)(request => jsonRpcController.handleRequest(request)) + .runToFuture(MonixGlobal) + } } } 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..99c82d1009 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 @@ -7,6 +7,7 @@ import akka.actor.ActorSystem import io.iohk.ethereum.jsonrpc.server.ipc.JsonRpcIpcServer.JsonRpcIpcServerConfig import io.iohk.ethereum.jsonrpc.{JsonRpcController, JsonRpcRequest} import io.iohk.ethereum.utils.Logger +import monix.execution.Scheduler.Implicits.global import org.json4s.JsonAST.JValue import org.json4s.native.JsonMethods._ import org.json4s.native.Serialization @@ -14,7 +15,6 @@ import org.json4s.{DefaultFormats, native} import org.scalasbt.ipcsocket.UnixDomainServerSocket import scala.annotation.tailrec -import scala.concurrent.Await import scala.concurrent.duration._ import scala.util.Try @@ -90,7 +90,7 @@ class JsonRpcIpcServer(jsonRpcController: JsonRpcController, config: JsonRpcIpcS case Some(nextMsgJson) => val request = nextMsgJson.extract[JsonRpcRequest] val responseF = jsonRpcController.handleRequest(request) - val response = Await.result(responseF, awaitTimeout) + val response = responseF.runSyncUnsafe(awaitTimeout) out.write((Serialization.write(response) + '\n').getBytes()) out.flush() case None => diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index f674b9c83a..c78581d9b9 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -28,6 +28,8 @@ import io.iohk.ethereum.transactions.PendingTransactionsManager.{ } import io.iohk.ethereum.utils._ import io.iohk.ethereum.{Fixtures, NormalPatience, Timeouts, crypto} +import monix.execution.Scheduler +import monix.execution.schedulers.TestScheduler import org.bouncycastle.util.encoders.Hex import org.scalactic.TypeCheckedTripleEquals import org.scalamock.scalatest.MockFactory @@ -50,24 +52,25 @@ class EthServiceSpec with TypeCheckedTripleEquals { // behavior of "EthService" + implicit val tx: Scheduler = TestScheduler() it should "answer eth_blockNumber with the latest block number" in new TestSetup { val bestBlockNumber = 10 blockchain.saveBestKnownBlocks(bestBlockNumber) - val response = Await.result(ethService.bestBlockNumber(BestBlockNumberRequest()), Duration.Inf).right.get + val response = ethService.bestBlockNumber(BestBlockNumberRequest()).runSyncUnsafe().right.get response.bestBlockNumber shouldEqual bestBlockNumber } it should "return ethereum protocol version" in new TestSetup { - val response = ethService.protocolVersion(ProtocolVersionRequest()) - val protocolVersion = response.futureValue.right.get.value + val response = ethService.protocolVersion(ProtocolVersionRequest()).runSyncUnsafe() + val protocolVersion = response.right.get.value Integer.parseInt(protocolVersion.drop(2), 16) shouldEqual currentProtocolVersion } it should "return configured chain id" in new TestSetup { - val Right(response) = ethService.chainId(ChainIdRequest()).futureValue + val response = ethService.chainId(ChainIdRequest()).runSyncUnsafe().right.get assert(response === ChainIdResponse(blockchainConfig.chainId)) } @@ -148,11 +151,9 @@ class EthServiceSpec val requestWithInvalidIndex = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, invalidTxIndex) // when - val response = Await - .result( - ethService.getRawTransactionByBlockHashAndIndex(requestWithInvalidIndex), - Duration.Inf - ) + val response = ethService + .getRawTransactionByBlockHashAndIndex(requestWithInvalidIndex) + .runSyncUnsafe() .toOption .value @@ -167,7 +168,7 @@ class EthServiceSpec val request = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, txIndexToRequest) // when - val response = Await.result(ethService.getRawTransactionByBlockHashAndIndex(request), Duration.Inf).right.get + val response = ethService.getRawTransactionByBlockHashAndIndex(request).runSyncUnsafe().right.get // then val expectedTxResponse = blockToRequest.body.transactionList.lift(txIndexToRequest) @@ -186,7 +187,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.futureValue shouldEqual Right(RawTransactionResponse(None)) + response.runSyncUnsafe shouldEqual Right(RawTransactionResponse(None)) } it should "handle eth_getRawTransactionByHash if the tx is still pending" in new TestSetup { @@ -203,7 +204,7 @@ class EthServiceSpec PendingTransactionsResponse(Seq(PendingTransaction(txToRequestWithSender, System.currentTimeMillis))) ) - response.futureValue shouldEqual Right(RawTransactionResponse(Some(txToRequest))) + response.runSyncUnsafe shouldEqual Right(RawTransactionResponse(Some(txToRequest))) } it should "handle eth_getRawTransactionByHash if the tx was already executed" in new TestSetup { @@ -221,7 +222,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.futureValue shouldEqual Right(RawTransactionResponse(Some(txToRequest))) + response.runSyncUnsafe shouldEqual Right(RawTransactionResponse(Some(txToRequest))) } it should "answer eth_getBlockByNumber with the correct block when the pending block is requested" in new TestSetup { @@ -234,7 +235,7 @@ class EthServiceSpec .returns(Some(PendingBlockAndState(PendingBlock(blockToRequest, Nil), fakeWorld))) val request = BlockByNumberRequest(BlockParam.Pending, fullTxs = true) - val response = ethService.getBlockByNumber(request).futureValue.right.get + val response = ethService.getBlockByNumber(request).runSyncUnsafe().right.get response.blockResponse.isDefined should be(true) val blockResponse = response.blockResponse.get @@ -258,13 +259,13 @@ class EthServiceSpec (blockGenerator.getPendingBlockAndState _).expects().returns(None) val request = BlockByNumberRequest(BlockParam.Pending, fullTxs = true) - val response = ethService.getBlockByNumber(request).futureValue.right.get + val response = ethService.getBlockByNumber(request).runSyncUnsafe().right.get response.blockResponse.get.hash.get shouldEqual blockToRequest.header.hash } it should "answer eth_getBlockByNumber with None when the requested block isn't in the blockchain" in new TestSetup { val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) - val response = Await.result(ethService.getBlockByNumber(request), Duration.Inf).right.get + val response = ethService.getBlockByNumber(request).runSyncUnsafe().right.get response.blockResponse shouldBe None } @@ -275,7 +276,7 @@ class EthServiceSpec .commit() val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) - val response = Await.result(ethService.getBlockByNumber(request), Duration.Inf).right.get + val response = ethService.getBlockByNumber(request).runSyncUnsafe().right.get val stxResponses = blockToRequest.body.transactionList.zipWithIndex.map { case (stx, txIndex) => TransactionResponse(stx, Some(blockToRequest.header), Some(txIndex)) @@ -290,7 +291,7 @@ class EthServiceSpec blockchain.storeBlock(blockToRequest).commit() val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) - val response = Await.result(ethService.getBlockByNumber(request), Duration.Inf).right.get + val response = ethService.getBlockByNumber(request).runSyncUnsafe().right.get val stxResponses = blockToRequest.body.transactionList.zipWithIndex.map { case (stx, txIndex) => TransactionResponse(stx, Some(blockToRequest.header), Some(txIndex)) @@ -497,7 +498,7 @@ class EthServiceSpec (appStateStorage.getEstimatedHighestBlock _).expects().returning(10000) blockchain.saveBestKnownBlocks(200) - val response = ethService.syncing(SyncingRequest()).futureValue.right.get + val response = ethService.syncing(SyncingRequest()).runSyncUnsafe().right.get response shouldEqual SyncingResponse( Some( @@ -515,7 +516,7 @@ class EthServiceSpec (appStateStorage.getSyncStartingBlock _).expects().returning(999) (appStateStorage.getEstimatedHighestBlock _).expects().returning(1000) blockchain.saveBestKnownBlocks(1000) - val response = ethService.syncing(SyncingRequest()).futureValue.right.get + val response = ethService.syncing(SyncingRequest()).runSyncUnsafe().right.get response shouldEqual SyncingResponse(None) } @@ -533,7 +534,7 @@ class EthServiceSpec ommersPool.expectMsg(OmmersPool.GetOmmers(parentBlock.hash)) ommersPool.reply(OmmersPool.Ommers(Nil)) - response.futureValue shouldEqual Right(GetWorkResponse(powHash, seedHash, target)) + response.runSyncUnsafe() shouldEqual Right(GetWorkResponse(powHash, seedHash, target)) } it should "accept submitted correct PoW" in new TestSetup { @@ -547,7 +548,7 @@ class EthServiceSpec val req = SubmitWorkRequest(ByteString("nonce"), headerHash, ByteString(Hex.decode("01" * 32))) val response = ethService.submitWork(req) - response.futureValue shouldEqual Right(SubmitWorkResponse(true)) + response.runSyncUnsafe() shouldEqual Right(SubmitWorkResponse(true)) } it should "reject submitted correct PoW when header is no longer in cache" in new TestSetup { @@ -561,7 +562,7 @@ class EthServiceSpec val req = SubmitWorkRequest(ByteString("nonce"), headerHash, ByteString(Hex.decode("01" * 32))) val response = ethService.submitWork(req) - response.futureValue shouldEqual Right(SubmitWorkResponse(false)) + response.runSyncUnsafe() shouldEqual Right(SubmitWorkResponse(false)) } it should "execute call and return a value" in new TestSetup { @@ -588,7 +589,7 @@ class EthServiceSpec ) val response = ethService.call(CallRequest(tx, BlockParam.Latest)) - response.futureValue shouldEqual Right(CallResponse(ByteString("return_value"))) + response.runSyncUnsafe() shouldEqual Right(CallResponse(ByteString("return_value"))) } it should "execute estimateGas and return a value" in new TestSetup { @@ -608,7 +609,7 @@ class EthServiceSpec ) val response = ethService.estimateGas(CallRequest(tx, BlockParam.Latest)) - response.futureValue shouldEqual Right(EstimateGasResponse(123)) + response.runSyncUnsafe() shouldEqual Right(EstimateGasResponse(123)) } it should "get uncle count by block number" in new TestSetup { @@ -617,7 +618,9 @@ class EthServiceSpec val response = ethService.getUncleCountByBlockNumber(GetUncleCountByBlockNumberRequest(BlockParam.Latest)) - response.futureValue shouldEqual Right(GetUncleCountByBlockNumberResponse(blockToRequest.body.uncleNodesList.size)) + response.runSyncUnsafe() shouldEqual Right( + GetUncleCountByBlockNumberResponse(blockToRequest.body.uncleNodesList.size) + ) } it should "get uncle count by block hash" in new TestSetup { @@ -625,7 +628,9 @@ class EthServiceSpec val response = ethService.getUncleCountByBlockHash(GetUncleCountByBlockHashRequest(blockToRequest.header.hash)) - response.futureValue shouldEqual Right(GetUncleCountByBlockHashResponse(blockToRequest.body.uncleNodesList.size)) + response.runSyncUnsafe() shouldEqual Right( + GetUncleCountByBlockHashResponse(blockToRequest.body.uncleNodesList.size) + ) } it should "get transaction count by block number" in new TestSetup { @@ -635,7 +640,7 @@ class EthServiceSpec GetBlockTransactionCountByNumberRequest(BlockParam.WithNumber(blockToRequest.header.number)) ) - response.futureValue shouldEqual Right( + response.runSyncUnsafe() shouldEqual Right( GetBlockTransactionCountByNumberResponse(blockToRequest.body.transactionList.size) ) } @@ -647,7 +652,7 @@ class EthServiceSpec val response = ethService.getBlockTransactionCountByNumber(GetBlockTransactionCountByNumberRequest(BlockParam.Latest)) - response.futureValue shouldEqual Right( + response.runSyncUnsafe() shouldEqual Right( GetBlockTransactionCountByNumberResponse(blockToRequest.body.transactionList.size) ) } @@ -672,7 +677,7 @@ class EthServiceSpec val response = ethService.getCode(GetCodeRequest(address, BlockParam.Latest)) - response.futureValue shouldEqual Right(GetCodeResponse(ByteString("code code code"))) + response.runSyncUnsafe() shouldEqual Right(GetCodeResponse(ByteString("code code code"))) } it should "accept and report hashrate" in new TestSetup { @@ -681,13 +686,15 @@ class EthServiceSpec val rate: BigInt = 42 val id = ByteString("id") - ethService.submitHashRate(SubmitHashRateRequest(12, id)).futureValue shouldEqual Right(SubmitHashRateResponse(true)) - ethService.submitHashRate(SubmitHashRateRequest(rate, id)).futureValue shouldEqual Right( + ethService.submitHashRate(SubmitHashRateRequest(12, id)).runSyncUnsafe() shouldEqual Right( + SubmitHashRateResponse(true) + ) + ethService.submitHashRate(SubmitHashRateRequest(rate, id)).runSyncUnsafe() shouldEqual Right( SubmitHashRateResponse(true) ) val response = ethService.getHashRate(GetHashRateRequest()) - response.futureValue shouldEqual Right(GetHashRateResponse(rate)) + response.runSyncUnsafe() shouldEqual Right(GetHashRateResponse(rate)) } it should "combine hashrates from many miners and remove timed out rates" in new TestSetup { @@ -697,26 +704,26 @@ class EthServiceSpec val id1 = ByteString("id1") val id2 = ByteString("id2") - ethService.submitHashRate(SubmitHashRateRequest(rate, id1)).futureValue shouldEqual Right( + ethService.submitHashRate(SubmitHashRateRequest(rate, id1)).runSyncUnsafe() shouldEqual Right( SubmitHashRateResponse(true) ) Thread.sleep(minerActiveTimeout.toMillis / 2) - ethService.submitHashRate(SubmitHashRateRequest(rate, id2)).futureValue shouldEqual Right( + ethService.submitHashRate(SubmitHashRateRequest(rate, id2)).runSyncUnsafe() shouldEqual Right( SubmitHashRateResponse(true) ) val response1 = ethService.getHashRate(GetHashRateRequest()) - response1.futureValue shouldEqual Right(GetHashRateResponse(rate * 2)) + response1.runSyncUnsafe() shouldEqual Right(GetHashRateResponse(rate * 2)) Thread.sleep(minerActiveTimeout.toMillis / 2) val response2 = ethService.getHashRate(GetHashRateRequest()) - response2.futureValue shouldEqual Right(GetHashRateResponse(rate)) + response2.runSyncUnsafe() shouldEqual Right(GetHashRateResponse(rate)) } it should "return if node is mining base on getWork" in new TestSetup { (ledger.consensus _: (() => Consensus)).expects().returns(consensus).anyNumberOfTimes() - ethService.getMining(GetMiningRequest()).futureValue shouldEqual Right(GetMiningResponse(false)) + ethService.getMining(GetMiningRequest()).runSyncUnsafe() shouldEqual Right(GetMiningResponse(false)) (blockGenerator.generateBlock _).expects(parentBlock, *, *, *).returning(Right(PendingBlock(block, Nil))) blockchain.storeBlock(parentBlock).commit() @@ -724,13 +731,13 @@ class EthServiceSpec val response = ethService.getMining(GetMiningRequest()) - response.futureValue shouldEqual Right(GetMiningResponse(true)) + response.runSyncUnsafe() shouldEqual Right(GetMiningResponse(true)) } it should "return if node is mining base on submitWork" in new TestSetup { (ledger.consensus _: (() => Consensus)).expects().returns(consensus).anyNumberOfTimes() - ethService.getMining(GetMiningRequest()).futureValue shouldEqual Right(GetMiningResponse(false)) + ethService.getMining(GetMiningRequest()).runSyncUnsafe() shouldEqual Right(GetMiningResponse(false)) (blockGenerator.getPrepared _).expects(*).returning(Some(PendingBlock(block, Nil))) (appStateStorage.getBestBlockNumber _).expects().returning(0) @@ -740,19 +747,19 @@ class EthServiceSpec val response = ethService.getMining(GetMiningRequest()) - response.futureValue shouldEqual Right(GetMiningResponse(true)) + response.runSyncUnsafe() shouldEqual Right(GetMiningResponse(true)) } it should "return if node is mining base on submitHashRate" in new TestSetup { (ledger.consensus _: (() => Consensus)).expects().returns(consensus).anyNumberOfTimes() - ethService.getMining(GetMiningRequest()).futureValue shouldEqual Right(GetMiningResponse(false)) + ethService.getMining(GetMiningRequest()).runSyncUnsafe() shouldEqual Right(GetMiningResponse(false)) ethService.submitHashRate(SubmitHashRateRequest(42, ByteString("id"))) val response = ethService.getMining(GetMiningRequest()) - response.futureValue shouldEqual Right(GetMiningResponse(true)) + response.runSyncUnsafe() shouldEqual Right(GetMiningResponse(true)) } it should "return if node is mining after time out" in new TestSetup { @@ -766,21 +773,21 @@ class EthServiceSpec val response = ethService.getMining(GetMiningRequest()) - response.futureValue shouldEqual Right(GetMiningResponse(false)) + response.runSyncUnsafe() shouldEqual Right(GetMiningResponse(false)) } it should "return correct coinbase" in new TestSetup { (ledger.consensus _: (() => Consensus)).expects().returns(consensus) val response = ethService.getCoinbase(GetCoinbaseRequest()) - response.futureValue shouldEqual Right(GetCoinbaseResponse(consensusConfig.coinbase)) + response.runSyncUnsafe() shouldEqual Right(GetCoinbaseResponse(consensusConfig.coinbase)) } it should "return 0 gas price if there are no transactions" in new TestSetup { (appStateStorage.getBestBlockNumber _).expects().returning(42) val response = ethService.getGetGasPrice(GetGasPriceRequest()) - response.futureValue shouldEqual Right(GetGasPriceResponse(0)) + response.runSyncUnsafe() shouldEqual Right(GetGasPriceResponse(0)) } it should "return average gas price" in new TestSetup { @@ -790,7 +797,7 @@ class EthServiceSpec .commit() val response = ethService.getGetGasPrice(GetGasPriceRequest()) - response.futureValue shouldEqual Right(GetGasPriceResponse(BigInt("20000000000"))) + response.runSyncUnsafe() shouldEqual Right(GetGasPriceResponse(BigInt("20000000000"))) } it should "getTransactionByBlockNumberAndIndexRequest return transaction by index" in new TestSetup { @@ -881,7 +888,7 @@ class EthServiceSpec val response = ethService.getBalance(GetBalanceRequest(address, BlockParam.Latest)) - response.futureValue shouldEqual Right(GetBalanceResponse(123)) + response.runSyncUnsafe() shouldEqual Right(GetBalanceResponse(123)) } it should "handle getStorageAt request" in new TestSetup { @@ -921,7 +928,7 @@ class EthServiceSpec blockchain.saveBestKnownBlocks(newblock.header.number) val response = ethService.getStorageAt(GetStorageAtRequest(address, 333, BlockParam.Latest)) - response.futureValue.map(v => UInt256(v.value)) shouldEqual Right(UInt256(123)) + response.runSyncUnsafe().map(v => UInt256(v.value)) shouldEqual Right(UInt256(123)) } it should "handle get transaction count request" in new TestSetup { @@ -940,7 +947,7 @@ class EthServiceSpec val response = ethService.getTransactionCount(GetTransactionCountRequest(address, BlockParam.Latest)) - response.futureValue shouldEqual Right(GetTransactionCountResponse(BigInt(999))) + response.runSyncUnsafe() shouldEqual Right(GetTransactionCountResponse(BigInt(999))) } it should "handle get transaction by hash if the tx is not on the blockchain and not in the tx pool" in new TestSetup { @@ -952,7 +959,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.futureValue shouldEqual Right(GetTransactionByHashResponse(None)) + response.runSyncUnsafe() shouldEqual Right(GetTransactionByHashResponse(None)) } it should "handle get transaction by hash if the tx is still pending" in new TestSetup { @@ -966,7 +973,7 @@ class EthServiceSpec PendingTransactionsResponse(Seq(PendingTransaction(txToRequestWithSender, System.currentTimeMillis))) ) - response.futureValue shouldEqual Right(GetTransactionByHashResponse(Some(TransactionResponse(txToRequest)))) + response.runSyncUnsafe() shouldEqual Right(GetTransactionByHashResponse(Some(TransactionResponse(txToRequest)))) } it should "handle get transaction by hash if the tx was already executed" in new TestSetup { @@ -981,7 +988,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.futureValue shouldEqual Right( + response.runSyncUnsafe() shouldEqual Right( GetTransactionByHashResponse(Some(TransactionResponse(txToRequest, Some(blockWithTx.header), Some(0)))) ) } @@ -1003,7 +1010,7 @@ class EthServiceSpec val request = GetTransactionReceiptRequest(contractCreatingTransaction.hash) val response = ethService.getTransactionReceipt(request) - response.futureValue shouldEqual Right( + response.runSyncUnsafe() shouldEqual Right( GetTransactionReceiptResponse( Some( TransactionReceiptResponse( @@ -1078,7 +1085,7 @@ class EthServiceSpec TransactionResponse(tx1, blockHeader = Some(blockWithTx1.header), pending = Some(false), isOutgoing = Some(false)) ) - response.futureValue shouldEqual Right(GetAccountTransactionsResponse(expectedTxs)) + response.runSyncUnsafe() shouldEqual Right(GetAccountTransactionsResponse(expectedTxs)) } it should "not return account recent transactions from older blocks and return pending txs" in new TestSetup { @@ -1102,7 +1109,7 @@ class EthServiceSpec val expectedSent = Seq(TransactionResponse(signedTx.tx, blockHeader = None, pending = Some(true), isOutgoing = Some(true))) - response.futureValue shouldEqual Right(GetAccountTransactionsResponse(expectedSent)) + response.runSyncUnsafe() shouldEqual Right(GetAccountTransactionsResponse(expectedSent)) } it should "send message to pendingTransactionsManager and return an empty GetPendingTransactionsResponse" in new TestSetup { @@ -1111,7 +1118,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - res.futureValue shouldBe PendingTransactionsResponse(Nil) + res.runSyncUnsafe() shouldBe PendingTransactionsResponse(Nil) } it should "send message to pendingTransactionsManager and return GetPendingTransactionsResponse with two transactions" in new TestSetup { @@ -1138,7 +1145,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(transactions)) - res.futureValue shouldBe PendingTransactionsResponse(transactions) + res.runSyncUnsafe() shouldBe PendingTransactionsResponse(transactions) } it should "send message to pendingTransactionsManager and return an empty GetPendingTransactionsResponse in case of error" in new TestSetup { @@ -1147,7 +1154,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(GetPendingTransactions) pendingTransactionsManager.reply(new ClassCastException("error")) - res.futureValue shouldBe PendingTransactionsResponse(Nil) + res.runSyncUnsafe() shouldBe PendingTransactionsResponse(Nil) } // NOTE TestSetup uses Ethash consensus; check `consensusConfig`. From 6335aac8e98f0a89901993e8db78a7b4f192d3dd Mon Sep 17 00:00:00 2001 From: lemastero Date: Thu, 22 Oct 2020 18:10:02 +0200 Subject: [PATCH 02/33] [ETCM-269] tests port Future to monix Task --- .../ethereum/jsonrpc/EthServiceSpec.scala | 78 ++++++------ .../jsonrpc/JsonRpcControllerEthSpec.scala | 115 +++++++++--------- .../JsonRpcControllerEthTransactionSpec.scala | 71 +++++------ .../JsonRpcControllerPersonalSpec.scala | 64 +++++----- .../jsonrpc/JsonRpcControllerSpec.scala | 52 ++++---- .../io/iohk/ethereum/jsonrpc/QaJRCSpec.scala | 55 +++++---- .../server/http/JsonRpcHttpServerSpec.scala | 16 +-- 7 files changed, 215 insertions(+), 236 deletions(-) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index c78581d9b9..b63bd79adc 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -27,7 +27,7 @@ import io.iohk.ethereum.transactions.PendingTransactionsManager.{ PendingTransactionsResponse } import io.iohk.ethereum.utils._ -import io.iohk.ethereum.{Fixtures, NormalPatience, Timeouts, crypto} +import io.iohk.ethereum.{Fixtures, Timeouts, crypto} import monix.execution.Scheduler import monix.execution.schedulers.TestScheduler import org.bouncycastle.util.encoders.Hex @@ -38,23 +38,19 @@ import org.scalatest.concurrent.ScalaFutures import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers -import scala.concurrent.Await -import scala.concurrent.duration.{Duration, DurationInt, FiniteDuration} +import scala.concurrent.duration.{DurationInt, FiniteDuration} // scalastyle:off file.size.limit class EthServiceSpec extends AnyFlatSpec with Matchers - with ScalaFutures with OptionValues with MockFactory - with NormalPatience with TypeCheckedTripleEquals { -// behavior of "EthService" implicit val tx: Scheduler = TestScheduler() - it should "answer eth_blockNumber with the latest block number" in new TestSetup { + "EthService" should "answer eth_blockNumber with the latest block number" in new TestSetup { val bestBlockNumber = 10 blockchain.saveBestKnownBlocks(bestBlockNumber) @@ -77,28 +73,28 @@ class EthServiceSpec it should "answer eth_getBlockTransactionCountByHash with None when the requested block isn't in the blockchain" in new TestSetup { val request = TxCountByBlockHashRequest(blockToRequestHash) - val response = Await.result(ethService.getBlockTransactionCountByHash(request), Duration.Inf).right.get + val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe().right.get response.txsQuantity shouldBe None } it should "answer eth_getBlockTransactionCountByHash with the block has no tx when the requested block is in the blockchain and has no tx" in new TestSetup { blockchain.storeBlock(blockToRequest.copy(body = BlockBody(Nil, Nil))).commit() val request = TxCountByBlockHashRequest(blockToRequestHash) - val response = Await.result(ethService.getBlockTransactionCountByHash(request), Duration.Inf).right.get + val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe().right.get response.txsQuantity shouldBe Some(0) } it should "answer eth_getBlockTransactionCountByHash correctly when the requested block is in the blockchain and has some tx" in new TestSetup { blockchain.storeBlock(blockToRequest).commit() val request = TxCountByBlockHashRequest(blockToRequestHash) - val response = Await.result(ethService.getBlockTransactionCountByHash(request), Duration.Inf).right.get + val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe().right.get response.txsQuantity shouldBe Some(blockToRequest.body.transactionList.size) } it should "answer eth_getTransactionByBlockHashAndIndex with None when there is no block with the requested hash" in new TestSetup { val txIndexToRequest = blockToRequest.body.transactionList.size / 2 val request = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, txIndexToRequest) - val response = Await.result(ethService.getTransactionByBlockHashAndIndex(request), Duration.Inf).right.get + val response = ethService.getTransactionByBlockHashAndIndex(request).runSyncUnsafe().right.get response.transactionResponse shouldBe None } @@ -108,11 +104,9 @@ class EthServiceSpec val invalidTxIndex = blockToRequest.body.transactionList.size val requestWithInvalidIndex = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, invalidTxIndex) - val response = Await - .result( - ethService.getTransactionByBlockHashAndIndex(requestWithInvalidIndex), - Duration.Inf - ) + val response = ethService + .getTransactionByBlockHashAndIndex(requestWithInvalidIndex) + .runSyncUnsafe() .right .get @@ -124,7 +118,7 @@ class EthServiceSpec val txIndexToRequest = blockToRequest.body.transactionList.size / 2 val request = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, txIndexToRequest) - val response = Await.result(ethService.getTransactionByBlockHashAndIndex(request), Duration.Inf).right.get + val response = ethService.getTransactionByBlockHashAndIndex(request).runSyncUnsafe().right.get val requestedStx = blockToRequest.body.transactionList.apply(txIndexToRequest) val expectedTxResponse = TransactionResponse(requestedStx, Some(blockToRequest.header), Some(txIndexToRequest)) @@ -137,7 +131,7 @@ class EthServiceSpec val request = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, txIndexToRequest) // when - val response = Await.result(ethService.getRawTransactionByBlockHashAndIndex(request), Duration.Inf).right.get + val response = ethService.getRawTransactionByBlockHashAndIndex(request).runSyncUnsafe().right.get // then response.transactionResponse shouldBe None @@ -309,7 +303,7 @@ class EthServiceSpec .commit() val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) - val response = Await.result(ethService.getBlockByNumber(request.copy(fullTxs = false)), Duration.Inf).right.get + val response = ethService.getBlockByNumber(request.copy(fullTxs = false)).runSyncUnsafe().right.get response.blockResponse shouldBe Some( BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd)) @@ -320,7 +314,7 @@ class EthServiceSpec it should "answer eth_getBlockByHash with None when the requested block isn't in the blockchain" in new TestSetup { val request = BlockByBlockHashRequest(blockToRequestHash, fullTxs = true) - val response = Await.result(ethService.getByBlockHash(request), Duration.Inf).right.get + val response = ethService.getByBlockHash(request).runSyncUnsafe().right.get response.blockResponse shouldBe None } @@ -331,7 +325,7 @@ class EthServiceSpec .commit() val request = BlockByBlockHashRequest(blockToRequestHash, fullTxs = true) - val response = Await.result(ethService.getByBlockHash(request), Duration.Inf).right.get + val response = ethService.getByBlockHash(request).runSyncUnsafe().right.get val stxResponses = blockToRequest.body.transactionList.zipWithIndex.map { case (stx, txIndex) => TransactionResponse(stx, Some(blockToRequest.header), Some(txIndex)) @@ -346,7 +340,7 @@ class EthServiceSpec blockchain.storeBlock(blockToRequest).commit() val request = BlockByBlockHashRequest(blockToRequestHash, fullTxs = true) - val response = Await.result(ethService.getByBlockHash(request), Duration.Inf).right.get + val response = ethService.getByBlockHash(request).runSyncUnsafe().right.get val stxResponses = blockToRequest.body.transactionList.zipWithIndex.map { case (stx, txIndex) => TransactionResponse(stx, Some(blockToRequest.header), Some(txIndex)) @@ -364,7 +358,7 @@ class EthServiceSpec .commit() val request = BlockByBlockHashRequest(blockToRequestHash, fullTxs = true) - val response = Await.result(ethService.getByBlockHash(request.copy(fullTxs = false)), Duration.Inf).right.get + val response = ethService.getByBlockHash(request.copy(fullTxs = false)).runSyncUnsafe().right.get response.blockResponse shouldBe Some( BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd)) @@ -376,7 +370,7 @@ class EthServiceSpec it should "answer eth_getUncleByBlockHashAndIndex with None when the requested block isn't in the blockchain" in new TestSetup { val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) - val response = Await.result(ethService.getUncleByBlockHashAndIndex(request), Duration.Inf).right.get + val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe().right.get response.uncleBlockResponse shouldBe None } @@ -385,7 +379,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) - val response = Await.result(ethService.getUncleByBlockHashAndIndex(request), Duration.Inf).right.get + val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe().right.get response.uncleBlockResponse shouldBe None } @@ -396,9 +390,9 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) val response1 = - Await.result(ethService.getUncleByBlockHashAndIndex(request.copy(uncleIndex = 1)), Duration.Inf).right.get + ethService.getUncleByBlockHashAndIndex(request.copy(uncleIndex = 1)).runSyncUnsafe().right.get val response2 = - Await.result(ethService.getUncleByBlockHashAndIndex(request.copy(uncleIndex = -1)), Duration.Inf).right.get + ethService.getUncleByBlockHashAndIndex(request.copy(uncleIndex = -1)).runSyncUnsafe().right.get response1.uncleBlockResponse shouldBe None response2.uncleBlockResponse shouldBe None @@ -409,7 +403,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) - val response = Await.result(ethService.getUncleByBlockHashAndIndex(request), Duration.Inf).right.get + val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe().right.get response.uncleBlockResponse shouldBe Some(BlockResponse(uncle, None, pendingBlock = false)) response.uncleBlockResponse.get.totalDifficulty shouldBe None @@ -425,7 +419,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) - val response = Await.result(ethService.getUncleByBlockHashAndIndex(request), Duration.Inf).right.get + val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe().right.get response.uncleBlockResponse shouldBe Some(BlockResponse(uncle, Some(uncleTd), pendingBlock = false)) response.uncleBlockResponse.get.totalDifficulty shouldBe Some(uncleTd) @@ -436,7 +430,7 @@ class EthServiceSpec it should "answer eth_getUncleByBlockNumberAndIndex with None when the requested block isn't in the blockchain" in new TestSetup { val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response = Await.result(ethService.getUncleByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe().right.get response.uncleBlockResponse shouldBe None } @@ -445,7 +439,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response = Await.result(ethService.getUncleByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe().right.get response.uncleBlockResponse shouldBe None } @@ -455,10 +449,8 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response1 = - Await.result(ethService.getUncleByBlockNumberAndIndex(request.copy(uncleIndex = 1)), Duration.Inf).right.get - val response2 = - Await.result(ethService.getUncleByBlockNumberAndIndex(request.copy(uncleIndex = -1)), Duration.Inf).right.get + val response1 = ethService.getUncleByBlockNumberAndIndex(request.copy(uncleIndex = 1)).runSyncUnsafe().right.get + val response2 = ethService.getUncleByBlockNumberAndIndex(request.copy(uncleIndex = -1)).runSyncUnsafe().right.get response1.uncleBlockResponse shouldBe None response2.uncleBlockResponse shouldBe None @@ -469,7 +461,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response = Await.result(ethService.getUncleByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe().right.get response.uncleBlockResponse shouldBe Some(BlockResponse(uncle, None, pendingBlock = false)) response.uncleBlockResponse.get.totalDifficulty shouldBe None @@ -485,7 +477,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response = Await.result(ethService.getUncleByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe().right.get response.uncleBlockResponse shouldBe Some(BlockResponse(uncle, Some(uncleTd), pendingBlock = false)) response.uncleBlockResponse.get.totalDifficulty shouldBe Some(uncleTd) @@ -806,7 +798,7 @@ class EthServiceSpec val txIndex: Int = 1 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.Latest, txIndex) - val response = Await.result(ethService.getTransactionByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get val expectedTxResponse = TransactionResponse(blockToRequest.body.transactionList(txIndex), Some(blockToRequest.header), Some(txIndex)) @@ -819,7 +811,7 @@ class EthServiceSpec val txIndex: Int = blockToRequest.body.transactionList.length + 42 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequest.header.number), txIndex) - val response = Await.result(ethService.getTransactionByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get response.transactionResponse shouldBe None } @@ -830,7 +822,7 @@ class EthServiceSpec val txIndex: Int = 1 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequest.header.number - 42), txIndex) - val response = Await.result(ethService.getTransactionByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get response.transactionResponse shouldBe None } @@ -841,7 +833,7 @@ class EthServiceSpec val txIndex: Int = 1 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.Latest, txIndex) - val response = Await.result(ethService.getRawTransactionByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get val expectedTxResponse = blockToRequest.body.transactionList.lift(txIndex) response.transactionResponse shouldBe expectedTxResponse @@ -853,7 +845,7 @@ class EthServiceSpec val txIndex: Int = blockToRequest.body.transactionList.length + 42 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequest.header.number), txIndex) - val response = Await.result(ethService.getRawTransactionByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get response.transactionResponse shouldBe None } @@ -864,7 +856,7 @@ class EthServiceSpec val txIndex: Int = 1 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequest.header.number - 42), txIndex) - val response = Await.result(ethService.getRawTransactionByBlockNumberAndIndex(request), Duration.Inf).right.get + val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get response.transactionResponse shouldBe None } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index 814ec39e6e..e2a539addc 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -8,50 +8,45 @@ 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.{ - OptionNoneToJNullSerializer, - QuantitiesSerializer, - UnformattedDataJsonSerializer -} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.ommers.OmmersPool import io.iohk.ethereum.ommers.OmmersPool.Ommers import io.iohk.ethereum.transactions.PendingTransactionsManager -import io.iohk.ethereum.{Fixtures, LongPatience, Timeouts} +import io.iohk.ethereum.{Fixtures, Timeouts} +import monix.eval.Task +import monix.execution.Scheduler +import monix.execution.schedulers.TestScheduler import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Extraction, Formats} -import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -import scala.concurrent.Future - // scalastyle:off magic.number class JsonRpcControllerEthSpec extends AnyFlatSpec with Matchers with JRCMatchers - with ScalaCheckPropertyChecks - with ScalaFutures - with LongPatience - with Eventually { + with ScalaCheckPropertyChecks { + + implicit val tx: Scheduler = TestScheduler() implicit val formats: Formats = DefaultFormats.preservingEmptyValues + OptionNoneToJNullSerializer + QuantitiesSerializer + UnformattedDataJsonSerializer it should "eth_protocolVersion" in new JsonRpcControllerFixture { val rpcRequest = newJsonRpcRequest("eth_protocolVersion") - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult("0x3f") } it should "handle eth_chainId" in new JsonRpcControllerFixture { val request = newJsonRpcRequest("eth_chainId") - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x3d") } @@ -61,7 +56,7 @@ class JsonRpcControllerEthSpec blockchain.saveBestKnownBlocks(bestBlockNumber) val rpcRequest = newJsonRpcRequest("eth_blockNumber") - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult(s"0xa") } @@ -74,7 +69,7 @@ class JsonRpcControllerEthSpec blockchain.saveBestKnownBlocks(200) val rpcRequest = newJsonRpcRequest("eth_syncing") - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveObjectResult( "startingBlock" -> "0x64", @@ -96,7 +91,7 @@ class JsonRpcControllerEthSpec "eth_getBlockByHash", List(JString(s"0x${blockToRequest.header.hashAsHexString}"), JBool(false)) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedBlockResponse = Extraction.decompose(BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd))) @@ -117,7 +112,7 @@ class JsonRpcControllerEthSpec "eth_getBlockByNumber", List(JString(s"0x${Hex.toHexString(blockToRequest.header.number.toByteArray)}"), JBool(false)) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedBlockResponse = Extraction.decompose(BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd))) @@ -138,7 +133,7 @@ class JsonRpcControllerEthSpec JString(s"0x${Hex.toHexString(BigInt(0).toByteArray)}") ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedUncleBlockResponse = Extraction .decompose(BlockResponse(uncle, None, pendingBlock = false)) @@ -163,7 +158,7 @@ class JsonRpcControllerEthSpec JString(s"0x${Hex.toHexString(BigInt(0).toByteArray)}") ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedUncleBlockResponse = Extraction .decompose(BlockResponse(uncle, None, pendingBlock = false)) @@ -195,7 +190,7 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_getWork") - val result: Future[JsonRpcResponse] = jsonRpcController.handleRequest(request) + val result: Task[JsonRpcResponse] = jsonRpcController.handleRequest(request) pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsManager.PendingTransactionsResponse(Nil)) @@ -203,7 +198,7 @@ class JsonRpcControllerEthSpec ommersPool.expectMsg(OmmersPool.GetOmmers(parentBlock.hash)) ommersPool.reply(Ommers(Nil)) - val response = result.futureValue + val response = result.runSyncUnsafe() response should haveResult( JArray( List( @@ -235,13 +230,13 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_getWork") - val result: Future[JsonRpcResponse] = jsonRpcController.handleRequest(request) + val result: Task[JsonRpcResponse] = jsonRpcController.handleRequest(request) pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) ommersPool.expectMsg(OmmersPool.GetOmmers(parentBlock.hash)) //on time out it should respond with empty list - val response = result.futureValue(timeout(Timeouts.longTimeout)) + val response = result.timeout(Timeouts.longTimeout).runSyncUnsafe() response should haveResult( JArray( List( @@ -280,7 +275,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveBooleanResult(true) } @@ -301,7 +296,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveBooleanResult(true) } @@ -316,7 +311,7 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_hashrate") - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x0") } @@ -328,7 +323,7 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_gasPrice") - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x4a817c800") } @@ -336,7 +331,7 @@ class JsonRpcControllerEthSpec val mockEthService = mock[EthService] override val jsonRpcController = newJsonRpcController(mockEthService) - (mockEthService.call _).expects(*).returning(Future.successful(Right(CallResponse(ByteString("asd"))))) + (mockEthService.call _).expects(*).returning(Task.now(Right(CallResponse(ByteString("asd"))))) val json = List( JObject( @@ -350,7 +345,7 @@ class JsonRpcControllerEthSpec JString("latest") ) val rpcRequest = newJsonRpcRequest("eth_call", json) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult("0x617364") } @@ -362,7 +357,7 @@ class JsonRpcControllerEthSpec (mockEthService.estimateGas _) .expects(*) .anyNumberOfTimes() - .returning(Future.successful(Right(EstimateGasResponse(2310)))) + .returning(Task.now(Right(EstimateGasResponse(2310)))) val callObj = JObject( "from" -> "0xabbb6bebfa05aa13e908eaa492bd7a8343760477", @@ -383,7 +378,7 @@ class JsonRpcControllerEthSpec forAll(table) { json => val rpcRequest = newJsonRpcRequest("eth_estimateGas", json) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult("0x906") } @@ -396,7 +391,7 @@ class JsonRpcControllerEthSpec (mockEthService.getCode _) .expects(*) - .returning(Future.successful(Right(GetCodeResponse(ByteString(Hex.decode("FFAA22")))))) + .returning(Task.now(Right(GetCodeResponse(ByteString(Hex.decode("FFAA22")))))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getCode", @@ -406,7 +401,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0xffaa22") } @@ -416,7 +411,7 @@ class JsonRpcControllerEthSpec (mockEthService.getUncleCountByBlockNumber _) .expects(*) - .returning(Future.successful(Right(GetUncleCountByBlockNumberResponse(2)))) + .returning(Task.now(Right(GetUncleCountByBlockNumberResponse(2)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getUncleCountByBlockNumber", @@ -425,7 +420,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x2") } @@ -435,7 +430,7 @@ class JsonRpcControllerEthSpec (mockEthService.getUncleCountByBlockHash _) .expects(*) - .returning(Future.successful(Right(GetUncleCountByBlockHashResponse(3)))) + .returning(Task.now(Right(GetUncleCountByBlockHashResponse(3)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getUncleCountByBlockHash", @@ -444,7 +439,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x3") } @@ -459,7 +454,7 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_coinbase") - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x000000000000000000000000000000000000002a") } @@ -469,7 +464,7 @@ class JsonRpcControllerEthSpec (mockEthService.getBalance _) .expects(*) - .returning(Future.successful(Right(GetBalanceResponse(17)))) + .returning(Task.now(Right(GetBalanceResponse(17)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getBalance", @@ -479,7 +474,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x11") } @@ -489,7 +484,7 @@ class JsonRpcControllerEthSpec (mockEthService.getStorageAt _) .expects(*) - .returning(Future.successful(Right(GetStorageAtResponse(ByteString("response"))))) + .returning(Task.now(Right(GetStorageAtResponse(ByteString("response"))))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getStorageAt", @@ -500,7 +495,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult(JString("0x" + Hex.toHexString(ByteString("response").toArray[Byte]))) } @@ -514,7 +509,7 @@ class JsonRpcControllerEthSpec None ) ) - .returns(Future.successful(Right(SignResponse(sig)))) + .returns(Task.now(Right(SignResponse(sig)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_sign", @@ -524,7 +519,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult( "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b" ) @@ -536,7 +531,7 @@ class JsonRpcControllerEthSpec (mockEthService.newFilter _) .expects(*) - .returning(Future.successful(Right(NewFilterResponse(123)))) + .returning(Task.now(Right(NewFilterResponse(123)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_newFilter", @@ -550,7 +545,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x7b") } @@ -560,7 +555,7 @@ class JsonRpcControllerEthSpec (mockEthService.newBlockFilter _) .expects(*) - .returning(Future.successful(Right(NewFilterResponse(999)))) + .returning(Task.now(Right(NewFilterResponse(999)))) val request: JsonRpcRequest = JsonRpcRequest( "2.0", @@ -569,7 +564,7 @@ class JsonRpcControllerEthSpec Some(JInt(1)) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x3e7") } @@ -579,14 +574,14 @@ class JsonRpcControllerEthSpec (mockEthService.newPendingTransactionFilter _) .expects(*) - .returning(Future.successful(Right(NewFilterResponse(2)))) + .returning(Task.now(Right(NewFilterResponse(2)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_newPendingTransactionFilter", Nil ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x2") } @@ -596,14 +591,14 @@ class JsonRpcControllerEthSpec (mockEthService.uninstallFilter _) .expects(*) - .returning(Future.successful(Right(UninstallFilterResponse(true)))) + .returning(Task.now(Right(UninstallFilterResponse(true)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_uninstallFilter", List(JString("0x1")) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveBooleanResult(true) } @@ -614,7 +609,7 @@ class JsonRpcControllerEthSpec (mockEthService.getFilterChanges _) .expects(*) .returning( - Future.successful( + Task.now( Right( GetFilterChangesResponse( FilterManager.LogFilterChanges( @@ -639,7 +634,7 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_getFilterChanges", List(JString("0x1"))) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult( JArray( List( @@ -665,7 +660,7 @@ class JsonRpcControllerEthSpec (mockEthService.getFilterLogs _) .expects(*) .returning( - Future.successful( + Task.now( Right( GetFilterLogsResponse( FilterManager.BlockFilterLogs( @@ -683,7 +678,7 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_getFilterLogs", List(JString("0x1"))) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult(JArray(List(JString("0x1234"), JString("0x4567"), JString("0x7890")))) } @@ -694,7 +689,7 @@ class JsonRpcControllerEthSpec (mockEthService.getLogs _) .expects(*) .returning( - Future.successful( + Task.now( Right( GetLogsResponse( LogFilterLogs( @@ -728,7 +723,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult( JArray( List( diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala index 364467dfb8..029ba7f4ad 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala @@ -5,34 +5,29 @@ 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.{ - OptionNoneToJNullSerializer, - QuantitiesSerializer, - UnformattedDataJsonSerializer -} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransaction -import io.iohk.ethereum.{Fixtures, LongPatience} +import io.iohk.ethereum.Fixtures +import monix.eval.Task +import monix.execution.Scheduler +import monix.execution.schedulers.TestScheduler import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Extraction, Formats} -import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -import scala.concurrent.Future - // scalastyle:off magic.number class JsonRpcControllerEthTransactionSpec extends AnyFlatSpec with Matchers with JRCMatchers - with ScalaCheckPropertyChecks - with ScalaFutures - with LongPatience - with Eventually { + with ScalaCheckPropertyChecks { + + implicit val tx: Scheduler = TestScheduler() implicit val formats: Formats = DefaultFormats.preservingEmptyValues + OptionNoneToJNullSerializer + QuantitiesSerializer + UnformattedDataJsonSerializer @@ -51,7 +46,7 @@ class JsonRpcControllerEthTransactionSpec JString(s"0x${Hex.toHexString(BigInt(txIndexToRequest).toByteArray)}") ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedStx = blockToRequest.body.transactionList.apply(txIndexToRequest) val expectedTxResponse = Extraction.decompose( TransactionResponse(expectedStx, Some(blockToRequest.header), Some(txIndexToRequest)) @@ -74,7 +69,7 @@ class JsonRpcControllerEthTransactionSpec JString(s"0x${Hex.toHexString(BigInt(txIndexToRequest).toByteArray)}") ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedTxResponse = rawTrnHex(blockToRequest.body.transactionList, txIndexToRequest) response should haveResult(expectedTxResponse) @@ -87,7 +82,7 @@ class JsonRpcControllerEthTransactionSpec val txResponse: SignedTransaction = Fixtures.Blocks.Block3125369.body.transactionList.head (mockEthService.getRawTransactionByHash _) .expects(*) - .returning(Future.successful(Right(RawTransactionResponse(Some(txResponse))))) + .returning(Task.now(Right(RawTransactionResponse(Some(txResponse))))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getRawTransactionByHash", @@ -96,7 +91,7 @@ class JsonRpcControllerEthTransactionSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult(encodeSignedTrx(txResponse)) } @@ -112,10 +107,10 @@ class JsonRpcControllerEthTransactionSpec (personalService .sendTransaction(_: SendTransactionRequest)) .expects(*) - .returning(Future.successful(Right(SendTransactionResponse(txHash)))) + .returning(Task.now(Right(SendTransactionResponse(txHash)))) val rpcRequest = newJsonRpcRequest("eth_sendTransaction", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveResult(JString(s"0x${Hex.toHexString(txHash.toArray)}")) } @@ -134,7 +129,7 @@ class JsonRpcControllerEthTransactionSpec JString(s"0x${Hex.toHexString(BigInt(txIndex).toByteArray)}") ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedStx = blockToRequest.body.transactionList(txIndex) val expectedTxResponse = Extraction.decompose( TransactionResponse(expectedStx, Some(blockToRequest.header), Some(txIndex)) @@ -157,7 +152,7 @@ class JsonRpcControllerEthTransactionSpec JString(s"0x${Hex.toHexString(BigInt(txIndex).toByteArray)}") ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedStx = blockToRequest.body.transactionList(txIndex) val expectedTxResponse = Extraction.decompose( TransactionResponse(expectedStx, Some(blockToRequest.header), Some(txIndex)) @@ -179,7 +174,7 @@ class JsonRpcControllerEthTransactionSpec JString(s"0x${Hex.toHexString(BigInt(txIndex).toByteArray)}") ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedStx = blockToRequest.body.transactionList(txIndex) val expectedTxResponse = Extraction.decompose( TransactionResponse(expectedStx, Some(blockToRequest.header), Some(txIndex)) @@ -205,7 +200,7 @@ class JsonRpcControllerEthTransactionSpec ) // when - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() // then val expectedTxResponse = rawTrnHex(blockToRequest.body.transactionList, txIndex) @@ -230,7 +225,7 @@ class JsonRpcControllerEthTransactionSpec ) // when - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() // then val expectedTxResponse = rawTrnHex(blockToRequest.body.transactionList, txIndex) @@ -251,7 +246,7 @@ class JsonRpcControllerEthTransactionSpec JString(s"0x${Hex.toHexString(BigInt(txIndex).toByteArray)}") ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedTxResponse = rawTrnHex(blockToRequest.body.transactionList, txIndex) response should haveResult(expectedTxResponse) @@ -264,7 +259,7 @@ class JsonRpcControllerEthTransactionSpec val txResponse = TransactionResponse(Fixtures.Blocks.Block3125369.body.transactionList.head) (mockEthService.getTransactionByHash _) .expects(*) - .returning(Future.successful(Right(GetTransactionByHashResponse(Some(txResponse))))) + .returning(Task.now(Right(GetTransactionByHashResponse(Some(txResponse))))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getTransactionByHash", @@ -273,7 +268,7 @@ class JsonRpcControllerEthTransactionSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult(Extraction.decompose(txResponse)) } @@ -283,7 +278,7 @@ class JsonRpcControllerEthTransactionSpec (mockEthService.getTransactionCount _) .expects(*) - .returning(Future.successful(Right(GetTransactionCountResponse(123)))) + .returning(Task.now(Right(GetTransactionCountResponse(123)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getTransactionCount", @@ -293,7 +288,7 @@ class JsonRpcControllerEthTransactionSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x7b") } @@ -303,7 +298,7 @@ class JsonRpcControllerEthTransactionSpec (mockEthService.getBlockTransactionCountByNumber _) .expects(*) - .returning(Future.successful(Right(GetBlockTransactionCountByNumberResponse(17)))) + .returning(Task.now(Right(GetBlockTransactionCountByNumberResponse(17)))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getBlockTransactionCountByNumber", @@ -312,7 +307,7 @@ class JsonRpcControllerEthTransactionSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x11") } @@ -325,7 +320,7 @@ class JsonRpcControllerEthTransactionSpec "eth_getBlockTransactionCountByHash", List(JString(s"0x${blockToRequest.header.hashAsHexString}")) ) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() val expectedTxCount = Extraction.decompose(BigInt(blockToRequest.body.transactionList.size)) response should haveResult(expectedTxCount) @@ -369,14 +364,14 @@ class JsonRpcControllerEthTransactionSpec ) ) - (mockEthService.getTransactionReceipt _).expects(*).returning(Future.successful(mockResponse)) + (mockEthService.getTransactionReceipt _).expects(*).returning(Task.now(mockResponse)) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getTransactionReceipt", List(JString(s"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238")) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult( JObject( JField("transactionHash", JString("0x" + "23" * 32)), @@ -414,7 +409,7 @@ class JsonRpcControllerEthTransactionSpec val mockEthService = mock[EthService] (mockEthService.ethPendingTransactions _) .expects(*) - .returning(Future.successful(Right(EthPendingTransactionsResponse(List())))) + .returning(Task.now(Right(EthPendingTransactionsResponse(List())))) val jRpcController = new JsonRpcController( web3Service, @@ -439,7 +434,7 @@ class JsonRpcControllerEthTransactionSpec Some(JInt(1)) ) - val response: JsonRpcResponse = jRpcController.handleRequest(request).futureValue + val response: JsonRpcResponse = jRpcController.handleRequest(request).runSyncUnsafe() response should haveResult(JArray(List())) } @@ -464,7 +459,7 @@ class JsonRpcControllerEthTransactionSpec val mockEthService = mock[EthService] (mockEthService.ethPendingTransactions _) .expects(*) - .returning(Future.successful(Right(EthPendingTransactionsResponse(transactions)))) + .returning(Task.now(Right(EthPendingTransactionsResponse(transactions)))) val jRpcController = new JsonRpcController( web3Service, @@ -488,7 +483,7 @@ class JsonRpcControllerEthTransactionSpec Some(JInt(1)) ) - val response: JsonRpcResponse = jRpcController.handleRequest(request).futureValue + val response: JsonRpcResponse = jRpcController.handleRequest(request).runSyncUnsafe() val result = JArray( transactions diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala index 8055b97590..3c383cbf79 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala @@ -3,33 +3,27 @@ package io.iohk.ethereum.jsonrpc import java.time.Duration import akka.util.ByteString -import io.iohk.ethereum.LongPatience import io.iohk.ethereum.domain._ -import io.iohk.ethereum.jsonrpc.JsonSerializers.{ - OptionNoneToJNullSerializer, - QuantitiesSerializer, - UnformattedDataJsonSerializer -} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} import io.iohk.ethereum.jsonrpc.PersonalService._ +import monix.eval.Task +import monix.execution.Scheduler +import monix.execution.schedulers.TestScheduler import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Formats} -import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -import scala.concurrent.Future - class JsonRpcControllerPersonalSpec extends AnyFlatSpec with Matchers with JRCMatchers - with ScalaCheckPropertyChecks - with ScalaFutures - with LongPatience - with Eventually { + with ScalaCheckPropertyChecks { + + implicit val tx: Scheduler = TestScheduler() implicit val formats: Formats = DefaultFormats.preservingEmptyValues + OptionNoneToJNullSerializer + QuantitiesSerializer + UnformattedDataJsonSerializer @@ -42,11 +36,11 @@ class JsonRpcControllerPersonalSpec (personalService.importRawKey _) .expects(ImportRawKeyRequest(keyBytes, pass)) - .returning(Future.successful(Right(ImportRawKeyResponse(addr)))) + .returning(Task.now(Right(ImportRawKeyResponse(addr)))) val params = JString(key) :: JString(pass) :: Nil val rpcRequest = newJsonRpcRequest("personal_importRawKey", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult(addr.toString) } @@ -57,11 +51,11 @@ class JsonRpcControllerPersonalSpec (personalService.newAccount _) .expects(NewAccountRequest(pass)) - .returning(Future.successful(Right(NewAccountResponse(addr)))) + .returning(Task.now(Right(NewAccountResponse(addr)))) val params = JString(pass) :: Nil val rpcRequest = newJsonRpcRequest("personal_newAccount", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult(addr.toString) } @@ -72,10 +66,10 @@ class JsonRpcControllerPersonalSpec (personalService.listAccounts _) .expects(ListAccountsRequest()) - .returning(Future.successful(Right(ListAccountsResponse(addresses)))) + .returning(Task.now(Right(ListAccountsResponse(addresses)))) val rpcRequest = newJsonRpcRequest("personal_listAccounts") - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveResult(JArray(addresses.map(a => JString(a.toString)))) } @@ -87,10 +81,10 @@ class JsonRpcControllerPersonalSpec (personalService.unlockAccount _) .expects(UnlockAccountRequest(address, pass, None)) - .returning(Future.successful(Right(UnlockAccountResponse(true)))) + .returning(Task.now(Right(UnlockAccountResponse(true)))) val rpcRequest = newJsonRpcRequest("personal_unlockAccount", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveBooleanResult(true) } @@ -103,10 +97,10 @@ class JsonRpcControllerPersonalSpec (personalService.unlockAccount _) .expects(UnlockAccountRequest(address, pass, Some(Duration.ofSeconds(1)))) - .returning(Future.successful(Right(UnlockAccountResponse(true)))) + .returning(Task.now(Right(UnlockAccountResponse(true)))) val rpcRequest = newJsonRpcRequest("personal_unlockAccount", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveBooleanResult(true) } @@ -118,14 +112,14 @@ class JsonRpcControllerPersonalSpec val params = JString(address.toString) :: JString(pass) :: JString(dur) :: Nil val rpcRequest = newJsonRpcRequest("personal_unlockAccount", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveError(JsonRpcError(-32602, "Invalid method parameters", None)) val dur2 = Long.MaxValue val params2 = JString(address.toString) :: JString(pass) :: JInt(dur2) :: Nil val rpcRequest2 = newJsonRpcRequest("personal_unlockAccount", params2) - val response2 = jsonRpcController.handleRequest(rpcRequest2).futureValue + val response2 = jsonRpcController.handleRequest(rpcRequest2).runSyncUnsafe() response2 should haveError( JsonRpcError(-32602, "Duration should be an number of seconds, less than 2^31 - 1", None) ) @@ -138,10 +132,10 @@ class JsonRpcControllerPersonalSpec (personalService.unlockAccount _) .expects(UnlockAccountRequest(address, pass, None)) - .returning(Future.successful(Right(UnlockAccountResponse(true)))) + .returning(Task.now(Right(UnlockAccountResponse(true)))) val rpcRequest = newJsonRpcRequest("personal_unlockAccount", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveBooleanResult(true) } @@ -152,10 +146,10 @@ class JsonRpcControllerPersonalSpec (personalService.lockAccount _) .expects(LockAccountRequest(address)) - .returning(Future.successful(Right(LockAccountResponse(true)))) + .returning(Task.now(Right(LockAccountResponse(true)))) val rpcRequest = newJsonRpcRequest("personal_lockAccount", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveBooleanResult(true) } @@ -172,10 +166,10 @@ class JsonRpcControllerPersonalSpec (personalService .sendTransaction(_: SendTransactionWithPassphraseRequest)) .expects(*) - .returning(Future.successful(Right(SendTransactionWithPassphraseResponse(txHash)))) + .returning(Task.now(Right(SendTransactionWithPassphraseResponse(txHash)))) val rpcRequest = newJsonRpcRequest("personal_sendTransaction", params) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveResult(JString(s"0x${Hex.toHexString(txHash.toArray)}")) } @@ -190,7 +184,7 @@ class JsonRpcControllerPersonalSpec Some("thePassphrase") ) ) - .returns(Future.successful(Right(SignResponse(sig)))) + .returns(Task.now(Right(SignResponse(sig)))) val request: JsonRpcRequest = newJsonRpcRequest( "personal_sign", @@ -201,7 +195,7 @@ class JsonRpcControllerPersonalSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult( "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b" ) @@ -212,7 +206,7 @@ class JsonRpcControllerPersonalSpec (personalService.ecRecover _) .expects(EcRecoverRequest(ByteString(Hex.decode("deadbeaf")), sig)) .returns( - Future.successful( + Task.now( Right(EcRecoverResponse(Address(ByteString(Hex.decode("9b2055d370f73ec7d8a03e965129118dc8f5bf83"))))) ) ) @@ -227,7 +221,7 @@ class JsonRpcControllerPersonalSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveStringResult("0x9b2055d370f73ec7d8a03e965129118dc8f5bf83") } } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala index f9fe65e66f..66ebf9aa13 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala @@ -3,37 +3,33 @@ package io.iohk.ethereum.jsonrpc 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.{ - OptionNoneToJNullSerializer, - QuantitiesSerializer, - UnformattedDataJsonSerializer -} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} import io.iohk.ethereum.jsonrpc.NetService.{ListeningResponse, PeerCountResponse, VersionResponse} import io.iohk.ethereum.jsonrpc.server.http.JsonRpcHttpServer import io.iohk.ethereum.jsonrpc.server.ipc.JsonRpcIpcServer import io.iohk.ethereum.network.EtcPeerManagerActor.PeerInfo import io.iohk.ethereum.network.p2p.messages.CommonMessages.Status import io.iohk.ethereum.network.p2p.messages.Versions -import io.iohk.ethereum.{Fixtures, LongPatience} +import io.iohk.ethereum.Fixtures +import monix.eval.Task +import monix.execution.Scheduler +import monix.execution.schedulers.TestScheduler import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Extraction, Formats} -import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -import scala.concurrent.Future import scala.concurrent.duration._ class JsonRpcControllerSpec extends AnyFlatSpec with Matchers with JRCMatchers - with ScalaCheckPropertyChecks - with ScalaFutures - with LongPatience - with Eventually { + with ScalaCheckPropertyChecks { + + implicit val tx: Scheduler = TestScheduler() implicit val formats: Formats = DefaultFormats.preservingEmptyValues + OptionNoneToJNullSerializer + QuantitiesSerializer + UnformattedDataJsonSerializer @@ -41,7 +37,7 @@ class JsonRpcControllerSpec "JsonRpcController" should "handle valid sha3 request" in new JsonRpcControllerFixture { val rpcRequest = newJsonRpcRequest("web3_sha3", JString("0x1234") :: Nil) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult("0x56570de287d73cd1cb6092bb8fdee6173974955fdef345ae579ee9f475ea7432") } @@ -49,7 +45,7 @@ class JsonRpcControllerSpec it should "fail when invalid request is received" in new JsonRpcControllerFixture { val rpcRequest = newJsonRpcRequest("web3_sha3", JString("asdasd") :: Nil) - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveError(JsonRpcErrors.InvalidParams("Invalid method parameters")) } @@ -57,26 +53,26 @@ class JsonRpcControllerSpec it should "handle clientVersion request" in new JsonRpcControllerFixture { val rpcRequest = newJsonRpcRequest("web3_clientVersion") - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult(version) } it should "Handle net_peerCount request" in new JsonRpcControllerFixture { - (netService.peerCount _).expects(*).returning(Future.successful(Right(PeerCountResponse(123)))) + (netService.peerCount _).expects(*).returning(Task.now(Right(PeerCountResponse(123)))) val rpcRequest = newJsonRpcRequest("net_peerCount") - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult("0x7b") } it should "Handle net_listening request" in new JsonRpcControllerFixture { - (netService.listening _).expects(*).returning(Future.successful(Right(ListeningResponse(false)))) + (netService.listening _).expects(*).returning(Task.now(Right(ListeningResponse(false)))) val rpcRequest = newJsonRpcRequest("net_listening") - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveBooleanResult(false) } @@ -84,10 +80,10 @@ class JsonRpcControllerSpec it should "Handle net_version request" in new JsonRpcControllerFixture { val netVersion = "99" - (netService.version _).expects(*).returning(Future.successful(Right(VersionResponse(netVersion)))) + (netService.version _).expects(*).returning(Task.now(Right(VersionResponse(netVersion)))) val rpcRequest = newJsonRpcRequest("net_version") - val response = jsonRpcController.handleRequest(rpcRequest).futureValue + val response = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveStringResult(netVersion) } @@ -102,12 +98,12 @@ class JsonRpcControllerSpec } val ethRpcRequest = newJsonRpcRequest("eth_protocolVersion") - val ethResponse = jsonRpcController.handleRequest(ethRpcRequest).futureValue + val ethResponse = jsonRpcController.handleRequest(ethRpcRequest).runSyncUnsafe() ethResponse should haveError(JsonRpcErrors.MethodNotFound) val web3RpcRequest = newJsonRpcRequest("web3_clientVersion") - val web3Response = jsonRpcController.handleRequest(web3RpcRequest).futureValue + val web3Response = jsonRpcController.handleRequest(web3RpcRequest).runSyncUnsafe() web3Response should haveStringResult(version) } @@ -131,10 +127,10 @@ class JsonRpcControllerSpec (debugService.listPeersInfo _) .expects(ListPeersInfoRequest()) - .returning(Future.successful(Right(ListPeersInfoResponse(peers)))) + .returning(Task.now(Right(ListPeersInfoResponse(peers)))) val rpcRequest = newJsonRpcRequest("debug_listPeersInfo") - val response: JsonRpcResponse = jsonRpcController.handleRequest(rpcRequest).futureValue + val response: JsonRpcResponse = jsonRpcController.handleRequest(rpcRequest).runSyncUnsafe() response should haveResult(JArray(peers.map(info => JString(info.toString)))) } @@ -142,7 +138,7 @@ class JsonRpcControllerSpec it should "rpc_modules" in new JsonRpcControllerFixture { val request: JsonRpcRequest = newJsonRpcRequest("rpc_modules") - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult( JObject( @@ -170,7 +166,7 @@ class JsonRpcControllerSpec (mockEthService.getAccountTransactions _) .expects(*) .returning( - Future.successful( + Task.now( Right( GetAccountTransactionsResponse( Seq( @@ -191,7 +187,7 @@ class JsonRpcControllerSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedTxs = Seq( Extraction.decompose(TransactionResponse(sentTx, Some(block.header), isOutgoing = Some(true))), Extraction.decompose(TransactionResponse(receivedTx, Some(block.header), isOutgoing = Some(false))) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala index 46a0478dd2..1368a5857e 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala @@ -11,25 +11,30 @@ import io.iohk.ethereum.jsonrpc.QAService.MineBlocksResponse.MinerResponseType._ import io.iohk.ethereum.jsonrpc.QAService._ import io.iohk.ethereum.nodebuilder.BlockchainConfigBuilder import io.iohk.ethereum.utils.{ByteStringUtils, Config} -import io.iohk.ethereum.{ByteGenerators, NormalPatience, crypto} +import io.iohk.ethereum.{ByteGenerators, crypto} +import monix.eval.Task +import monix.execution.Scheduler +import monix.execution.schedulers.TestScheduler import org.json4s.Extraction import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.scalamock.scalatest.MockFactory -import org.scalatest.concurrent.ScalaFutures import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -import scala.concurrent.Future +class QaJRCSpec + extends AnyWordSpec + with Matchers + with JsonMethodsImplicits { -class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalPatience with JsonMethodsImplicits { + implicit val tx: Scheduler = TestScheduler() "QaJRC" should { "request block mining and return valid response with correct message" when { "mining ordered" in new TestSetup { mockSuccessfulMineBlocksBehaviour(MinerResponses.MiningOrdered) - val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).futureValue + val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).runSyncUnsafe() response should haveObjectResult(responseType(MiningOrdered), nullMessage) } @@ -37,7 +42,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP "miner is working" in new TestSetup { mockSuccessfulMineBlocksBehaviour(MinerResponses.MinerIsWorking) - val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).futureValue + val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).runSyncUnsafe() response should haveObjectResult(responseType(MinerIsWorking), nullMessage) } @@ -45,7 +50,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP "miner doesn't exist" in new TestSetup { mockSuccessfulMineBlocksBehaviour(MinerResponses.MinerNotExist) - val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).futureValue + val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).runSyncUnsafe() response should haveObjectResult(responseType(MinerNotExist), nullMessage) } @@ -53,7 +58,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP "miner not support current msg" in new TestSetup { mockSuccessfulMineBlocksBehaviour(MinerResponses.MinerNotSupport(MineBlocks(1, true))) - val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).futureValue + val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).runSyncUnsafe() response should haveObjectResult(responseType(MinerNotSupport), msg("MineBlocks(1,true,None)")) } @@ -61,7 +66,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP "miner return error" in new TestSetup { mockSuccessfulMineBlocksBehaviour(MinerResponses.MiningError("error")) - val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).futureValue + val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).runSyncUnsafe() response should haveObjectResult(responseType(MiningError), msg("error")) } @@ -71,9 +76,9 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP "communication with miner failed" in new TestSetup { (qaService.mineBlocks _) .expects(mineBlocksReq) - .returning(Future.failed(new ClassCastException("error"))) + .returning(Task.raiseError(new ClassCastException("error"))) - val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).futureValue + val response: JsonRpcResponse = jsonRpcController.handleRequest(mineBlocksRpcRequest).runSyncUnsafe() response should haveError(JsonRpcErrors.InternalError) } @@ -83,10 +88,10 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP "given block to be checkpointed exists and checkpoint is generated correctly" in new TestSetup { (qaService.generateCheckpoint _) .expects(generateCheckpointReq) - .returning(Future.successful(Right(GenerateCheckpointResponse(checkpoint)))) + .returning(Task.now(Right(GenerateCheckpointResponse(checkpoint)))) val response: JsonRpcResponse = - jsonRpcController.handleRequest(generateCheckpointRpcRequest).futureValue + jsonRpcController.handleRequest(generateCheckpointRpcRequest).runSyncUnsafe() response should haveResult(Extraction.decompose(checkpoint)) } @@ -108,10 +113,10 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP val expectedServiceReq = generateCheckpointReq.copy(blockHash = None) (qaService.generateCheckpoint _) .expects(expectedServiceReq) - .returning(Future.successful(Right(GenerateCheckpointResponse(checkpoint)))) + .returning(Task.now(Right(GenerateCheckpointResponse(checkpoint)))) val response: JsonRpcResponse = - jsonRpcController.handleRequest(req).futureValue + jsonRpcController.handleRequest(req).runSyncUnsafe() response should haveResult(Extraction.decompose(checkpoint)) } @@ -132,7 +137,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP ) ) val response: JsonRpcResponse = - jsonRpcController.handleRequest(req).futureValue + jsonRpcController.handleRequest(req).runSyncUnsafe() response should haveError(JsonRpcErrors.InvalidParams()) } @@ -151,7 +156,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP ) ) val response: JsonRpcResponse = - jsonRpcController.handleRequest(req).futureValue + jsonRpcController.handleRequest(req).runSyncUnsafe() response should haveError( JsonRpcErrors.InvalidParams("Unable to parse private key, expected byte data but got: JInt(1)") @@ -172,7 +177,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP ) ) val response: JsonRpcResponse = - jsonRpcController.handleRequest(req).futureValue + jsonRpcController.handleRequest(req).runSyncUnsafe() response should haveError(JsonRpcErrors.InvalidParams()) } @@ -182,10 +187,10 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP "generating failed" in new TestSetup { (qaService.generateCheckpoint _) .expects(generateCheckpointReq) - .returning(Future.failed(new RuntimeException("error"))) + .returning(Task.raiseError(new RuntimeException("error"))) val response: JsonRpcResponse = - jsonRpcController.handleRequest(generateCheckpointRpcRequest).futureValue + jsonRpcController.handleRequest(generateCheckpointRpcRequest).runSyncUnsafe() response should haveError(JsonRpcErrors.InternalError) } @@ -196,10 +201,10 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP val checkpointPubKeys: Seq[ByteString] = blockchainConfig.checkpointPubKeys.toList (qaService.getFederationMembersInfo _) .expects(GetFederationMembersInfoRequest()) - .returning(Future.successful(Right(GetFederationMembersInfoResponse(checkpointPubKeys)))) + .returning(Task.now(Right(GetFederationMembersInfoResponse(checkpointPubKeys)))) val response: JsonRpcResponse = - jsonRpcController.handleRequest(getFederationMembersInfoRpcRequest).futureValue + jsonRpcController.handleRequest(getFederationMembersInfoRpcRequest).runSyncUnsafe() val result = JObject( "membersPublicKeys" -> JArray( @@ -215,10 +220,10 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP "getting federation members info failed" in new TestSetup { (qaService.getFederationMembersInfo _) .expects(GetFederationMembersInfoRequest()) - .returning(Future.failed(new RuntimeException("error"))) + .returning(Task.raiseError(new RuntimeException("error"))) val response: JsonRpcResponse = - jsonRpcController.handleRequest(getFederationMembersInfoRpcRequest).futureValue + jsonRpcController.handleRequest(getFederationMembersInfoRpcRequest).runSyncUnsafe() response should haveError(JsonRpcErrors.InternalError) } @@ -316,7 +321,7 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP def mockSuccessfulMineBlocksBehaviour(resp: MinerResponse) = { (qaService.mineBlocks _) .expects(mineBlocksReq) - .returning(Future.successful(Right(MineBlocksResponse(resp)))) + .returning(Task.now(Right(MineBlocksResponse(resp)))) } val fakeChainId: Byte = 42.toByte diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala index 3a572ea62a..cb2b3fadd7 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala @@ -7,19 +7,22 @@ import akka.http.scaladsl.testkit.ScalatestRouteTest import akka.util.ByteString import ch.megard.akka.http.cors.scaladsl.model.HttpOriginMatcher import io.iohk.ethereum.jsonrpc.server.http.JsonRpcHttpServer.JsonRpcHttpServerConfig -import io.iohk.ethereum.jsonrpc.{JsonRpcController, JsonRpcResponse, JsonRpcHealthChecker} +import io.iohk.ethereum.jsonrpc.{JsonRpcController, JsonRpcHealthChecker, JsonRpcResponse} +import monix.eval.Task import org.json4s.JsonAST.{JInt, JString} import org.scalamock.scalatest.MockFactory -import scala.concurrent.Future import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers -class JsonRpcHttpServerSpec extends AnyFlatSpec with Matchers with ScalatestRouteTest { +class JsonRpcHttpServerSpec + extends AnyFlatSpec + with Matchers + with ScalatestRouteTest { it should "pass valid json request to controller" in new TestSetup { (mockJsonRpcController.handleRequest _) .expects(*) - .returning(Future.successful(JsonRpcResponse("2.0", Some(JString("this is a response")), None, JInt(1)))) + .returning(Task.now(JsonRpcResponse("2.0", Some(JString("this is a response")), None, JInt(1)))) val jsonRequest = ByteString("""{"jsonrpc":"2.0", "method": "asd", "id": "1"}""") val postRequest = @@ -35,7 +38,7 @@ class JsonRpcHttpServerSpec extends AnyFlatSpec with Matchers with ScalatestRout (mockJsonRpcController.handleRequest _) .expects(*) .twice() - .returning(Future.successful(JsonRpcResponse("2.0", Some(JString("this is a response")), None, JInt(1)))) + .returning(Task.now(JsonRpcResponse("2.0", Some(JString("this is a response")), None, JInt(1)))) val jsonRequest = ByteString("""[{"jsonrpc":"2.0", "method": "asd", "id": "1"}, {"jsonrpc":"2.0", "method": "asd", "id": "2"}]""") @@ -77,7 +80,7 @@ class JsonRpcHttpServerSpec extends AnyFlatSpec with Matchers with ScalatestRout (mockJsonRpcController.handleRequest _) .expects(*) - .returning(Future.successful(JsonRpcResponse("2.0", Some(JString("this is a response")), None, JInt(1)))) + .returning(Task.now(JsonRpcResponse("2.0", Some(JString("this is a response")), None, JInt(1)))) val jsonRequest = ByteString("""{"jsonrpc":"2.0", "method": "eth_blockNumber", "id": "1"}""") val postRequest = HttpRequest( @@ -126,5 +129,4 @@ class JsonRpcHttpServerSpec extends AnyFlatSpec with Matchers with ScalatestRout override def corsAllowedOrigins: HttpOriginMatcher = HttpOriginMatcher(corsAllowedOrigin) } } - } From 163114316cc7bc91f3c61560baa6f461e8a874fd Mon Sep 17 00:00:00 2001 From: lemastero Date: Thu, 22 Oct 2020 20:07:07 +0200 Subject: [PATCH 03/33] [ETCM-269] port tests Future to Task in JSON-RPC 2 --- .../scala/io/iohk/ethereum/SpecBase.scala | 13 ---- .../consensus/ethash/EthashMinerSpec.scala | 5 +- .../jsonrpc/CheckpointingJRCSpec.scala | 30 ++++---- .../jsonrpc/CheckpointingServiceSpec.scala | 7 +- .../ethereum/jsonrpc/DebugServiceSpec.scala | 7 +- .../ethereum/jsonrpc/EthServiceSpec.scala | 12 ++-- .../jsonrpc/JsonRpcControllerEthSpec.scala | 12 ++-- .../JsonRpcControllerEthTransactionSpec.scala | 6 +- .../JsonRpcControllerPersonalSpec.scala | 12 ++-- .../jsonrpc/JsonRpcControllerSpec.scala | 12 ++-- .../ethereum/jsonrpc/NetServiceSpec.scala | 14 ++-- .../jsonrpc/PersonalServiceSpec.scala | 71 ++++++++++--------- .../iohk/ethereum/jsonrpc/QAServiceSpec.scala | 10 +-- .../io/iohk/ethereum/jsonrpc/QaJRCSpec.scala | 5 +- .../server/http/JsonRpcHttpServerSpec.scala | 5 +- 15 files changed, 108 insertions(+), 113 deletions(-) diff --git a/src/test/scala/io/iohk/ethereum/SpecBase.scala b/src/test/scala/io/iohk/ethereum/SpecBase.scala index c020650799..d59b704204 100644 --- a/src/test/scala/io/iohk/ethereum/SpecBase.scala +++ b/src/test/scala/io/iohk/ethereum/SpecBase.scala @@ -27,19 +27,11 @@ trait SpecBase extends TypeCheckedTripleEquals with Diagrams with Matchers { sel fixture.use(theTest).toIO.unsafeToFuture() } - def customTestCaseResourceF[T](fixture: Resource[Task, T])(theTest: T => Future[Assertion]): Future[Assertion] = - customTestCaseResourceM(fixture)(f => Task.deferFuture(theTest(f))) - def customTestCaseM[M[_]: Effect, T](fixture: => T)(theTest: T => M[Assertion]): Future[Assertion] = customTestCaseResourceM(Resource.pure[M, T](fixture))(theTest) - def customTestCaseF[T](fixture: => T)(theTest: T => Future[Assertion]): Future[Assertion] = - customTestCaseResourceF(Resource.pure[Task, T](fixture))(theTest) - def testCaseM[M[_]: Effect](theTest: => M[Assertion]): Future[Assertion] = customTestCaseM(())(_ => theTest) - def testCaseF(theTest: => Future[Assertion]): Future[Assertion] = customTestCaseF(())(_ => theTest) - def testCase(theTest: => Assertion): Future[Assertion] = testCaseM(Task.pure(theTest)) } @@ -57,8 +49,6 @@ trait SpecFixtures { self: SpecBase => def testCaseM[M[_]: Effect](theTest: Fixture => M[Assertion]): Future[Assertion] = customTestCaseM(createFixture())(theTest) - def testCaseF(theTest: Fixture => Future[Assertion]): Future[Assertion] = customTestCaseF(createFixture())(theTest) - def testCase(theTest: Fixture => Assertion): Future[Assertion] = testCaseM((fixture: Fixture) => Task.pure(theTest(fixture))) } @@ -77,9 +67,6 @@ trait ResourceFixtures { self: SpecBase => def testCaseT(theTest: Fixture => Task[Assertion]): Future[Assertion] = customTestCaseResourceM(fixtureResource)(theTest) - def testCaseF(theTest: Fixture => Future[Assertion]): Future[Assertion] = - customTestCaseResourceF(fixtureResource)(theTest) - def testCase(theTest: Fixture => Assertion): Future[Assertion] = customTestCaseResourceM(fixtureResource)(fixture => Task.pure(theTest(fixture))) } diff --git a/src/test/scala/io/iohk/ethereum/consensus/ethash/EthashMinerSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/ethash/EthashMinerSpec.scala index 959443f75c..34d95d4b3a 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/ethash/EthashMinerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/ethash/EthashMinerSpec.scala @@ -12,10 +12,11 @@ import io.iohk.ethereum.jsonrpc.EthService import io.iohk.ethereum.jsonrpc.EthService.SubmitHashRateResponse import io.iohk.ethereum.ommers.OmmersPool import io.iohk.ethereum.transactions.PendingTransactionsManager +import monix.eval.Task import org.bouncycastle.util.encoders.Hex import org.scalamock.scalatest.MockFactory import org.scalatest.Tag -import scala.concurrent.Future + import scala.concurrent.duration._ import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers @@ -32,7 +33,7 @@ class EthashMinerSpec extends TestKit(ActorSystem("EthashMinerSpec_System")) wit (blockchain.getBestBlock _).expects().returns(parent).anyNumberOfTimes() (ethService.submitHashRate _) .expects(*) - .returns(Future.successful(Right(SubmitHashRateResponse(true)))) + .returns(Task.now(Right(SubmitHashRateResponse(true)))) .atLeastOnce() (blockGenerator.generateBlock _) .expects(parent, Nil, consensusConfig.coinbase, Nil) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingJRCSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingJRCSpec.scala index fab2ec379d..d40b64de1a 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingJRCSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingJRCSpec.scala @@ -8,6 +8,8 @@ import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams import io.iohk.ethereum.nodebuilder.SecureRandomBuilder import io.iohk.ethereum.utils.{ByteStringUtils, Config} import io.iohk.ethereum.{Fixtures, NormalPatience, crypto} +import monix.eval.Task +import monix.execution.Scheduler.Implicits.global import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.scalamock.scalatest.MockFactory @@ -15,8 +17,6 @@ import org.scalatest.concurrent.ScalaFutures import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers -import scala.concurrent.Future - class CheckpointingJRCSpec extends AnyFlatSpec with Matchers @@ -34,35 +34,35 @@ class CheckpointingJRCSpec val servResp = GetLatestBlockResponse(block.hash, block.number) (checkpointingService.getLatestBlock _) .expects(GetLatestBlockRequest(4)) - .returning(Future.successful(Right(servResp))) + .returning(Task.now(Right(servResp))) val expectedResult = JObject( "hash" -> JString("0x" + ByteStringUtils.hash2string(block.hash)), "number" -> JInt(block.number) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult(expectedResult) } it should "return invalid params when checkpoint interval is not positive (getLatestBlock)" in new TestSetup { val request = getLatestBlockRequestBuilder(JArray(JInt(-1) :: Nil)) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(expectedPositiveIntegerError) } it should "return invalid params when checkpoint interval is too big (getLatestBlock)" in new TestSetup { val request = getLatestBlockRequestBuilder(JArray(JInt(BigInt(Int.MaxValue) + 1) :: Nil)) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(expectedPositiveIntegerError) } it should "return invalid params when checkpoint interval is missing (getLatestBlock)" in new TestSetup { val request = getLatestBlockRequestBuilder(JArray(Nil)) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(InvalidParams()) } @@ -82,11 +82,11 @@ class CheckpointingJRCSpec (checkpointingService.pushCheckpoint _) .expects(servReq) - .returning(Future.successful(Right(servResp))) + .returning(Task.now(Right(servResp))) val expectedResult = JBool(true) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveResult(expectedResult) } @@ -95,7 +95,7 @@ class CheckpointingJRCSpec JArray(JString(ByteStringUtils.hash2string(block.hash)) :: Nil) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(InvalidParams()) } @@ -111,7 +111,7 @@ class CheckpointingJRCSpec val expectedError = InvalidParams(s"Invalid value [$badHash], expected 32 bytes") - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(expectedError) } @@ -125,7 +125,7 @@ class CheckpointingJRCSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(InvalidParams()) } @@ -140,7 +140,7 @@ class CheckpointingJRCSpec val expectedError = InvalidParams("Unable to extract a signature from: JBool(true)") - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(expectedError) } @@ -153,7 +153,7 @@ class CheckpointingJRCSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(InvalidParams()) } @@ -168,7 +168,7 @@ class CheckpointingJRCSpec val expectedError = InvalidParams("Bad signature length") - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(expectedError) } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala index a4941050d1..6024c82786 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala @@ -6,6 +6,7 @@ import io.iohk.ethereum.blockchain.sync.regular.RegularSync.NewCheckpoint import io.iohk.ethereum.domain.{Block, BlockBody, BlockchainImpl} import io.iohk.ethereum.jsonrpc.CheckpointingService._ import io.iohk.ethereum.{Fixtures, NormalPatience} +import monix.execution.Scheduler.Implicits.global import org.scalacheck.Gen import org.scalamock.scalatest.MockFactory import org.scalatest.concurrent.ScalaFutures @@ -42,7 +43,7 @@ class CheckpointingServiceSpec (blockchain.getBlockByNumber _).expects(checkpointedBlockNum).returning(Some(block)) val result = service.getLatestBlock(request) - result.futureValue shouldEqual Right(expectedResponse) + result.runSyncUnsafe() shouldEqual Right(expectedResponse) } } @@ -56,7 +57,7 @@ class CheckpointingServiceSpec val result = service.pushCheckpoint(request) syncController.expectMsg(NewCheckpoint(hash, signatures)) - result.futureValue shouldEqual Right(expectedResponse) + result.runSyncUnsafe() shouldEqual Right(expectedResponse) } it should "get latest block in case of blockchain re-org" in new TestSetup { @@ -77,7 +78,7 @@ class CheckpointingServiceSpec val result = service.getLatestBlock(GetLatestBlockRequest(4)) - result.futureValue shouldEqual Right(expectedResponse) + result.runSyncUnsafe() shouldEqual Right(expectedResponse) } trait TestSetup { diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala index 95b65122a3..69e5b04d60 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala @@ -11,6 +11,7 @@ import io.iohk.ethereum.network.PeerManagerActor.Peers import io.iohk.ethereum.network.p2p.messages.CommonMessages.Status import io.iohk.ethereum.network.p2p.messages.Versions import io.iohk.ethereum.network.{EtcPeerManagerActor, Peer, PeerActor, PeerManagerActor} +import monix.execution.Scheduler.Implicits.global import org.scalamock.scalatest.MockFactory import org.scalatest.concurrent.ScalaFutures import org.scalatest.flatspec.AnyFlatSpec @@ -28,7 +29,7 @@ class DebugServiceSpec extends AnyFlatSpec with Matchers with MockFactory with S etcPeerManager.expectMsg(EtcPeerManagerActor.PeerInfoRequest(peer1.id)) etcPeerManager.reply(EtcPeerManagerActor.PeerInfoResponse(Some(peer1Info))) - result.futureValue shouldBe Right(ListPeersInfoResponse(List(peer1Info))) + result.runSyncUnsafe() shouldBe Right(ListPeersInfoResponse(List(peer1Info))) } @@ -39,7 +40,7 @@ class DebugServiceSpec extends AnyFlatSpec with Matchers with MockFactory with S peerManager.expectMsg(PeerManagerActor.GetPeers) peerManager.reply(Peers(Map.empty)) - result.futureValue shouldBe Right(ListPeersInfoResponse(List.empty)) + result.runSyncUnsafe() shouldBe Right(ListPeersInfoResponse(List.empty)) } it should "return empty list if there is no peer info" in new TestSetup { @@ -52,7 +53,7 @@ class DebugServiceSpec extends AnyFlatSpec with Matchers with MockFactory with S etcPeerManager.expectMsg(EtcPeerManagerActor.PeerInfoRequest(peer1.id)) etcPeerManager.reply(EtcPeerManagerActor.PeerInfoResponse(None)) - result.futureValue shouldBe Right(ListPeersInfoResponse(List.empty)) + result.runSyncUnsafe() shouldBe Right(ListPeersInfoResponse(List.empty)) } trait TestSetup { diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index b63bd79adc..8b21c792f8 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -28,8 +28,7 @@ import io.iohk.ethereum.transactions.PendingTransactionsManager.{ } import io.iohk.ethereum.utils._ import io.iohk.ethereum.{Fixtures, Timeouts, crypto} -import monix.execution.Scheduler -import monix.execution.schedulers.TestScheduler +import monix.execution.Scheduler.Implicits.global import org.bouncycastle.util.encoders.Hex import org.scalactic.TypeCheckedTripleEquals import org.scalamock.scalatest.MockFactory @@ -44,12 +43,11 @@ import scala.concurrent.duration.{DurationInt, FiniteDuration} class EthServiceSpec extends AnyFlatSpec with Matchers + with ScalaFutures with OptionValues with MockFactory with TypeCheckedTripleEquals { - implicit val tx: Scheduler = TestScheduler() - "EthService" should "answer eth_blockNumber with the latest block number" in new TestSetup { val bestBlockNumber = 10 blockchain.saveBestKnownBlocks(bestBlockNumber) @@ -181,7 +179,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.runSyncUnsafe shouldEqual Right(RawTransactionResponse(None)) + response.runSyncUnsafe() shouldEqual Right(RawTransactionResponse(None)) } it should "handle eth_getRawTransactionByHash if the tx is still pending" in new TestSetup { @@ -198,7 +196,7 @@ class EthServiceSpec PendingTransactionsResponse(Seq(PendingTransaction(txToRequestWithSender, System.currentTimeMillis))) ) - response.runSyncUnsafe shouldEqual Right(RawTransactionResponse(Some(txToRequest))) + response.runSyncUnsafe() shouldEqual Right(RawTransactionResponse(Some(txToRequest))) } it should "handle eth_getRawTransactionByHash if the tx was already executed" in new TestSetup { @@ -216,7 +214,7 @@ class EthServiceSpec pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.runSyncUnsafe shouldEqual Right(RawTransactionResponse(Some(txToRequest))) + response.runSyncUnsafe() shouldEqual Right(RawTransactionResponse(Some(txToRequest))) } it should "answer eth_getBlockByNumber with the correct block when the pending block is requested" in new TestSetup { diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index e2a539addc..231f56b3f1 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -8,7 +8,11 @@ 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.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{ + OptionNoneToJNullSerializer, + QuantitiesSerializer, + UnformattedDataJsonSerializer +} import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.ommers.OmmersPool import io.iohk.ethereum.ommers.OmmersPool.Ommers @@ -26,11 +30,7 @@ import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks // scalastyle:off magic.number -class JsonRpcControllerEthSpec - extends AnyFlatSpec - with Matchers - with JRCMatchers - with ScalaCheckPropertyChecks { +class JsonRpcControllerEthSpec extends AnyFlatSpec with Matchers with JRCMatchers with ScalaCheckPropertyChecks { implicit val tx: Scheduler = TestScheduler() diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala index 029ba7f4ad..287bb8368a 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala @@ -5,7 +5,11 @@ 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.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{ + OptionNoneToJNullSerializer, + QuantitiesSerializer, + UnformattedDataJsonSerializer +} import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransaction import io.iohk.ethereum.Fixtures diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala index 3c383cbf79..af28e3648f 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala @@ -4,7 +4,11 @@ import java.time.Duration import akka.util.ByteString import io.iohk.ethereum.domain._ -import io.iohk.ethereum.jsonrpc.JsonSerializers.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{ + OptionNoneToJNullSerializer, + QuantitiesSerializer, + UnformattedDataJsonSerializer +} import io.iohk.ethereum.jsonrpc.PersonalService._ import monix.eval.Task import monix.execution.Scheduler @@ -17,11 +21,7 @@ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -class JsonRpcControllerPersonalSpec - extends AnyFlatSpec - with Matchers - with JRCMatchers - with ScalaCheckPropertyChecks { +class JsonRpcControllerPersonalSpec extends AnyFlatSpec with Matchers with JRCMatchers with ScalaCheckPropertyChecks { implicit val tx: Scheduler = TestScheduler() diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala index 66ebf9aa13..ebd0a8da26 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala @@ -3,7 +3,11 @@ package io.iohk.ethereum.jsonrpc 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.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{ + OptionNoneToJNullSerializer, + QuantitiesSerializer, + UnformattedDataJsonSerializer +} import io.iohk.ethereum.jsonrpc.NetService.{ListeningResponse, PeerCountResponse, VersionResponse} import io.iohk.ethereum.jsonrpc.server.http.JsonRpcHttpServer import io.iohk.ethereum.jsonrpc.server.ipc.JsonRpcIpcServer @@ -23,11 +27,7 @@ import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import scala.concurrent.duration._ -class JsonRpcControllerSpec - extends AnyFlatSpec - with Matchers - with JRCMatchers - with ScalaCheckPropertyChecks { +class JsonRpcControllerSpec extends AnyFlatSpec with Matchers with JRCMatchers with ScalaCheckPropertyChecks { implicit val tx: Scheduler = TestScheduler() diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala index f89a1fe717..d62c0db2be 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala @@ -1,6 +1,7 @@ package io.iohk.ethereum.jsonrpc import java.net.InetSocketAddress + import akka.actor.ActorSystem import akka.testkit.TestProbe import io.iohk.ethereum.{NormalPatience, crypto} @@ -9,13 +10,19 @@ import io.iohk.ethereum.network.{Peer, PeerActor, PeerManagerActor} import io.iohk.ethereum.nodebuilder.SecureRandomBuilder import io.iohk.ethereum.utils.{NodeStatus, ServerStatus} import java.util.concurrent.atomic.AtomicReference + +import monix.execution.Scheduler +import monix.execution.schedulers.TestScheduler import org.scalatest.concurrent.ScalaFutures + import scala.concurrent.duration._ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers class NetServiceSpec extends AnyFlatSpec with Matchers with ScalaFutures with NormalPatience with SecureRandomBuilder { + implicit val tx: Scheduler = TestScheduler() + "NetService" should "return handshaked peer count" in new TestSetup { val resF = netService.peerCount(PeerCountRequest()) @@ -30,15 +37,15 @@ class NetServiceSpec extends AnyFlatSpec with Matchers with ScalaFutures with No ) ) - resF.futureValue shouldBe Right(PeerCountResponse(2)) + resF.runSyncUnsafe() shouldBe Right(PeerCountResponse(2)) } it should "return listening response" in new TestSetup { - netService.listening(ListeningRequest()).futureValue shouldBe Right(ListeningResponse(true)) + netService.listening(ListeningRequest()).runSyncUnsafe() shouldBe Right(ListeningResponse(true)) } it should "return version response" in new TestSetup { - netService.version(VersionRequest()).futureValue shouldBe Right(VersionResponse("42")) + netService.version(VersionRequest()).runSyncUnsafe() shouldBe Right(VersionResponse("42")) } trait TestSetup { @@ -56,5 +63,4 @@ class NetServiceSpec extends AnyFlatSpec with Matchers with ScalaFutures with No val netService = new NetService(new AtomicReference[NodeStatus](nodeStatus), peerManager.ref, NetServiceConfig(5.seconds)) } - } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala index a673ea0387..5a5a00584d 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala @@ -16,6 +16,7 @@ import io.iohk.ethereum.keystore.{KeyStore, Wallet} import io.iohk.ethereum.transactions.PendingTransactionsManager._ import io.iohk.ethereum.utils.{BlockchainConfig, MonetaryPolicyConfig, TxPoolConfig} import io.iohk.ethereum.{Fixtures, NormalPatience, Timeouts} +import monix.execution.Scheduler.Implicits.global import org.bouncycastle.util.encoders.Hex import org.scalamock.matchers.MatcherBase import org.scalamock.scalatest.MockFactory @@ -37,11 +38,13 @@ class PersonalServiceSpec with Eventually with ScalaCheckPropertyChecks { + //implicit val tx: Scheduler = TestScheduler() + "PersonalService" should "import private keys" in new TestSetup { (keyStore.importPrivateKey _).expects(prvKey, passphrase).returning(Right(address)) val req = ImportRawKeyRequest(prvKey, passphrase) - val res = personal.importRawKey(req).futureValue + val res = personal.importRawKey(req).runSyncUnsafe() res shouldEqual Right(ImportRawKeyResponse(address)) } @@ -50,7 +53,7 @@ class PersonalServiceSpec (keyStore.newAccount _).expects(passphrase).returning(Right(address)) val req = NewAccountRequest(passphrase) - val res = personal.newAccount(req).futureValue + val res = personal.newAccount(req).runSyncUnsafe() res shouldEqual Right(NewAccountResponse(address)) } @@ -59,7 +62,7 @@ class PersonalServiceSpec (keyStore.newAccount _).expects(passphrase).returning(Left(KeyStore.PassPhraseTooShort(7))) val req = NewAccountRequest(passphrase) - val res = personal.newAccount(req).futureValue + val res = personal.newAccount(req).runSyncUnsafe() res shouldEqual Left(PersonalService.PassPhraseTooShort(7)) } @@ -68,29 +71,29 @@ class PersonalServiceSpec val addresses = List(123, 42, 1).map(Address(_)) (keyStore.listAccounts _).expects().returning(Right(addresses)) - val res = personal.listAccounts(ListAccountsRequest()).futureValue + val res = personal.listAccounts(ListAccountsRequest()).runSyncUnsafe() res shouldEqual Right(ListAccountsResponse(addresses)) } it should "translate KeyStore errors to JsonRpc errors" in new TestSetup { (keyStore.listAccounts _).expects().returning(Left(IOError("boom!"))) - val res1 = personal.listAccounts(ListAccountsRequest()).futureValue + val res1 = personal.listAccounts(ListAccountsRequest()).runSyncUnsafe() res1 shouldEqual Left(LogicError("boom!")) (keyStore.unlockAccount _).expects(*, *).returning(Left(KeyStore.KeyNotFound)) - val res2 = personal.unlockAccount(UnlockAccountRequest(Address(42), "passphrase", None)).futureValue + val res2 = personal.unlockAccount(UnlockAccountRequest(Address(42), "passphrase", None)).runSyncUnsafe() res2 shouldEqual Left(KeyNotFound) (keyStore.unlockAccount _).expects(*, *).returning(Left(KeyStore.DecryptionFailed)) - val res3 = personal.unlockAccount(UnlockAccountRequest(Address(42), "passphrase", None)).futureValue + val res3 = personal.unlockAccount(UnlockAccountRequest(Address(42), "passphrase", None)).runSyncUnsafe() res3 shouldEqual Left(InvalidPassphrase) } it should "return an error when trying to import an invalid key" in new TestSetup { val invalidKey = prvKey.tail val req = ImportRawKeyRequest(invalidKey, passphrase) - val res = personal.importRawKey(req).futureValue + val res = personal.importRawKey(req).runSyncUnsafe() res shouldEqual Left(InvalidKey) } @@ -98,7 +101,7 @@ class PersonalServiceSpec (keyStore.unlockAccount _).expects(address, passphrase).returning(Right(wallet)) val req = UnlockAccountRequest(address, passphrase, None) - val res = personal.unlockAccount(req).futureValue + val res = personal.unlockAccount(req).runSyncUnsafe() res shouldEqual Right(UnlockAccountResponse(true)) } @@ -118,7 +121,7 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.futureValue shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) + res.runSyncUnsafe() shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } @@ -139,7 +142,7 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Seq(PendingTransaction(stxWithSender, 0)))) - res.futureValue shouldEqual Right(SendTransactionWithPassphraseResponse(newTx.hash)) + res.runSyncUnsafe() shouldEqual Right(SendTransactionWithPassphraseResponse(newTx.hash)) txPool.expectMsg(AddOrOverrideTransaction(newTx)) } @@ -149,7 +152,7 @@ class PersonalServiceSpec .returning(Left(KeyStore.DecryptionFailed)) val req = SendTransactionWithPassphraseRequest(tx, passphrase) - val res = personal.sendTransaction(req).futureValue + val res = personal.sendTransaction(req).runSyncUnsafe() res shouldEqual Left(InvalidPassphrase) txPool.expectNoMessage() @@ -160,7 +163,7 @@ class PersonalServiceSpec .expects(address, passphrase) .returning(Right(wallet)) - personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).futureValue + personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe() (blockchain.getBestBlockNumber _).expects().returning(1234) (blockchain.getAccount _).expects(address, BigInt(1234)).returning(Some(Account(nonce, 2 * txValue))) @@ -172,13 +175,13 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.futureValue shouldEqual Right(SendTransactionResponse(stx.hash)) + res.runSyncUnsafe() shouldEqual Right(SendTransactionResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } it should "fail to send a transaction when account is locked" in new TestSetup { val req = SendTransactionRequest(tx) - val res = personal.sendTransaction(req).futureValue + val res = personal.sendTransaction(req).runSyncUnsafe() res shouldEqual Left(AccountLocked) txPool.expectNoMessage() @@ -189,10 +192,10 @@ class PersonalServiceSpec .expects(address, passphrase) .returning(Right(wallet)) - personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).futureValue + personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe() - val lockRes = personal.lockAccount(LockAccountRequest(address)).futureValue - val txRes = personal.sendTransaction(SendTransactionRequest(tx)).futureValue + val lockRes = personal.lockAccount(LockAccountRequest(address)).runSyncUnsafe() + val txRes = personal.sendTransaction(SendTransactionRequest(tx)).runSyncUnsafe() lockRes shouldEqual Right(LockAccountResponse(true)) txRes shouldEqual Left(AccountLocked) @@ -212,12 +215,12 @@ class PersonalServiceSpec val req = SignRequest(message, address, Some(passphrase)) - val res = personal.sign(req).futureValue + val res = personal.sign(req).runSyncUnsafe() res shouldEqual Right(SignResponse(ECDSASignature(r, s, v))) // Account should still be locked after calling sign with passphrase val txReq = SendTransactionRequest(tx) - val txRes = personal.sendTransaction(txReq).futureValue + val txRes = personal.sendTransaction(txReq).runSyncUnsafe() txRes shouldEqual Left(AccountLocked) } @@ -236,8 +239,8 @@ class PersonalServiceSpec val req = SignRequest(message, address, None) - personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).futureValue - val res = personal.sign(req).futureValue + personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe() + val res = personal.sign(req).runSyncUnsafe() res shouldEqual Right(SignResponse(ECDSASignature(r, s, v))) } @@ -247,7 +250,7 @@ class PersonalServiceSpec val req = SignRequest(message, address, None) - val res = personal.sign(req).futureValue + val res = personal.sign(req).runSyncUnsafe() res shouldEqual Left(AccountLocked) } @@ -263,7 +266,7 @@ class PersonalServiceSpec val req = SignRequest(message, address, Some(wrongPassphase)) - val res = personal.sign(req).futureValue + val res = personal.sign(req).runSyncUnsafe() res shouldEqual Left(InvalidPassphrase) } @@ -277,7 +280,7 @@ class PersonalServiceSpec val req = SignRequest(message, address, Some(passphrase)) - val res = personal.sign(req).futureValue + val res = personal.sign(req).runSyncUnsafe() res shouldEqual Left(KeyNotFound) } @@ -292,7 +295,7 @@ class PersonalServiceSpec val req = EcRecoverRequest(message, ECDSASignature(r, s, v)) - val res = personal.ecRecover(req).futureValue + val res = personal.ecRecover(req).runSyncUnsafe() res shouldEqual Right(EcRecoverResponse(sigAddress)) } @@ -306,12 +309,12 @@ class PersonalServiceSpec personal .sign(SignRequest(message, address, Some(passphrase))) - .futureValue + .runSyncUnsafe() .left .map(_ => fail()) .map(response => EcRecoverRequest(message, response.signature)) .foreach { req => - val res = personal.ecRecover(req).futureValue + val res = personal.ecRecover(req).runSyncUnsafe() res shouldEqual Right(EcRecoverResponse(address)) } @@ -332,7 +335,7 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.futureValue shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) + res.runSyncUnsafe() shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } @@ -352,7 +355,7 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.futureValue shouldEqual Right(SendTransactionWithPassphraseResponse(chainSpecificStx.hash)) + res.runSyncUnsafe() shouldEqual Right(SendTransactionWithPassphraseResponse(chainSpecificStx.hash)) txPool.expectMsg(AddOrOverrideTransaction(chainSpecificStx)) } @@ -360,7 +363,7 @@ class PersonalServiceSpec (keyStore.importPrivateKey _).expects(prvKey, passphrase).returning(Left(KeyStore.DuplicateKeySaved)) val req = ImportRawKeyRequest(prvKey, passphrase) - val res = personal.importRawKey(req).futureValue + val res = personal.importRawKey(req).runSyncUnsafe() res shouldEqual Left(LogicError("account already exists")) } @@ -379,14 +382,14 @@ class PersonalServiceSpec val reqSign = SignRequest(message, address, None) val req = UnlockAccountRequest(address, passphrase, Some(Duration.ofSeconds(2))) - val res = personal.unlockAccount(req).futureValue + val res = personal.unlockAccount(req).runSyncUnsafe() res shouldEqual Right(UnlockAccountResponse(true)) - val res2 = personal.sign(reqSign).futureValue + val res2 = personal.sign(reqSign).runSyncUnsafe() res2 shouldEqual Right(SignResponse(ECDSASignature(r, s, v))) eventually { - personal.sign(reqSign).futureValue shouldEqual Left(AccountLocked) + personal.sign(reqSign).runSyncUnsafe() shouldEqual Left(AccountLocked) } } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala index 43bd8d363a..2307a17a21 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala @@ -27,7 +27,7 @@ class QAServiceSpec TestKit.shutdownActorSystem(system) } - "QAService" should "send msg to miner and return miner's response" in testCaseF { fixture => + "QAService" should "send msg to miner and return miner's response" in testCaseM { fixture => import fixture._ (testConsensus.sendMiner _) .expects(mineBlocksMsg) @@ -37,7 +37,7 @@ class QAServiceSpec qaService.mineBlocks(mineBlocksReq).map(_ shouldBe Right(MineBlocksResponse(MiningOrdered))) } - it should "send msg to miner and return InternalError in case of problems" in testCaseF { fixture => + it should "send msg to miner and return InternalError in case of problems" in testCaseM { fixture => import fixture._ (testConsensus.sendMiner _) .expects(mineBlocksMsg) @@ -47,7 +47,7 @@ class QAServiceSpec qaService.mineBlocks(mineBlocksReq).map(_ shouldBe Left(JsonRpcErrors.InternalError)) } - it should "generate checkpoint for block with given blockHash and send it to sync" in customTestCaseF( + it should "generate checkpoint for block with given blockHash and send it to sync" in customTestCaseM( new Fixture with CheckpointsGenerationFixture ) { fixture => import fixture._ @@ -60,7 +60,7 @@ class QAServiceSpec result.map(_ shouldBe Right(GenerateCheckpointResponse(checkpoint))) } - it should "generate checkpoint for best block when no block hash given and send it to sync" in customTestCaseF( + it should "generate checkpoint for best block when no block hash given and send it to sync" in customTestCaseM( new Fixture with CheckpointsGenerationFixture ) { fixture => import fixture._ @@ -78,7 +78,7 @@ class QAServiceSpec result.map(_ shouldBe Right(GenerateCheckpointResponse(checkpoint))) } - it should "return federation public keys when requesting federation members info" in testCaseF { fixture => + it should "return federation public keys when requesting federation members info" in testCaseM { fixture => import fixture._ val result: ServiceResponse[GetFederationMembersInfoResponse] = qaService.getFederationMembersInfo(GetFederationMembersInfoRequest()) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala index 1368a5857e..6f37912dd3 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala @@ -22,10 +22,7 @@ import org.scalamock.scalatest.MockFactory import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -class QaJRCSpec - extends AnyWordSpec - with Matchers - with JsonMethodsImplicits { +class QaJRCSpec extends AnyWordSpec with Matchers with JsonMethodsImplicits { implicit val tx: Scheduler = TestScheduler() diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala index cb2b3fadd7..52470d2578 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala @@ -14,10 +14,7 @@ import org.scalamock.scalatest.MockFactory import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers -class JsonRpcHttpServerSpec - extends AnyFlatSpec - with Matchers - with ScalatestRouteTest { +class JsonRpcHttpServerSpec extends AnyFlatSpec with Matchers with ScalatestRouteTest { it should "pass valid json request to controller" in new TestSetup { (mockJsonRpcController.handleRequest _) From 2c63426323708b58512354e0ed13d974b53d0556 Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 13:42:10 +0200 Subject: [PATCH 04/33] [ETCM-269] extract TaskAsk pattern --- .../io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala | 14 ++++++++++++++ .../io/iohk/ethereum/jsonrpc/EthService.scala | 17 ++++------------- .../io/iohk/ethereum/jsonrpc/NetService.scala | 10 +++------- .../iohk/ethereum/jsonrpc/PersonalService.scala | 4 ++-- .../io/iohk/ethereum/jsonrpc/TestService.scala | 8 ++------ .../jsonrpc/JsonRpcControllerEthSpec.scala | 4 +--- .../JsonRpcControllerEthTransactionSpec.scala | 3 +-- .../jsonrpc/JsonRpcControllerPersonalSpec.scala | 1 - .../jsonrpc/JsonRpcControllerSpec.scala | 4 +--- 9 files changed, 28 insertions(+), 37 deletions(-) create mode 100644 src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala new file mode 100644 index 0000000000..2d6ddc5b2f --- /dev/null +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala @@ -0,0 +1,14 @@ +package io.iohk.ethereum.jsonrpc + +import akka.actor.{Actor, ActorRef} +import akka.util.Timeout +import monix.eval.Task + +object AkkaTaskOps { self: ActorRef => + implicit class TaskActorOps(to: ActorRef) { + import akka.pattern.ask + + def askFor[A](message: Any)(implicit timeout: Timeout, sender: ActorRef = Actor.noSender): Task[A] = + Task.fromFuture(to ? message).timeout(timeout.duration).map(_.asInstanceOf[A]) + } +} diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala index 737fa94a01..2d25a5f0e4 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala @@ -4,7 +4,7 @@ import java.time.Duration import java.util.Date import java.util.concurrent.atomic.AtomicReference -import akka.actor.{Actor, ActorRef} +import akka.actor.ActorRef import akka.util.{ByteString, Timeout} import io.iohk.ethereum.blockchain.sync.regular.RegularSync import io.iohk.ethereum.consensus.ConsensusConfig @@ -25,24 +25,15 @@ import io.iohk.ethereum.rlp.UInt256RLPImplicits._ import io.iohk.ethereum.transactions.PendingTransactionsManager import io.iohk.ethereum.transactions.PendingTransactionsManager.{PendingTransaction, PendingTransactionsResponse} import io.iohk.ethereum.utils._ +import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ +import io.iohk.ethereum.jsonrpc.{FilterManager => FM} import monix.eval.Task import org.bouncycastle.util.encoders.Hex -import AkkaTaskOps._ -import io.iohk.ethereum.jsonrpc.{FilterManager => FM} import scala.concurrent.duration.FiniteDuration import scala.language.existentials import scala.util.{Failure, Success, Try} -object AkkaTaskOps { self: ActorRef => - implicit class TaskActorOps(to: ActorRef) { - import akka.pattern.ask - - def askFor[A](message: Any)(implicit timeout: Timeout, sender: ActorRef = Actor.noSender): Task[A] = - Task.fromFuture(to ? message).map(_.asInstanceOf[A]) - } -} - // scalastyle:off number.of.methods number.of.types file.size.limit object EthService { @@ -864,7 +855,7 @@ class EthService( def getFilterLogs(req: GetFilterLogsRequest): ServiceResponse[GetFilterLogsResponse] = { implicit val timeout: Timeout = Timeout(filterConfig.filterManagerQueryTimeout) filterManager - .askFor[FilterManager.FilterLogs](FM.GetFilterLogs(req.filterId)) + .askFor[FM.FilterLogs](FM.GetFilterLogs(req.filterId)) .map { filterLogs => Right(GetFilterLogsResponse(filterLogs)) } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala index 05f11abf50..5165732bef 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala @@ -50,14 +50,10 @@ class NetService(nodeStatusHolder: AtomicReference[NodeStatus], peerManager: Act } def peerCount(req: PeerCountRequest): ServiceResponse[PeerCountResponse] = { - import akka.pattern.ask implicit val timeout: Timeout = Timeout(config.peerManagerTimeout) - - Task - .fromFuture( - (peerManager ? PeerManagerActor.GetPeers) - .mapTo[PeerManagerActor.Peers] - ) + import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ + peerManager + .askFor[PeerManagerActor.Peers](PeerManagerActor.GetPeers) .map { peers => Right(PeerCountResponse(peers.handshaked.size)) } .timeout(timeout.duration) } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index 98bda124de..f967825df1 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -3,7 +3,6 @@ package io.iohk.ethereum.jsonrpc import java.time.Duration import akka.actor.ActorRef -import akka.pattern.ask import akka.util.{ByteString, Timeout} import cats.syntax.either._ import io.iohk.ethereum.crypto @@ -193,9 +192,10 @@ class PersonalService( private def sendTransaction(request: TransactionRequest, wallet: Wallet): Task[ByteString] = { implicit val timeout = Timeout(txPoolConfig.pendingTxManagerQueryTimeout) + import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ val pendingTxsFuture = - Task.fromFuture((txPool ? PendingTransactionsManager.GetPendingTransactions).mapTo[PendingTransactionsResponse]) + txPool.askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) val latestPendingTxNonceAction: Task[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => val senderTxsNonces = pendingTxs.pendingTransactions .collect { case ptx if ptx.stx.senderAddress == wallet.address => ptx.stx.tx.tx.nonce } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala index 87106adcd1..cff19d0948 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala @@ -69,7 +69,7 @@ class TestService( ) extends Logger { import TestService._ - import akka.pattern.ask + import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ private var etherbase: Address = consensusConfig.coinbase @@ -146,11 +146,7 @@ class TestService( private def getBlockForMining(parentBlock: Block): Task[PendingBlock] = { implicit val timeout = Timeout(5.seconds) - Task - .fromFuture( - (pendingTransactionsManager ? PendingTransactionsManager.GetPendingTransactions) - .mapTo[PendingTransactionsResponse] - ) + pendingTransactionsManager.askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) .onErrorRecover { case _ => PendingTransactionsResponse(Nil) } .flatMap { pendingTxs => consensus.blockGenerator.generateBlock( diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index cca4f0bd11..a54b393ac5 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -19,7 +19,7 @@ import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.ommers.OmmersPool import io.iohk.ethereum.ommers.OmmersPool.Ommers import io.iohk.ethereum.transactions.PendingTransactionsManager -import io.iohk.ethereum.{Fixtures, LongPatience, Timeouts, WithActorSystemShutDown} +import io.iohk.ethereum.{LongPatience, WithActorSystemShutDown} import io.iohk.ethereum.{Fixtures, Timeouts} import monix.eval.Task import monix.execution.Scheduler @@ -30,8 +30,6 @@ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Extraction, Formats} import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpecLike -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks // scalastyle:off magic.number diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala index 67159b949b..49f0278531 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala @@ -10,7 +10,7 @@ import io.iohk.ethereum.jsonrpc.FilterManager.TxLog import io.iohk.ethereum.jsonrpc.JsonSerializers.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransaction -import io.iohk.ethereum.{Fixtures, LongPatience, WithActorSystemShutDown} +import io.iohk.ethereum.{LongPatience, WithActorSystemShutDown} import io.iohk.ethereum.Fixtures import monix.eval.Task import monix.execution.Scheduler @@ -21,7 +21,6 @@ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Extraction, Formats} import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpecLike -import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala index b8a7da7d5e..488a1e461b 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala @@ -20,7 +20,6 @@ import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Formats} -import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala index e6fba9fa4a..98338bd032 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala @@ -16,17 +16,15 @@ import io.iohk.ethereum.jsonrpc.server.ipc.JsonRpcIpcServer import io.iohk.ethereum.network.EtcPeerManagerActor.PeerInfo import io.iohk.ethereum.network.p2p.messages.CommonMessages.Status import io.iohk.ethereum.network.p2p.messages.Versions -import io.iohk.ethereum.Fixtures +import io.iohk.ethereum.{Fixtures, LongPatience, WithActorSystemShutDown} import monix.eval.Task import monix.execution.Scheduler import monix.execution.schedulers.TestScheduler -import io.iohk.ethereum.{Fixtures, LongPatience, WithActorSystemShutDown} import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Extraction, Formats} import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpecLike -import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks From 2e1e29f0d2e3fa004b7df7298356024046202558 Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 14:24:47 +0200 Subject: [PATCH 05/33] [ETCM-269] scalafmt on compile --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index e51ce7dd6b..5745adedd7 100644 --- a/build.sbt +++ b/build.sbt @@ -102,6 +102,8 @@ scalacOptions in (Compile, console) ~= (_.filterNot( ) )) +scalafmtOnCompile := true + scalacOptions ~= (options => if (mantisDev) options.filterNot(_ == "-Xfatal-warnings") else options) Test / parallelExecution := true From bb1d7b8197e79474dce0643c2e96db938c1e908b Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 14:25:15 +0200 Subject: [PATCH 06/33] [ETCM-269] add 60 min timeout on build --- .buildkite/pipeline.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 6801c614ca..931f390b28 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -5,4 +5,5 @@ steps: nix eval --json '(import ./.buildkite { pipeline = ./.buildkite/pipeline.nix; })' \ | buildkite-agent pipeline upload --no-interpolation agents: - queue: project42 \ No newline at end of file + queue: project42 + timeout_in_minutes: 60 \ No newline at end of file From 95ae5b6d9a73c209efd9d439f7c0b84f5529b51a Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 14:25:45 +0200 Subject: [PATCH 07/33] [ETCM-269] scalafmt --- .../iohk/ethereum/jsonrpc/TestService.scala | 3 ++- .../JsonRpcControllerEthTransactionSpec.scala | 22 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala index cff19d0948..50f1993eb1 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala @@ -146,7 +146,8 @@ class TestService( private def getBlockForMining(parentBlock: Block): Task[PendingBlock] = { implicit val timeout = Timeout(5.seconds) - pendingTransactionsManager.askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) + pendingTransactionsManager + .askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) .onErrorRecover { case _ => PendingTransactionsResponse(Nil) } .flatMap { pendingTxs => consensus.blockGenerator.generateBlock( diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala index 49f0278531..1d0c747de0 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala @@ -7,7 +7,11 @@ 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.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} +import io.iohk.ethereum.jsonrpc.JsonSerializers.{ + OptionNoneToJNullSerializer, + QuantitiesSerializer, + UnformattedDataJsonSerializer +} import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransaction import io.iohk.ethereum.{LongPatience, WithActorSystemShutDown} @@ -27,14 +31,14 @@ import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks // scalastyle:off magic.number class JsonRpcControllerEthTransactionSpec extends TestKit(ActorSystem("JsonRpcControllerEthTransactionSpec_System")) - with AnyFlatSpecLike - with WithActorSystemShutDown - with Matchers - with JRCMatchers - with ScalaCheckPropertyChecks - with ScalaFutures - with LongPatience - with Eventually { + with AnyFlatSpecLike + with WithActorSystemShutDown + with Matchers + with JRCMatchers + with ScalaCheckPropertyChecks + with ScalaFutures + with LongPatience + with Eventually { implicit val tx: Scheduler = TestScheduler() From effc77b8769489fa72f391705859e7a5e179245e Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 15:22:16 +0200 Subject: [PATCH 08/33] [ETCM-269] add AkkaAsk in DebugService --- .../iohk/ethereum/jsonrpc/DebugService.scala | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala index ae6b96d74a..171545fd7a 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala @@ -1,53 +1,44 @@ package io.iohk.ethereum.jsonrpc import akka.actor.ActorRef -import akka.pattern._ import akka.util.Timeout +import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} import io.iohk.ethereum.network.EtcPeerManagerActor.{PeerInfo, PeerInfoResponse} import io.iohk.ethereum.network.PeerManagerActor.Peers import io.iohk.ethereum.network.{EtcPeerManagerActor, Peer, PeerActor, PeerId, PeerManagerActor} import monix.eval.Task -import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ object DebugService { - case class ListPeersInfoRequest() case class ListPeersInfoResponse(peers: List[PeerInfo]) - } class DebugService(peerManager: ActorRef, etcPeerManager: ActorRef) { def listPeersInfo(getPeersInfoRequest: ListPeersInfoRequest): ServiceResponse[ListPeersInfoResponse] = { - val result = for { + for { ids <- getPeerIds peers <- Task.traverse(ids)(getPeerInfo) - } yield ListPeersInfoResponse(peers.flatten) - - Task.from(result.map(Right(_))) + } yield Right(ListPeersInfoResponse(peers.flatten)) } private def getPeerIds: Task[List[PeerId]] = { implicit val timeout: Timeout = Timeout(5.seconds) - Task.fromFuture( - (peerManager ? PeerManagerActor.GetPeers) - .mapTo[Peers] - .recover { case _ => Peers(Map.empty[Peer, PeerActor.Status]) } - .map(_.peers.keySet.map(_.id).toList) - ) + peerManager + .askFor[Peers](PeerManagerActor.GetPeers) + .onErrorRecover { case _ => Peers(Map.empty[Peer, PeerActor.Status]) } + .map(_.peers.keySet.map(_.id).toList) } private def getPeerInfo(peer: PeerId): Task[Option[PeerInfo]] = { implicit val timeout: Timeout = Timeout(5.seconds) - Task.fromFuture { - (etcPeerManager ? EtcPeerManagerActor.PeerInfoRequest(peer)) - .mapTo[PeerInfoResponse] - .collect { case PeerInfoResponse(info) => info } - } + etcPeerManager + .askFor[PeerInfoResponse](EtcPeerManagerActor.PeerInfoRequest(peer)) + .map(resp => resp.peerInfo) } } From e2960da4ef84ed22968eb64bdfaba86e8f8fa37c Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 16:48:37 +0200 Subject: [PATCH 09/33] [ETCM-269] improve patience --- .../scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala | 5 ++++- .../scala/io/iohk/ethereum/jsonrpc/EthService.scala | 9 +++++---- .../io/iohk/ethereum/jsonrpc/JsonRpcController.scala | 2 +- .../scala/io/iohk/ethereum/jsonrpc/NetService.scala | 1 - .../io/iohk/ethereum/jsonrpc/PersonalService.scala | 4 ++-- .../io/iohk/ethereum/jsonrpc/EthServiceSpec.scala | 1 + .../io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala | 2 -- .../scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala | 10 ++++++++-- src/test/scala/io/iohk/ethereum/patience.scala | 6 ++++++ 9 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala index 2d6ddc5b2f..b447ec7772 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala @@ -9,6 +9,9 @@ object AkkaTaskOps { self: ActorRef => import akka.pattern.ask def askFor[A](message: Any)(implicit timeout: Timeout, sender: ActorRef = Actor.noSender): Task[A] = - Task.fromFuture(to ? message).timeout(timeout.duration).map(_.asInstanceOf[A]) + Task + .fromFuture(to ? message) + .timeout(timeout.duration) + .map(_.asInstanceOf[A]) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala index 2d25a5f0e4..3802ba54ae 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala @@ -225,8 +225,9 @@ class EthService( private[this] def consensusConfig: ConsensusConfig = fullConsensusConfig.generic private[this] def ifEthash[Req, Res](req: Req)(f: Req => Res): ServiceResponse[Res] = { - @inline def F[A](x: A): Task[A] = Task.now(x) - consensus.ifEthash[ServiceResponse[Res]](_ => F(Right(f(req))))(F(Left(JsonRpcErrors.ConsensusIsNotEthash))) + consensus.ifEthash[ServiceResponse[Res]](_ => Task.now(Right(f(req))))( + Task.now(Left(JsonRpcErrors.ConsensusIsNotEthash)) + ) } def protocolVersion(req: ProtocolVersionRequest): ServiceResponse[ProtocolVersionResponse] = @@ -581,9 +582,9 @@ class EthService( pendingTransactionsManager .askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) - .onErrorHandle { ex => + .onErrorRecoverWith { case ex: Throwable => log.error("failed to get transactions, mining block with empty transactions list", ex) - PendingTransactionsResponse(Nil) + Task.now(PendingTransactionsResponse(Nil)) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala index dce2d32232..f3a16eb651 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala @@ -425,7 +425,7 @@ class JsonRpcController( errorResponse(rpcReq, InternalError) } case Left(error) => - Task(errorResponse(rpcReq, error)) + Task.now(errorResponse(rpcReq, error)) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala index 5165732bef..94a56e5394 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/NetService.scala @@ -55,6 +55,5 @@ class NetService(nodeStatusHolder: AtomicReference[NodeStatus], peerManager: Act peerManager .askFor[PeerManagerActor.Peers](PeerManagerActor.GetPeers) .map { peers => Right(PeerCountResponse(peers.handshaked.size)) } - .timeout(timeout.duration) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index f967825df1..c3fa358b95 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -196,12 +196,12 @@ class PersonalService( val pendingTxsFuture = txPool.askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) - val latestPendingTxNonceAction: Task[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => + val latestPendingTxNonceFuture: Task[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => val senderTxsNonces = pendingTxs.pendingTransactions .collect { case ptx if ptx.stx.senderAddress == wallet.address => ptx.stx.tx.tx.nonce } Either.catchNonFatal(senderTxsNonces.max).toOption } - latestPendingTxNonceAction + latestPendingTxNonceFuture .map { maybeLatestPendingTxNonce => val maybeCurrentNonce = getCurrentAccount(request.from).map(_.nonce.toBigInt) val maybeNextTxNonce = maybeLatestPendingTxNonce.map(_ + 1) orElse maybeCurrentNonce diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index 8b21c792f8..dc33e03b47 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -28,6 +28,7 @@ import io.iohk.ethereum.transactions.PendingTransactionsManager.{ } import io.iohk.ethereum.utils._ import io.iohk.ethereum.{Fixtures, Timeouts, crypto} +import monix.eval.Task import monix.execution.Scheduler.Implicits.global import org.bouncycastle.util.encoders.Hex import org.scalactic.TypeCheckedTripleEquals diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala index 5a5a00584d..5654e84426 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala @@ -38,8 +38,6 @@ class PersonalServiceSpec with Eventually with ScalaCheckPropertyChecks { - //implicit val tx: Scheduler = TestScheduler() - "PersonalService" should "import private keys" in new TestSetup { (keyStore.importPrivateKey _).expects(prvKey, passphrase).returning(Right(address)) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala index 6f37912dd3..fcb54ff402 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala @@ -11,7 +11,7 @@ import io.iohk.ethereum.jsonrpc.QAService.MineBlocksResponse.MinerResponseType._ import io.iohk.ethereum.jsonrpc.QAService._ import io.iohk.ethereum.nodebuilder.BlockchainConfigBuilder import io.iohk.ethereum.utils.{ByteStringUtils, Config} -import io.iohk.ethereum.{ByteGenerators, crypto} +import io.iohk.ethereum.{ByteGenerators, NormalPatience, crypto} import monix.eval.Task import monix.execution.Scheduler import monix.execution.schedulers.TestScheduler @@ -19,10 +19,16 @@ import org.json4s.Extraction import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.scalamock.scalatest.MockFactory +import org.scalatest.concurrent.PatienceConfiguration import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -class QaJRCSpec extends AnyWordSpec with Matchers with JsonMethodsImplicits { +class QaJRCSpec + extends AnyWordSpec + with Matchers + with PatienceConfiguration + with NormalPatience + with JsonMethodsImplicits { implicit val tx: Scheduler = TestScheduler() diff --git a/src/test/scala/io/iohk/ethereum/patience.scala b/src/test/scala/io/iohk/ethereum/patience.scala index 67c90eb6e3..cd1f55f4b9 100644 --- a/src/test/scala/io/iohk/ethereum/patience.scala +++ b/src/test/scala/io/iohk/ethereum/patience.scala @@ -15,6 +15,8 @@ trait NormalPatience { ) implicit val actorAskTimeout: Timeout = Timeouts.normalTimeout + + implicit val taskTimeout: Duration = Timeouts.normalTimeout } trait LongPatience { @@ -27,6 +29,8 @@ trait LongPatience { ) implicit val actorAskTimeout: Timeout = Timeouts.longTimeout + + implicit val taskTimeout: Duration = Timeouts.longTimeout } trait VeryLongPatience { @@ -39,4 +43,6 @@ trait VeryLongPatience { ) implicit val actorAskTimeout: Timeout = Timeouts.veryLongTimeout + + implicit val taskTimeout: Duration = Timeouts.veryLongTimeout } From 5bac969f825c317e3c627c689ad0ed615a07177b Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 16:49:10 +0200 Subject: [PATCH 10/33] [ETCM-269] buildkite pipeline --- .buildkite/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 931f390b28..19c264f4f6 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -6,4 +6,4 @@ steps: | buildkite-agent pipeline upload --no-interpolation agents: queue: project42 - timeout_in_minutes: 60 \ No newline at end of file + timeout_in_minutes: 60 From 4fb71523cb639db11f455c023988e62096453b3a Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 20:38:54 +0200 Subject: [PATCH 11/33] [ETC-269] cleanup actor systems and monix scheduler in tests to avoid tests hang --- .../iohk/ethereum/sync/FastSyncItSpec.scala | 2 +- .../ethereum/sync/RegularSyncItSpec.scala | 2 +- .../blockchain/sync/BlockBroadcastSpec.scala | 17 +-- .../sync/FastSyncStateStorageActorSpec.scala | 29 ++--- .../jsonrpc/CheckpointingServiceSpec.scala | 3 +- .../ethereum/jsonrpc/DebugServiceSpec.scala | 18 ++-- .../ethereum/jsonrpc/EthServiceSpec.scala | 100 +++++++++--------- .../ethereum/jsonrpc/FilterManagerSpec.scala | 17 +-- .../jsonrpc/JsonRpcControllerEthSpec.scala | 9 +- .../JsonRpcControllerEthTransactionSpec.scala | 5 +- .../JsonRpcControllerPersonalSpec.scala | 5 +- .../jsonrpc/JsonRpcControllerSpec.scala | 5 +- .../ethereum/jsonrpc/NetServiceSpec.scala | 14 +-- .../jsonrpc/PersonalServiceSpec.scala | 12 +-- .../iohk/ethereum/jsonrpc/QAServiceSpec.scala | 7 +- .../io/iohk/ethereum/jsonrpc/QaJRCSpec.scala | 5 +- .../network/PeerActorHandshakingSpec.scala | 2 +- .../ethereum/network/p2p/PeerActorSpec.scala | 17 +-- .../rlpx/RLPxConnectionHandlerSpec.scala | 15 +-- 19 files changed, 142 insertions(+), 142 deletions(-) diff --git a/src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala b/src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala index 3937a59aed..5ce9ebe020 100644 --- a/src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala +++ b/src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala @@ -15,7 +15,7 @@ import org.scalatest.matchers.should.Matchers import scala.concurrent.duration._ class FastSyncItSpec extends FlatSpecBase with Matchers with BeforeAndAfterAll { - implicit val testScheduler = Scheduler.fixedPool("test", 16) + implicit val testScheduler = Scheduler.fixedPool("Scheduler_FastSyncItSpec", 16) override def afterAll(): Unit = { testScheduler.shutdown() diff --git a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala index ad1986504f..368df5ab8a 100644 --- a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala +++ b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala @@ -10,7 +10,7 @@ import org.scalatest.matchers.should.Matchers import scala.concurrent.duration._ class RegularSyncItSpec extends FlatSpecBase with Matchers with BeforeAndAfterAll { - implicit val testScheduler = Scheduler.fixedPool("test", 16) + implicit val testScheduler = Scheduler.fixedPool("Scheduler_RegularSyncItSpec", 16) override def afterAll(): Unit = { testScheduler.shutdown() diff --git a/src/test/scala/io/iohk/ethereum/blockchain/sync/BlockBroadcastSpec.scala b/src/test/scala/io/iohk/ethereum/blockchain/sync/BlockBroadcastSpec.scala index a3cc0386cb..1c1edb1d1e 100644 --- a/src/test/scala/io/iohk/ethereum/blockchain/sync/BlockBroadcastSpec.scala +++ b/src/test/scala/io/iohk/ethereum/blockchain/sync/BlockBroadcastSpec.scala @@ -3,8 +3,8 @@ package io.iohk.ethereum.blockchain.sync import java.net.InetSocketAddress import akka.actor.ActorSystem -import akka.testkit.TestProbe -import io.iohk.ethereum.Fixtures +import akka.testkit.{TestKit, TestProbe} +import io.iohk.ethereum.{Fixtures, WithActorSystemShutDown} import io.iohk.ethereum.domain.{Block, BlockBody, BlockHeader} import io.iohk.ethereum.network.{EtcPeerManagerActor, Peer} import io.iohk.ethereum.network.EtcPeerManagerActor.PeerInfo @@ -14,10 +14,14 @@ import io.iohk.ethereum.network.p2p.messages.{PV62, Versions} import io.iohk.ethereum.utils.Config import scala.concurrent.duration._ -import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers -class BlockBroadcastSpec extends AnyFlatSpec with Matchers { +class BlockBroadcastSpec + extends TestKit(ActorSystem("BlockBroadcastSpec_System")) + with AnyFlatSpecLike + with WithActorSystemShutDown + with Matchers { it should "send a new block when it is not known by the peer (known by comparing total difficulties)" in new TestSetup { //given @@ -125,9 +129,7 @@ class BlockBroadcastSpec extends AnyFlatSpec with Matchers { etcPeerManagerProbe.expectNoMessage(100.millis) } - trait TestSetup { - implicit val system = ActorSystem("BlockBroadcastSpec_System") - + class TestSetup(implicit system: ActorSystem) { val etcPeerManagerProbe = TestProbe() val syncConfig = Config.SyncConfig(Config.config) @@ -154,5 +156,4 @@ class BlockBroadcastSpec extends AnyFlatSpec with Matchers { val peerProbe = TestProbe() val peer = Peer(new InetSocketAddress("127.0.0.1", 0), peerProbe.ref, false) } - } diff --git a/src/test/scala/io/iohk/ethereum/blockchain/sync/FastSyncStateStorageActorSpec.scala b/src/test/scala/io/iohk/ethereum/blockchain/sync/FastSyncStateStorageActorSpec.scala index d51c31e12b..7d0d9d8dc5 100644 --- a/src/test/scala/io/iohk/ethereum/blockchain/sync/FastSyncStateStorageActorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/blockchain/sync/FastSyncStateStorageActorSpec.scala @@ -2,23 +2,26 @@ package io.iohk.ethereum.blockchain.sync import akka.actor.ActorSystem import akka.pattern._ -import akka.testkit.TestActorRef -import io.iohk.ethereum.NormalPatience +import akka.testkit.{TestActorRef, TestKit} +import io.iohk.ethereum.{Fixtures, NormalPatience, WithActorSystemShutDown} import io.iohk.ethereum.blockchain.sync.FastSync.SyncState import io.iohk.ethereum.blockchain.sync.FastSyncStateStorageActor.GetStorage import io.iohk.ethereum.db.dataSource.EphemDataSource import io.iohk.ethereum.db.storage.FastSyncStateStorage -import io.iohk.ethereum.Fixtures import org.scalatest.concurrent.Eventually -import org.scalatest.flatspec.AsyncFlatSpec +import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers -class FastSyncStateStorageActorSpec extends AsyncFlatSpec with Matchers with Eventually with NormalPatience { +class FastSyncStateStorageActorSpec + extends TestKit(ActorSystem("FastSyncStateActorSpec_System")) + with AnyFlatSpecLike + with WithActorSystemShutDown + with Matchers + with Eventually + with NormalPatience { "FastSyncStateActor" should "eventually persist a newest state of a fast sync" in { - val dataSource = EphemDataSource() - implicit val system = ActorSystem("FastSyncStateActorSpec_System") val syncStateActor = TestActorRef(new FastSyncStateStorageActor) val maxN = 10 @@ -27,12 +30,12 @@ class FastSyncStateStorageActorSpec extends AsyncFlatSpec with Matchers with Eve (0 to maxN).foreach(n => syncStateActor ! SyncState(targetBlockHeader).copy(downloadedNodesCount = n)) eventually { - (syncStateActor ? GetStorage).mapTo[Option[SyncState]].map { syncState => - val expected = SyncState(targetBlockHeader).copy(downloadedNodesCount = maxN) - syncState shouldEqual Some(expected) - } + (syncStateActor ? GetStorage) + .mapTo[Option[SyncState]] + .map { syncState => + val expected = SyncState(targetBlockHeader).copy(downloadedNodesCount = maxN) + syncState shouldEqual Some(expected) + }(system.dispatcher) } - } - } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala index 6024c82786..690ada8cb2 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala @@ -5,7 +5,7 @@ import akka.testkit.{TestKit, TestProbe} import io.iohk.ethereum.blockchain.sync.regular.RegularSync.NewCheckpoint import io.iohk.ethereum.domain.{Block, BlockBody, BlockchainImpl} import io.iohk.ethereum.jsonrpc.CheckpointingService._ -import io.iohk.ethereum.{Fixtures, NormalPatience} +import io.iohk.ethereum.{Fixtures, NormalPatience, WithActorSystemShutDown} import monix.execution.Scheduler.Implicits.global import org.scalacheck.Gen import org.scalamock.scalatest.MockFactory @@ -17,6 +17,7 @@ import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks class CheckpointingServiceSpec extends TestKit(ActorSystem("CheckpointingServiceSpec_System")) with AnyFlatSpecLike + with WithActorSystemShutDown with MockFactory with ScalaFutures with NormalPatience diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala index 69e5b04d60..5cb6bd745a 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala @@ -3,8 +3,8 @@ package io.iohk.ethereum.jsonrpc import java.net.InetSocketAddress import akka.actor.ActorSystem -import akka.testkit.TestProbe -import io.iohk.ethereum.Fixtures +import akka.testkit.{TestKit, TestProbe} +import io.iohk.ethereum.{Fixtures, WithActorSystemShutDown} import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} import io.iohk.ethereum.network.EtcPeerManagerActor.PeerInfo import io.iohk.ethereum.network.PeerManagerActor.Peers @@ -14,10 +14,16 @@ import io.iohk.ethereum.network.{EtcPeerManagerActor, Peer, PeerActor, PeerManag import monix.execution.Scheduler.Implicits.global import org.scalamock.scalatest.MockFactory import org.scalatest.concurrent.ScalaFutures -import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers -class DebugServiceSpec extends AnyFlatSpec with Matchers with MockFactory with ScalaFutures { +class DebugServiceSpec + extends TestKit(ActorSystem("ActorSystem_DebugServiceSpec")) + with AnyFlatSpecLike + with WithActorSystemShutDown + with Matchers + with MockFactory + with ScalaFutures { "DebugService" should "return list of peers info" in new TestSetup { val result: ServiceResponse[ListPeersInfoResponse] = @@ -56,9 +62,7 @@ class DebugServiceSpec extends AnyFlatSpec with Matchers with MockFactory with S result.runSyncUnsafe() shouldBe Right(ListPeersInfoResponse(List.empty)) } - trait TestSetup { - implicit val system: ActorSystem = ActorSystem("debug-service-test") - + class TestSetup(implicit system: ActorSystem) { val peerManager = TestProbe() val etcPeerManager = TestProbe() val debugService = new DebugService(peerManager.ref, etcPeerManager.ref) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index dc33e03b47..3453b28b97 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -3,7 +3,7 @@ package io.iohk.ethereum.jsonrpc import java.security.SecureRandom import akka.actor.ActorSystem -import akka.testkit.TestProbe +import akka.testkit.{TestKit, TestProbe} import akka.util.ByteString import io.iohk.ethereum.blockchain.sync.EphemBlockchainTestSetup import io.iohk.ethereum.consensus._ @@ -27,33 +27,35 @@ import io.iohk.ethereum.transactions.PendingTransactionsManager.{ PendingTransactionsResponse } import io.iohk.ethereum.utils._ -import io.iohk.ethereum.{Fixtures, Timeouts, crypto} -import monix.eval.Task +import io.iohk.ethereum.{Fixtures, NormalPatience, Timeouts, WithActorSystemShutDown, crypto} import monix.execution.Scheduler.Implicits.global import org.bouncycastle.util.encoders.Hex import org.scalactic.TypeCheckedTripleEquals import org.scalamock.scalatest.MockFactory import org.scalatest.OptionValues import org.scalatest.concurrent.ScalaFutures -import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers -import scala.concurrent.duration.{DurationInt, FiniteDuration} +import scala.concurrent.duration.{Duration, DurationInt, FiniteDuration} // scalastyle:off file.size.limit class EthServiceSpec - extends AnyFlatSpec + extends TestKit(ActorSystem("EthServiceSpec_ActorSystem")) + with AnyFlatSpecLike + with WithActorSystemShutDown with Matchers with ScalaFutures with OptionValues with MockFactory + with NormalPatience with TypeCheckedTripleEquals { "EthService" should "answer eth_blockNumber with the latest block number" in new TestSetup { val bestBlockNumber = 10 blockchain.saveBestKnownBlocks(bestBlockNumber) - val response = ethService.bestBlockNumber(BestBlockNumberRequest()).runSyncUnsafe().right.get + val response = ethService.bestBlockNumber(BestBlockNumberRequest()).runSyncUnsafe(Duration.Inf).right.get response.bestBlockNumber shouldEqual bestBlockNumber } @@ -72,28 +74,28 @@ class EthServiceSpec it should "answer eth_getBlockTransactionCountByHash with None when the requested block isn't in the blockchain" in new TestSetup { val request = TxCountByBlockHashRequest(blockToRequestHash) - val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe().right.get + val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe(Duration.Inf).right.get response.txsQuantity shouldBe None } it should "answer eth_getBlockTransactionCountByHash with the block has no tx when the requested block is in the blockchain and has no tx" in new TestSetup { blockchain.storeBlock(blockToRequest.copy(body = BlockBody(Nil, Nil))).commit() val request = TxCountByBlockHashRequest(blockToRequestHash) - val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe().right.get + val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe(Duration.Inf).right.get response.txsQuantity shouldBe Some(0) } it should "answer eth_getBlockTransactionCountByHash correctly when the requested block is in the blockchain and has some tx" in new TestSetup { blockchain.storeBlock(blockToRequest).commit() val request = TxCountByBlockHashRequest(blockToRequestHash) - val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe().right.get + val response = ethService.getBlockTransactionCountByHash(request).runSyncUnsafe(Duration.Inf).right.get response.txsQuantity shouldBe Some(blockToRequest.body.transactionList.size) } it should "answer eth_getTransactionByBlockHashAndIndex with None when there is no block with the requested hash" in new TestSetup { val txIndexToRequest = blockToRequest.body.transactionList.size / 2 val request = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, txIndexToRequest) - val response = ethService.getTransactionByBlockHashAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getTransactionByBlockHashAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.transactionResponse shouldBe None } @@ -105,7 +107,7 @@ class EthServiceSpec val requestWithInvalidIndex = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, invalidTxIndex) val response = ethService .getTransactionByBlockHashAndIndex(requestWithInvalidIndex) - .runSyncUnsafe() + .runSyncUnsafe(Duration.Inf) .right .get @@ -117,7 +119,7 @@ class EthServiceSpec val txIndexToRequest = blockToRequest.body.transactionList.size / 2 val request = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, txIndexToRequest) - val response = ethService.getTransactionByBlockHashAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getTransactionByBlockHashAndIndex(request).runSyncUnsafe(Duration.Inf).right.get val requestedStx = blockToRequest.body.transactionList.apply(txIndexToRequest) val expectedTxResponse = TransactionResponse(requestedStx, Some(blockToRequest.header), Some(txIndexToRequest)) @@ -130,7 +132,7 @@ class EthServiceSpec val request = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, txIndexToRequest) // when - val response = ethService.getRawTransactionByBlockHashAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getRawTransactionByBlockHashAndIndex(request).runSyncUnsafe(Duration.Inf).right.get // then response.transactionResponse shouldBe None @@ -146,7 +148,7 @@ class EthServiceSpec // when val response = ethService .getRawTransactionByBlockHashAndIndex(requestWithInvalidIndex) - .runSyncUnsafe() + .runSyncUnsafe(Duration.Inf) .toOption .value @@ -161,7 +163,7 @@ class EthServiceSpec val request = GetTransactionByBlockHashAndIndexRequest(blockToRequest.header.hash, txIndexToRequest) // when - val response = ethService.getRawTransactionByBlockHashAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getRawTransactionByBlockHashAndIndex(request).runSyncUnsafe(Duration.Inf).right.get // then val expectedTxResponse = blockToRequest.body.transactionList.lift(txIndexToRequest) @@ -258,7 +260,7 @@ class EthServiceSpec it should "answer eth_getBlockByNumber with None when the requested block isn't in the blockchain" in new TestSetup { val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) - val response = ethService.getBlockByNumber(request).runSyncUnsafe().right.get + val response = ethService.getBlockByNumber(request).runSyncUnsafe(Duration.Inf).right.get response.blockResponse shouldBe None } @@ -269,7 +271,7 @@ class EthServiceSpec .commit() val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) - val response = ethService.getBlockByNumber(request).runSyncUnsafe().right.get + val response = ethService.getBlockByNumber(request).runSyncUnsafe(Duration.Inf).right.get val stxResponses = blockToRequest.body.transactionList.zipWithIndex.map { case (stx, txIndex) => TransactionResponse(stx, Some(blockToRequest.header), Some(txIndex)) @@ -284,7 +286,7 @@ class EthServiceSpec blockchain.storeBlock(blockToRequest).commit() val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) - val response = ethService.getBlockByNumber(request).runSyncUnsafe().right.get + val response = ethService.getBlockByNumber(request).runSyncUnsafe(Duration.Inf).right.get val stxResponses = blockToRequest.body.transactionList.zipWithIndex.map { case (stx, txIndex) => TransactionResponse(stx, Some(blockToRequest.header), Some(txIndex)) @@ -302,7 +304,7 @@ class EthServiceSpec .commit() val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) - val response = ethService.getBlockByNumber(request.copy(fullTxs = false)).runSyncUnsafe().right.get + val response = ethService.getBlockByNumber(request.copy(fullTxs = false)).runSyncUnsafe(Duration.Inf).right.get response.blockResponse shouldBe Some( BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd)) @@ -313,7 +315,7 @@ class EthServiceSpec it should "answer eth_getBlockByHash with None when the requested block isn't in the blockchain" in new TestSetup { val request = BlockByBlockHashRequest(blockToRequestHash, fullTxs = true) - val response = ethService.getByBlockHash(request).runSyncUnsafe().right.get + val response = ethService.getByBlockHash(request).runSyncUnsafe(Duration.Inf).right.get response.blockResponse shouldBe None } @@ -324,7 +326,7 @@ class EthServiceSpec .commit() val request = BlockByBlockHashRequest(blockToRequestHash, fullTxs = true) - val response = ethService.getByBlockHash(request).runSyncUnsafe().right.get + val response = ethService.getByBlockHash(request).runSyncUnsafe(Duration.Inf).right.get val stxResponses = blockToRequest.body.transactionList.zipWithIndex.map { case (stx, txIndex) => TransactionResponse(stx, Some(blockToRequest.header), Some(txIndex)) @@ -339,7 +341,7 @@ class EthServiceSpec blockchain.storeBlock(blockToRequest).commit() val request = BlockByBlockHashRequest(blockToRequestHash, fullTxs = true) - val response = ethService.getByBlockHash(request).runSyncUnsafe().right.get + val response = ethService.getByBlockHash(request).runSyncUnsafe(Duration.Inf).right.get val stxResponses = blockToRequest.body.transactionList.zipWithIndex.map { case (stx, txIndex) => TransactionResponse(stx, Some(blockToRequest.header), Some(txIndex)) @@ -357,7 +359,7 @@ class EthServiceSpec .commit() val request = BlockByBlockHashRequest(blockToRequestHash, fullTxs = true) - val response = ethService.getByBlockHash(request.copy(fullTxs = false)).runSyncUnsafe().right.get + val response = ethService.getByBlockHash(request.copy(fullTxs = false)).runSyncUnsafe(Duration.Inf).right.get response.blockResponse shouldBe Some( BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd)) @@ -369,7 +371,7 @@ class EthServiceSpec it should "answer eth_getUncleByBlockHashAndIndex with None when the requested block isn't in the blockchain" in new TestSetup { val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) - val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.uncleBlockResponse shouldBe None } @@ -378,7 +380,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) - val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.uncleBlockResponse shouldBe None } @@ -389,9 +391,9 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) val response1 = - ethService.getUncleByBlockHashAndIndex(request.copy(uncleIndex = 1)).runSyncUnsafe().right.get + ethService.getUncleByBlockHashAndIndex(request.copy(uncleIndex = 1)).runSyncUnsafe(Duration.Inf).right.get val response2 = - ethService.getUncleByBlockHashAndIndex(request.copy(uncleIndex = -1)).runSyncUnsafe().right.get + ethService.getUncleByBlockHashAndIndex(request.copy(uncleIndex = -1)).runSyncUnsafe(Duration.Inf).right.get response1.uncleBlockResponse shouldBe None response2.uncleBlockResponse shouldBe None @@ -402,7 +404,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) - val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.uncleBlockResponse shouldBe Some(BlockResponse(uncle, None, pendingBlock = false)) response.uncleBlockResponse.get.totalDifficulty shouldBe None @@ -418,7 +420,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) - val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getUncleByBlockHashAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.uncleBlockResponse shouldBe Some(BlockResponse(uncle, Some(uncleTd), pendingBlock = false)) response.uncleBlockResponse.get.totalDifficulty shouldBe Some(uncleTd) @@ -429,7 +431,7 @@ class EthServiceSpec it should "answer eth_getUncleByBlockNumberAndIndex with None when the requested block isn't in the blockchain" in new TestSetup { val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.uncleBlockResponse shouldBe None } @@ -438,7 +440,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.uncleBlockResponse shouldBe None } @@ -448,8 +450,10 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response1 = ethService.getUncleByBlockNumberAndIndex(request.copy(uncleIndex = 1)).runSyncUnsafe().right.get - val response2 = ethService.getUncleByBlockNumberAndIndex(request.copy(uncleIndex = -1)).runSyncUnsafe().right.get + val response1 = + ethService.getUncleByBlockNumberAndIndex(request.copy(uncleIndex = 1)).runSyncUnsafe(Duration.Inf).right.get + val response2 = + ethService.getUncleByBlockNumberAndIndex(request.copy(uncleIndex = -1)).runSyncUnsafe(Duration.Inf).right.get response1.uncleBlockResponse shouldBe None response2.uncleBlockResponse shouldBe None @@ -460,7 +464,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.uncleBlockResponse shouldBe Some(BlockResponse(uncle, None, pendingBlock = false)) response.uncleBlockResponse.get.totalDifficulty shouldBe None @@ -476,7 +480,7 @@ class EthServiceSpec val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) - val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getUncleByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.uncleBlockResponse shouldBe Some(BlockResponse(uncle, Some(uncleTd), pendingBlock = false)) response.uncleBlockResponse.get.totalDifficulty shouldBe Some(uncleTd) @@ -797,7 +801,7 @@ class EthServiceSpec val txIndex: Int = 1 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.Latest, txIndex) - val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get val expectedTxResponse = TransactionResponse(blockToRequest.body.transactionList(txIndex), Some(blockToRequest.header), Some(txIndex)) @@ -810,52 +814,52 @@ class EthServiceSpec val txIndex: Int = blockToRequest.body.transactionList.length + 42 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequest.header.number), txIndex) - val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.transactionResponse shouldBe None } - it should "getTransactionByBlockNumberAndIndexRequest return empty response if block does not exists when getting by index" in new TestSetup { + it should "getTransactionByBlockNumberAndIndex return empty response if block does not exists when getting by index" in new TestSetup { blockchain.storeBlock(blockToRequest).commit() val txIndex: Int = 1 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequest.header.number - 42), txIndex) - val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getTransactionByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.transactionResponse shouldBe None } - it should "getRawTransactionByBlockNumberAndIndexRequest return transaction by index" in new TestSetup { + it should "getRawTransactionByBlockNumberAndIndex return transaction by index" in new TestSetup { blockchain.storeBlock(blockToRequest).commit() blockchain.saveBestKnownBlocks(blockToRequest.header.number) val txIndex: Int = 1 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.Latest, txIndex) - val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get val expectedTxResponse = blockToRequest.body.transactionList.lift(txIndex) response.transactionResponse shouldBe expectedTxResponse } - it should "getRawTransactionByBlockNumberAndIndexRequest return empty response if transaction does not exists when getting by index" in new TestSetup { + it should "getRawTransactionByBlockNumberAndIndex return empty response if transaction does not exists when getting by index" in new TestSetup { blockchain.storeBlock(blockToRequest).commit() val txIndex: Int = blockToRequest.body.transactionList.length + 42 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequest.header.number), txIndex) - val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.transactionResponse shouldBe None } - it should "getRawTransactionByBlockNumberAndIndexRequest return empty response if block does not exists when getting by index" in new TestSetup { + it should "getRawTransactionByBlockNumberAndIndex return empty response if block does not exists when getting by index" in new TestSetup { blockchain.storeBlock(blockToRequest).commit() val txIndex: Int = 1 val request = GetTransactionByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequest.header.number - 42), txIndex) - val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe().right.get + val response = ethService.getRawTransactionByBlockNumberAndIndex(request).runSyncUnsafe(Duration.Inf).right.get response.transactionResponse shouldBe None } @@ -1149,7 +1153,7 @@ class EthServiceSpec } // NOTE TestSetup uses Ethash consensus; check `consensusConfig`. - trait TestSetup extends MockFactory with EphemBlockchainTestSetup { + class TestSetup(implicit system: ActorSystem) extends MockFactory with EphemBlockchainTestSetup { val blockGenerator = mock[EthashBlockGenerator] val appStateStorage = mock[AppStateStorage] val keyStore = mock[KeyStore] @@ -1158,8 +1162,6 @@ class EthServiceSpec override lazy val consensus: TestConsensus = buildTestConsensus().withBlockGenerator(blockGenerator) - override implicit lazy val system = ActorSystem("EthServiceSpec_System") - val syncingController = TestProbe() val pendingTransactionsManager = TestProbe() val ommersPool = TestProbe() diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/FilterManagerSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/FilterManagerSpec.scala index 8bebd5b4b0..6f31476782 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/FilterManagerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/FilterManagerSpec.scala @@ -1,7 +1,7 @@ package io.iohk.ethereum.jsonrpc import akka.actor.{ActorSystem, Props} -import akka.testkit.{TestActorRef, TestProbe} +import akka.testkit.{TestActorRef, TestKit, TestProbe} import akka.util.ByteString import io.iohk.ethereum.db.storage.AppStateStorage import io.iohk.ethereum.domain._ @@ -12,7 +12,7 @@ import org.bouncycastle.util.encoders.Hex import akka.pattern.ask import com.miguno.akka.testing.VirtualTime import io.iohk.ethereum.consensus.blocks.{BlockGenerator, PendingBlock} -import io.iohk.ethereum.{NormalPatience, Timeouts} +import io.iohk.ethereum.{NormalPatience, Timeouts, WithActorSystemShutDown} import io.iohk.ethereum.crypto.{ECDSASignature, generateKeyPair} import io.iohk.ethereum.jsonrpc.FilterManager.LogFilterLogs import io.iohk.ethereum.ledger.BloomFilter @@ -24,10 +24,16 @@ import org.bouncycastle.crypto.AsymmetricCipherKeyPair import org.scalatest.concurrent.ScalaFutures import scala.concurrent.duration._ -import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers -class FilterManagerSpec extends AnyFlatSpec with Matchers with ScalaFutures with NormalPatience { +class FilterManagerSpec + extends TestKit(ActorSystem("FilterManagerSpec_System")) + with AnyFlatSpecLike + with WithActorSystemShutDown + with Matchers + with ScalaFutures + with NormalPatience { "FilterManager" should "handle log filter logs and changes" in new TestSetup { @@ -460,8 +466,7 @@ class FilterManagerSpec extends AnyFlatSpec with Matchers with ScalaFutures with getLogsRes2 shouldBe LogFilterLogs(Nil) } - trait TestSetup extends MockFactory with SecureRandomBuilder { - implicit val system = ActorSystem("FilterManagerSpec_System") + class TestSetup(implicit system: ActorSystem) extends MockFactory with SecureRandomBuilder { val config = new FilterConfig { override val filterTimeout = Timeouts.longTimeout diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index a54b393ac5..e419764d68 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -22,8 +22,7 @@ import io.iohk.ethereum.transactions.PendingTransactionsManager import io.iohk.ethereum.{LongPatience, WithActorSystemShutDown} import io.iohk.ethereum.{Fixtures, Timeouts} import monix.eval.Task -import monix.execution.Scheduler -import monix.execution.schedulers.TestScheduler +import monix.execution.Scheduler.Implicits.global import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ import org.json4s.JsonDSL._ @@ -39,12 +38,10 @@ class JsonRpcControllerEthSpec with WithActorSystemShutDown with JRCMatchers with ScalaCheckPropertyChecks - with ScalaFutures // TODO PP not needed ? - with LongPatience // TODO PP .timeout in Task? + with ScalaFutures + with LongPatience with Eventually { - implicit val tx: Scheduler = TestScheduler() // TODO PP use global or - implicit val formats: Formats = DefaultFormats.preservingEmptyValues + 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 1d0c747de0..69df56007f 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala @@ -17,8 +17,7 @@ import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransacti import io.iohk.ethereum.{LongPatience, WithActorSystemShutDown} import io.iohk.ethereum.Fixtures import monix.eval.Task -import monix.execution.Scheduler -import monix.execution.schedulers.TestScheduler +import monix.execution.Scheduler.Implicits.global import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ import org.json4s.JsonDSL._ @@ -40,8 +39,6 @@ class JsonRpcControllerEthTransactionSpec with LongPatience with Eventually { - implicit val tx: Scheduler = TestScheduler() - implicit val formats: Formats = DefaultFormats.preservingEmptyValues + 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 488a1e461b..fd9901083e 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerPersonalSpec.scala @@ -14,8 +14,7 @@ import io.iohk.ethereum.jsonrpc.JsonSerializers.{ } import io.iohk.ethereum.jsonrpc.PersonalService._ import monix.eval.Task -import monix.execution.Scheduler -import monix.execution.schedulers.TestScheduler +import monix.execution.Scheduler.Implicits.global import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ import org.json4s.JsonDSL._ @@ -36,8 +35,6 @@ class JsonRpcControllerPersonalSpec with LongPatience with Eventually { - implicit val tx: Scheduler = TestScheduler() - implicit val formats: Formats = DefaultFormats.preservingEmptyValues + 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 98338bd032..0553b240b7 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerSpec.scala @@ -18,8 +18,7 @@ import io.iohk.ethereum.network.p2p.messages.CommonMessages.Status import io.iohk.ethereum.network.p2p.messages.Versions import io.iohk.ethereum.{Fixtures, LongPatience, WithActorSystemShutDown} import monix.eval.Task -import monix.execution.Scheduler -import monix.execution.schedulers.TestScheduler +import monix.execution.Scheduler.Implicits.global import org.json4s.JsonAST._ import org.json4s.JsonDSL._ import org.json4s.{DefaultFormats, Extraction, Formats} @@ -41,8 +40,6 @@ class JsonRpcControllerSpec with LongPatience with Eventually { - implicit val tx: Scheduler = TestScheduler() - implicit val formats: Formats = DefaultFormats.preservingEmptyValues + OptionNoneToJNullSerializer + QuantitiesSerializer + UnformattedDataJsonSerializer diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala index d62c0db2be..bcb5dd113a 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala @@ -1,27 +1,23 @@ package io.iohk.ethereum.jsonrpc import java.net.InetSocketAddress +import java.util.concurrent.atomic.AtomicReference import akka.actor.ActorSystem import akka.testkit.TestProbe -import io.iohk.ethereum.{NormalPatience, crypto} import io.iohk.ethereum.jsonrpc.NetService._ import io.iohk.ethereum.network.{Peer, PeerActor, PeerManagerActor} import io.iohk.ethereum.nodebuilder.SecureRandomBuilder import io.iohk.ethereum.utils.{NodeStatus, ServerStatus} -import java.util.concurrent.atomic.AtomicReference - -import monix.execution.Scheduler -import monix.execution.schedulers.TestScheduler +import io.iohk.ethereum.{NormalPatience, crypto} +import monix.execution.Scheduler.Implicits.global import org.scalatest.concurrent.ScalaFutures - -import scala.concurrent.duration._ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers -class NetServiceSpec extends AnyFlatSpec with Matchers with ScalaFutures with NormalPatience with SecureRandomBuilder { +import scala.concurrent.duration._ - implicit val tx: Scheduler = TestScheduler() +class NetServiceSpec extends AnyFlatSpec with Matchers with ScalaFutures with NormalPatience with SecureRandomBuilder { "NetService" should "return handshaked peer count" in new TestSetup { val resF = netService.peerCount(PeerCountRequest()) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala index 5654e84426..ba11226f47 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala @@ -3,7 +3,7 @@ package io.iohk.ethereum.jsonrpc import java.time.Duration import akka.actor.ActorSystem -import akka.testkit.TestProbe +import akka.testkit.{TestKit, TestProbe} import akka.util.ByteString import com.miguno.akka.testing.VirtualTime import io.iohk.ethereum.crypto.ECDSASignature @@ -15,13 +15,13 @@ import io.iohk.ethereum.keystore.KeyStore.{DecryptionFailed, IOError} import io.iohk.ethereum.keystore.{KeyStore, Wallet} import io.iohk.ethereum.transactions.PendingTransactionsManager._ import io.iohk.ethereum.utils.{BlockchainConfig, MonetaryPolicyConfig, TxPoolConfig} -import io.iohk.ethereum.{Fixtures, NormalPatience, Timeouts} +import io.iohk.ethereum.{Fixtures, NormalPatience, Timeouts, WithActorSystemShutDown} import monix.execution.Scheduler.Implicits.global import org.bouncycastle.util.encoders.Hex import org.scalamock.matchers.MatcherBase import org.scalamock.scalatest.MockFactory import org.scalatest.concurrent.{Eventually, ScalaFutures} -import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers import org.scalatest.time.{Millis, Seconds, Span} import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks @@ -30,7 +30,9 @@ import scala.concurrent.duration.FiniteDuration import scala.reflect.ClassTag class PersonalServiceSpec - extends AnyFlatSpec + extends TestKit(ActorSystem("JsonRpcControllerEthSpec_System")) + with AnyFlatSpecLike + with WithActorSystemShutDown with Matchers with MockFactory with ScalaFutures @@ -439,8 +441,6 @@ class PersonalServiceSpec val stx = stxWithSender.tx val chainSpecificStx = wallet.signTx(tx.toTransaction(nonce), Some(blockchainConfig.chainId)).tx - implicit val system = ActorSystem("personal-service-test") - val txPoolConfig = new TxPoolConfig { override val txPoolSize: Int = 30 override val pendingTxManagerQueryTimeout: FiniteDuration = Timeouts.normalTimeout diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala index 2307a17a21..17023f55bd 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala @@ -17,16 +17,13 @@ import org.scalamock.scalatest.AsyncMockFactory import scala.concurrent.Future class QAServiceSpec - extends TestKit(ActorSystem("QAServiceSpec_System")) + extends TestKit(ActorSystem("QAServiceSpec_ActorSystem")) with FlatSpecBase + with WithActorSystemShutDown with SpecFixtures with ByteGenerators with AsyncMockFactory { - def afterAll: Unit = { - TestKit.shutdownActorSystem(system) - } - "QAService" should "send msg to miner and return miner's response" in testCaseM { fixture => import fixture._ (testConsensus.sendMiner _) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala index fcb54ff402..d1184ab0f8 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala @@ -13,8 +13,7 @@ import io.iohk.ethereum.nodebuilder.BlockchainConfigBuilder import io.iohk.ethereum.utils.{ByteStringUtils, Config} import io.iohk.ethereum.{ByteGenerators, NormalPatience, crypto} import monix.eval.Task -import monix.execution.Scheduler -import monix.execution.schedulers.TestScheduler +import monix.execution.Scheduler.Implicits.global import org.json4s.Extraction import org.json4s.JsonAST._ import org.json4s.JsonDSL._ @@ -30,8 +29,6 @@ class QaJRCSpec with NormalPatience with JsonMethodsImplicits { - implicit val tx: Scheduler = TestScheduler() - "QaJRC" should { "request block mining and return valid response with correct message" when { "mining ordered" in new TestSetup { diff --git a/src/test/scala/io/iohk/ethereum/network/PeerActorHandshakingSpec.scala b/src/test/scala/io/iohk/ethereum/network/PeerActorHandshakingSpec.scala index 0567897755..e41ea21ba1 100644 --- a/src/test/scala/io/iohk/ethereum/network/PeerActorHandshakingSpec.scala +++ b/src/test/scala/io/iohk/ethereum/network/PeerActorHandshakingSpec.scala @@ -139,7 +139,7 @@ class PeerActorHandshakingSpec extends AnyFlatSpec with Matchers { } trait TestSetup extends EphemBlockchainTestSetup { - override implicit lazy val system = ActorSystem("PeerActorSpec_System") + override implicit lazy val system = ActorSystem("PeerActorSpec_System") // TODO this is never closed val time = new VirtualTime diff --git a/src/test/scala/io/iohk/ethereum/network/p2p/PeerActorSpec.scala b/src/test/scala/io/iohk/ethereum/network/p2p/PeerActorSpec.scala index e784ae75d1..f31f563bd0 100644 --- a/src/test/scala/io/iohk/ethereum/network/p2p/PeerActorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/network/p2p/PeerActorSpec.scala @@ -5,7 +5,7 @@ import java.security.SecureRandom import java.util.concurrent.atomic.AtomicReference import akka.actor.{ActorSystem, PoisonPill, Props, Terminated} -import akka.testkit.{TestActorRef, TestProbe} +import akka.testkit.{TestActorRef, TestKit, TestProbe} import akka.util.ByteString import com.miguno.akka.testing.VirtualTime import io.iohk.ethereum.blockchain.sync.EphemBlockchainTestSetup @@ -30,17 +30,22 @@ import io.iohk.ethereum.network.rlpx.RLPxConnectionHandler.RLPxConfiguration import io.iohk.ethereum.network.{ForkResolver, PeerActor, PeerEventBusActor, _} import io.iohk.ethereum.nodebuilder.SecureRandomBuilder import io.iohk.ethereum.utils.{Config, NodeStatus, ServerStatus} -import io.iohk.ethereum.{Fixtures, Mocks, Timeouts, crypto} +import io.iohk.ethereum.{Fixtures, Mocks, Timeouts, WithActorSystemShutDown, crypto} import org.bouncycastle.crypto.AsymmetricCipherKeyPair import org.bouncycastle.crypto.params.ECPublicKeyParameters import org.bouncycastle.util.encoders.Hex +import org.scalatest.flatspec.AnyFlatSpecLike +import org.scalatest.matchers.should.Matchers + import scala.concurrent.duration._ import scala.language.postfixOps -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers -class PeerActorSpec extends AnyFlatSpec with Matchers { +class PeerActorSpec + extends TestKit(ActorSystem("PeerActorSpec_System")) + with AnyFlatSpecLike + with WithActorSystemShutDown + with Matchers { val remoteNodeKey: AsymmetricCipherKeyPair = generateKeyPair(new SecureRandom) val remoteNodeId: ByteString = ByteString(remoteNodeKey.getPublic.asInstanceOf[ECPublicKeyParameters].toNodeId) @@ -520,8 +525,6 @@ class PeerActorSpec extends AnyFlatSpec with Matchers { rlpxConnection.send(peer, RLPxConnectionHandler.MessageReceived(BlockHeaders(Nil))) } - override implicit lazy val system = ActorSystem("PeerActorSpec_System") - val rlpxConnection = TestProbe() val time = new VirtualTime diff --git a/src/test/scala/io/iohk/ethereum/network/rlpx/RLPxConnectionHandlerSpec.scala b/src/test/scala/io/iohk/ethereum/network/rlpx/RLPxConnectionHandlerSpec.scala index 0b712aa60b..3506a2299d 100644 --- a/src/test/scala/io/iohk/ethereum/network/rlpx/RLPxConnectionHandlerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/network/rlpx/RLPxConnectionHandlerSpec.scala @@ -4,9 +4,9 @@ import java.net.{InetSocketAddress, URI} import akka.actor.{ActorRef, ActorSystem, Props} import akka.io.Tcp -import akka.testkit.{TestActorRef, TestProbe} +import akka.testkit.{TestActorRef, TestKit, TestProbe} import akka.util.ByteString -import io.iohk.ethereum.Timeouts +import io.iohk.ethereum.{Timeouts, WithActorSystemShutDown} import io.iohk.ethereum.network.p2p.Message.Version import io.iohk.ethereum.network.p2p.{MessageDecoder, MessageSerializable} import io.iohk.ethereum.network.p2p.messages.Versions @@ -16,10 +16,15 @@ import io.iohk.ethereum.nodebuilder.SecureRandomBuilder import org.scalamock.scalatest.MockFactory import scala.concurrent.duration.FiniteDuration -import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers -class RLPxConnectionHandlerSpec extends AnyFlatSpec with Matchers with MockFactory { +class RLPxConnectionHandlerSpec + extends TestKit(ActorSystem("RLPxConnectionHandlerSpec_System")) + with AnyFlatSpecLike + with WithActorSystemShutDown + with Matchers + with MockFactory { it should "write messages send to TCP connection" in new TestSetup { @@ -166,7 +171,6 @@ class RLPxConnectionHandlerSpec extends AnyFlatSpec with Matchers with MockFacto } trait TestSetup extends MockFactory with SecureRandomBuilder { - implicit val system = ActorSystem("RLPxHandlerSpec_System") //Mock parameters for RLPxConnectionHandler val mockMessageDecoder = new MessageDecoder { @@ -231,5 +235,4 @@ class RLPxConnectionHandlerSpec extends AnyFlatSpec with Matchers with MockFacto rlpxConnectionParent.expectMsgClass(classOf[RLPxConnectionHandler.ConnectionEstablished]) } } - } From 9b798df635f228883d687c7e40376521c57836f4 Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 23 Oct 2020 20:57:46 +0200 Subject: [PATCH 12/33] [ETC-269] cleanup actor systems and monix scheduler in tests to avoid tests hang 2 --- .../scala/io/iohk/ethereum/jsonrpc/PersonalService.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index c3fa358b95..0e1831429c 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -4,7 +4,6 @@ import java.time.Duration import akka.actor.ActorRef import akka.util.{ByteString, Timeout} -import cats.syntax.either._ import io.iohk.ethereum.crypto import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.db.storage.AppStateStorage @@ -21,6 +20,8 @@ import io.iohk.ethereum.rlp.RLPImplicits._ import io.iohk.ethereum.rlp.RLPImplicitConversions._ import monix.eval.Task +import scala.util.Try + object PersonalService { case class ImportRawKeyRequest(prvKey: ByteString, passphrase: String) @@ -160,8 +161,8 @@ class PersonalService( def sendTransaction(request: SendTransactionRequest): ServiceResponse[SendTransactionResponse] = { unlockedWallets.get(request.tx.from) match { case Some(wallet) => - val txHashAction = sendTransaction(request.tx, wallet) - txHashAction.map(txHash => Right(SendTransactionResponse(txHash))) + val futureTxHash = sendTransaction(request.tx, wallet) + futureTxHash.map(txHash => Right(SendTransactionResponse(txHash))) case None => Task.now(Left(AccountLocked)) @@ -199,7 +200,7 @@ class PersonalService( val latestPendingTxNonceFuture: Task[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => val senderTxsNonces = pendingTxs.pendingTransactions .collect { case ptx if ptx.stx.senderAddress == wallet.address => ptx.stx.tx.tx.nonce } - Either.catchNonFatal(senderTxsNonces.max).toOption + Try(senderTxsNonces.max).toOption } latestPendingTxNonceFuture .map { maybeLatestPendingTxNonce => From 5b8a5c4bdc39d69b958dcbf9eac39fd32d04858d Mon Sep 17 00:00:00 2001 From: lemastero Date: Mon, 26 Oct 2020 11:33:41 +0100 Subject: [PATCH 13/33] [ETCM-126] set explicit timeouts for runSyncUnsafe that is how Future behaves --- .../jsonrpc/PersonalServiceSpec.scala | 71 +++++++++---------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala index ba11226f47..fc1a8264cc 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala @@ -44,7 +44,7 @@ class PersonalServiceSpec (keyStore.importPrivateKey _).expects(prvKey, passphrase).returning(Right(address)) val req = ImportRawKeyRequest(prvKey, passphrase) - val res = personal.importRawKey(req).runSyncUnsafe() + val res = personal.importRawKey(req).runSyncUnsafe(taskTimeout) res shouldEqual Right(ImportRawKeyResponse(address)) } @@ -53,7 +53,7 @@ class PersonalServiceSpec (keyStore.newAccount _).expects(passphrase).returning(Right(address)) val req = NewAccountRequest(passphrase) - val res = personal.newAccount(req).runSyncUnsafe() + val res = personal.newAccount(req).runSyncUnsafe(taskTimeout) res shouldEqual Right(NewAccountResponse(address)) } @@ -62,7 +62,7 @@ class PersonalServiceSpec (keyStore.newAccount _).expects(passphrase).returning(Left(KeyStore.PassPhraseTooShort(7))) val req = NewAccountRequest(passphrase) - val res = personal.newAccount(req).runSyncUnsafe() + val res = personal.newAccount(req).runSyncUnsafe(taskTimeout) res shouldEqual Left(PersonalService.PassPhraseTooShort(7)) } @@ -71,29 +71,29 @@ class PersonalServiceSpec val addresses = List(123, 42, 1).map(Address(_)) (keyStore.listAccounts _).expects().returning(Right(addresses)) - val res = personal.listAccounts(ListAccountsRequest()).runSyncUnsafe() + val res = personal.listAccounts(ListAccountsRequest()).runSyncUnsafe(taskTimeout) res shouldEqual Right(ListAccountsResponse(addresses)) } it should "translate KeyStore errors to JsonRpc errors" in new TestSetup { (keyStore.listAccounts _).expects().returning(Left(IOError("boom!"))) - val res1 = personal.listAccounts(ListAccountsRequest()).runSyncUnsafe() + val res1 = personal.listAccounts(ListAccountsRequest()).runSyncUnsafe(taskTimeout) res1 shouldEqual Left(LogicError("boom!")) (keyStore.unlockAccount _).expects(*, *).returning(Left(KeyStore.KeyNotFound)) - val res2 = personal.unlockAccount(UnlockAccountRequest(Address(42), "passphrase", None)).runSyncUnsafe() + val res2 = personal.unlockAccount(UnlockAccountRequest(Address(42), "passphrase", None)).runSyncUnsafe(taskTimeout) res2 shouldEqual Left(KeyNotFound) (keyStore.unlockAccount _).expects(*, *).returning(Left(KeyStore.DecryptionFailed)) - val res3 = personal.unlockAccount(UnlockAccountRequest(Address(42), "passphrase", None)).runSyncUnsafe() + val res3 = personal.unlockAccount(UnlockAccountRequest(Address(42), "passphrase", None)).runSyncUnsafe(taskTimeout) res3 shouldEqual Left(InvalidPassphrase) } it should "return an error when trying to import an invalid key" in new TestSetup { val invalidKey = prvKey.tail val req = ImportRawKeyRequest(invalidKey, passphrase) - val res = personal.importRawKey(req).runSyncUnsafe() + val res = personal.importRawKey(req).runSyncUnsafe(taskTimeout) res shouldEqual Left(InvalidKey) } @@ -101,7 +101,7 @@ class PersonalServiceSpec (keyStore.unlockAccount _).expects(address, passphrase).returning(Right(wallet)) val req = UnlockAccountRequest(address, passphrase, None) - val res = personal.unlockAccount(req).runSyncUnsafe() + val res = personal.unlockAccount(req).runSyncUnsafe(taskTimeout) res shouldEqual Right(UnlockAccountResponse(true)) } @@ -121,7 +121,7 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe() shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) + res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } @@ -142,7 +142,7 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Seq(PendingTransaction(stxWithSender, 0)))) - res.runSyncUnsafe() shouldEqual Right(SendTransactionWithPassphraseResponse(newTx.hash)) + res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionWithPassphraseResponse(newTx.hash)) txPool.expectMsg(AddOrOverrideTransaction(newTx)) } @@ -152,7 +152,7 @@ class PersonalServiceSpec .returning(Left(KeyStore.DecryptionFailed)) val req = SendTransactionWithPassphraseRequest(tx, passphrase) - val res = personal.sendTransaction(req).runSyncUnsafe() + val res = personal.sendTransaction(req).runSyncUnsafe(taskTimeout) res shouldEqual Left(InvalidPassphrase) txPool.expectNoMessage() @@ -163,7 +163,7 @@ class PersonalServiceSpec .expects(address, passphrase) .returning(Right(wallet)) - personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe() + personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe(taskTimeout) (blockchain.getBestBlockNumber _).expects().returning(1234) (blockchain.getAccount _).expects(address, BigInt(1234)).returning(Some(Account(nonce, 2 * txValue))) @@ -175,13 +175,13 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe() shouldEqual Right(SendTransactionResponse(stx.hash)) + res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } it should "fail to send a transaction when account is locked" in new TestSetup { val req = SendTransactionRequest(tx) - val res = personal.sendTransaction(req).runSyncUnsafe() + val res = personal.sendTransaction(req).runSyncUnsafe(taskTimeout) res shouldEqual Left(AccountLocked) txPool.expectNoMessage() @@ -192,10 +192,10 @@ class PersonalServiceSpec .expects(address, passphrase) .returning(Right(wallet)) - personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe() + personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe(taskTimeout) - val lockRes = personal.lockAccount(LockAccountRequest(address)).runSyncUnsafe() - val txRes = personal.sendTransaction(SendTransactionRequest(tx)).runSyncUnsafe() + val lockRes = personal.lockAccount(LockAccountRequest(address)).runSyncUnsafe(taskTimeout) + val txRes = personal.sendTransaction(SendTransactionRequest(tx)).runSyncUnsafe(taskTimeout) lockRes shouldEqual Right(LockAccountResponse(true)) txRes shouldEqual Left(AccountLocked) @@ -215,12 +215,12 @@ class PersonalServiceSpec val req = SignRequest(message, address, Some(passphrase)) - val res = personal.sign(req).runSyncUnsafe() + val res = personal.sign(req).runSyncUnsafe(taskTimeout) res shouldEqual Right(SignResponse(ECDSASignature(r, s, v))) // Account should still be locked after calling sign with passphrase val txReq = SendTransactionRequest(tx) - val txRes = personal.sendTransaction(txReq).runSyncUnsafe() + val txRes = personal.sendTransaction(txReq).runSyncUnsafe(taskTimeout) txRes shouldEqual Left(AccountLocked) } @@ -239,8 +239,8 @@ class PersonalServiceSpec val req = SignRequest(message, address, None) - personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe() - val res = personal.sign(req).runSyncUnsafe() + personal.unlockAccount(UnlockAccountRequest(address, passphrase, None)).runSyncUnsafe(taskTimeout) + val res = personal.sign(req).runSyncUnsafe(taskTimeout) res shouldEqual Right(SignResponse(ECDSASignature(r, s, v))) } @@ -250,7 +250,7 @@ class PersonalServiceSpec val req = SignRequest(message, address, None) - val res = personal.sign(req).runSyncUnsafe() + val res = personal.sign(req).runSyncUnsafe(taskTimeout) res shouldEqual Left(AccountLocked) } @@ -266,7 +266,7 @@ class PersonalServiceSpec val req = SignRequest(message, address, Some(wrongPassphase)) - val res = personal.sign(req).runSyncUnsafe() + val res = personal.sign(req).runSyncUnsafe(taskTimeout) res shouldEqual Left(InvalidPassphrase) } @@ -280,7 +280,7 @@ class PersonalServiceSpec val req = SignRequest(message, address, Some(passphrase)) - val res = personal.sign(req).runSyncUnsafe() + val res = personal.sign(req).runSyncUnsafe(taskTimeout) res shouldEqual Left(KeyNotFound) } @@ -295,7 +295,7 @@ class PersonalServiceSpec val req = EcRecoverRequest(message, ECDSASignature(r, s, v)) - val res = personal.ecRecover(req).runSyncUnsafe() + val res = personal.ecRecover(req).runSyncUnsafe(taskTimeout) res shouldEqual Right(EcRecoverResponse(sigAddress)) } @@ -309,15 +309,14 @@ class PersonalServiceSpec personal .sign(SignRequest(message, address, Some(passphrase))) - .runSyncUnsafe() + .runSyncUnsafe(taskTimeout) .left .map(_ => fail()) .map(response => EcRecoverRequest(message, response.signature)) .foreach { req => - val res = personal.ecRecover(req).runSyncUnsafe() + val res = personal.ecRecover(req).runSyncUnsafe(taskTimeout) res shouldEqual Right(EcRecoverResponse(address)) } - } it should "produce not chain specific transaction before eip155" in new TestSetup { @@ -335,7 +334,7 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe() shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) + res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } @@ -355,7 +354,7 @@ class PersonalServiceSpec txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe() shouldEqual Right(SendTransactionWithPassphraseResponse(chainSpecificStx.hash)) + res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionWithPassphraseResponse(chainSpecificStx.hash)) txPool.expectMsg(AddOrOverrideTransaction(chainSpecificStx)) } @@ -363,14 +362,14 @@ class PersonalServiceSpec (keyStore.importPrivateKey _).expects(prvKey, passphrase).returning(Left(KeyStore.DuplicateKeySaved)) val req = ImportRawKeyRequest(prvKey, passphrase) - val res = personal.importRawKey(req).runSyncUnsafe() + val res = personal.importRawKey(req).runSyncUnsafe(taskTimeout) res shouldEqual Left(LogicError("account already exists")) } it should "unlock an account given a correct passphrase for specified duration" in new TestSetup { (keyStore.unlockAccount _).expects(address, passphrase).returning(Right(wallet)) - implicit val patienceConfig = + implicit val patienceConfig = // TODO identical timeout is defined in NormalPatience PatienceConfig(timeout = scaled(Span(3, Seconds)), interval = scaled(Span(100, Millis))) val message = ByteString(Hex.decode("deadbeaf")) @@ -382,14 +381,14 @@ class PersonalServiceSpec val reqSign = SignRequest(message, address, None) val req = UnlockAccountRequest(address, passphrase, Some(Duration.ofSeconds(2))) - val res = personal.unlockAccount(req).runSyncUnsafe() + val res = personal.unlockAccount(req).runSyncUnsafe(taskTimeout) res shouldEqual Right(UnlockAccountResponse(true)) - val res2 = personal.sign(reqSign).runSyncUnsafe() + val res2 = personal.sign(reqSign).runSyncUnsafe(taskTimeout) res2 shouldEqual Right(SignResponse(ECDSASignature(r, s, v))) eventually { - personal.sign(reqSign).runSyncUnsafe() shouldEqual Left(AccountLocked) + personal.sign(reqSign).runSyncUnsafe(taskTimeout) shouldEqual Left(AccountLocked) } } From 90f7761276938b14b3bd1eb81f6739309bf75439 Mon Sep 17 00:00:00 2001 From: lemastero Date: Mon, 26 Oct 2020 15:02:45 +0100 Subject: [PATCH 14/33] [ETCM-126] fix after merge --- .../scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala | 9 ++++++--- src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala | 2 +- .../io/iohk/ethereum/consensus/BlockGeneratorSpec.scala | 4 +++- .../BlockWithCheckpointHeaderValidatorSpec.scala | 5 +++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala index b447ec7772..42217814ac 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala @@ -4,14 +4,17 @@ import akka.actor.{Actor, ActorRef} import akka.util.Timeout import monix.eval.Task +import scala.reflect.ClassTag + object AkkaTaskOps { self: ActorRef => implicit class TaskActorOps(to: ActorRef) { import akka.pattern.ask - def askFor[A](message: Any)(implicit timeout: Timeout, sender: ActorRef = Actor.noSender): Task[A] = + def askFor[A]( + message: Any + )(implicit timeout: Timeout, classTag: ClassTag[A], sender: ActorRef = Actor.noSender): Task[A] = Task - .fromFuture(to ? message) + .fromFuture((to ? message).mapTo[A]) .timeout(timeout.duration) - .map(_.asInstanceOf[A]) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala index 7556f3a38d..565fd9dc5a 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala @@ -541,7 +541,7 @@ class EthService( val bestBlock = blockchain.getBestBlock() val response: ServiceResponse[GetWorkResponse] = - Task.zip(getOmmersFromPool(bestBlock.hash), getTransactionsFromPool).map { case (ommers, pendingTxs) => + Task.parZip2(getOmmersFromPool(bestBlock.hash), getTransactionsFromPool()).map { case (ommers, pendingTxs) => val blockGenerator = ethash.blockGenerator val pb = blockGenerator.generateBlock( bestBlock, diff --git a/src/test/scala/io/iohk/ethereum/consensus/BlockGeneratorSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/BlockGeneratorSpec.scala index 5ad92fae24..d7ab4dee30 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/BlockGeneratorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/BlockGeneratorSpec.scala @@ -406,7 +406,9 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val fullBlock = pendingBlock.block.copy(header = pendingBlock.block.header.copy(nonce = minedNonce, mixHash = minedMixHash, unixTimestamp = miningTimestamp) ) - validators.blockHeaderValidator.validate(fullBlock.header, blockchain.getBlockHeaderByHash) shouldBe Right(BlockHeaderValid) + validators.blockHeaderValidator.validate(fullBlock.header, blockchain.getBlockHeaderByHash) shouldBe Right( + BlockHeaderValid + ) blockExecution.executeBlock(fullBlock) shouldBe a[Right[_, Seq[Receipt]]] fullBlock.body.transactionList shouldBe Seq(signedTransaction.tx) fullBlock.header.extraData shouldBe headerExtraData diff --git a/src/test/scala/io/iohk/ethereum/consensus/validators/BlockWithCheckpointHeaderValidatorSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/validators/BlockWithCheckpointHeaderValidatorSpec.scala index f14e9de48e..1ccb266d78 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/validators/BlockWithCheckpointHeaderValidatorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/validators/BlockWithCheckpointHeaderValidatorSpec.scala @@ -225,7 +225,7 @@ class BlockWithCheckpointHeaderValidatorSpec val duplicatedSigner = ByteString(crypto.pubKeyFromKeyPair(keys.head)) val expectedSigners = (keys.map(kp => ByteString(crypto.pubKeyFromKeyPair(kp))) :+ duplicatedSigner) - .sortBy(_.toSeq) + .sortBy(_.toSeq) actualSigners shouldEqual expectedSigners val headerWithInvalidCheckpoint = checkpointBlockGenerator @@ -247,7 +247,8 @@ class BlockWithCheckpointHeaderValidatorSpec } it should "return when failure when checkpoint has too many signatures" in new TestSetup { - val invalidCheckpoint = validCheckpoint.copy(signatures = (validCheckpoint.signatures ++ validCheckpoint.signatures).sorted) + val invalidCheckpoint = + validCheckpoint.copy(signatures = (validCheckpoint.signatures ++ validCheckpoint.signatures).sorted) val invalidBlockHeaderExtraFields = HefPostEcip1097(false, Some(invalidCheckpoint)) val invalidBlockHeader = validBlockHeaderWithCheckpoint.copy(extraFields = invalidBlockHeaderExtraFields) From 00f31d34a75b9eecb5804d3a98dd88a5d83e6313 Mon Sep 17 00:00:00 2001 From: lemastero Date: Mon, 26 Oct 2020 15:04:07 +0100 Subject: [PATCH 15/33] [ETCM-126] partial Future and Task implementation to keep original ex used, to keep tests pass --- .../iohk/ethereum/jsonrpc/DebugService.scala | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala index 171545fd7a..1422de558a 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala @@ -1,14 +1,16 @@ package io.iohk.ethereum.jsonrpc import akka.actor.ActorRef +import akka.pattern._ import akka.util.Timeout -import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} import io.iohk.ethereum.network.EtcPeerManagerActor.{PeerInfo, PeerInfoResponse} import io.iohk.ethereum.network.PeerManagerActor.Peers import io.iohk.ethereum.network.{EtcPeerManagerActor, Peer, PeerActor, PeerId, PeerManagerActor} import monix.eval.Task +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future import scala.concurrent.duration._ object DebugService { @@ -19,26 +21,28 @@ object DebugService { class DebugService(peerManager: ActorRef, etcPeerManager: ActorRef) { def listPeersInfo(getPeersInfoRequest: ListPeersInfoRequest): ServiceResponse[ListPeersInfoResponse] = { - for { + val result = for { ids <- getPeerIds - peers <- Task.traverse(ids)(getPeerInfo) + peers <- Future.traverse(ids)(getPeerInfo) } yield Right(ListPeersInfoResponse(peers.flatten)) + + Task.fromFuture(result) } - private def getPeerIds: Task[List[PeerId]] = { + private def getPeerIds: Future[List[PeerId]] = { implicit val timeout: Timeout = Timeout(5.seconds) - peerManager - .askFor[Peers](PeerManagerActor.GetPeers) - .onErrorRecover { case _ => Peers(Map.empty[Peer, PeerActor.Status]) } + (peerManager ? PeerManagerActor.GetPeers) + .mapTo[Peers] + .recover { case _ => Peers(Map.empty[Peer, PeerActor.Status]) } .map(_.peers.keySet.map(_.id).toList) } - private def getPeerInfo(peer: PeerId): Task[Option[PeerInfo]] = { + private def getPeerInfo(peer: PeerId): Future[Option[PeerInfo]] = { implicit val timeout: Timeout = Timeout(5.seconds) - etcPeerManager - .askFor[PeerInfoResponse](EtcPeerManagerActor.PeerInfoRequest(peer)) - .map(resp => resp.peerInfo) + (etcPeerManager ? EtcPeerManagerActor.PeerInfoRequest(peer)) + .mapTo[PeerInfoResponse] + .collect { case PeerInfoResponse(info) => info } } } From 442d187aea597b945a060ea72498312140f8a09a Mon Sep 17 00:00:00 2001 From: lemastero Date: Mon, 26 Oct 2020 16:06:48 +0100 Subject: [PATCH 16/33] [ETCM-126] partial Future and Task implementation to keep original ex used, to keep tests pass 2 --- .../jsonrpc/CheckpointingService.scala | 27 ++--- .../ethereum/jsonrpc/PersonalService.scala | 111 +++++++++--------- .../io/iohk/ethereum/jsonrpc/QAService.scala | 10 +- 3 files changed, 77 insertions(+), 71 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala index 1c2af54ebe..73f3b3f92e 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala @@ -7,6 +7,9 @@ import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.domain.Blockchain import io.iohk.ethereum.utils.Logger import monix.eval.Task +import monix.execution.Scheduler.Implicits.global + +import scala.concurrent.Future class CheckpointingService( blockchain: Blockchain, @@ -19,30 +22,26 @@ class CheckpointingService( lazy val bestBlockNum = blockchain.getBestBlockNumber() lazy val blockToReturnNum = bestBlockNum - bestBlockNum % req.checkpointingInterval - Task { + Task.fromFuture(Future { blockchain.getBlockByNumber(blockToReturnNum) }.flatMap { case Some(b) => val resp = GetLatestBlockResponse(b.hash, b.number) - Task.now(Right(resp)) + Future.successful(Right(resp)) case None => - Task - .now( - log.error( - s"Failed to retrieve block for checkpointing: block at number $blockToReturnNum was unavailable " + - s"even though best block number was $bestBlockNum (re-org occurred?)" - ) - ) - .flatMap(_ => getLatestBlock(req) // this can fail only during a re-org, so we just try again - ) - } + log.error( + s"Failed to retrieve block for checkpointing: block at number $blockToReturnNum was unavailable " + + s"even though best block number was $bestBlockNum (re-org occurred?)" + ) + getLatestBlock(req).runToFuture // this can fail only during a re-org, so we just try again + }) } - def pushCheckpoint(req: PushCheckpointRequest): ServiceResponse[PushCheckpointResponse] = Task { + def pushCheckpoint(req: PushCheckpointRequest): ServiceResponse[PushCheckpointResponse] = Task.fromFuture(Future { syncController ! NewCheckpoint(req.hash, req.signatures) Right(PushCheckpointResponse()) - } + }) } object CheckpointingService { diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index 0e1831429c..86dfd39b22 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -3,6 +3,7 @@ package io.iohk.ethereum.jsonrpc import java.time.Duration import akka.actor.ActorRef +import akka.pattern.ask import akka.util.{ByteString, Timeout} import io.iohk.ethereum.crypto import io.iohk.ethereum.crypto.ECDSASignature @@ -18,8 +19,11 @@ import io.iohk.ethereum.utils.{BlockchainConfig, TxPoolConfig} import io.iohk.ethereum.rlp import io.iohk.ethereum.rlp.RLPImplicits._ import io.iohk.ethereum.rlp.RLPImplicitConversions._ +import monix.execution.Scheduler.Implicits.{global => mglobal} import monix.eval.Task +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future import scala.util.Try object PersonalService { @@ -75,30 +79,30 @@ class PersonalService( private val unlockedWallets: ExpiringMap[Address, Wallet] = ExpiringMap.empty(Duration.ofSeconds(defaultUnlockTime)) - def importRawKey(req: ImportRawKeyRequest): ServiceResponse[ImportRawKeyResponse] = Task { + def importRawKey(req: ImportRawKeyRequest): ServiceResponse[ImportRawKeyResponse] = Task.fromFuture(Future { for { prvKey <- Right(req.prvKey).filterOrElse(_.length == PrivateKeyLength, InvalidKey) addr <- keyStore.importPrivateKey(prvKey, req.passphrase).left.map(handleError) } yield ImportRawKeyResponse(addr) - } + }) - def newAccount(req: NewAccountRequest): ServiceResponse[NewAccountResponse] = Task { + def newAccount(req: NewAccountRequest): ServiceResponse[NewAccountResponse] = Task.fromFuture(Future { keyStore .newAccount(req.passphrase) .map(NewAccountResponse.apply) .left .map(handleError) - } + }) - def listAccounts(request: ListAccountsRequest): ServiceResponse[ListAccountsResponse] = Task { + def listAccounts(request: ListAccountsRequest): ServiceResponse[ListAccountsResponse] = Task.fromFuture(Future { keyStore .listAccounts() .map(ListAccountsResponse.apply) .left .map(handleError) - } + }) - def unlockAccount(request: UnlockAccountRequest): ServiceResponse[UnlockAccountResponse] = Task { + def unlockAccount(request: UnlockAccountRequest): ServiceResponse[UnlockAccountResponse] = Task.fromFuture(Future { keyStore .unlockAccount(request.address, request.passphrase) .left @@ -113,14 +117,14 @@ class PersonalService( UnlockAccountResponse(true) } - } + }) - def lockAccount(request: LockAccountRequest): ServiceResponse[LockAccountResponse] = Task.now { + def lockAccount(request: LockAccountRequest): ServiceResponse[LockAccountResponse] = Task.fromFuture(Future { unlockedWallets.remove(request.address) Right(LockAccountResponse(true)) - } + }) - def sign(request: SignRequest): ServiceResponse[SignResponse] = Task { + def sign(request: SignRequest): ServiceResponse[SignResponse] = Task.fromFuture(Future { import request._ val accountWallet = { @@ -132,9 +136,9 @@ class PersonalService( .map { wallet => SignResponse(ECDSASignature.sign(getMessageToSign(message), wallet.keyPair)) } - } + }) - def ecRecover(req: EcRecoverRequest): ServiceResponse[EcRecoverResponse] = Task { + def ecRecover(req: EcRecoverRequest): ServiceResponse[EcRecoverResponse] = Task.fromFuture(Future { import req._ signature .publicKey(getMessageToSign(message)) @@ -142,30 +146,32 @@ class PersonalService( Right(EcRecoverResponse(Address(crypto.kec256(publicKey)))) } .getOrElse(Left(InvalidParams("unable to recover address"))) - } + }) def sendTransaction( request: SendTransactionWithPassphraseRequest ): ServiceResponse[SendTransactionWithPassphraseResponse] = { - val maybeWalletUnlocked = Task { + val maybeWalletUnlocked = Future { keyStore.unlockAccount(request.tx.from, request.passphrase).left.map(handleError) } - maybeWalletUnlocked.flatMap { + Task.fromFuture(maybeWalletUnlocked.flatMap { case Right(wallet) => val futureTxHash = sendTransaction(request.tx, wallet) futureTxHash.map(txHash => Right(SendTransactionWithPassphraseResponse(txHash))) - case Left(err) => Task.now(Left(err)) - } + case Left(err) => Future.successful(Left(err)) + }) } def sendTransaction(request: SendTransactionRequest): ServiceResponse[SendTransactionResponse] = { - unlockedWallets.get(request.tx.from) match { - case Some(wallet) => - val futureTxHash = sendTransaction(request.tx, wallet) - futureTxHash.map(txHash => Right(SendTransactionResponse(txHash))) - - case None => - Task.now(Left(AccountLocked)) + Task.fromFuture { + unlockedWallets.get(request.tx.from) match { + case Some(wallet) => + val futureTxHash = sendTransaction(request.tx, wallet) + futureTxHash.map(txHash => Right(SendTransactionResponse(txHash))) + + case None => + Future.successful(Left(AccountLocked)) + } } } @@ -179,46 +185,45 @@ class PersonalService( case _ => Left(JsonRpcErrors.InvalidParams("Iele transaction should contain either functionName or contractCode")) } - dataEither match { - case Right(data) => - sendTransaction( - SendTransactionRequest( - TransactionRequest(tx.from, tx.to, tx.value, tx.gasLimit, tx.gasPrice, tx.nonce, Some(ByteString(data))) - ) - ) - case Left(error) => - Task.now(Left(error)) + Task.fromFuture { + dataEither match { + case Right(data) => + sendTransaction( + SendTransactionRequest( + TransactionRequest(tx.from, tx.to, tx.value, tx.gasLimit, tx.gasPrice, tx.nonce, Some(ByteString(data))) + ) + ).runToFuture + case Left(error) => + Future.successful(Left(error)) + } } } - private def sendTransaction(request: TransactionRequest, wallet: Wallet): Task[ByteString] = { + private def sendTransaction(request: TransactionRequest, wallet: Wallet): Future[ByteString] = { implicit val timeout = Timeout(txPoolConfig.pendingTxManagerQueryTimeout) - import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ val pendingTxsFuture = - txPool.askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) - val latestPendingTxNonceFuture: Task[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => + (txPool ? PendingTransactionsManager.GetPendingTransactions).mapTo[PendingTransactionsResponse] + val latestPendingTxNonceFuture: Future[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => val senderTxsNonces = pendingTxs.pendingTransactions .collect { case ptx if ptx.stx.senderAddress == wallet.address => ptx.stx.tx.tx.nonce } Try(senderTxsNonces.max).toOption } - latestPendingTxNonceFuture - .map { maybeLatestPendingTxNonce => - val maybeCurrentNonce = getCurrentAccount(request.from).map(_.nonce.toBigInt) - val maybeNextTxNonce = maybeLatestPendingTxNonce.map(_ + 1) orElse maybeCurrentNonce - val tx = request.toTransaction(maybeNextTxNonce.getOrElse(blockchainConfig.accountStartNonce)) - - val stx = if (blockchain.getBestBlockNumber() >= blockchainConfig.eip155BlockNumber) { - wallet.signTx(tx, Some(blockchainConfig.chainId)) - } else { - wallet.signTx(tx, None) - } + latestPendingTxNonceFuture.map { maybeLatestPendingTxNonce => + val maybeCurrentNonce = getCurrentAccount(request.from).map(_.nonce.toBigInt) + val maybeNextTxNonce = maybeLatestPendingTxNonce.map(_ + 1) orElse maybeCurrentNonce + val tx = request.toTransaction(maybeNextTxNonce.getOrElse(blockchainConfig.accountStartNonce)) + + val stx = if (blockchain.getBestBlockNumber() >= blockchainConfig.eip155BlockNumber) { + wallet.signTx(tx, Some(blockchainConfig.chainId)) + } else { + wallet.signTx(tx, None) + } - txPool ! AddOrOverrideTransaction(stx.tx) + txPool ! AddOrOverrideTransaction(stx.tx) - stx.tx.hash - } - .timeout(timeout.duration) + stx.tx.hash + } } private def getCurrentAccount(address: Address): Option[Account] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala index 5250394c88..e6c1a4c5a2 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala @@ -19,6 +19,8 @@ import monix.eval.Task import monix.execution.Scheduler.Implicits.global import mouse.all._ +import scala.concurrent.Future + class QAService( consensus: Consensus, blockchain: Blockchain, @@ -47,12 +49,12 @@ class QAService( def generateCheckpoint( req: GenerateCheckpointRequest ): ServiceResponse[GenerateCheckpointResponse] = { - Task { + Task.fromFuture(Future { val hash = req.blockHash.getOrElse(blockchain.getBestBlock().hash) val checkpoint = generateCheckpoint(hash, req.privateKeys) syncController ! NewCheckpoint(hash, checkpoint.signatures) Right(GenerateCheckpointResponse(checkpoint)) - } + }) } private def generateCheckpoint(blockHash: ByteString, privateKeys: Seq[ByteString]): Checkpoint = { @@ -66,9 +68,9 @@ class QAService( def getFederationMembersInfo( req: GetFederationMembersInfoRequest ): ServiceResponse[GetFederationMembersInfoResponse] = { - Task.now { + Task.fromFuture(Future { Right(GetFederationMembersInfoResponse(blockchainConfig.checkpointPubKeys.toList)) - } + }) } } From 37aa0108a589d305948b9f403e7e6be7cd0366e4 Mon Sep 17 00:00:00 2001 From: lemastero Date: Mon, 26 Oct 2020 17:12:14 +0100 Subject: [PATCH 17/33] [ETCM-269] drop unused imports --- .../scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala | 4 ---- .../io/iohk/ethereum/network/PeerActorHandshakingSpec.scala | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala index fc1a8264cc..76cf7a1356 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala @@ -23,7 +23,6 @@ import org.scalamock.scalatest.MockFactory import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers -import org.scalatest.time.{Millis, Seconds, Span} import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import scala.concurrent.duration.FiniteDuration @@ -369,9 +368,6 @@ class PersonalServiceSpec it should "unlock an account given a correct passphrase for specified duration" in new TestSetup { (keyStore.unlockAccount _).expects(address, passphrase).returning(Right(wallet)) - implicit val patienceConfig = // TODO identical timeout is defined in NormalPatience - PatienceConfig(timeout = scaled(Span(3, Seconds)), interval = scaled(Span(100, Millis))) - val message = ByteString(Hex.decode("deadbeaf")) val r = ByteString(Hex.decode("d237344891a90a389b7747df6fbd0091da20d1c61adb961b4491a4c82f58dcd2")) diff --git a/src/test/scala/io/iohk/ethereum/network/PeerActorHandshakingSpec.scala b/src/test/scala/io/iohk/ethereum/network/PeerActorHandshakingSpec.scala index e41ea21ba1..0567897755 100644 --- a/src/test/scala/io/iohk/ethereum/network/PeerActorHandshakingSpec.scala +++ b/src/test/scala/io/iohk/ethereum/network/PeerActorHandshakingSpec.scala @@ -139,7 +139,7 @@ class PeerActorHandshakingSpec extends AnyFlatSpec with Matchers { } trait TestSetup extends EphemBlockchainTestSetup { - override implicit lazy val system = ActorSystem("PeerActorSpec_System") // TODO this is never closed + override implicit lazy val system = ActorSystem("PeerActorSpec_System") val time = new VirtualTime From 4b1aa9c3ad9b7026d97ebe628b0ec92aa0020833 Mon Sep 17 00:00:00 2001 From: lemastero Date: Mon, 26 Oct 2020 17:14:46 +0100 Subject: [PATCH 18/33] [ETCM-269] revert rename --- src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala | 2 +- src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala b/src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala index 5ce9ebe020..3937a59aed 100644 --- a/src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala +++ b/src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala @@ -15,7 +15,7 @@ import org.scalatest.matchers.should.Matchers import scala.concurrent.duration._ class FastSyncItSpec extends FlatSpecBase with Matchers with BeforeAndAfterAll { - implicit val testScheduler = Scheduler.fixedPool("Scheduler_FastSyncItSpec", 16) + implicit val testScheduler = Scheduler.fixedPool("test", 16) override def afterAll(): Unit = { testScheduler.shutdown() diff --git a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala index 368df5ab8a..ad1986504f 100644 --- a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala +++ b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala @@ -10,7 +10,7 @@ import org.scalatest.matchers.should.Matchers import scala.concurrent.duration._ class RegularSyncItSpec extends FlatSpecBase with Matchers with BeforeAndAfterAll { - implicit val testScheduler = Scheduler.fixedPool("Scheduler_RegularSyncItSpec", 16) + implicit val testScheduler = Scheduler.fixedPool("test", 16) override def afterAll(): Unit = { testScheduler.shutdown() From 789186cb382dbd7d84c34a1e37d336641de8d66e Mon Sep 17 00:00:00 2001 From: lemastero Date: Tue, 27 Oct 2020 13:37:40 +0100 Subject: [PATCH 19/33] [ETCM-269] replace Task.fromFuture + Future to just Task in getFederationMembersInfo --- src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala index e6c1a4c5a2..3313632d99 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala @@ -68,9 +68,9 @@ class QAService( def getFederationMembersInfo( req: GetFederationMembersInfoRequest ): ServiceResponse[GetFederationMembersInfoResponse] = { - Task.fromFuture(Future { + Task { Right(GetFederationMembersInfoResponse(blockchainConfig.checkpointPubKeys.toList)) - }) + } } } From a8051fd79f092dc23744cb6f7df72294fd58e5d3 Mon Sep 17 00:00:00 2001 From: lemastero Date: Tue, 27 Oct 2020 14:09:33 +0100 Subject: [PATCH 20/33] [ETCM-269] replace Task.fromFuture + Future with Task in QaService --- .../io/iohk/ethereum/jsonrpc/QAService.scala | 6 ++---- .../iohk/ethereum/jsonrpc/QAServiceSpec.scala | 17 +++++++++-------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala index 3313632d99..4daff19a51 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala @@ -19,8 +19,6 @@ import monix.eval.Task import monix.execution.Scheduler.Implicits.global import mouse.all._ -import scala.concurrent.Future - class QAService( consensus: Consensus, blockchain: Blockchain, @@ -49,12 +47,12 @@ class QAService( def generateCheckpoint( req: GenerateCheckpointRequest ): ServiceResponse[GenerateCheckpointResponse] = { - Task.fromFuture(Future { + Task { val hash = req.blockHash.getOrElse(blockchain.getBestBlock().hash) val checkpoint = generateCheckpoint(hash, req.privateKeys) syncController ! NewCheckpoint(hash, checkpoint.signatures) Right(GenerateCheckpointResponse(checkpoint)) - }) + } } private def generateCheckpoint(blockHash: ByteString, privateKeys: Seq[ByteString]): Checkpoint = { diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala index 17023f55bd..dfd32b3a30 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala @@ -49,12 +49,12 @@ class QAServiceSpec ) { fixture => import fixture._ - val result: ServiceResponse[GenerateCheckpointResponse] = - qaService.generateCheckpoint(req) - - syncController.expectMsg(NewCheckpoint(block.hash, signatures)) + val result = qaService.generateCheckpoint(req) - result.map(_ shouldBe Right(GenerateCheckpointResponse(checkpoint))) + result.map { r => + syncController.expectMsg(NewCheckpoint(block.hash, signatures)) + r shouldBe Right(GenerateCheckpointResponse(checkpoint)) + } } it should "generate checkpoint for best block when no block hash given and send it to sync" in customTestCaseM( @@ -70,9 +70,10 @@ class QAServiceSpec val result: ServiceResponse[GenerateCheckpointResponse] = qaService.generateCheckpoint(reqWithoutBlockHash) - syncController.expectMsg(NewCheckpoint(block.hash, signatures)) - - result.map(_ shouldBe Right(GenerateCheckpointResponse(checkpoint))) + result.map { r => + syncController.expectMsg(NewCheckpoint(block.hash, signatures)) + r shouldBe Right(GenerateCheckpointResponse(checkpoint)) + } } it should "return federation public keys when requesting federation members info" in testCaseM { fixture => From e074b155501c51ebdf629111cc5b1a9d80d362f8 Mon Sep 17 00:00:00 2001 From: lemastero Date: Tue, 27 Oct 2020 16:02:49 +0100 Subject: [PATCH 21/33] [ETCM-269] replace Future + Task with Task in DebugService --- .../iohk/ethereum/jsonrpc/DebugService.scala | 26 ++++++++----------- .../ethereum/jsonrpc/DebugServiceSpec.scala | 17 +++++------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala index 1422de558a..171545fd7a 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/DebugService.scala @@ -1,16 +1,14 @@ package io.iohk.ethereum.jsonrpc import akka.actor.ActorRef -import akka.pattern._ import akka.util.Timeout +import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ import io.iohk.ethereum.jsonrpc.DebugService.{ListPeersInfoRequest, ListPeersInfoResponse} import io.iohk.ethereum.network.EtcPeerManagerActor.{PeerInfo, PeerInfoResponse} import io.iohk.ethereum.network.PeerManagerActor.Peers import io.iohk.ethereum.network.{EtcPeerManagerActor, Peer, PeerActor, PeerId, PeerManagerActor} import monix.eval.Task -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future import scala.concurrent.duration._ object DebugService { @@ -21,28 +19,26 @@ object DebugService { class DebugService(peerManager: ActorRef, etcPeerManager: ActorRef) { def listPeersInfo(getPeersInfoRequest: ListPeersInfoRequest): ServiceResponse[ListPeersInfoResponse] = { - val result = for { + for { ids <- getPeerIds - peers <- Future.traverse(ids)(getPeerInfo) + peers <- Task.traverse(ids)(getPeerInfo) } yield Right(ListPeersInfoResponse(peers.flatten)) - - Task.fromFuture(result) } - private def getPeerIds: Future[List[PeerId]] = { + private def getPeerIds: Task[List[PeerId]] = { implicit val timeout: Timeout = Timeout(5.seconds) - (peerManager ? PeerManagerActor.GetPeers) - .mapTo[Peers] - .recover { case _ => Peers(Map.empty[Peer, PeerActor.Status]) } + peerManager + .askFor[Peers](PeerManagerActor.GetPeers) + .onErrorRecover { case _ => Peers(Map.empty[Peer, PeerActor.Status]) } .map(_.peers.keySet.map(_.id).toList) } - private def getPeerInfo(peer: PeerId): Future[Option[PeerInfo]] = { + private def getPeerInfo(peer: PeerId): Task[Option[PeerInfo]] = { implicit val timeout: Timeout = Timeout(5.seconds) - (etcPeerManager ? EtcPeerManagerActor.PeerInfoRequest(peer)) - .mapTo[PeerInfoResponse] - .collect { case PeerInfoResponse(info) => info } + etcPeerManager + .askFor[PeerInfoResponse](EtcPeerManagerActor.PeerInfoRequest(peer)) + .map(resp => resp.peerInfo) } } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala index 5cb6bd745a..95e0cd7524 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/DebugServiceSpec.scala @@ -26,8 +26,8 @@ class DebugServiceSpec with ScalaFutures { "DebugService" should "return list of peers info" in new TestSetup { - val result: ServiceResponse[ListPeersInfoResponse] = - debugService.listPeersInfo(ListPeersInfoRequest()) + val result = + debugService.listPeersInfo(ListPeersInfoRequest()).runToFuture peerManager.expectMsg(PeerManagerActor.GetPeers) peerManager.reply(Peers(Map(peer1 -> PeerActor.Status.Connecting))) @@ -35,23 +35,20 @@ class DebugServiceSpec etcPeerManager.expectMsg(EtcPeerManagerActor.PeerInfoRequest(peer1.id)) etcPeerManager.reply(EtcPeerManagerActor.PeerInfoResponse(Some(peer1Info))) - result.runSyncUnsafe() shouldBe Right(ListPeersInfoResponse(List(peer1Info))) - + result.futureValue shouldBe Right(ListPeersInfoResponse(List(peer1Info))) } it should "return empty list if there are no peers available" in new TestSetup { - val result: ServiceResponse[ListPeersInfoResponse] = - debugService.listPeersInfo(ListPeersInfoRequest()) + val result = debugService.listPeersInfo(ListPeersInfoRequest()).runToFuture peerManager.expectMsg(PeerManagerActor.GetPeers) peerManager.reply(Peers(Map.empty)) - result.runSyncUnsafe() shouldBe Right(ListPeersInfoResponse(List.empty)) + result.futureValue shouldBe Right(ListPeersInfoResponse(List.empty)) } it should "return empty list if there is no peer info" in new TestSetup { - val result: ServiceResponse[ListPeersInfoResponse] = - debugService.listPeersInfo(ListPeersInfoRequest()) + val result = debugService.listPeersInfo(ListPeersInfoRequest()).runToFuture peerManager.expectMsg(PeerManagerActor.GetPeers) peerManager.reply(Peers(Map(peer1 -> PeerActor.Status.Connecting))) @@ -59,7 +56,7 @@ class DebugServiceSpec etcPeerManager.expectMsg(EtcPeerManagerActor.PeerInfoRequest(peer1.id)) etcPeerManager.reply(EtcPeerManagerActor.PeerInfoResponse(None)) - result.runSyncUnsafe() shouldBe Right(ListPeersInfoResponse(List.empty)) + result.futureValue shouldBe Right(ListPeersInfoResponse(List.empty)) } class TestSetup(implicit system: ActorSystem) { From 4500bce5f0b3cf15a069c94a767b775ffaaa20d2 Mon Sep 17 00:00:00 2001 From: lemastero Date: Tue, 27 Oct 2020 16:08:12 +0100 Subject: [PATCH 22/33] [ETCM-269] replace Future + Task with Task in Checkpointing --- .../ethereum/jsonrpc/CheckpointingService.scala | 15 ++++++--------- .../iohk/ethereum/jsonrpc/PersonalService.scala | 1 - .../jsonrpc/CheckpointingServiceSpec.scala | 7 +++---- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala index 73f3b3f92e..c66b197811 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala @@ -7,9 +7,6 @@ import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.domain.Blockchain import io.iohk.ethereum.utils.Logger import monix.eval.Task -import monix.execution.Scheduler.Implicits.global - -import scala.concurrent.Future class CheckpointingService( blockchain: Blockchain, @@ -22,26 +19,26 @@ class CheckpointingService( lazy val bestBlockNum = blockchain.getBestBlockNumber() lazy val blockToReturnNum = bestBlockNum - bestBlockNum % req.checkpointingInterval - Task.fromFuture(Future { + Task { blockchain.getBlockByNumber(blockToReturnNum) }.flatMap { case Some(b) => val resp = GetLatestBlockResponse(b.hash, b.number) - Future.successful(Right(resp)) + Task.now(Right(resp)) case None => log.error( s"Failed to retrieve block for checkpointing: block at number $blockToReturnNum was unavailable " + s"even though best block number was $bestBlockNum (re-org occurred?)" ) - getLatestBlock(req).runToFuture // this can fail only during a re-org, so we just try again - }) + getLatestBlock(req) // this can fail only during a re-org, so we just try again + } } - def pushCheckpoint(req: PushCheckpointRequest): ServiceResponse[PushCheckpointResponse] = Task.fromFuture(Future { + def pushCheckpoint(req: PushCheckpointRequest): ServiceResponse[PushCheckpointResponse] = Task { syncController ! NewCheckpoint(req.hash, req.signatures) Right(PushCheckpointResponse()) - }) + } } object CheckpointingService { diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index 86dfd39b22..d70b7c5dac 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -22,7 +22,6 @@ import io.iohk.ethereum.rlp.RLPImplicitConversions._ import monix.execution.Scheduler.Implicits.{global => mglobal} import monix.eval.Task -import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future import scala.util.Try diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala index 690ada8cb2..76777c4d47 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala @@ -51,14 +51,13 @@ class CheckpointingServiceSpec it should "send new checkpoint to Sync" in new TestSetup { val hash = Fixtures.Blocks.ValidBlock.block.hash val signatures = Nil - val request = PushCheckpointRequest(hash, signatures) val expectedResponse = PushCheckpointResponse() - val result = service.pushCheckpoint(request) - syncController.expectMsg(NewCheckpoint(hash, signatures)) + val result = service.pushCheckpoint(request).runSyncUnsafe() - result.runSyncUnsafe() shouldEqual Right(expectedResponse) + syncController.expectMsg(NewCheckpoint(hash, signatures)) + result shouldEqual Right(expectedResponse) } it should "get latest block in case of blockchain re-org" in new TestSetup { From e6d923ff778e2fb17975874b6f3ae65552e9c729 Mon Sep 17 00:00:00 2001 From: lemastero Date: Tue, 27 Oct 2020 16:22:55 +0100 Subject: [PATCH 23/33] [ETCM-269] replace Future + Task with Task in PersonalService --- .../ethereum/jsonrpc/PersonalService.scala | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index d70b7c5dac..8cceae37d3 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -78,30 +78,30 @@ class PersonalService( private val unlockedWallets: ExpiringMap[Address, Wallet] = ExpiringMap.empty(Duration.ofSeconds(defaultUnlockTime)) - def importRawKey(req: ImportRawKeyRequest): ServiceResponse[ImportRawKeyResponse] = Task.fromFuture(Future { + def importRawKey(req: ImportRawKeyRequest): ServiceResponse[ImportRawKeyResponse] = Task { for { prvKey <- Right(req.prvKey).filterOrElse(_.length == PrivateKeyLength, InvalidKey) addr <- keyStore.importPrivateKey(prvKey, req.passphrase).left.map(handleError) } yield ImportRawKeyResponse(addr) - }) + } - def newAccount(req: NewAccountRequest): ServiceResponse[NewAccountResponse] = Task.fromFuture(Future { + def newAccount(req: NewAccountRequest): ServiceResponse[NewAccountResponse] = Task { keyStore .newAccount(req.passphrase) .map(NewAccountResponse.apply) .left .map(handleError) - }) + } - def listAccounts(request: ListAccountsRequest): ServiceResponse[ListAccountsResponse] = Task.fromFuture(Future { + def listAccounts(request: ListAccountsRequest): ServiceResponse[ListAccountsResponse] = Task { keyStore .listAccounts() .map(ListAccountsResponse.apply) .left .map(handleError) - }) + } - def unlockAccount(request: UnlockAccountRequest): ServiceResponse[UnlockAccountResponse] = Task.fromFuture(Future { + def unlockAccount(request: UnlockAccountRequest): ServiceResponse[UnlockAccountResponse] = Task { keyStore .unlockAccount(request.address, request.passphrase) .left @@ -116,14 +116,14 @@ class PersonalService( UnlockAccountResponse(true) } - }) + } - def lockAccount(request: LockAccountRequest): ServiceResponse[LockAccountResponse] = Task.fromFuture(Future { + def lockAccount(request: LockAccountRequest): ServiceResponse[LockAccountResponse] = Task { unlockedWallets.remove(request.address) Right(LockAccountResponse(true)) - }) + } - def sign(request: SignRequest): ServiceResponse[SignResponse] = Task.fromFuture(Future { + def sign(request: SignRequest): ServiceResponse[SignResponse] = Task { import request._ val accountWallet = { @@ -135,9 +135,9 @@ class PersonalService( .map { wallet => SignResponse(ECDSASignature.sign(getMessageToSign(message), wallet.keyPair)) } - }) + } - def ecRecover(req: EcRecoverRequest): ServiceResponse[EcRecoverResponse] = Task.fromFuture(Future { + def ecRecover(req: EcRecoverRequest): ServiceResponse[EcRecoverResponse] = Task { import req._ signature .publicKey(getMessageToSign(message)) @@ -145,7 +145,7 @@ class PersonalService( Right(EcRecoverResponse(Address(crypto.kec256(publicKey)))) } .getOrElse(Left(InvalidParams("unable to recover address"))) - }) + } def sendTransaction( request: SendTransactionWithPassphraseRequest From a20cc7b8dfaa537b92874caebae8198df80f183c Mon Sep 17 00:00:00 2001 From: lemastero Date: Wed, 28 Oct 2020 13:08:59 +0100 Subject: [PATCH 24/33] [ETCM-269] review remove format on compile --- build.sbt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index 5745adedd7..27284b8587 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)): _*) @@ -102,8 +106,6 @@ scalacOptions in (Compile, console) ~= (_.filterNot( ) )) -scalafmtOnCompile := true - scalacOptions ~= (options => if (mantisDev) options.filterNot(_ == "-Xfatal-warnings") else options) Test / parallelExecution := true From f4ae08275a4d3a60053726ad38b849285595b7ba Mon Sep 17 00:00:00 2001 From: lemastero Date: Thu, 29 Oct 2020 11:06:07 +0100 Subject: [PATCH 25/33] [ETCM-269] replace () => Task in Healthcheck --- .../ethereum/healthcheck/Healthcheck.scala | 20 ++++++++----------- .../ethereum/jsonrpc/JsonRpcHealthcheck.scala | 2 +- .../jsonrpc/NodeJsonRpcHealthChecker.scala | 12 +++++------ 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/healthcheck/Healthcheck.scala b/src/main/scala/io/iohk/ethereum/healthcheck/Healthcheck.scala index dfe85e4574..a57cf556d4 100644 --- a/src/main/scala/io/iohk/ethereum/healthcheck/Healthcheck.scala +++ b/src/main/scala/io/iohk/ethereum/healthcheck/Healthcheck.scala @@ -2,8 +2,6 @@ package io.iohk.ethereum.healthcheck import monix.eval.Task -import scala.concurrent.ExecutionContext - /** * Represents a health check, runs it and interprets the outcome. * The outcome can be either a normal result, an application error, or @@ -19,20 +17,18 @@ import scala.concurrent.ExecutionContext */ case class Healthcheck[Error, Result]( description: String, - f: () => Task[Either[Error, Result]], + f: Task[Either[Error, Result]], mapResultToError: Result => Option[String] = (_: Result) => None, mapErrorToError: Error => Option[String] = (error: Error) => Some(String.valueOf(error)), mapExceptionToError: Throwable => Option[String] = (t: Throwable) => Some(String.valueOf(t)) ) { - def apply()(implicit ec: ExecutionContext): Task[HealthcheckResult] = { - f() - .map { - case Left(error) => - HealthcheckResult(description, mapErrorToError(error)) - case Right(result) => - HealthcheckResult(description, mapResultToError(result)) - } - .onErrorHandle(t => HealthcheckResult(description, mapExceptionToError(t))) + def apply(): Task[HealthcheckResult] = { + f.map { + case Left(error) => + HealthcheckResult(description, mapErrorToError(error)) + case Right(result) => + HealthcheckResult(description, mapResultToError(result)) + }.onErrorHandle(t => HealthcheckResult(description, mapExceptionToError(t))) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcHealthcheck.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcHealthcheck.scala index c486cab870..e428389902 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcHealthcheck.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcHealthcheck.scala @@ -5,5 +5,5 @@ import io.iohk.ethereum.healthcheck.Healthcheck object JsonRpcHealthcheck { type T[R] = Healthcheck[JsonRpcError, R] - def apply[R](description: String, f: () => ServiceResponse[R]): T[R] = Healthcheck(description, f) + def apply[R](description: String, f: ServiceResponse[R]): T[R] = Healthcheck(description, f) } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/NodeJsonRpcHealthChecker.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/NodeJsonRpcHealthChecker.scala index d04c87ac50..c56d052687 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/NodeJsonRpcHealthChecker.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/NodeJsonRpcHealthChecker.scala @@ -5,8 +5,6 @@ import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.NetService._ import monix.eval.Task -import scala.concurrent.ExecutionContext.Implicits.global - class NodeJsonRpcHealthChecker( netService: NetService, ethService: EthService @@ -14,19 +12,19 @@ class NodeJsonRpcHealthChecker( protected def mainService: String = "node health" - final val listeningHC = JsonRpcHealthcheck("listening", () => netService.listening(NetService.ListeningRequest())) - final val peerCountHC = JsonRpcHealthcheck("peerCount", () => netService.peerCount(PeerCountRequest())) + final val listeningHC = JsonRpcHealthcheck("listening", netService.listening(NetService.ListeningRequest())) + final val peerCountHC = JsonRpcHealthcheck("peerCount", netService.peerCount(PeerCountRequest())) final val earliestBlockHC = JsonRpcHealthcheck( "earliestBlock", - () => ethService.getBlockByNumber(BlockByNumberRequest(BlockParam.Earliest, true)) + ethService.getBlockByNumber(BlockByNumberRequest(BlockParam.Earliest, true)) ) final val latestBlockHC = JsonRpcHealthcheck( "latestBlock", - () => ethService.getBlockByNumber(BlockByNumberRequest(BlockParam.Latest, true)) + ethService.getBlockByNumber(BlockByNumberRequest(BlockParam.Latest, true)) ) final val pendingBlockHC = JsonRpcHealthcheck( "pendingBlock", - () => ethService.getBlockByNumber(BlockByNumberRequest(BlockParam.Pending, true)) + ethService.getBlockByNumber(BlockByNumberRequest(BlockParam.Pending, true)) ) override def healthCheck(): Task[HealthcheckResponse] = { From 18adc3548160229b86e343951f6144bb8a86532a Mon Sep 17 00:00:00 2001 From: lemastero Date: Thu, 29 Oct 2020 12:27:15 +0100 Subject: [PATCH 26/33] [ETCM-269] review remove () => Task in TestService --- src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala index cfc1f324f8..e6903d8290 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala @@ -2,6 +2,7 @@ package io.iohk.ethereum.jsonrpc import akka.actor.ActorRef import akka.util.{ByteString, Timeout} +import cats.syntax.functor._ import io.iohk.ethereum.blockchain.data.{AllocAccount, GenesisData, GenesisDataLoader} import io.iohk.ethereum.consensus.ConsensusConfig import io.iohk.ethereum.consensus.blocks._ @@ -118,12 +119,12 @@ class TestService( } } - def doNTimesF(n: Int)(fn: () => Task[Unit]): Task[Unit] = fn().flatMap { res => + def doNTimesF(n: Int)(fn: Task[Unit]): Task[Unit] = fn.flatMap { res => if (n <= 1) Task.now(res) else doNTimesF(n - 1)(fn) } - doNTimesF(request.num)(mineBlock _).map(_ => Right(MineBlocksResponse())) + doNTimesF(request.num)(mineBlock()).as(Right(MineBlocksResponse())) } def modifyTimestamp(request: ModifyTimestampRequest): ServiceResponse[ModifyTimestampResponse] = { From 8388abde36f3bc2b490d4a687352a93067cb0a02 Mon Sep 17 00:00:00 2001 From: lemastero Date: Thu, 29 Oct 2020 12:33:19 +0100 Subject: [PATCH 27/33] [ETCM-269] review remove self type in AkkaTaskOps and changed to value class --- src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala index 42217814ac..995316d294 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala @@ -1,14 +1,14 @@ package io.iohk.ethereum.jsonrpc import akka.actor.{Actor, ActorRef} +import akka.pattern.ask import akka.util.Timeout import monix.eval.Task import scala.reflect.ClassTag -object AkkaTaskOps { self: ActorRef => - implicit class TaskActorOps(to: ActorRef) { - import akka.pattern.ask +object AkkaTaskOps { + implicit class TaskActorOps(val to: ActorRef) extends AnyVal { def askFor[A]( message: Any From 36c381fcb6cb6614cd4436784d1b1507274bfc07 Mon Sep 17 00:00:00 2001 From: lemastero Date: Thu, 29 Oct 2020 14:48:34 +0100 Subject: [PATCH 28/33] [ETCM-269] resolve issues after merge --- .../io/iohk/ethereum/jsonrpc/EthService.scala | 10 +++++----- .../ethereum/jsonrpc/JsonRpcController.scala | 11 ----------- .../io/iohk/ethereum/jsonrpc/QAService.scala | 16 +++++++++------- .../server/http/JsonRpcHttpServer.scala | 6 ------ .../iohk/ethereum/jsonrpc/EthServiceSpec.scala | 10 +++++----- .../jsonrpc/JsonRpcControllerEthSpec.scala | 4 ++-- .../ethereum/network/p2p/PeerActorSpec.scala | 18 ++++++++---------- 7 files changed, 29 insertions(+), 46 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala index db4e91805c..7eaf53ec0f 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala @@ -6,7 +6,7 @@ import java.util.concurrent.atomic.AtomicReference import akka.actor.ActorRef import akka.util.{ByteString, Timeout} -import cats.implicits.catsSyntaxEitherId +import cats.syntax.either._ import io.iohk.ethereum.blockchain.sync.SyncProtocol import io.iohk.ethereum.blockchain.sync.SyncProtocol.Status import io.iohk.ethereum.blockchain.sync.SyncProtocol.Status.Progress @@ -35,6 +35,7 @@ import org.bouncycastle.util.encoders.Hex import scala.concurrent.duration.FiniteDuration import scala.language.existentials +import scala.reflect.ClassTag import scala.util.{Failure, Success, Try} // scalastyle:off number.of.methods number.of.types file.size.limit @@ -621,8 +622,7 @@ class EthService( */ def syncing(req: SyncingRequest): ServiceResponse[SyncingResponse] = syncingController - .ask(SyncProtocol.GetStatus)(askTimeout) - .mapTo[SyncProtocol.Status] + .askFor(SyncProtocol.GetStatus)(timeout = askTimeout, implicitly[ClassTag[SyncProtocol.Status]]) .map { case Status.Syncing(startingBlockNumber, blocksProgress, maybeStateNodesProgress) => val stateNodesProgress = maybeStateNodesProgress.getOrElse(Progress.empty) @@ -875,7 +875,7 @@ class EthService( } private def withAccount[T](address: Address, blockParam: BlockParam)(makeResponse: Account => T): ServiceResponse[T] = - Future { // TODO PP rm Future + Task { resolveBlock(blockParam) .map { case ResolvedBlock(block, _) => blockchain @@ -883,7 +883,7 @@ class EthService( .getOrElse(Account.empty(blockchainConfig.accountStartNonce)) } .map(makeResponse) - }.recover { case _: MissingNodeException => + }.onErrorRecover { case _: MissingNodeException => Left(JsonRpcError.NodeNotFound) } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala index 1c1f320037..6a7c79b457 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala @@ -6,11 +6,8 @@ import cats.syntax.all._ 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.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.JsonRpcErrors.InvalidParams import io.iohk.ethereum.jsonrpc.NetService._ import io.iohk.ethereum.jsonrpc.PersonalService._ import io.iohk.ethereum.jsonrpc.QAService.{ @@ -21,19 +18,13 @@ import io.iohk.ethereum.jsonrpc.QAService.{ } import io.iohk.ethereum.jsonrpc.TestService._ import io.iohk.ethereum.jsonrpc.Web3Service._ -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 io.iohk.ethereum.utils.Logger import monix.eval.Task -import org.json4s.JsonAST.{JArray, JValue} -import org.json4s.JsonDSL._ -import io.iohk.ethereum.utils.Logger import org.json4s.JsonDSL._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration object JsonRpcController { @@ -104,8 +95,6 @@ class JsonRpcController( import IeleJsonMethodsImplicits._ import JsonMethodsImplicits._ import JsonRpcController._ - import JsonRpcErrors._ - import JsonRpcController._ import JsonRpcError._ import QAJsonMethodsImplicits._ import TestJsonMethodsImplicits._ diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala index 646fc7406b..35bdab55e7 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala @@ -33,13 +33,15 @@ class QAService( * @return nothing */ def mineBlocks(req: MineBlocksRequest): ServiceResponse[MineBlocksResponse] = { - consensus - .sendMiner(MineBlocks(req.numBlocks, req.withTransactions, req.parentBlock)) - .map(_ |> (MineBlocksResponse(_)) |> (_.asRight)) - .recover { case t: Throwable => - log.info("Unable to mine requested blocks", t) - Left(JsonRpcError.InternalError) - } + Task.fromFuture( + consensus + .sendMiner(MineBlocks(req.numBlocks, req.withTransactions, req.parentBlock)) + .map(_ |> (MineBlocksResponse(_)) |> (_.asRight)) + .recover { case t: Throwable => + log.info("Unable to mine requested blocks", t) + Left(JsonRpcError.InternalError) + } + ) } def generateCheckpoint( 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 ff2bc6dc8b..edd218bf1b 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 @@ -14,16 +14,10 @@ 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 monix.eval.Task import monix.execution.Scheduler.Implicits.{global => MonixGlobal} -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 trait JsonRpcHttpServer extends Json4sSupport { diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index e7c155b56e..012c82ad38 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -516,9 +516,9 @@ class EthServiceSpec SyncProtocol.Status.NotSyncing }) - val response = ethService.syncing(SyncingRequest()).futureValue.right.get + val response = ethService.syncing(SyncingRequest()).runSyncUnsafe() - response shouldEqual SyncingResponse(None) + response shouldEqual Right(SyncingResponse(None)) } it should "return no syncing info if sync is done" in new TestSetup { @@ -526,9 +526,9 @@ class EthServiceSpec SyncProtocol.Status.SyncDone }) - val response = ethService.syncing(SyncingRequest()).futureValue.right.get + val response = ethService.syncing(SyncingRequest()).runSyncUnsafe() - response shouldEqual SyncingResponse(None) + response shouldEqual Right(SyncingResponse(None)) } it should "return requested work" in new TestSetup { @@ -911,7 +911,7 @@ class EthServiceSpec val response = ethService.getBalance(GetBalanceRequest(address, BlockParam.Latest)) - response.futureValue shouldEqual Left(JsonRpcError.NodeNotFound) + response.runSyncUnsafe() shouldEqual Left(JsonRpcError.NodeNotFound) } it should "handle getStorageAt request" in new TestSetup { diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index 9868f6aaec..a04a5507e2 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -496,7 +496,7 @@ class JsonRpcControllerEthSpec (mockEthService.getBalance _) .expects(*) - .returning(Future.successful(Left(JsonRpcError.NodeNotFound))) + .returning(Task.now(Left(JsonRpcError.NodeNotFound))) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getBalance", @@ -506,7 +506,7 @@ class JsonRpcControllerEthSpec ) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() response should haveError(JsonRpcError.NodeNotFound) } diff --git a/src/test/scala/io/iohk/ethereum/network/p2p/PeerActorSpec.scala b/src/test/scala/io/iohk/ethereum/network/p2p/PeerActorSpec.scala index 0e6e3d8757..f2c4dc96aa 100644 --- a/src/test/scala/io/iohk/ethereum/network/p2p/PeerActorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/network/p2p/PeerActorSpec.scala @@ -29,14 +29,11 @@ import io.iohk.ethereum.network.rlpx.RLPxConnectionHandler import io.iohk.ethereum.network.rlpx.RLPxConnectionHandler.RLPxConfiguration import io.iohk.ethereum.network.{ForkResolver, PeerActor, PeerEventBusActor, _} import io.iohk.ethereum.nodebuilder.SecureRandomBuilder -import io.iohk.ethereum.utils.{Config, NodeStatus, ServerStatus} -import io.iohk.ethereum.{Fixtures, Mocks, Timeouts, WithActorSystemShutDown, crypto} import io.iohk.ethereum.utils.{BlockchainConfig, Config, NodeStatus, ServerStatus} -import io.iohk.ethereum.{Fixtures, Mocks, Timeouts, crypto} +import io.iohk.ethereum.{Fixtures, Mocks, Timeouts, WithActorSystemShutDown, crypto} import org.bouncycastle.crypto.AsymmetricCipherKeyPair import org.bouncycastle.crypto.params.ECPublicKeyParameters import org.bouncycastle.util.encoders.Hex - import org.scalatest.flatspec.AnyFlatSpecLike import org.scalatest.matchers.should.Matchers @@ -477,15 +474,16 @@ class PeerActorSpec } - trait HandshakerSetup extends NodeStatusSetup { + trait HandshakerSetup extends NodeStatusSetup { self => val handshakerConfiguration = new EtcHandshakerConfiguration { override val forkResolverOpt: Option[ForkResolver] = Some( - new ForkResolver.EtcForkResolver(HandshakerSetup.this.blockchainConfig.daoForkConfig.get) + new ForkResolver.EtcForkResolver(self.blockchainConfig.daoForkConfig.get) ) - override val nodeStatusHolder: AtomicReference[NodeStatus] = HandshakerSetup.this.nodeStatusHolder - override val peerConfiguration: PeerConfiguration = HandshakerSetup.this.peerConf - override val blockchain: Blockchain = HandshakerSetup.this.blockchain - override val appStateStorage: AppStateStorage = HandshakerSetup.this.storagesInstance.storages.appStateStorage + override val nodeStatusHolder: AtomicReference[NodeStatus] = self.nodeStatusHolder + override val peerConfiguration: PeerConfiguration = self.peerConf + override val blockchain: Blockchain = self.blockchain + override val blockchainConfig: BlockchainConfig = self.blockchainConfig + override val appStateStorage: AppStateStorage = self.storagesInstance.storages.appStateStorage } val handshaker = EtcHandshaker(handshakerConfiguration) From 2ccb7f930ad16290cc75817a6f15b72c65d8e174 Mon Sep 17 00:00:00 2001 From: lemastero Date: Thu, 29 Oct 2020 16:03:06 +0100 Subject: [PATCH 29/33] [ETCM-269] WIP change PersonalService --- .../ethereum/jsonrpc/PersonalService.scala | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala index c84e5ff627..07ed3fd5ba 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/PersonalService.scala @@ -3,15 +3,15 @@ package io.iohk.ethereum.jsonrpc import java.time.Duration import akka.actor.ActorRef -import akka.pattern.ask import akka.util.{ByteString, Timeout} import io.iohk.ethereum.crypto import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.db.storage.AppStateStorage import io.iohk.ethereum.domain.{Account, Address, Blockchain} +import io.iohk.ethereum.jsonrpc.AkkaTaskOps._ import io.iohk.ethereum.jsonrpc.PersonalService._ -import io.iohk.ethereum.keystore.{KeyStore, Wallet} import io.iohk.ethereum.jsonrpc.JsonRpcError._ +import io.iohk.ethereum.keystore.{KeyStore, Wallet} import io.iohk.ethereum.rlp.RLPList import io.iohk.ethereum.transactions.PendingTransactionsManager import io.iohk.ethereum.transactions.PendingTransactionsManager.{AddOrOverrideTransaction, PendingTransactionsResponse} @@ -19,10 +19,8 @@ import io.iohk.ethereum.utils.{BlockchainConfig, TxPoolConfig} import io.iohk.ethereum.rlp import io.iohk.ethereum.rlp.RLPImplicits._ import io.iohk.ethereum.rlp.RLPImplicitConversions._ -import monix.execution.Scheduler.Implicits.{global => mglobal} import monix.eval.Task -import scala.concurrent.Future import scala.util.Try object PersonalService { @@ -150,27 +148,25 @@ class PersonalService( def sendTransaction( request: SendTransactionWithPassphraseRequest ): ServiceResponse[SendTransactionWithPassphraseResponse] = { - val maybeWalletUnlocked = Future { + val maybeWalletUnlocked = Task { keyStore.unlockAccount(request.tx.from, request.passphrase).left.map(handleError) } - Task.fromFuture(maybeWalletUnlocked.flatMap { + + maybeWalletUnlocked.flatMap { case Right(wallet) => val futureTxHash = sendTransaction(request.tx, wallet) futureTxHash.map(txHash => Right(SendTransactionWithPassphraseResponse(txHash))) - case Left(err) => Future.successful(Left(err)) - }) + case Left(err) => Task.now(Left(err)) + } } def sendTransaction(request: SendTransactionRequest): ServiceResponse[SendTransactionResponse] = { - Task.fromFuture { - unlockedWallets.get(request.tx.from) match { - case Some(wallet) => - val futureTxHash = sendTransaction(request.tx, wallet) - futureTxHash.map(txHash => Right(SendTransactionResponse(txHash))) - - case None => - Future.successful(Left(AccountLocked)) - } + Task(unlockedWallets.get(request.tx.from)).flatMap { + case Some(wallet) => + val futureTxHash = sendTransaction(request.tx, wallet) + futureTxHash.map(txHash => Right(SendTransactionResponse(txHash))) + + case None => Task.now(Left(AccountLocked)) } } @@ -184,26 +180,24 @@ class PersonalService( case _ => Left(JsonRpcError.InvalidParams("Iele transaction should contain either functionName or contractCode")) } - Task.fromFuture { - dataEither match { - case Right(data) => - sendTransaction( - SendTransactionRequest( - TransactionRequest(tx.from, tx.to, tx.value, tx.gasLimit, tx.gasPrice, tx.nonce, Some(ByteString(data))) - ) - ).runToFuture - case Left(error) => - Future.successful(Left(error)) - } + dataEither match { + case Right(data) => + sendTransaction( + SendTransactionRequest( + TransactionRequest(tx.from, tx.to, tx.value, tx.gasLimit, tx.gasPrice, tx.nonce, Some(ByteString(data))) + ) + ) + case Left(error) => + Task.now(Left(error)) } } - private def sendTransaction(request: TransactionRequest, wallet: Wallet): Future[ByteString] = { + private def sendTransaction(request: TransactionRequest, wallet: Wallet): Task[ByteString] = { implicit val timeout = Timeout(txPoolConfig.pendingTxManagerQueryTimeout) val pendingTxsFuture = - (txPool ? PendingTransactionsManager.GetPendingTransactions).mapTo[PendingTransactionsResponse] - val latestPendingTxNonceFuture: Future[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => + txPool.askFor[PendingTransactionsResponse](PendingTransactionsManager.GetPendingTransactions) + val latestPendingTxNonceFuture: Task[Option[BigInt]] = pendingTxsFuture.map { pendingTxs => val senderTxsNonces = pendingTxs.pendingTransactions .collect { case ptx if ptx.stx.senderAddress == wallet.address => ptx.stx.tx.tx.nonce } Try(senderTxsNonces.max).toOption From cee6d27b8787b853b31e8857cb72a58df53caabb Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 30 Oct 2020 16:44:26 +0100 Subject: [PATCH 30/33] [ETCM-269] change PersonalService --- .../jsonrpc/PersonalServiceSpec.scala | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala index 3708b5dfb7..b0f07d6d7a 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/PersonalServiceSpec.scala @@ -115,12 +115,12 @@ class PersonalServiceSpec (blockchain.getBestBlockNumber _).expects().returning(blockchainConfig.eip155BlockNumber - 1) val req = SendTransactionWithPassphraseRequest(tx, passphrase) - val res = personal.sendTransaction(req) + val res = personal.sendTransaction(req).runToFuture txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) + res.futureValue shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } @@ -136,12 +136,12 @@ class PersonalServiceSpec (blockchain.getBestBlockNumber _).expects().returning(blockchainConfig.eip155BlockNumber - 1) val req = SendTransactionWithPassphraseRequest(tx, passphrase) - val res = personal.sendTransaction(req) + val res = personal.sendTransaction(req).runToFuture txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Seq(PendingTransaction(stxWithSender, 0)))) - res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionWithPassphraseResponse(newTx.hash)) + res.futureValue shouldEqual Right(SendTransactionWithPassphraseResponse(newTx.hash)) txPool.expectMsg(AddOrOverrideTransaction(newTx)) } @@ -169,12 +169,12 @@ class PersonalServiceSpec (blockchain.getBestBlockNumber _).expects().returning(blockchainConfig.eip155BlockNumber - 1) val req = SendTransactionRequest(tx) - val res = personal.sendTransaction(req) + val res = personal.sendTransaction(req).runToFuture txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionResponse(stx.hash)) + res.futureValue shouldEqual Right(SendTransactionResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } @@ -328,12 +328,12 @@ class PersonalServiceSpec (blockchain.getBestBlockNumber _).expects().returning(blockchainConfig.eip155BlockNumber - 1) val req = SendTransactionWithPassphraseRequest(tx, passphrase) - val res = personal.sendTransaction(req) + val res = personal.sendTransaction(req).runToFuture txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) + res.futureValue shouldEqual Right(SendTransactionWithPassphraseResponse(stx.hash)) txPool.expectMsg(AddOrOverrideTransaction(stx)) } @@ -348,12 +348,12 @@ class PersonalServiceSpec (blockchain.getBestBlockNumber _).expects().returning(blockchainConfig.eip155BlockNumber) val req = SendTransactionWithPassphraseRequest(tx, passphrase) - val res = personal.sendTransaction(req) + val res = personal.sendTransaction(req).runToFuture txPool.expectMsg(GetPendingTransactions) txPool.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe(taskTimeout) shouldEqual Right(SendTransactionWithPassphraseResponse(chainSpecificStx.hash)) + res.futureValue shouldEqual Right(SendTransactionWithPassphraseResponse(chainSpecificStx.hash)) txPool.expectMsg(AddOrOverrideTransaction(chainSpecificStx)) } From 490f30a57975707055b5df49d3bbad05e015ee4b Mon Sep 17 00:00:00 2001 From: lemastero Date: Fri, 30 Oct 2020 17:18:46 +0100 Subject: [PATCH 31/33] [ETCM-269] removed unneccessary rename of global monix Scheduler --- .../ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 edd218bf1b..934a29adc7 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 @@ -15,7 +15,7 @@ import io.iohk.ethereum.jsonrpc._ import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers import io.iohk.ethereum.utils.{ConfigUtils, Logger} import monix.eval.Task -import monix.execution.Scheduler.Implicits.{global => MonixGlobal} +import monix.execution.Scheduler.Implicits.global import org.json4s.{DefaultFormats, JInt, native} import scala.util.Try @@ -81,14 +81,14 @@ trait JsonRpcHttpServer extends Json4sSupport { } private def handleRequest(request: JsonRpcRequest) = { - complete(jsonRpcController.handleRequest(request).runToFuture(MonixGlobal)) + complete(jsonRpcController.handleRequest(request).runToFuture) } private def handleBatchRequest(requests: Seq[JsonRpcRequest]) = { complete { Task .traverse(requests)(request => jsonRpcController.handleRequest(request)) - .runToFuture(MonixGlobal) + .runToFuture } } } From ef3c041389ed1d34eb2225ec3a9c04ae63215a74 Mon Sep 17 00:00:00 2001 From: lemastero Date: Tue, 3 Nov 2020 15:41:29 +0100 Subject: [PATCH 32/33] [ETCM-269] fix after merge from master --- .../jsonrpc/JsonRpcControllerEthSpec.scala | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index 12bffd2dd7..94702c20b1 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -13,7 +13,11 @@ import io.iohk.ethereum.domain._ import io.iohk.ethereum.jsonrpc.EthService._ import io.iohk.ethereum.jsonrpc.FilterManager.LogFilterLogs import io.iohk.ethereum.jsonrpc.PersonalService._ -import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.{OptionNoneToJNullSerializer, QuantitiesSerializer, UnformattedDataJsonSerializer} +import io.iohk.ethereum.jsonrpc.serialization.JsonSerializers.{ + OptionNoneToJNullSerializer, + QuantitiesSerializer, + UnformattedDataJsonSerializer +} import io.iohk.ethereum.ommers.OmmersPool import io.iohk.ethereum.ommers.OmmersPool.Ommers import io.iohk.ethereum.testing.ActorsTesting.simpleAutoPilot @@ -120,7 +124,7 @@ class JsonRpcControllerEthSpec "eth_getBlockByHash", List(JString(s"0x${blockToRequest.header.hashAsHexString}"), JBool(false)) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedBlockResponse = Extraction.decompose(BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd))) @@ -141,7 +145,7 @@ class JsonRpcControllerEthSpec "eth_getBlockByHash", List(JString(s"0x${blockToRequest.header.hashAsHexString}"), JBool(false)) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedBlockResponse = Extraction.decompose(BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd))) @@ -183,7 +187,7 @@ class JsonRpcControllerEthSpec "eth_getBlockByNumber", List(JString(s"0x${Hex.toHexString(blockToRequest.header.number.toByteArray)}"), JBool(false)) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedBlockResponse = Extraction.decompose(BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd))) @@ -204,7 +208,7 @@ class JsonRpcControllerEthSpec "eth_getBlockByNumber", List(JString(s"0x${Hex.toHexString(blockToRequest.header.number.toByteArray)}"), JBool(false)) ) - val response = jsonRpcController.handleRequest(request).futureValue + val response = jsonRpcController.handleRequest(request).runSyncUnsafe() val expectedBlockResponse = Extraction.decompose(BlockResponse(blockToRequest, fullTxs = false, totalDifficulty = Some(blockTd))) From 7494676cc21ff01b75df74207c35f6061c110bbe Mon Sep 17 00:00:00 2001 From: lemastero Date: Tue, 3 Nov 2020 21:10:24 +0100 Subject: [PATCH 33/33] [ETCM-269] review: AkkaAskTask using defereFuture + fix tests --- .../iohk/ethereum/jsonrpc/AkkaTaskOps.scala | 2 +- .../ethereum/jsonrpc/EthServiceSpec.scala | 48 +++++++++---------- .../jsonrpc/JsonRpcControllerEthSpec.scala | 10 ++-- .../jsonrpc/JsonRpcControllerFixture.scala | 5 +- .../ethereum/jsonrpc/NetServiceSpec.scala | 6 ++- 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala index 995316d294..7ac4b11244 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/AkkaTaskOps.scala @@ -14,7 +14,7 @@ object AkkaTaskOps { message: Any )(implicit timeout: Timeout, classTag: ClassTag[A], sender: ActorRef = Actor.noSender): Task[A] = Task - .fromFuture((to ? message).mapTo[A]) + .deferFuture((to ? message).mapTo[A]) .timeout(timeout.duration) } } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index 012c82ad38..5c3f7128fe 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -178,13 +178,13 @@ class EthServiceSpec val request = GetTransactionByHashRequest(txToRequestHash) // when - val response = ethService.getRawTransactionByHash(request) + val response = ethService.getRawTransactionByHash(request).runSyncUnsafe() // then pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.runSyncUnsafe() shouldEqual Right(RawTransactionResponse(None)) + response shouldEqual Right(RawTransactionResponse(None)) } it should "handle eth_getRawTransactionByHash if the tx is still pending" in new TestSetup { @@ -193,7 +193,7 @@ class EthServiceSpec val request = GetTransactionByHashRequest(txToRequestHash) // when - val response = ethService.getRawTransactionByHash(request) + val response = ethService.getRawTransactionByHash(request).runToFuture // then pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) @@ -201,7 +201,7 @@ class EthServiceSpec PendingTransactionsResponse(Seq(PendingTransaction(txToRequestWithSender, System.currentTimeMillis))) ) - response.runSyncUnsafe() shouldEqual Right(RawTransactionResponse(Some(txToRequest))) + response.futureValue shouldEqual Right(RawTransactionResponse(Some(txToRequest))) } it should "handle eth_getRawTransactionByHash if the tx was already executed" in new TestSetup { @@ -213,13 +213,13 @@ class EthServiceSpec val request = GetTransactionByHashRequest(txToRequestHash) // when - val response = ethService.getRawTransactionByHash(request) + val response = ethService.getRawTransactionByHash(request).runSyncUnsafe() // then pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.runSyncUnsafe() shouldEqual Right(RawTransactionResponse(Some(txToRequest))) + response shouldEqual Right(RawTransactionResponse(Some(txToRequest))) } it should "answer eth_getBlockByNumber with the correct block when the pending block is requested" in new TestSetup { @@ -537,14 +537,14 @@ class EthServiceSpec (blockGenerator.generateBlock _).expects(parentBlock, Nil, *, *).returning(PendingBlock(block, Nil)) blockchain.save(parentBlock, Nil, parentBlock.header.difficulty, true) - val response: ServiceResponse[GetWorkResponse] = ethService.getWork(GetWorkRequest()) + val response = ethService.getWork(GetWorkRequest()).runSyncUnsafe() pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsManager.PendingTransactionsResponse(Nil)) ommersPool.expectMsg(OmmersPool.GetOmmers(parentBlock.hash)) ommersPool.reply(OmmersPool.Ommers(Nil)) - response.runSyncUnsafe() shouldEqual Right(GetWorkResponse(powHash, seedHash, target)) + response shouldEqual Right(GetWorkResponse(powHash, seedHash, target)) } it should "accept submitted correct PoW" in new TestSetup { @@ -977,26 +977,26 @@ class EthServiceSpec (ledger.consensus _: (() => Consensus)).expects().returns(consensus) val request = GetTransactionByHashRequest(txToRequestHash) - val response = ethService.getTransactionByHash(request) + val response = ethService.getTransactionByHash(request).runSyncUnsafe() pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.runSyncUnsafe() shouldEqual Right(GetTransactionByHashResponse(None)) + response shouldEqual Right(GetTransactionByHashResponse(None)) } it should "handle get transaction by hash if the tx is still pending" in new TestSetup { (ledger.consensus _: (() => Consensus)).expects().returns(consensus) val request = GetTransactionByHashRequest(txToRequestHash) - val response = ethService.getTransactionByHash(request) + val response = ethService.getTransactionByHash(request).runToFuture pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply( PendingTransactionsResponse(Seq(PendingTransaction(txToRequestWithSender, System.currentTimeMillis))) ) - response.runSyncUnsafe() shouldEqual Right(GetTransactionByHashResponse(Some(TransactionResponse(txToRequest)))) + response.futureValue shouldEqual Right(GetTransactionByHashResponse(Some(TransactionResponse(txToRequest)))) } it should "handle get transaction by hash if the tx was already executed" in new TestSetup { @@ -1006,12 +1006,12 @@ class EthServiceSpec blockchain.storeBlock(blockWithTx).commit() val request = GetTransactionByHashRequest(txToRequestHash) - val response = ethService.getTransactionByHash(request) + val response = ethService.getTransactionByHash(request).runSyncUnsafe() pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - response.runSyncUnsafe() shouldEqual Right( + response shouldEqual Right( GetTransactionByHashResponse(Some(TransactionResponse(txToRequest, Some(blockWithTx.header), Some(0)))) ) } @@ -1088,7 +1088,7 @@ class EthServiceSpec val request = GetAccountTransactionsRequest(address, 3125360, 3125370) - val response = ethService.getAccountTransactions(request) + val response = ethService.getAccountTransactions(request).runSyncUnsafe() pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) @@ -1108,7 +1108,7 @@ class EthServiceSpec TransactionResponse(tx1, blockHeader = Some(blockWithTx1.header), pending = Some(false), isOutgoing = Some(false)) ) - response.runSyncUnsafe() shouldEqual Right(GetAccountTransactionsResponse(expectedTxs)) + response shouldEqual Right(GetAccountTransactionsResponse(expectedTxs)) } it should "not return account recent transactions from older blocks and return pending txs" in new TestSetup { @@ -1125,23 +1125,23 @@ class EthServiceSpec val request = GetAccountTransactionsRequest(signedTx.senderAddress, 3125371, 3125381) - val response = ethService.getAccountTransactions(request) + val response = ethService.getAccountTransactions(request).runToFuture pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Seq(pendingTx))) val expectedSent = Seq(TransactionResponse(signedTx.tx, blockHeader = None, pending = Some(true), isOutgoing = Some(true))) - response.runSyncUnsafe() shouldEqual Right(GetAccountTransactionsResponse(expectedSent)) + response.futureValue shouldEqual Right(GetAccountTransactionsResponse(expectedSent)) } it should "send message to pendingTransactionsManager and return an empty GetPendingTransactionsResponse" in new TestSetup { - val res = ethService.getTransactionsFromPool() + val res = ethService.getTransactionsFromPool().runSyncUnsafe() pendingTransactionsManager.expectMsg(GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - res.runSyncUnsafe() shouldBe PendingTransactionsResponse(Nil) + res shouldBe PendingTransactionsResponse(Nil) } it should "send message to pendingTransactionsManager and return GetPendingTransactionsResponse with two transactions" in new TestSetup { @@ -1163,21 +1163,21 @@ class EthServiceSpec }) .toList - val res = ethService.getTransactionsFromPool() + val res = ethService.getTransactionsFromPool().runToFuture pendingTransactionsManager.expectMsg(GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsResponse(transactions)) - res.runSyncUnsafe() shouldBe PendingTransactionsResponse(transactions) + res.futureValue shouldBe PendingTransactionsResponse(transactions) } it should "send message to pendingTransactionsManager and return an empty GetPendingTransactionsResponse in case of error" in new TestSetup { - val res = ethService.getTransactionsFromPool() + val res = ethService.getTransactionsFromPool().runSyncUnsafe() pendingTransactionsManager.expectMsg(GetPendingTransactions) pendingTransactionsManager.reply(new ClassCastException("error")) - res.runSyncUnsafe() shouldBe PendingTransactionsResponse(Nil) + res shouldBe PendingTransactionsResponse(Nil) } // NOTE TestSetup uses Ethash consensus; check `consensusConfig`. diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index 94702c20b1..be749d7b7f 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -286,7 +286,7 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_getWork") - val result: Task[JsonRpcResponse] = jsonRpcController.handleRequest(request) + val response: JsonRpcResponse = jsonRpcController.handleRequest(request).runSyncUnsafe() pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) pendingTransactionsManager.reply(PendingTransactionsManager.PendingTransactionsResponse(Nil)) @@ -294,7 +294,6 @@ class JsonRpcControllerEthSpec ommersPool.expectMsg(OmmersPool.GetOmmers(parentBlock.hash)) ommersPool.reply(Ommers(Nil)) - val response = result.runSyncUnsafe() response should haveResult( JArray( List( @@ -326,13 +325,16 @@ class JsonRpcControllerEthSpec val request: JsonRpcRequest = newJsonRpcRequest("eth_getWork") - val result: Task[JsonRpcResponse] = jsonRpcController.handleRequest(request) + val result: JsonRpcResponse = jsonRpcController + .handleRequest(request) + .timeout(Timeouts.longTimeout) + .runSyncUnsafe() pendingTransactionsManager.expectMsg(PendingTransactionsManager.GetPendingTransactions) ommersPool.expectMsg(OmmersPool.GetOmmers(parentBlock.hash)) //on time out it should respond with empty list - val response = result.timeout(Timeouts.longTimeout).runSyncUnsafe() + val response = result response should haveResult( JArray( List( diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerFixture.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerFixture.scala index 6ff22eef68..402e26061b 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerFixture.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerFixture.scala @@ -119,7 +119,10 @@ class JsonRpcControllerFixture(implicit system: ActorSystem) val checkpointBlockGenerator = new CheckpointBlockGenerator() val blockWithCheckpoint = checkpointBlockGenerator.generate(Fixtures.Blocks.Block3125369.block, checkpoint) val blockWithTreasuryOptOut = - Block(Fixtures.Blocks.Block3125369.header.copy(extraFields = HefPostEcip1098(true)), Fixtures.Blocks.Block3125369.body) + Block( + Fixtures.Blocks.Block3125369.header.copy(extraFields = HefPostEcip1098(true)), + Fixtures.Blocks.Block3125369.body + ) val parentBlock = Block(blockHeader.copy(number = 1), BlockBody.empty) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala index bcb5dd113a..4ecec066e2 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/NetServiceSpec.scala @@ -20,7 +20,9 @@ import scala.concurrent.duration._ class NetServiceSpec extends AnyFlatSpec with Matchers with ScalaFutures with NormalPatience with SecureRandomBuilder { "NetService" should "return handshaked peer count" in new TestSetup { - val resF = netService.peerCount(PeerCountRequest()) + val resF = netService + .peerCount(PeerCountRequest()) + .runToFuture peerManager.expectMsg(PeerManagerActor.GetPeers) peerManager.reply( @@ -33,7 +35,7 @@ class NetServiceSpec extends AnyFlatSpec with Matchers with ScalaFutures with No ) ) - resF.runSyncUnsafe() shouldBe Right(PeerCountResponse(2)) + resF.futureValue shouldBe Right(PeerCountResponse(2)) } it should "return listening response" in new TestSetup {