Skip to content

Commit

Permalink
add GetTxOfBlock
Browse files Browse the repository at this point in the history
  • Loading branch information
fluency03 committed May 1, 2018
1 parent e1ba541 commit f4c5e81
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ com.fluency03.blockchain.api.Server

- Complete APIs' Todos
- Make states in actor persistent (using Akka Persistent)
- Concurrent collections?
- Make data distributed within cluster of peer (using Akka Cluster)
- Block propagation among peers
- etc.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ object BlockchainActor {
final case object CreateBlockchain
final case object DeleteBlockchain
final case class GetBlock(hash: String)
final case class GetTxOfBlock(id: String, hash: String)

def props: Props = Props[BlockchainActor]
}
Expand All @@ -26,22 +27,21 @@ class BlockchainActor extends ActorSupport {

// TODO (Chang): need persistence
var blockchainOpt: Option[Blockchain] = None
var hashIndexMapping = mutable.Map.empty[String, Int]
val hashIndexMapping = mutable.Map.empty[String, Int]

def receive: Receive = {
case GetBlockchain => onGetBlockchain()
case CreateBlockchain => onCreateBlockchain()
case DeleteBlockchain => onDeleteBlockchain()
case GetBlock(hash) => onGetBlock(hash)
case GetTxOfBlock(id, hash) => onGetTxOfBlock(id, hash)
case _ => unhandled _
}

/**
* TODO (Chang): new APIS:
* - AddBlockOnBlockchain
* - GetBlockFromBlockchain
* - CheckBlockchainIsValid
* - GetTransactionOfABlock
* - MineNextBlock
*
*/
Expand All @@ -67,7 +67,16 @@ class BlockchainActor extends ActorSupport {
sender() ! SuccessMsg(s"Blockchain deleted.")
} else sender() ! FailureMsg(s"Blockchain does not exist.")

private def onGetBlock(hash: String): Unit = sender() ! {
private def onGetBlock(hash: String): Unit = sender() ! getBlock(hash)

private def onGetTxOfBlock(id: String, hash: String): Unit = sender() ! {
getBlock(hash) match {
case Some(block) => block.transactions.find(_.id == id)
case None => None
}
}

private def getBlock(hash: String): Option[Block] = {
hashIndexMapping.get(hash) match {
case Some(index) => blockchainOpt match {
case Some(blockchain) => Some(blockchain.chain(index))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import akka.http.scaladsl.server.directives.RouteDirectives.complete
import akka.pattern.ask
import com.fluency03.blockchain.api.Message
import com.fluency03.blockchain.api.actors.BlockchainActor._
import com.fluency03.blockchain.core.{Block, Blockchain}
import com.fluency03.blockchain.core.{Block, Blockchain, Transaction}

import scala.concurrent.Future

Expand All @@ -21,9 +21,7 @@ trait BlockchainRoutes extends RoutesSupport {
/**
* TODO (Chang): new APIS:
* - AddBlockOnBlockchain
* - GetBlockFromBlockchain
* - CheckBlockchainIsValid
* - GetTransactionOfABlock
* - MineNextBlock
*
*/
Expand All @@ -43,11 +41,22 @@ trait BlockchainRoutes extends RoutesSupport {
val blockchainDeleted: Future[Message] = (blockchainActor ? DeleteBlockchain).mapTo[Message]
onSuccess(blockchainDeleted) { respondOnDeletion }
}
}
path(BLOCK / Segment) { hash =>
get {
val maybeBlock: Future[Option[Block]] = (blockchainActor ? GetBlock(hash)).mapTo[Option[Block]]
rejectEmptyResponse { complete(maybeBlock) }
} ~
pathPrefix(BLOCK / Segment) { hash =>
pathEnd {
get {
val maybeBlock: Future[Option[Block]] = (blockchainActor ? GetBlock(hash)).mapTo[Option[Block]]
rejectEmptyResponse {
complete(maybeBlock)
}
}
} ~
path(TRANSACTION / Segment) { id =>
get {
log.info(s"$id; $hash")
val maybeTx: Future[Option[Transaction]] = (blockchainActor ? GetTxOfBlock(id, hash)).mapTo[Option[Transaction]]
rejectEmptyResponse { complete(maybeTx) }
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{DefaultTimeout, ImplicitSender, TestKit}
import com.fluency03.blockchain.api.actors.BlockchainActor._
import com.fluency03.blockchain.api.{FailureMsg, SuccessMsg}
import com.fluency03.blockchain.core.Blockchain
import com.fluency03.blockchain.core.{Block, Blockchain}
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}

import scala.concurrent.duration._
Expand Down Expand Up @@ -39,8 +39,18 @@ class BlockchainActorTest extends TestKit(ActorSystem("BlockchainActorTest")) wi
blockchainActor ! GetBlock("somehash")
expectMsg(None)

blockchainActor ! GetBlock(blockchain.chain.head.hash)
expectMsg(Some(blockchain.chain.head))
val genesis = Block.genesisBlock
blockchainActor ! GetBlock(genesis.hash)
expectMsg(Some(genesis))

blockchainActor ! GetTxOfBlock(genesis.transactions.head.id, genesis.hash)
expectMsg(Some(genesis.transactions.head))

blockchainActor ! GetTxOfBlock("aa", genesis.hash)
expectMsg(None)

blockchainActor ! GetTxOfBlock(genesis.transactions.head.id, "bb")
expectMsg(None)

blockchainActor ! DeleteBlockchain
expectMsg(SuccessMsg(s"Blockchain deleted."))
Expand Down

0 comments on commit f4c5e81

Please sign in to comment.