From d583b4c28b486d7a88a0e9a3f1701bdf0161165c Mon Sep 17 00:00:00 2001 From: fluency03 Date: Fri, 4 May 2018 14:06:33 +0200 Subject: [PATCH] add test for MineNextBlock --- .../api/actors/BlockchainActor.scala | 7 ++-- .../blockchain/api/actors/TxPoolActor.scala | 7 ++-- .../blockchain/api/routes/TxPoolRoutes.scala | 2 +- .../api/actors/BlockchainActorTest.scala | 33 +++++++++++++++++-- .../api/actors/TxPoolActorTest.scala | 18 ++++++++-- 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/BlockchainActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/BlockchainActor.scala index 6f0aa75..12efb56 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/BlockchainActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/BlockchainActor.scala @@ -137,10 +137,11 @@ class BlockchainActor extends ActorSupport { if (ids.isEmpty) sender() ! Some(blockchain.mineNextBlock(data, Seq.empty[Transaction])) else { val maybeTrans: Future[Seq[Transaction]] = - (txPoolActor ? TxPoolActor.GetTransactions(ids.toSet)).mapTo[Seq[Transaction]] + (txPoolActor ? TxPoolActor.GetTransactions(ids)).mapTo[Seq[Transaction]] + val theSender: ActorRef = sender() maybeTrans onComplete { - case Success(trans) => sender() ! Some(blockchain.mineNextBlock(data, trans)) - case Failure(_) => sender() ! None + case Success(trans) => theSender ! Some(blockchain.mineNextBlock(data, trans)) + case Failure(_) => theSender ! None } } case None => diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/TxPoolActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/TxPoolActor.scala index de949a4..2a4dc74 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/TxPoolActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/TxPoolActor.scala @@ -10,7 +10,7 @@ import scala.collection.mutable object TxPoolActor { final case object GetTransactions - final case class GetTransactions(ids: Set[String]) + final case class GetTransactions(ids: Seq[String]) final case class CreateTransaction(tx: Transaction) final case class GetTransaction(id: String) final case class DeleteTransaction(id: String) @@ -48,9 +48,8 @@ class TxPoolActor extends ActorSupport { private def onGetTransactions(): Unit = sender() ! transPool.values.toSeq - private def onGetTransactions(ids: Set[String]): Unit = sender() ! transPool.filterKeys( - k => ids.contains(k) - ).values.toSeq + private def onGetTransactions(ids: Seq[String]): Unit = + sender() ! ids.map(id => transPool.get(id)).filter(_.isDefined).map(_.get) private def onCreateTransaction(tx: Transaction): Unit = if (transPool.contains(tx.id)) sender() ! FailureMsg(s"Transaction ${tx.id} already exists in the Pool.") diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/TxPoolRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/TxPoolRoutes.scala index 6479013..4ad9104 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/TxPoolRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/TxPoolRoutes.scala @@ -32,7 +32,7 @@ trait TxPoolRoutes extends RoutesSupport { path(TRANSACTIONS) { parameters( 'ids.as(CsvSeq[String]).? ) { idsOpt => val transactions: Future[Transactions] = idsOpt match { - case Some(ids) => (txPoolActor ? GetTransactions(ids.toSet)).mapTo[Transactions] + case Some(ids) => (txPoolActor ? GetTransactions(ids)).mapTo[Transactions] case None => (txPoolActor ? GetTransactions).mapTo[Transactions] } complete(transactions) diff --git a/src/test/scala/com/fluency03/blockchain/api/actors/BlockchainActorTest.scala b/src/test/scala/com/fluency03/blockchain/api/actors/BlockchainActorTest.scala index 7f2fd66..21b7c3b 100644 --- a/src/test/scala/com/fluency03/blockchain/api/actors/BlockchainActorTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/actors/BlockchainActorTest.scala @@ -1,11 +1,14 @@ package com.fluency03.blockchain.api.actors -import akka.actor.{ActorRef, ActorSelection, ActorSystem, Props} +import akka.actor.{ActorRef, ActorSystem, Props} import akka.testkit.{DefaultTimeout, ImplicitSender, TestKit} import com.fluency03.blockchain.api.actors.BlockPoolActor.CreateBlock import com.fluency03.blockchain.api.actors.BlockchainActor._ -import com.fluency03.blockchain.api.{BLOCKCHAIN_ACTOR_NAME, BLOCK_POOL_ACTOR_NAME, FailureMsg, SuccessMsg} +import com.fluency03.blockchain.api._ +import com.fluency03.blockchain.api.actors.TxPoolActor.CreateTransaction +import com.fluency03.blockchain.core.Transaction.createCoinbaseTx import com.fluency03.blockchain.core.{Block, Blockchain, Transaction} +import com.fluency03.blockchain.{genesisMiner, genesisTimestamp} import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike} import scala.concurrent.duration._ @@ -19,6 +22,7 @@ class BlockchainActorTest extends TestKit(ActorSystem("BlockchainActorTest")) wi val blockchainActor: ActorRef = system.actorOf(Props[BlockchainActor], BLOCKCHAIN_ACTOR_NAME) val blockPoolActor: ActorRef = system.actorOf(Props[BlockPoolActor], BLOCK_POOL_ACTOR_NAME) + val txPoolActor: ActorRef = system.actorOf(Props[TxPoolActor], TX_POOL_ACTOR_NAME) "A BlockchainActor" should { "Respond with a Blockchain." in { @@ -80,7 +84,7 @@ class BlockchainActorTest extends TestKit(ActorSystem("BlockchainActorTest")) wi expectMsg(None) } - within(30 seconds) { + within(15 seconds) { blockchainActor ! AddBlockFromPool(genesis.hash) expectMsg(SuccessMsg(s"New Block ${genesis.hash} added on the chain.")) @@ -102,6 +106,29 @@ class BlockchainActorTest extends TestKit(ActorSystem("BlockchainActorTest")) wi actualBlock.previousHash shouldEqual genesis.hash } + val tx1: Transaction = createCoinbaseTx(1, genesisMiner, genesisTimestamp) + val tx2: Transaction = createCoinbaseTx(2, genesisMiner, genesisTimestamp) + val tx3: Transaction = createCoinbaseTx(3, genesisMiner, genesisTimestamp) + txPoolActor ! CreateTransaction(tx1) + expectMsg(SuccessMsg(s"Transaction ${tx1.id} created in the Pool.")) + + txPoolActor ! CreateTransaction(tx2) + expectMsg(SuccessMsg(s"Transaction ${tx2.id} created in the Pool.")) + + txPoolActor ! CreateTransaction(tx3) + expectMsg(SuccessMsg(s"Transaction ${tx3.id} created in the Pool.")) + + within(15 seconds) { + blockchainActor ! MineNextBlock("next", Seq(tx1.id, tx2.id, tx3.id)) + val actualBlock = expectMsgType[Some[Block]].get + actualBlock.data shouldEqual "next" + actualBlock.transactions shouldEqual Seq(tx1, tx2, tx3) + actualBlock.difficulty shouldEqual blockchain.difficulty + actualBlock.index shouldEqual 1 + actualBlock.hasValidHash shouldEqual true + actualBlock.previousHash shouldEqual genesis.hash + } + blockchainActor ! DeleteBlockchain expectMsg(SuccessMsg("Blockchain deleted.")) diff --git a/src/test/scala/com/fluency03/blockchain/api/actors/TxPoolActorTest.scala b/src/test/scala/com/fluency03/blockchain/api/actors/TxPoolActorTest.scala index 590a3af..34cb7fa 100644 --- a/src/test/scala/com/fluency03/blockchain/api/actors/TxPoolActorTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/actors/TxPoolActorTest.scala @@ -25,7 +25,7 @@ class TxPoolActorTest extends TestKit(ActorSystem("TransactionsActorTest")) with txPoolActor ! GetTransactions expectMsg(Seq.empty[Transaction]) - txPoolActor ! GetTransactions(Set("someid")) + txPoolActor ! GetTransactions(Seq("someid")) expectMsg(Seq.empty[Transaction]) val genesisTx: Transaction = createCoinbaseTx(0, genesisMiner, genesisTimestamp) @@ -38,12 +38,24 @@ class TxPoolActorTest extends TestKit(ActorSystem("TransactionsActorTest")) with txPoolActor ! GetTransactions expectMsg(Seq(genesisTx)) - txPoolActor ! GetTransactions(Set("someid")) + val tx2: Transaction = createCoinbaseTx(2, genesisMiner, genesisTimestamp) + val tx3: Transaction = createCoinbaseTx(3, genesisMiner, genesisTimestamp) + + txPoolActor ! CreateTransaction(tx2) + expectMsg(SuccessMsg(s"Transaction ${tx2.id} created in the Pool.")) + + txPoolActor ! CreateTransaction(tx3) + expectMsg(SuccessMsg(s"Transaction ${tx3.id} created in the Pool.")) + + txPoolActor ! GetTransactions(Seq("someid")) expectMsg(Seq.empty[Transaction]) - txPoolActor ! GetTransactions(Set(genesisTx.id)) + txPoolActor ! GetTransactions(Seq(genesisTx.id)) expectMsg(Seq(genesisTx)) + txPoolActor ! GetTransactions(Seq(genesisTx.id, tx2.id, tx3.id)) + expectMsg(Seq(genesisTx, tx2, tx3)) + txPoolActor ! GetTransaction(genesisTx.id) expectMsg(Some(genesisTx))