@@ -82,6 +82,8 @@ object EthService {
8282 case class GetTransactionByBlockNumberAndIndexRequest (block : BlockParam , transactionIndex : BigInt )
8383 case class GetTransactionByBlockNumberAndIndexResponse (transactionResponse : Option [TransactionResponse ])
8484
85+ case class RawTransactionResponse (transactionResponse : Option [SignedTransaction ])
86+
8587 case class GetHashRateRequest ()
8688 case class GetHashRateResponse (hashRate : BigInt )
8789
@@ -281,6 +283,21 @@ class EthService(
281283 Right (BlockByNumberResponse (blockResponseOpt))
282284 }
283285
286+ /**
287+ * Implements the eth_getRawTransactionByHash - fetch raw transaction data of a transaction with the given hash.
288+ *
289+ * The tx requested will be fetched from the pending tx pool or from the already executed txs (depending on the tx state)
290+ *
291+ * @param req with the tx requested (by it's hash)
292+ * @return the raw transaction hask or None if the client doesn't have the tx
293+ */
294+ def getRawTransactionByHash (req : GetTransactionByHashRequest ): ServiceResponse [RawTransactionResponse ] = {
295+ getTransactionDataByHash(req.txHash).map(asRawTransactionResponse)
296+ }
297+
298+ private def asRawTransactionResponse (txResponse : Option [TransactionData ]): Right [Nothing , RawTransactionResponse ] =
299+ Right (RawTransactionResponse (txResponse.map(_.stx)))
300+
284301 /**
285302 * Implements the eth_getTransactionByHash method that fetches a requested tx.
286303 * The tx requested will be fetched from the pending tx pool or from the already executed txs (depending on the tx state)
@@ -289,23 +306,24 @@ class EthService(
289306 * @return the tx requested or None if the client doesn't have the tx
290307 */
291308 def getTransactionByHash (req : GetTransactionByHashRequest ): ServiceResponse [GetTransactionByHashResponse ] = {
292- val maybeTxPendingResponse : Future [Option [TransactionResponse ]] = getTransactionsFromPool.map {
293- _.pendingTransactions.map(_.stx.tx).find(_.hash == req.txHash).map(TransactionResponse (_))
309+ val eventualMaybeData = getTransactionDataByHash(req.txHash)
310+ eventualMaybeData.map(txResponse => Right (GetTransactionByHashResponse (txResponse.map(TransactionResponse (_)))))
311+ }
312+
313+ def getTransactionDataByHash (txHash : ByteString ): Future [Option [TransactionData ]] = {
314+ val maybeTxPendingResponse : Future [Option [TransactionData ]] = getTransactionsFromPool.map {
315+ _.pendingTransactions.map(_.stx.tx).find(_.hash == txHash).map(TransactionData (_))
294316 }
295317
296- val maybeTxResponse : Future [Option [TransactionResponse ]] = maybeTxPendingResponse.flatMap { txPending =>
297- Future {
298- txPending.orElse {
299- for {
300- TransactionLocation (blockHash, txIndex) <- blockchain.getTransactionLocation(req.txHash)
301- Block (header, body) <- blockchain.getBlockByHash(blockHash)
302- stx <- body.transactionList.lift(txIndex)
303- } yield TransactionResponse (stx, Some (header), Some (txIndex))
304- }
318+ maybeTxPendingResponse.map { txPending =>
319+ txPending.orElse {
320+ for {
321+ TransactionLocation (blockHash, txIndex) <- blockchain.getTransactionLocation(txHash)
322+ Block (header, body) <- blockchain.getBlockByHash(blockHash)
323+ stx <- body.transactionList.lift(txIndex)
324+ } yield TransactionData (stx, Some (header), Some (txIndex))
305325 }
306326 }
307-
308- maybeTxResponse.map(txResponse => Right (GetTransactionByHashResponse (txResponse)))
309327 }
310328
311329 def getTransactionReceipt (req : GetTransactionReceiptRequest ): ServiceResponse [GetTransactionReceiptResponse ] =
@@ -361,20 +379,32 @@ class EthService(
361379 *
362380 * @return the tx requested or None if the client doesn't have the block or if there's no tx in the that index
363381 */
364- def getTransactionByBlockHashAndIndexRequest (
382+ def getTransactionByBlockHashAndIndex (
365383 req : GetTransactionByBlockHashAndIndexRequest
366- ): ServiceResponse [GetTransactionByBlockHashAndIndexResponse ] = Future {
367- import req ._
368- val maybeTransactionResponse = blockchain.getBlockByHash(blockHash).flatMap { blockWithTx =>
369- val blockTxs = blockWithTx.body.transactionList
370- if (transactionIndex >= 0 && transactionIndex < blockTxs.size)
371- Some (
372- TransactionResponse (blockTxs(transactionIndex.toInt), Some (blockWithTx.header), Some (transactionIndex.toInt))
373- )
374- else None
384+ ): ServiceResponse [GetTransactionByBlockHashAndIndexResponse ] =
385+ getTransactionByBlockHashAndIndex(req.blockHash, req.transactionIndex)
386+ .map(td => Right (GetTransactionByBlockHashAndIndexResponse (td.map(TransactionResponse (_)))))
387+
388+ /**
389+ * eth_getRawTransactionByBlockHashAndIndex returns raw transaction data of a transaction with the block hash and index of which it was mined
390+ *
391+ * @return the tx requested or None if the client doesn't have the block or if there's no tx in the that index
392+ */
393+ def getRawTransactionByBlockHashAndIndex (
394+ req : GetTransactionByBlockHashAndIndexRequest
395+ ): ServiceResponse [RawTransactionResponse ] =
396+ getTransactionByBlockHashAndIndex(req.blockHash, req.transactionIndex)
397+ .map(asRawTransactionResponse)
398+
399+
400+ private def getTransactionByBlockHashAndIndex (blockHash : ByteString , transactionIndex : BigInt ) =
401+ Future {
402+ for {
403+ blockWithTx <- blockchain.getBlockByHash(blockHash)
404+ blockTxs = blockWithTx.body.transactionList if transactionIndex >= 0 && transactionIndex < blockTxs.size
405+ transaction <- blockTxs.lift(transactionIndex.toInt)
406+ } yield TransactionData (transaction, Some (blockWithTx.header), Some (transactionIndex.toInt))
375407 }
376- Right (GetTransactionByBlockHashAndIndexResponse (maybeTransactionResponse))
377- }
378408
379409 /**
380410 * Implements the eth_getUncleByBlockHashAndIndex method that fetches an uncle from a certain index in a requested block.
@@ -697,28 +727,52 @@ class EthService(
697727 }
698728 }
699729
700- def getTransactionByBlockNumberAndIndexRequest (
730+ /**
731+ * eth_getTransactionByBlockNumberAndIndex Returns the information about a transaction with
732+ * the block number and index of which it was mined.
733+ *
734+ * @param req block number and index
735+ * @return transaction
736+ */
737+ def getTransactionByBlockNumberAndIndex (
701738 req : GetTransactionByBlockNumberAndIndexRequest
702739 ): ServiceResponse [GetTransactionByBlockNumberAndIndexResponse ] = Future {
703- import req ._
740+ getTransactionDataByBlockNumberAndIndex(req.block, req.transactionIndex)
741+ .map(_.map(TransactionResponse (_)))
742+ .map(GetTransactionByBlockNumberAndIndexResponse )
743+ }
744+
745+ /**
746+ * eth_getRawTransactionByBlockNumberAndIndex Returns raw transaction data of a transaction
747+ * with the block number and index of which it was mined.
748+ *
749+ * @param req block number and ordering in which a transaction is mined within its block
750+ * @return raw transaction data
751+ */
752+ def getRawTransactionByBlockNumberAndIndex (
753+ req : GetTransactionByBlockNumberAndIndexRequest
754+ ): ServiceResponse [RawTransactionResponse ] = Future {
755+ getTransactionDataByBlockNumberAndIndex(req.block, req.transactionIndex)
756+ .map(x => x.map(_.stx))
757+ .map(RawTransactionResponse )
758+ }
759+
760+ private def getTransactionDataByBlockNumberAndIndex (block : BlockParam , transactionIndex : BigInt ) = {
704761 resolveBlock(block)
705762 .map { blockWithTx =>
706763 val blockTxs = blockWithTx.block.body.transactionList
707764 if (transactionIndex >= 0 && transactionIndex < blockTxs.size)
708- GetTransactionByBlockNumberAndIndexResponse (
709- Some (
710- TransactionResponse (
711- blockTxs(transactionIndex.toInt),
712- Some (blockWithTx.block.header),
713- Some (transactionIndex.toInt)
714- )
765+ Some (
766+ TransactionData (
767+ blockTxs(transactionIndex.toInt),
768+ Some (blockWithTx.block.header),
769+ Some (transactionIndex.toInt)
715770 )
716771 )
717- else
718- GetTransactionByBlockNumberAndIndexResponse (None )
772+ else None
719773 }
720774 .left
721- .flatMap(_ => Right (GetTransactionByBlockNumberAndIndexResponse ( None ) ))
775+ .flatMap(_ => Right (None ))
722776 }
723777
724778 def getBalance (req : GetBalanceRequest ): ServiceResponse [GetBalanceResponse ] = {
0 commit comments