Skip to content

Commit

Permalink
Merge branch 'develop' into dev-sbt-mode
Browse files Browse the repository at this point in the history
  • Loading branch information
lemastero committed Oct 16, 2020
2 parents 6c37762 + 5fb0b41 commit 843cbdc
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 226 deletions.
10 changes: 10 additions & 0 deletions build.sbt
Expand Up @@ -151,3 +151,13 @@ addCommandAlias(
|;benchmark:compile
|""".stripMargin
)

// prepare PR
addCommandAlias(
"pp",
""";compile-all
|;test
|;scalastyle
|;test:scalastyle
|""".stripMargin
)
74 changes: 37 additions & 37 deletions insomnia_workspace.json
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Expand Up @@ -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] =
Expand Down
19 changes: 16 additions & 3 deletions src/main/scala/io/iohk/ethereum/jsonrpc/EthService.scala
Expand Up @@ -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

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
}
}
Expand Up @@ -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
Expand Down Expand Up @@ -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]] = {
Expand Down Expand Up @@ -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]] = {
Expand Down
@@ -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 {
Expand All @@ -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)
})
}
}
27 changes: 3 additions & 24 deletions 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
Expand All @@ -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 {
Expand Down Expand Up @@ -88,7 +70,4 @@ object QAService {
}
}
}

case class GetPendingTransactionsRequest()
case class GetPendingTransactionsResponse(pendingTransactions: Seq[PendingTransaction])
}
Expand Up @@ -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 {
Expand Down
48 changes: 47 additions & 1 deletion src/test/scala/io/iohk/ethereum/jsonrpc/EthServiceSpec.scala
Expand Up @@ -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, _}
Expand All @@ -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
Expand Down Expand Up @@ -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]
Expand Down

0 comments on commit 843cbdc

Please sign in to comment.