diff --git a/build.sbt b/build.sbt index b94a44bae6..b2afbd99ef 100644 --- a/build.sbt +++ b/build.sbt @@ -151,3 +151,13 @@ addCommandAlias( |;benchmark:compile |""".stripMargin ) + +// prepare PR +addCommandAlias( + "pp", + """;compile-all + |;test + |;scalastyle + |;test:scalastyle + |""".stripMargin +) diff --git a/insomnia_workspace.json b/insomnia_workspace.json index 22cdd69d87..5fe9fcf0d1 100644 --- a/insomnia_workspace.json +++ b/insomnia_workspace.json @@ -139,43 +139,6 @@ "metaSortKey": -1600249374160, "_type": "request_group" }, - { - "_id": "req_6197fefa1e1448a89f30712ec12295f8", - "parentId": "fld_2b54cbb84e244284b3ef752c5f805376", - "modified": 1600249571669, - "created": 1600249491560, - "url": "{{ node_url }}", - "name": "qa_getPendingTransactions", - "description": "", - "method": "POST", - "body": { - "mimeType": "application/json", - "text": "{\n\t\"jsonrpc\": \"2.0\",\n \"method\": \"qa_getPendingTransactions\", \n \"params\": [],\n \"id\": 1\n}" - }, - "parameters": [], - "headers": [ - { - "id": "pair_9f4d6a9dde554cd384487e04fa3b21aa", - "name": "Content-Type", - "value": "application/json" - }, - { - "id": "pair_088edc31f5e04f20a16b465a673871bb", - "name": "Cache-Control", - "value": "no-cache" - } - ], - "authentication": {}, - "metaSortKey": -1552939150156.832, - "isPrivate": false, - "settingStoreCookies": true, - "settingSendCookies": true, - "settingDisableRenderRequestBody": false, - "settingEncodeUrl": true, - "settingRebuildPath": true, - "settingFollowRedirects": "global", - "_type": "request" - }, { "_id": "req_dd6e5c718f974407bb79fe3c953b7106", "parentId": "fld_72829b866f0441e184e0d1a2030f8220", @@ -961,6 +924,43 @@ "settingFollowRedirects": "global", "_type": "request" }, + { + "_id": "req_4c1135a4a69644fe9850292131197b47", + "parentId": "fld_a06eb77e183c4727800eb7dc43ceabe1", + "modified": 1602234543563, + "created": 1602234438767, + "url": "{{ node_url }}", + "name": "eth_pendingTransactions", + "description": "Returns the transactions that are pending in the transaction pool and have a from address that is one of the accounts this node manages", + "method": "POST", + "body": { + "mimeType": "application/json", + "text": "{\n\t\"jsonrpc\": \"2.0\",\n \"method\": \"eth_pendingTransactions\", \n\t\"params\": [],\n \"id\": 1\n}" + }, + "parameters": [], + "headers": [ + { + "id": "pair_9f4d6a9dde554cd384487e04fa3b21aa", + "name": "Content-Type", + "value": "application/json" + }, + { + "id": "pair_088edc31f5e04f20a16b465a673871bb", + "name": "Cache-Control", + "value": "no-cache" + } + ], + "authentication": {}, + "metaSortKey": -1552732410719.375, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, { "_id": "req_579a127b434b4ac7aa51ee6c93f04630", "parentId": "fld_a06eb77e183c4727800eb7dc43ceabe1", diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala index 546f22f168..b12bb3408d 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthJsonMethodsImplicits.scala @@ -125,6 +125,15 @@ object EthJsonMethodsImplicits extends JsonMethodsImplicits { Extraction.decompose(t.blockResponse) } + implicit val eth_pendingTransactions = new NoParamsDecoder(EthPendingTransactionsRequest()) + with JsonEncoder[EthPendingTransactionsResponse] { + + override def encodeJson(t: EthPendingTransactionsResponse): JValue = + JArray(t.pendingTransactions.toList.map { pendingTx => + encodeAsHex(pendingTx.stx.tx.hash) + }) + } + implicit val eth_getTransactionByHash = new JsonDecoder[GetTransactionByHashRequest] with JsonEncoder[GetTransactionByHashResponse] { override def decodeJson(params: Option[JArray]): Either[JsonRpcError, GetTransactionByHashRequest] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala index 8bea7a41d2..e8329b6d74 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala @@ -24,7 +24,7 @@ import io.iohk.ethereum.rlp.RLPImplicits._ import io.iohk.ethereum.rlp.RLPList import io.iohk.ethereum.rlp.UInt256RLPImplicits._ import io.iohk.ethereum.transactions.PendingTransactionsManager -import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransactionsResponse +import io.iohk.ethereum.transactions.PendingTransactionsManager.{PendingTransaction, PendingTransactionsResponse} import io.iohk.ethereum.utils._ import org.bouncycastle.util.encoders.Hex @@ -191,6 +191,9 @@ object EthService { case class GetStorageRootRequest(address: Address, block: BlockParam) case class GetStorageRootResponse(storageRoot: ByteString) + + case class EthPendingTransactionsRequest() + case class EthPendingTransactionsResponse(pendingTransactions: Seq[PendingTransaction]) } class EthService( @@ -573,8 +576,8 @@ class EthService( } })(Future.successful(OmmersPool.Ommers(Nil))) // NOTE If not Ethash consensus, ommers do not make sense, so => Nil - // TODO This seems to be re-implemented elsewhere, probably move to a better place? Also generalize the error message. - private def getTransactionsFromPool: Future[PendingTransactionsResponse] = { + // 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] = { implicit val timeout: Timeout = Timeout(getTransactionFromPoolTimeout) (pendingTransactionsManager ? PendingTransactionsManager.GetPendingTransactions) @@ -972,4 +975,14 @@ class EthService( } } + /** + * Returns the transactions that are pending in the transaction pool and have a from address that is one of the accounts this node manages. + * + * @param req request + * @return pending transactions + */ + def ethPendingTransactions(req: EthPendingTransactionsRequest): ServiceResponse[EthPendingTransactionsResponse] = + getTransactionsFromPool().map { resp => + Right(EthPendingTransactionsResponse(resp.pendingTransactions)) + } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala index 3098186265..e641b01212 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcController.scala @@ -11,7 +11,6 @@ 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.{GetPendingTransactionsRequest, GetPendingTransactionsResponse} import io.iohk.ethereum.jsonrpc.TestService._ import io.iohk.ethereum.jsonrpc.server.http.JsonRpcHttpServer.JsonRpcHttpServerConfig import io.iohk.ethereum.jsonrpc.server.ipc.JsonRpcIpcServer.JsonRpcIpcServerConfig @@ -278,6 +277,8 @@ class JsonRpcController( ethService.getRawTransactionByBlockNumberAndIndex, req ) + case req @ JsonRpcRequest(_, "eth_pendingTransactions", _, _) => + handle[EthPendingTransactionsRequest, EthPendingTransactionsResponse](ethService.ethPendingTransactions, req) } private def handleDebugRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { @@ -349,9 +350,6 @@ class JsonRpcController( private def handleQARequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { case req @ JsonRpcRequest(_, "qa_mineBlocks", _, _) => handle[QAService.MineBlocksRequest, QAService.MineBlocksResponse](qaService.mineBlocks, req) - - case req @ JsonRpcRequest(_, "qa_getPendingTransactions", _, _) => - handle[GetPendingTransactionsRequest, GetPendingTransactionsResponse](qaService.getPendingTransactions, req) } private def handleCheckpointingRequest: PartialFunction[JsonRpcRequest, Future[JsonRpcResponse]] = { diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala index 2ffa00afa3..ea9433a19b 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAJsonMethodsImplicits.scala @@ -1,15 +1,11 @@ package io.iohk.ethereum.jsonrpc -import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonDecoder.NoParamsDecoder -import io.iohk.ethereum.jsonrpc.JsonRpcController.{Codec, JsonEncoder} +import io.iohk.ethereum.jsonrpc.JsonRpcController.Codec import io.iohk.ethereum.jsonrpc.JsonRpcErrors.InvalidParams import io.iohk.ethereum.jsonrpc.QAService.{ - GetPendingTransactionsRequest, - GetPendingTransactionsResponse, MineBlocksRequest, MineBlocksResponse } -import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransaction import org.json4s.JsonAST._ object QAJsonMethodsImplicits extends JsonMethodsImplicits { @@ -36,12 +32,4 @@ object QAJsonMethodsImplicits extends JsonMethodsImplicits { "message" -> t.message.fold[JValue](JNull)(JString) ) } - - implicit val qa_getPendingTransactions: Codec[GetPendingTransactionsRequest, GetPendingTransactionsResponse] = - new NoParamsDecoder(GetPendingTransactionsRequest()) with JsonEncoder[GetPendingTransactionsResponse] { - def encodeJson(t: GetPendingTransactionsResponse): JValue = - JArray(t.pendingTransactions.toList.map { pendingTx: PendingTransaction => - encodeAsHex(pendingTx.stx.tx.hash) - }) - } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala index 162b0f2616..8b5f0b1d5c 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala @@ -1,32 +1,24 @@ package io.iohk.ethereum.jsonrpc -import akka.actor.ActorRef import akka.util.ByteString import cats.implicits._ import enumeratum._ import io.iohk.ethereum.consensus._ import io.iohk.ethereum.consensus.ethash.MinerResponses._ import io.iohk.ethereum.consensus.ethash.MockedMinerProtocol.MineBlocks -import io.iohk.ethereum.consensus.ethash.{MinerResponse, MinerResponses, TransactionPicker} +import io.iohk.ethereum.consensus.ethash.{MinerResponse, MinerResponses} import io.iohk.ethereum.jsonrpc.QAService.MineBlocksResponse.MinerResponseType import io.iohk.ethereum.jsonrpc.QAService.{ - GetPendingTransactionsRequest, - GetPendingTransactionsResponse, MineBlocksRequest, MineBlocksResponse } -import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransaction import io.iohk.ethereum.utils.Logger import monix.execution.Scheduler.Implicits.global import mouse.all._ -import scala.concurrent.duration.FiniteDuration class QAService( - consensus: Consensus, - val pendingTransactionsManager: ActorRef, - val getTransactionFromPoolTimeout: FiniteDuration -) extends Logger - with TransactionPicker { + consensus: Consensus +) extends Logger { /** * qa_mineBlocks that instructs mocked miner to mine given number of blocks @@ -44,16 +36,6 @@ class QAService( Left(JsonRpcErrors.InternalError) } } - - /** - * qa_getPendingTransactions that returns all pending transactions from the mempool - * - * @return all pending transactions from the mempool - */ - def getPendingTransactions(req: GetPendingTransactionsRequest): ServiceResponse[GetPendingTransactionsResponse] = - getTransactionsFromPool.map { resp => - Right(GetPendingTransactionsResponse(resp.pendingTransactions)) - } } object QAService { @@ -88,7 +70,4 @@ object QAService { } } } - - case class GetPendingTransactionsRequest() - case class GetPendingTransactionsResponse(pendingTransactions: Seq[PendingTransaction]) } diff --git a/src/main/scala/io/iohk/ethereum/nodebuilder/NodeBuilder.scala b/src/main/scala/io/iohk/ethereum/nodebuilder/NodeBuilder.scala index e979d785f6..f6e81750c7 100644 --- a/src/main/scala/io/iohk/ethereum/nodebuilder/NodeBuilder.scala +++ b/src/main/scala/io/iohk/ethereum/nodebuilder/NodeBuilder.scala @@ -366,12 +366,7 @@ trait PersonalServiceBuilder { trait QaServiceBuilder { self: ConsensusBuilder with PendingTransactionsManagerBuilder with TxPoolConfigBuilder => - lazy val qaService = - new QAService( - consensus, - pendingTransactionsManager, - txPoolConfig.getTransactionFromPoolTimeout - ) + lazy val qaService = new QAService(consensus) } trait CheckpointingServiceBuilder { diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala index 7a04c7aacf..f4016d216a 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala @@ -9,6 +9,7 @@ import io.iohk.ethereum.blockchain.sync.EphemBlockchainTestSetup import io.iohk.ethereum.consensus._ import io.iohk.ethereum.consensus.blocks.{PendingBlock, PendingBlockAndState} import io.iohk.ethereum.consensus.ethash.blocks.EthashBlockGenerator +import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.db.storage.AppStateStorage import io.iohk.ethereum.domain.{Address, Block, BlockHeader, BlockchainImpl, UInt256, _} import io.iohk.ethereum.jsonrpc.EthService.{ProtocolVersionRequest, _} @@ -20,7 +21,7 @@ import io.iohk.ethereum.ledger.{Ledger, StxLedger} import io.iohk.ethereum.mpt.{ByteArrayEncoder, ByteArraySerializable, MerklePatriciaTrie} import io.iohk.ethereum.ommers.OmmersPool import io.iohk.ethereum.transactions.PendingTransactionsManager -import io.iohk.ethereum.transactions.PendingTransactionsManager.{PendingTransaction, PendingTransactionsResponse} +import io.iohk.ethereum.transactions.PendingTransactionsManager.{GetPendingTransactions, PendingTransaction, PendingTransactionsResponse} import io.iohk.ethereum.utils._ import io.iohk.ethereum.{Fixtures, NormalPatience, Timeouts, crypto} import org.bouncycastle.util.encoders.Hex @@ -1100,6 +1101,51 @@ class EthServiceSpec response.futureValue shouldEqual Right(GetAccountTransactionsResponse(expectedSent)) } + it should "send message to pendingTransactionsManager and return an empty GetPendingTransactionsResponse" in new TestSetup { + val res = ethService.getTransactionsFromPool() + + pendingTransactionsManager.expectMsg(GetPendingTransactions) + pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) + + res.futureValue shouldBe PendingTransactionsResponse(Nil) + } + + it should "send message to pendingTransactionsManager and return GetPendingTransactionsResponse with two transactions" in new TestSetup { + val transactions = (0 to 1) + .map(_ => { + val fakeTransaction = SignedTransactionWithSender( + Transaction( + nonce = 0, + gasPrice = 123, + gasLimit = 123, + receivingAddress = Address("0x1234"), + value = 0, + payload = ByteString() + ), + signature = ECDSASignature(0, 0, 0.toByte), + sender = Address("0x1234") + ) + PendingTransaction(fakeTransaction, System.currentTimeMillis) + }) + .toList + + val res = ethService.getTransactionsFromPool() + + pendingTransactionsManager.expectMsg(GetPendingTransactions) + pendingTransactionsManager.reply(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() + + pendingTransactionsManager.expectMsg(GetPendingTransactions) + pendingTransactionsManager.reply(new ClassCastException("error")) + + res.futureValue shouldBe PendingTransactionsResponse(Nil) + } + // NOTE TestSetup uses Ethash consensus; check `consensusConfig`. trait TestSetup extends MockFactory with EphemBlockchainTestSetup { val blockGenerator = mock[EthashBlockGenerator] diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala index 7a00df37c4..a0a55a3159 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthTransactionSpec.scala @@ -1,11 +1,13 @@ package io.iohk.ethereum.jsonrpc import akka.util.ByteString +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.PersonalService._ +import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransaction import io.iohk.ethereum.{Fixtures, LongPatience} import org.bouncycastle.util.encoders.Hex import org.json4s.JsonAST._ @@ -403,4 +405,95 @@ class JsonRpcControllerEthTransactionSpec ) ) } + + "eth_pendingTransactions" should "request pending transactions and return valid response when mempool is empty" in new JsonRpcControllerFixture { + val mockEthService = mock[EthService] + (mockEthService.ethPendingTransactions _) + .expects(*) + .returning(Future.successful(Right(EthPendingTransactionsResponse(List())))) + val jRpcController = + new JsonRpcController( + web3Service, + netService, + mockEthService, + personalService, + None, + debugService, + qaService, + checkpointingService, + config + ) + + val request = JsonRpcRequest( + "2.0", + "eth_pendingTransactions", + Some( + JArray( + List() + ) + ), + Some(JInt(1)) + ) + + val response: JsonRpcResponse = jRpcController.handleRequest(request).futureValue + + response should haveResult(JArray(List())) + } + + it should "request pending transactions and return valid response when mempool has transactions" in new JsonRpcControllerFixture { + val transactions = (0 to 1).map(_ => { + val fakeTransaction = SignedTransactionWithSender( + Transaction( + nonce = 0, + gasPrice = 123, + gasLimit = 123, + receivingAddress = Address("0x1234"), + value = 0, + payload = ByteString() + ), + signature = ECDSASignature(0, 0, 0.toByte), + sender = Address("0x1234") + ) + PendingTransaction(fakeTransaction, System.currentTimeMillis) + }) + + val mockEthService = mock[EthService] + (mockEthService.ethPendingTransactions _) + .expects(*) + .returning(Future.successful(Right(EthPendingTransactionsResponse(transactions)))) + val jRpcController = + new JsonRpcController( + web3Service, + netService, + mockEthService, + personalService, + None, + debugService, + qaService, + checkpointingService, + config + ) + val request = JsonRpcRequest( + "2.0", + "eth_pendingTransactions", + Some( + JArray( + List() + ) + ), + Some(JInt(1)) + ) + + val response: JsonRpcResponse = jRpcController.handleRequest(request).futureValue + + val result = JArray( + transactions + .map(tx => { + encodeAsHex(tx.stx.tx.hash) + }) + .toList + ) + + response should haveResult(result) + } } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala index ab926a078f..695d3077d4 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala @@ -1,29 +1,16 @@ package io.iohk.ethereum.jsonrpc import akka.actor.ActorSystem -import akka.testkit.{TestKit, TestProbe} -import akka.util.ByteString +import akka.testkit.TestKit import io.iohk.ethereum.consensus.Consensus import io.iohk.ethereum.consensus.ethash.EthashConfig import io.iohk.ethereum.consensus.ethash.MinerResponses.MiningOrdered import io.iohk.ethereum.consensus.ethash.MockedMinerProtocol.MineBlocks -import io.iohk.ethereum.crypto.ECDSASignature -import io.iohk.ethereum.domain.{Address, SignedTransactionWithSender, Transaction} -import io.iohk.ethereum.jsonrpc.QAService.{ - GetPendingTransactionsRequest, - GetPendingTransactionsResponse, - MineBlocksRequest, - MineBlocksResponse -} -import io.iohk.ethereum.transactions.PendingTransactionsManager.{ - GetPendingTransactions, - PendingTransaction, - PendingTransactionsResponse -} -import io.iohk.ethereum.{ByteGenerators, FlatSpecBase, SpecFixtures, Timeouts} +import io.iohk.ethereum.jsonrpc.QAService.{MineBlocksRequest, MineBlocksResponse} +import io.iohk.ethereum.{ByteGenerators, FlatSpecBase, SpecFixtures} import org.scalamock.scalatest.AsyncMockFactory + import scala.concurrent.Future -import scala.concurrent.duration.FiniteDuration class QAServiceSpec extends TestKit(ActorSystem("QAServiceSpec_System")) @@ -56,70 +43,13 @@ class QAServiceSpec qaService.mineBlocks(mineBlocksReq).map(_ shouldBe Left(JsonRpcErrors.InternalError)) } - it should "send message to pendingTransactionsManager and return an empty GetPendingTransactionsResponse" in testCaseF { - fixture => - import fixture._ - val res = qaService.getPendingTransactions(GetPendingTransactionsRequest()) - - pendingTransactionsManager.expectMsg(GetPendingTransactions) - pendingTransactionsManager.reply(PendingTransactionsResponse(Nil)) - - res.map(_ shouldBe Right(GetPendingTransactionsResponse(Nil))) - } - - it should "send message to pendingTransactionsManager and return GetPendingTransactionsResponse with two transactions" in testCaseF { - fixture => - import fixture._ - val transactions = (0 to 1) - .map(_ => { - val fakeTransaction = SignedTransactionWithSender( - Transaction( - nonce = 0, - gasPrice = 123, - gasLimit = 123, - receivingAddress = Address("0x1234"), - value = 0, - payload = ByteString() - ), - signature = ECDSASignature(0, 0, 0.toByte), - sender = Address("0x1234") - ) - PendingTransaction(fakeTransaction, System.currentTimeMillis) - }) - .toList - - val res = qaService.getPendingTransactions(GetPendingTransactionsRequest()) - - pendingTransactionsManager.expectMsg(GetPendingTransactions) - pendingTransactionsManager.reply(PendingTransactionsResponse(transactions)) - - res.map(_ shouldBe Right(GetPendingTransactionsResponse(transactions))) - } - - it should "send message to pendingTransactionsManager and return an empty GetPendingTransactionsResponse in case of error" in testCaseF { - fixture => - import fixture._ - val res = qaService.getPendingTransactions(GetPendingTransactionsRequest()) - - pendingTransactionsManager.expectMsg(GetPendingTransactions) - pendingTransactionsManager.reply(new ClassCastException("error")) - - res.map(_ shouldBe Right(GetPendingTransactionsResponse(Nil))) - } - class Fixture { protected trait TestConsensus extends Consensus { override type Config = EthashConfig } lazy val testConsensus: TestConsensus = mock[TestConsensus] - lazy val pendingTransactionsManager = TestProbe() - lazy val getTransactionFromPoolTimeout: FiniteDuration = Timeouts.normalTimeout - lazy val qaService = new QAService( - testConsensus, - pendingTransactionsManager.ref, - getTransactionFromPoolTimeout - ) + lazy val qaService = new QAService(testConsensus) lazy val mineBlocksReq = MineBlocksRequest(1, true, None) lazy val mineBlocksMsg = diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala index 67d100a297..037a61c239 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QaJRCSpec.scala @@ -1,21 +1,15 @@ package io.iohk.ethereum.jsonrpc -import akka.util.ByteString import io.iohk.ethereum.NormalPatience import io.iohk.ethereum.consensus.ethash.MockedMinerProtocol.MineBlocks import io.iohk.ethereum.consensus.ethash.{MinerResponse, MinerResponses} -import io.iohk.ethereum.crypto.ECDSASignature import io.iohk.ethereum.db.storage.AppStateStorage -import io.iohk.ethereum.domain.{Address, SignedTransactionWithSender, Transaction} import io.iohk.ethereum.jsonrpc.JsonRpcController.JsonRpcConfig import io.iohk.ethereum.jsonrpc.QAService.MineBlocksResponse.MinerResponseType._ import io.iohk.ethereum.jsonrpc.QAService.{ - GetPendingTransactionsRequest, - GetPendingTransactionsResponse, MineBlocksRequest, MineBlocksResponse } -import io.iohk.ethereum.transactions.PendingTransactionsManager.PendingTransaction import io.iohk.ethereum.utils.Config import org.json4s.JsonAST._ import org.scalamock.scalatest.MockFactory @@ -80,51 +74,6 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP response should haveError(JsonRpcErrors.InternalError) } } - - "request pending transactions and return valid response" when { - "mempool is empty" in new TestSetup { - (qaService.getPendingTransactions _) - .expects(getPendingTransactionReq) - .returning(Future.successful(Right(GetPendingTransactionsResponse(List())))) - - val response: JsonRpcResponse = jsonRpcController.handleRequest(getPendingTransactionsRpcRequest).futureValue - - response should haveResult(JArray(List())) - } - - "mempool has transactions" in new TestSetup { - val transactions = (0 to 1).map(_ => { - val fakeTransaction = SignedTransactionWithSender( - Transaction( - nonce = 0, - gasPrice = 123, - gasLimit = 123, - receivingAddress = Address("0x1234"), - value = 0, - payload = ByteString() - ), - signature = ECDSASignature(0, 0, 0.toByte), - sender = Address("0x1234") - ) - PendingTransaction(fakeTransaction, System.currentTimeMillis) - }) - (qaService.getPendingTransactions _) - .expects(getPendingTransactionReq) - .returning(Future.successful(Right(GetPendingTransactionsResponse(transactions)))) - - val response: JsonRpcResponse = jsonRpcController.handleRequest(getPendingTransactionsRpcRequest).futureValue - - val result = JArray( - transactions - .map(tx => { - encodeAsHex(tx.stx.tx.hash) - }) - .toList - ) - - response should haveResult(result) - } - } } trait TestSetup extends MockFactory with JRCMatchers { @@ -143,7 +92,6 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP new JsonRpcController(web3Service, netService, ethService, personalService, None, debugService, qaService, checkpointingService, config) val mineBlocksReq = MineBlocksRequest(1, true, None) - val getPendingTransactionReq = GetPendingTransactionsRequest() val mineBlocksRpcRequest = JsonRpcRequest( "2.0", @@ -159,17 +107,6 @@ class QaJRCSpec extends AnyWordSpec with Matchers with ScalaFutures with NormalP Some(JInt(1)) ) - val getPendingTransactionsRpcRequest = JsonRpcRequest( - "2.0", - "qa_getPendingTransactions", - Some( - JArray( - List() - ) - ), - Some(JInt(1)) - ) - def msg(str: String): JField = "message" -> JString(str) val nullMessage: JField = "message" -> JNull