From 983993ff8da3adff2bf45fd875c3a83cf178ce0c Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sun, 29 Apr 2018 14:45:00 +0200 Subject: [PATCH 1/8] add some todos and onGetNetwork --- .../api/actors/BlockchainActor.scala | 13 ++++++++++--- .../blockchain/api/actors/BlocksActor.scala | 10 +++++++++- .../blockchain/api/actors/NetworkActor.scala | 10 +++++++++- .../blockchain/api/routes/BlockRoutes.scala | 9 +++++++++ .../api/routes/BlockchainRoutes.scala | 11 +++++++++++ .../blockchain/api/routes/NetworkRoutes.scala | 18 ++++++++++++------ .../blockchain/api/routes/package.scala | 1 + .../api/actors/NetworkActorTest.scala | 13 +++++++++++-- 8 files changed, 72 insertions(+), 13 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 2c0f293..e0620df 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/BlockchainActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/BlockchainActor.scala @@ -31,6 +31,16 @@ class BlockchainActor extends ActorSupport { case _ => unhandled _ } + /** + * TODO (Chang): new APIS: + * - AddBlockOnBlockchain + * - GetBlockFromBlockchain + * - CheckBlockchainIsValid + * - GetTransactionOfABlock + * - MineNextBlock + * + */ + private def onGetBlockchain(): Unit = sender() ! blockchainOpt private def onCreateBlockchain(): Unit = @@ -46,8 +56,5 @@ class BlockchainActor extends ActorSupport { sender() ! SuccessMsg(s"Blockchain deleted.") } else sender() ! FailureMsg(s"Blockchain does not exist.") - // TODO (Chang): APIs for adding new Block on the chain - - } diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala index d03a204..8e16726 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala @@ -35,6 +35,15 @@ class BlocksActor extends ActorSupport { case _ => unhandled _ } + /** + * TODO (Chang): new APIS: + * - CreateBlock + * - GetBlock (onChain or offChain) + * - GetTransactionOfABlock + * - AddBlockOnChain + * + */ + private[this] def onGetBlocks(): Unit = sender() ! blocks.values.toSeq private[this] def onCreateBlock(block: Block): Unit = { @@ -55,5 +64,4 @@ class BlocksActor extends ActorSupport { } - } diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala index 3b0b838..41b73fe 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala @@ -7,7 +7,10 @@ import com.fluency03.blockchain.api.actors.NetworkActor._ import com.fluency03.blockchain.api.actors.PeerActor.GetPublicKeys import com.fluency03.blockchain.core.Peer +import scala.concurrent.Future + object NetworkActor { + final case object GetNetwork final case object GetPeers final case class CreatePeer(name: String) final case class GetPeer(name: String) @@ -29,6 +32,7 @@ class NetworkActor extends ActorSupport { // TODO (Chang): need persistence def receive: Receive = { + case GetNetwork => onGetNetwork() case GetPeers => onGetPeers() case CreatePeer(name) => onCreatePeer(name) case GetPeer(name) => onGetPeer(name) @@ -36,7 +40,11 @@ class NetworkActor extends ActorSupport { case _ => unhandled _ } - private def onGetPeers(): Unit = sender() ! context.children.map(_.path.name).toSet + private def onGetNetwork(): Unit = sender() ! context.children.map(_.path.name).toSet + + private def onGetPeers(): Unit = Future.sequence(context.children.map(p => { + (p ? GetPublicKeys).mapTo[Set[String]].map(keys => p.path.name -> keys) + })).map(_.toMap).pipeTo(sender()) private def onCreatePeer(name: String): Unit = if (context.child(name).isDefined) sender() ! FailureMsg(s"Peer $name has been created.") diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala index 172f9d8..53e1c24 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala @@ -20,6 +20,15 @@ trait BlockRoutes extends RoutesSupport { def blocksActor: ActorRef + /** + * TODO (Chang): new APIS: + * - CreateBlock + * - GetBlock (onChain or offChain) + * - GetTransactionOfABlock + * - AddBlockOnChain + * + */ + lazy val blockRoutes: Route = path(BLOCKS) { get { diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/BlockchainRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/BlockchainRoutes.scala index fb0ef81..816a1b8 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/BlockchainRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/BlockchainRoutes.scala @@ -18,6 +18,17 @@ trait BlockchainRoutes extends RoutesSupport { def blockchainActor: ActorRef + /** + * TODO (Chang): new APIS: + * - AddBlockOnBlockchain + * - GetBlockFromBlockchain + * - CheckBlockchainIsValid + * - GetTransactionOfABlock + * - MineNextBlock + * + * + */ + lazy val blockchainRoutes: Route = pathPrefix(BLOCKCHAIN) { pathEnd { diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala index 64991df..619e680 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala @@ -9,7 +9,7 @@ import akka.http.scaladsl.server.directives.MethodDirectives.{delete, get, post} import akka.http.scaladsl.server.directives.PathDirectives.path import akka.http.scaladsl.server.directives.RouteDirectives.complete import akka.pattern.ask -import com.fluency03.blockchain.api.actors.NetworkActor.{CreatePeer, DeletePeer, GetPeer, GetPeers} +import com.fluency03.blockchain.api.actors.NetworkActor._ import com.fluency03.blockchain.api.{FailureMsg, Message, SuccessMsg} import com.fluency03.blockchain.core.{Peer, PeerSimple} @@ -21,9 +21,15 @@ trait NetworkRoutes extends RoutesSupport { def networkActor: ActorRef lazy val networkRoutes: Route = + path(NETWORK) { + get { + val network: Future[Set[String]] = (networkActor ? GetNetwork).mapTo[Set[String]] + complete(network) + } + } ~ path(PEERS) { get { - val peers: Future[Set[String]] = (networkActor ? GetPeers).mapTo[Set[String]] + val peers: Future[Map[String, Set[String]]] = (networkActor ? GetPeers).mapTo[Map[String, Set[String]]] complete(peers) } } ~ @@ -41,10 +47,10 @@ trait NetworkRoutes extends RoutesSupport { val maybePeer: Future[Option[Peer]] = (networkActor ? GetPeer(name)).mapTo[Option[Peer]] rejectEmptyResponse { complete(maybePeer) } } ~ - delete { - val peerDeleted: Future[Message] = (networkActor ? DeletePeer(name)).mapTo[Message] - onSuccess(peerDeleted) { respondOnDeletion } - } + delete { + val peerDeleted: Future[Message] = (networkActor ? DeletePeer(name)).mapTo[Message] + onSuccess(peerDeleted) { respondOnDeletion } + } } } diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/package.scala b/src/main/scala/com/fluency03/blockchain/api/routes/package.scala index 29d2cbd..8990774 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/package.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/package.scala @@ -21,6 +21,7 @@ package object routes { val BLOCK = "block" // network + val NETWORK = "network" val PEERS = "peers" val PEER = "peer" diff --git a/src/test/scala/com/fluency03/blockchain/api/actors/NetworkActorTest.scala b/src/test/scala/com/fluency03/blockchain/api/actors/NetworkActorTest.scala index 7b4116a..be65646 100644 --- a/src/test/scala/com/fluency03/blockchain/api/actors/NetworkActorTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/actors/NetworkActorTest.scala @@ -20,9 +20,12 @@ class NetworkActorTest extends TestKit(ActorSystem("NetworkActorTest")) with Imp "Respond with a Set of Peers." in { NetworkActor.props shouldEqual Props[NetworkActor] - networkActor ! GetPeers + networkActor ! GetNetwork expectMsg(Set.empty[String]) + networkActor ! GetPeers + expectMsg(Map.empty[String, Set[String]]) + val name = "peer" networkActor ! CreatePeer(name) expectMsg(SuccessMsg(s"Peer $name created.")) @@ -30,9 +33,15 @@ class NetworkActorTest extends TestKit(ActorSystem("NetworkActorTest")) with Imp networkActor ! CreatePeer(name) expectMsg(FailureMsg(s"Peer $name has been created.")) - networkActor ! GetPeers + networkActor ! GetNetwork expectMsg(Set(name)) + networkActor ! GetPeers + val peers = expectMsgType[Map[String, Set[String]]] + peers.size shouldEqual 1 + peers.contains(name) shouldEqual true + peers(name).size shouldEqual 1 + networkActor ! GetPeer(name) val peerOpt = expectMsgType[Some[Peer]] peerOpt.isDefined shouldEqual true From 5e1a315d37e78cdef476a52206736ec09f8d3b82 Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sun, 29 Apr 2018 15:10:06 +0200 Subject: [PATCH 2/8] add GetPeers based on names --- .../blockchain/api/actors/NetworkActor.scala | 11 +++++++---- .../blockchain/api/routes/NetworkRoutes.scala | 14 ++++++++++++-- .../blockchain/api/actors/NetworkActorTest.scala | 10 ++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala index 41b73fe..bd953f1 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala @@ -12,6 +12,7 @@ import scala.concurrent.Future object NetworkActor { final case object GetNetwork final case object GetPeers + final case class GetPeers(names: Set[String]) final case class CreatePeer(name: String) final case class GetPeer(name: String) final case class DeletePeer(name: String) @@ -34,6 +35,7 @@ class NetworkActor extends ActorSupport { def receive: Receive = { case GetNetwork => onGetNetwork() case GetPeers => onGetPeers() + case GetPeers(names) => onGetPeers(names) case CreatePeer(name) => onCreatePeer(name) case GetPeer(name) => onGetPeer(name) case DeletePeer(name) => onDeletePeer(name) @@ -46,6 +48,11 @@ class NetworkActor extends ActorSupport { (p ? GetPublicKeys).mapTo[Set[String]].map(keys => p.path.name -> keys) })).map(_.toMap).pipeTo(sender()) + private def onGetPeers(names: Set[String]): Unit = Future.sequence(context.children + .filter(p => names.contains(p.path.name)) + .map(p => { (p ? GetPublicKeys).mapTo[Set[String]].map(keys => p.path.name -> keys) }) + ).map(_.toMap).pipeTo(sender()) + private def onCreatePeer(name: String): Unit = if (context.child(name).isDefined) sender() ! FailureMsg(s"Peer $name has been created.") else { @@ -67,8 +74,4 @@ class NetworkActor extends ActorSupport { sender() ! SuccessMsg(s"Peer $name deleted.") } else sender() ! FailureMsg(s"Peer $name does not exist.") - // TODO (Chang): APIs for selecting Peers based on Seq of ids - - - } diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala index 619e680..4abf69c 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala @@ -2,6 +2,7 @@ package com.fluency03.blockchain.api.routes import akka.actor.ActorRef import akka.event.Logging +import akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers.CsvSeq import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route @@ -29,8 +30,17 @@ trait NetworkRoutes extends RoutesSupport { } ~ path(PEERS) { get { - val peers: Future[Map[String, Set[String]]] = (networkActor ? GetPeers).mapTo[Map[String, Set[String]]] - complete(peers) + parameters( 'names.as(CsvSeq[String]) ? ) { names => + if (names.isDefined) { + val peers: Future[Map[String, Set[String]]] = + (networkActor ? GetPeers(names.get.toSet)).mapTo[Map[String, Set[String]]] + complete(peers) + } else { + val peers: Future[Map[String, Set[String]]] = + (networkActor ? GetPeers).mapTo[Map[String, Set[String]]] + complete(peers) + } + } } } ~ pathPrefix(PEER) { diff --git a/src/test/scala/com/fluency03/blockchain/api/actors/NetworkActorTest.scala b/src/test/scala/com/fluency03/blockchain/api/actors/NetworkActorTest.scala index be65646..2e78763 100644 --- a/src/test/scala/com/fluency03/blockchain/api/actors/NetworkActorTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/actors/NetworkActorTest.scala @@ -26,6 +26,9 @@ class NetworkActorTest extends TestKit(ActorSystem("NetworkActorTest")) with Imp networkActor ! GetPeers expectMsg(Map.empty[String, Set[String]]) + networkActor ! GetPeers(Set("somename")) + expectMsg(Map.empty[String, Set[String]]) + val name = "peer" networkActor ! CreatePeer(name) expectMsg(SuccessMsg(s"Peer $name created.")) @@ -42,6 +45,13 @@ class NetworkActorTest extends TestKit(ActorSystem("NetworkActorTest")) with Imp peers.contains(name) shouldEqual true peers(name).size shouldEqual 1 + networkActor ! GetPeers(Set("somename")) + expectMsg(Map.empty[String, Set[String]]) + + networkActor ! GetPeers(Set(name)) + val peers2 = expectMsgType[Map[String, Set[String]]] + peers2 shouldEqual peers + networkActor ! GetPeer(name) val peerOpt = expectMsgType[Some[Peer]] peerOpt.isDefined shouldEqual true From 3043e68c892dcfeb60e899a0b58b412f4be0a44c Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sun, 29 Apr 2018 15:24:54 +0200 Subject: [PATCH 3/8] fix PeerSimple cannot be treated as entity --- src/main/scala/com/fluency03/blockchain/core/Peer.scala | 7 ++----- src/main/scala/com/fluency03/blockchain/package.scala | 5 +++++ .../scala/com/fluency03/blockchain/core/PeerTest.scala | 5 ++++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/scala/com/fluency03/blockchain/core/Peer.scala b/src/main/scala/com/fluency03/blockchain/core/Peer.scala index 94e2f9b..69c24fb 100644 --- a/src/main/scala/com/fluency03/blockchain/core/Peer.scala +++ b/src/main/scala/com/fluency03/blockchain/core/Peer.scala @@ -1,7 +1,4 @@ package com.fluency03.blockchain.core -trait PeerSimple { - def name: String -} - -case class Peer(name: String, publicKeys: Set[String]) extends PeerSimple +case class PeerSimple(name: String) +case class Peer(name: String, publicKeys: Set[String]) diff --git a/src/main/scala/com/fluency03/blockchain/package.scala b/src/main/scala/com/fluency03/blockchain/package.scala index 4c7e5e9..25474fd 100644 --- a/src/main/scala/com/fluency03/blockchain/package.scala +++ b/src/main/scala/com/fluency03/blockchain/package.scala @@ -5,6 +5,7 @@ import java.security.{MessageDigest, PrivateKey, PublicKey} import java.time.Instant import com.fluency03.blockchain.Crypto.{privateKeyToHex, publicKeyToHex} +import com.fluency03.blockchain.core.{Peer, PeerSimple} import org.bouncycastle.util.encoders.{Base64, Hex} import org.json4s.{Formats, NoTypeHints} import org.json4s.native.Serialization @@ -50,6 +51,10 @@ package object blockchain { def toHex: String = privateKeyToHex(privateKey) } + implicit class PeerImplicit(val peer: Peer) { + def toSimple: PeerSimple = PeerSimple(peer.name) + } + /** * Generate SHA256 Hash from a input String. diff --git a/src/test/scala/com/fluency03/blockchain/core/PeerTest.scala b/src/test/scala/com/fluency03/blockchain/core/PeerTest.scala index c95d101..619c589 100644 --- a/src/test/scala/com/fluency03/blockchain/core/PeerTest.scala +++ b/src/test/scala/com/fluency03/blockchain/core/PeerTest.scala @@ -8,8 +8,11 @@ class PeerTest extends FlatSpec with Matchers { val p = Peer("peer", Set("abcd")) p.name shouldEqual "peer" p.publicKeys shouldEqual Set("abcd") - p shouldBe a[PeerSimple] p shouldBe a[Peer] + p should not be a[PeerSimple] + val ps = p.toSimple + ps shouldBe a[PeerSimple] + ps.name shouldEqual "peer" } } From 12f47c5b6ab97717d6f38f7becd001c0b19fb0c0 Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sun, 29 Apr 2018 15:49:37 +0200 Subject: [PATCH 4/8] add GetTransactions based on ids --- .../api/actors/BlockchainActor.scala | 5 ++++- .../api/actors/TransactionsActor.scala | 17 ++++++++++------- .../blockchain/api/routes/BlockRoutes.scala | 3 +-- .../blockchain/api/routes/NetworkRoutes.scala | 18 ++++++------------ .../api/routes/TransactionRoutes.scala | 10 ++++++---- .../api/actors/TransactionsActorTest.scala | 9 +++++++++ .../api/routes/BlockRoutesTest.scala | 3 ++- .../api/routes/BlockchainRoutesTest.scala | 3 ++- .../api/routes/NetworkRoutesTest.scala | 3 ++- .../api/routes/TransactionRoutesTest.scala | 3 ++- 10 files changed, 44 insertions(+), 30 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 e0620df..99de84c 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/BlockchainActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/BlockchainActor.scala @@ -3,7 +3,9 @@ package com.fluency03.blockchain.api.actors import akka.actor.{ActorSelection, Props} import com.fluency03.blockchain.api.actors.BlockchainActor._ import com.fluency03.blockchain.api._ -import com.fluency03.blockchain.core.Blockchain +import com.fluency03.blockchain.core.{Block, Blockchain} + +import scala.collection.mutable object BlockchainActor { final case object GetBlockchain @@ -23,6 +25,7 @@ class BlockchainActor extends ActorSupport { // TODO (Chang): need persistence var blockchainOpt: Option[Blockchain] = None + var hashIndexMapping = mutable.Map.empty[String, Int] def receive: Receive = { case GetBlockchain => onGetBlockchain() diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/TransactionsActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/TransactionsActor.scala index d6e273d..b644aa8 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/TransactionsActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/TransactionsActor.scala @@ -9,9 +9,10 @@ import scala.collection.mutable object TransactionsActor { final case object GetTransactions + final case class GetTransactions(ids: Set[String]) final case class CreateTransaction(tx: Transaction) - final case class GetTransaction(hash: String) - final case class DeleteTransaction(hash: String) + final case class GetTransaction(id: String) + final case class DeleteTransaction(id: String) def props: Props = Props[TransactionsActor] } @@ -30,14 +31,19 @@ class TransactionsActor extends ActorSupport { def receive: Receive = { case GetTransactions => onGetTransactions() + case GetTransactions(ids) => onGetTransactions(ids) case CreateTransaction(tx) => onCreateTransaction(tx) - case GetTransaction(hash) => onGetTransaction(hash) - case DeleteTransaction(hash) => onDeleteTransaction(hash) + case GetTransaction(id) => onGetTransaction(id) + case DeleteTransaction(id) => onDeleteTransaction(id) case _ => unhandled _ } private def onGetTransactions(): Unit = sender() ! currentTransactions.values.toSeq + private def onGetTransactions(ids: Set[String]): Unit = sender() ! currentTransactions.filterKeys( + k => ids.contains(k) + ).values.toSeq + private def onCreateTransaction(tx: Transaction): Unit = { if (currentTransactions.contains(tx.id)) sender() ! FailureMsg(s"Transaction ${tx.id} already exists.") else { @@ -54,7 +60,4 @@ class TransactionsActor extends ActorSupport { sender() ! SuccessMsg(s"Transaction $id deleted.") } else sender() ! FailureMsg(s"Transaction $id does not exist.") - // TODO (Chang): APIs for selecting transactions based on Seq of ids - - } diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala index 53e1c24..6e36ac1 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala @@ -2,14 +2,13 @@ package com.fluency03.blockchain.api.routes import akka.actor.ActorRef import akka.event.Logging -import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.http.scaladsl.server.directives.MethodDirectives.{delete, get, post} import akka.http.scaladsl.server.directives.PathDirectives.path import akka.http.scaladsl.server.directives.RouteDirectives.complete import akka.pattern.ask -import com.fluency03.blockchain.api.{Blocks, FailureMsg, Message, SuccessMsg} +import com.fluency03.blockchain.api.{Blocks, Message} import com.fluency03.blockchain.api.actors.BlocksActor._ import com.fluency03.blockchain.core.Block diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala index 4abf69c..12f4a3e 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala @@ -2,16 +2,15 @@ package com.fluency03.blockchain.api.routes import akka.actor.ActorRef import akka.event.Logging -import akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers.CsvSeq -import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.http.scaladsl.server.directives.MethodDirectives.{delete, get, post} import akka.http.scaladsl.server.directives.PathDirectives.path import akka.http.scaladsl.server.directives.RouteDirectives.complete +import akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers.CsvSeq import akka.pattern.ask +import com.fluency03.blockchain.api.Message import com.fluency03.blockchain.api.actors.NetworkActor._ -import com.fluency03.blockchain.api.{FailureMsg, Message, SuccessMsg} import com.fluency03.blockchain.core.{Peer, PeerSimple} import scala.concurrent.Future @@ -31,15 +30,10 @@ trait NetworkRoutes extends RoutesSupport { path(PEERS) { get { parameters( 'names.as(CsvSeq[String]) ? ) { names => - if (names.isDefined) { - val peers: Future[Map[String, Set[String]]] = - (networkActor ? GetPeers(names.get.toSet)).mapTo[Map[String, Set[String]]] - complete(peers) - } else { - val peers: Future[Map[String, Set[String]]] = - (networkActor ? GetPeers).mapTo[Map[String, Set[String]]] - complete(peers) - } + val peers: Future[Map[String, Set[String]]] = + if (names.isDefined) (networkActor ? GetPeers(names.get.toSet)).mapTo[Map[String, Set[String]]] + else (networkActor ? GetPeers).mapTo[Map[String, Set[String]]] + complete(peers) } } } ~ diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/TransactionRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/TransactionRoutes.scala index 3f241b2..ae24724 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/TransactionRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/TransactionRoutes.scala @@ -2,15 +2,15 @@ package com.fluency03.blockchain.api.routes import akka.actor.ActorRef import akka.event.Logging -import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.http.scaladsl.server.directives.MethodDirectives.{delete, get, post} import akka.http.scaladsl.server.directives.PathDirectives.path import akka.http.scaladsl.server.directives.RouteDirectives.complete +import akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers.CsvSeq import akka.pattern.ask -import com.fluency03.blockchain.api.{FailureMsg, Message, SuccessMsg, Transactions} import com.fluency03.blockchain.api.actors.TransactionsActor._ +import com.fluency03.blockchain.api.{Message, Transactions} import com.fluency03.blockchain.core.Transaction import scala.concurrent.Future @@ -22,8 +22,10 @@ trait TransactionRoutes extends RoutesSupport { lazy val transRoutes: Route = path(TRANSACTIONS) { - get { - val transactions: Future[Transactions] = (transActor ? GetTransactions).mapTo[Transactions] + parameters( 'ids.as(CsvSeq[String]) ? ) { ids => + val transactions: Future[Transactions] = + if (ids.isDefined) (transActor ? GetTransactions(ids.get.toSet)).mapTo[Transactions] + else (transActor ? GetTransactions).mapTo[Transactions] complete(transactions) } } ~ diff --git a/src/test/scala/com/fluency03/blockchain/api/actors/TransactionsActorTest.scala b/src/test/scala/com/fluency03/blockchain/api/actors/TransactionsActorTest.scala index 5bc716d..d0162e6 100644 --- a/src/test/scala/com/fluency03/blockchain/api/actors/TransactionsActorTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/actors/TransactionsActorTest.scala @@ -25,6 +25,9 @@ class TransactionsActorTest extends TestKit(ActorSystem("TransactionsActorTest") transActor ! GetTransactions expectMsg(Seq.empty[Transaction]) + transActor ! GetTransactions(Set("someid")) + expectMsg(Seq.empty[Transaction]) + val genesisTx: Transaction = createCoinbaseTx(0, genesisMiner, genesisTimestamp) transActor ! CreateTransaction(genesisTx) expectMsg(SuccessMsg(s"Transaction ${genesisTx.id} created.")) @@ -35,6 +38,12 @@ class TransactionsActorTest extends TestKit(ActorSystem("TransactionsActorTest") transActor ! GetTransactions expectMsg(Seq(genesisTx)) + transActor ! GetTransactions(Set("someid")) + expectMsg(Seq.empty[Transaction]) + + transActor ! GetTransactions(Set(genesisTx.id)) + expectMsg(Seq(genesisTx)) + transActor ! GetTransaction(genesisTx.id) expectMsg(Some(genesisTx)) diff --git a/src/test/scala/com/fluency03/blockchain/api/routes/BlockRoutesTest.scala b/src/test/scala/com/fluency03/blockchain/api/routes/BlockRoutesTest.scala index 486af66..aff84b5 100644 --- a/src/test/scala/com/fluency03/blockchain/api/routes/BlockRoutesTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/routes/BlockRoutesTest.scala @@ -1,8 +1,9 @@ package com.fluency03.blockchain.api.routes import akka.http.scaladsl.testkit.ScalatestRouteTest +import com.fluency03.blockchain.api.JsonSupport import org.scalatest.{Matchers, WordSpec} -class BlockRoutesTest extends WordSpec with Matchers with ScalatestRouteTest { +class BlockRoutesTest extends WordSpec with Matchers with ScalatestRouteTest with JsonSupport { } diff --git a/src/test/scala/com/fluency03/blockchain/api/routes/BlockchainRoutesTest.scala b/src/test/scala/com/fluency03/blockchain/api/routes/BlockchainRoutesTest.scala index 2b8a8a1..ed3a460 100644 --- a/src/test/scala/com/fluency03/blockchain/api/routes/BlockchainRoutesTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/routes/BlockchainRoutesTest.scala @@ -1,9 +1,10 @@ package com.fluency03.blockchain.api.routes import akka.http.scaladsl.testkit.ScalatestRouteTest +import com.fluency03.blockchain.api.JsonSupport import org.scalatest.{Matchers, WordSpec} -class BlockchainRoutesTest extends WordSpec with Matchers with ScalatestRouteTest { +class BlockchainRoutesTest extends WordSpec with Matchers with ScalatestRouteTest with JsonSupport { diff --git a/src/test/scala/com/fluency03/blockchain/api/routes/NetworkRoutesTest.scala b/src/test/scala/com/fluency03/blockchain/api/routes/NetworkRoutesTest.scala index f5f013d..28e9567 100644 --- a/src/test/scala/com/fluency03/blockchain/api/routes/NetworkRoutesTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/routes/NetworkRoutesTest.scala @@ -1,8 +1,9 @@ package com.fluency03.blockchain.api.routes import akka.http.scaladsl.testkit.ScalatestRouteTest +import com.fluency03.blockchain.api.JsonSupport import org.scalatest.{Matchers, WordSpec} -class NetworkRoutesTest extends WordSpec with Matchers with ScalatestRouteTest { +class NetworkRoutesTest extends WordSpec with Matchers with ScalatestRouteTest with JsonSupport { } diff --git a/src/test/scala/com/fluency03/blockchain/api/routes/TransactionRoutesTest.scala b/src/test/scala/com/fluency03/blockchain/api/routes/TransactionRoutesTest.scala index 7788748..6dbe8cc 100644 --- a/src/test/scala/com/fluency03/blockchain/api/routes/TransactionRoutesTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/routes/TransactionRoutesTest.scala @@ -1,8 +1,9 @@ package com.fluency03.blockchain.api.routes import akka.http.scaladsl.testkit.ScalatestRouteTest +import com.fluency03.blockchain.api.JsonSupport import org.scalatest.{Matchers, WordSpec} -class TransactionRoutesTest extends WordSpec with Matchers with ScalatestRouteTest { +class TransactionRoutesTest extends WordSpec with Matchers with ScalatestRouteTest with JsonSupport { } From e4db873612dc4b488415891c2a70d6e185c38ca5 Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sun, 29 Apr 2018 16:01:25 +0200 Subject: [PATCH 5/8] add GetBlocks based on hashes --- .../fluency03/blockchain/api/actors/BlocksActor.scala | 5 +++++ .../fluency03/blockchain/api/routes/BlockRoutes.scala | 7 +++++-- .../blockchain/api/actors/BlocksActorTest.scala | 9 +++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala index 8e16726..ce03d09 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala @@ -9,6 +9,7 @@ import scala.collection.mutable object BlocksActor { final case object GetBlocks + final case class GetBlocks(hashes: Set[String]) final case class CreateBlock(block: Block) final case class GetBlock(hash: String) final case class DeleteBlock(hash: String) @@ -29,6 +30,7 @@ class BlocksActor extends ActorSupport { def receive: Receive = { case GetBlocks => onGetBlocks() + case GetBlocks(hashes) => onGetBlocks(hashes) case CreateBlock(block) => onCreateBlock(block) case GetBlock(hash) => onGetBlock(hash) case DeleteBlock(hash) => onDeleteBlock(hash) @@ -45,6 +47,9 @@ class BlocksActor extends ActorSupport { */ private[this] def onGetBlocks(): Unit = sender() ! blocks.values.toSeq + private[this] def onGetBlocks(hashes: Set[String]): Unit = sender() ! blocks.filterKeys( + k => hashes.contains(k) + ).values.toSeq private[this] def onCreateBlock(block: Block): Unit = { if (blocks.contains(block.hash)) sender() ! FailureMsg(s"Block ${block.hash} already exists.") diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala index 6e36ac1..d3b1351 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/BlockRoutes.scala @@ -7,6 +7,7 @@ import akka.http.scaladsl.server.Route import akka.http.scaladsl.server.directives.MethodDirectives.{delete, get, post} import akka.http.scaladsl.server.directives.PathDirectives.path import akka.http.scaladsl.server.directives.RouteDirectives.complete +import akka.http.scaladsl.unmarshalling.PredefinedFromStringUnmarshallers.CsvSeq import akka.pattern.ask import com.fluency03.blockchain.api.{Blocks, Message} import com.fluency03.blockchain.api.actors.BlocksActor._ @@ -30,8 +31,10 @@ trait BlockRoutes extends RoutesSupport { lazy val blockRoutes: Route = path(BLOCKS) { - get { - val blocks: Future[Blocks] = (blocksActor ? GetBlocks).mapTo[Blocks] + parameters( 'hashes.as(CsvSeq[String]) ? ) { hashes => + val blocks: Future[Blocks] = + if (hashes.isDefined) (blocksActor ? GetBlocks(hashes.get.toSet)).mapTo[Blocks] + else (blocksActor ? GetBlocks).mapTo[Blocks] complete(blocks) } } ~ diff --git a/src/test/scala/com/fluency03/blockchain/api/actors/BlocksActorTest.scala b/src/test/scala/com/fluency03/blockchain/api/actors/BlocksActorTest.scala index 958751c..ee51ed5 100644 --- a/src/test/scala/com/fluency03/blockchain/api/actors/BlocksActorTest.scala +++ b/src/test/scala/com/fluency03/blockchain/api/actors/BlocksActorTest.scala @@ -23,6 +23,9 @@ class BlocksActorTest extends TestKit(ActorSystem("BlocksActorTest")) with Impli blocksActor ! GetBlocks expectMsg(Seq.empty[Block]) + blocksActor ! GetBlocks(Set("somehash")) + expectMsg(Seq.empty[Block]) + blocksActor ! CreateBlock(Block.genesisBlock) expectMsg(SuccessMsg(s"Block ${Block.genesisBlock.hash} created.")) @@ -32,6 +35,12 @@ class BlocksActorTest extends TestKit(ActorSystem("BlocksActorTest")) with Impli blocksActor ! GetBlocks expectMsg(Seq(Block.genesisBlock)) + blocksActor ! GetBlocks(Set("somehash")) + expectMsg(Seq.empty[Block]) + + blocksActor ! GetBlocks(Set(Block.genesisBlock.hash)) + expectMsg(Seq(Block.genesisBlock)) + blocksActor ! GetBlock(Block.genesisBlock.hash) expectMsg(Some(Block.genesisBlock)) From 8c983df7fd4ee8e8404b41556fe1f08d7a284c21 Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sun, 29 Apr 2018 17:05:19 +0200 Subject: [PATCH 6/8] add api docs --- README.md | 8 ++++++++ .../blockchain/api/routes/BlockchainRoutes.scala | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2083c46..cd6e0c2 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,11 @@ Inspired by: - [Naivecoin](https://github.com/lhartikk/naivecoin) of [@lhartikk](https://github.com/lhartikk) REST API service is built on the open source projects [akka](https://github.com/akka/akka) and [akka-http](https://github.com/akka/akka-http). + +API Documentation on Postman: [blockchain-in-scala](https://documenter.getpostman.com/view/1231202/blockchain-in-scala/RVu8iTUP) + +Start the service, run the following Class: + +``` +com.fluency03.blockchain.api.Server +``` diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/BlockchainRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/BlockchainRoutes.scala index 816a1b8..c32da2c 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/BlockchainRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/BlockchainRoutes.scala @@ -26,7 +26,6 @@ trait BlockchainRoutes extends RoutesSupport { * - GetTransactionOfABlock * - MineNextBlock * - * */ lazy val blockchainRoutes: Route = From 7dfeddb3825f472b43f0863a8f56397a55e0214a Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sun, 29 Apr 2018 17:19:43 +0200 Subject: [PATCH 7/8] add sbt-assembly --- README.md | 2 +- build.sbt | 5 ++++- project/plugins.sbt | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cd6e0c2..040f8a4 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ REST API service is built on the open source projects [akka](https://github.com/ API Documentation on Postman: [blockchain-in-scala](https://documenter.getpostman.com/view/1231202/blockchain-in-scala/RVu8iTUP) -Start the service, run the following Class: +Start the service, run this Class: ``` com.fluency03.blockchain.api.Server diff --git a/build.sbt b/build.sbt index ebd2f83..5e54ee7 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,7 @@ organization := "com.fluency03" name := "blockchain-in-scala" -version := "0.0.2" +version := "0.0.6" scalaVersion := "2.12.0" @@ -43,3 +43,6 @@ libraryDependencies ++= { "org.bouncycastle" % "bcprov-jdk15on" % "1.59" ) } ++ httpDependencies ++ testDependencies + + +mainClass in assembly := Some("com.fluency03.blockchain.api.Server") diff --git a/project/plugins.sbt b/project/plugins.sbt index 5c39736..b34f37d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,3 +6,4 @@ addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") addSbtPlugin("com.artima.supersafe" %% "sbtplugin" % "1.1.3") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.2.4") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") From 0e578199e8c542abde040afccc1a7b3031eec13e Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sun, 29 Apr 2018 17:38:23 +0200 Subject: [PATCH 8/8] ad api todos --- .../blockchain/api/actors/BlocksActor.scala | 17 +++++++------- .../blockchain/api/actors/NetworkActor.scala | 7 ++++++ .../blockchain/api/actors/PeerActor.scala | 7 ++++++ .../api/actors/TransactionsActor.scala | 23 ++++++++++++------- .../blockchain/api/routes/NetworkRoutes.scala | 6 +++++ .../api/routes/TransactionRoutes.scala | 7 ++++++ 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala index ce03d09..a10b252 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/BlocksActor.scala @@ -26,7 +26,7 @@ class BlocksActor extends ActorSupport { val transActor: ActorSelection = context.actorSelection(PARENT_UP + TRANS_ACTOR_NAME) // TODO (Chang): need persistence - var blocks = mutable.Map.empty[String, Block] + var blocksPool = mutable.Map.empty[String, Block] def receive: Receive = { case GetBlocks => onGetBlocks() @@ -46,24 +46,25 @@ class BlocksActor extends ActorSupport { * */ - private[this] def onGetBlocks(): Unit = sender() ! blocks.values.toSeq - private[this] def onGetBlocks(hashes: Set[String]): Unit = sender() ! blocks.filterKeys( + private[this] def onGetBlocks(): Unit = sender() ! blocksPool.values.toSeq + + private[this] def onGetBlocks(hashes: Set[String]): Unit = sender() ! blocksPool.filterKeys( k => hashes.contains(k) ).values.toSeq private[this] def onCreateBlock(block: Block): Unit = { - if (blocks.contains(block.hash)) sender() ! FailureMsg(s"Block ${block.hash} already exists.") + if (blocksPool.contains(block.hash)) sender() ! FailureMsg(s"Block ${block.hash} already exists.") else { - blocks += (block.hash -> block) + blocksPool += (block.hash -> block) sender() ! SuccessMsg(s"Block ${block.hash} created.") } } - private[this] def onGetBlock(hash: String): Unit = sender() ! blocks.get(hash) + private[this] def onGetBlock(hash: String): Unit = sender() ! blocksPool.get(hash) private[this] def onDeleteBlock(hash: String): Unit = { - if (blocks.contains(hash)) { - blocks -= hash + if (blocksPool.contains(hash)) { + blocksPool -= hash sender() ! SuccessMsg(s"Block $hash deleted.") } else sender() ! FailureMsg(s"Block $hash does not exist.") } diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala index bd953f1..c953beb 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/NetworkActor.scala @@ -32,6 +32,13 @@ class NetworkActor extends ActorSupport { // TODO (Chang): need persistence + /** + * TODO (Chang): + * - Remove wallet + * - Sign transaction + * + */ + def receive: Receive = { case GetNetwork => onGetNetwork() case GetPeers => onGetPeers() diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/PeerActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/PeerActor.scala index bcde51b..92b1d2d 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/PeerActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/PeerActor.scala @@ -27,6 +27,13 @@ class PeerActor extends ActorSupport { val wallets = mutable.Map.empty[String, Wallet] val others = mutable.Map.empty[String, Peer] + /** + * TODO (Chang): + * - Remove wallet + * - Sign transactions + * + */ + def receive: Receive = { case GetPublicKeys => sender() ! wallets.values.map(_.address).toSet case CreateWallet => sender() ! addWallet() diff --git a/src/main/scala/com/fluency03/blockchain/api/actors/TransactionsActor.scala b/src/main/scala/com/fluency03/blockchain/api/actors/TransactionsActor.scala index b644aa8..1fc0699 100644 --- a/src/main/scala/com/fluency03/blockchain/api/actors/TransactionsActor.scala +++ b/src/main/scala/com/fluency03/blockchain/api/actors/TransactionsActor.scala @@ -22,13 +22,20 @@ class TransactionsActor extends ActorSupport { override def postStop(): Unit = log.info("{} stopped!", this.getClass.getSimpleName) // TODO (Chang): need persistence - val currentTransactions: mutable.Map[String, Transaction] = mutable.Map.empty[String, Transaction] + val transPool: mutable.Map[String, Transaction] = mutable.Map.empty[String, Transaction] val uTxOs: mutable.Map[Outpoint, TxOut] = mutable.Map.empty[Outpoint, TxOut] val blockchainActor: ActorSelection = context.actorSelection(PARENT_UP + BLOCKCHAIN_ACTOR_NAME) val blockActor: ActorSelection = context.actorSelection(PARENT_UP + BLOCKS_ACTOR_NAME) val networkActor: ActorSelection = context.actorSelection(PARENT_UP + NETWORK_ACTOR_NAME) + /** + * TODO (Chang): + * - Update transaction + * - Sign transaction + * + */ + def receive: Receive = { case GetTransactions => onGetTransactions() case GetTransactions(ids) => onGetTransactions(ids) @@ -38,25 +45,25 @@ class TransactionsActor extends ActorSupport { case _ => unhandled _ } - private def onGetTransactions(): Unit = sender() ! currentTransactions.values.toSeq + private def onGetTransactions(): Unit = sender() ! transPool.values.toSeq - private def onGetTransactions(ids: Set[String]): Unit = sender() ! currentTransactions.filterKeys( + private def onGetTransactions(ids: Set[String]): Unit = sender() ! transPool.filterKeys( k => ids.contains(k) ).values.toSeq private def onCreateTransaction(tx: Transaction): Unit = { - if (currentTransactions.contains(tx.id)) sender() ! FailureMsg(s"Transaction ${tx.id} already exists.") + if (transPool.contains(tx.id)) sender() ! FailureMsg(s"Transaction ${tx.id} already exists.") else { - currentTransactions += (tx.id -> tx) + transPool += (tx.id -> tx) sender() ! SuccessMsg(s"Transaction ${tx.id} created.") } } - private def onGetTransaction(id: String): Unit = sender() ! currentTransactions.get(id) + private def onGetTransaction(id: String): Unit = sender() ! transPool.get(id) private def onDeleteTransaction(id: String): Unit = - if (currentTransactions contains id) { - currentTransactions -= id + if (transPool contains id) { + transPool -= id sender() ! SuccessMsg(s"Transaction $id deleted.") } else sender() ! FailureMsg(s"Transaction $id does not exist.") diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala index 12f4a3e..d4f301a 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/NetworkRoutes.scala @@ -20,6 +20,12 @@ trait NetworkRoutes extends RoutesSupport { def networkActor: ActorRef + /** + * TODO (Chang): + * - Sign transaction + * + */ + lazy val networkRoutes: Route = path(NETWORK) { get { diff --git a/src/main/scala/com/fluency03/blockchain/api/routes/TransactionRoutes.scala b/src/main/scala/com/fluency03/blockchain/api/routes/TransactionRoutes.scala index ae24724..4f63ace 100644 --- a/src/main/scala/com/fluency03/blockchain/api/routes/TransactionRoutes.scala +++ b/src/main/scala/com/fluency03/blockchain/api/routes/TransactionRoutes.scala @@ -20,6 +20,13 @@ trait TransactionRoutes extends RoutesSupport { def transActor: ActorRef + /** + * TODO (Chang): + * - Update transaction + * - Sign transaction + * + */ + lazy val transRoutes: Route = path(TRANSACTIONS) { parameters( 'ids.as(CsvSeq[String]) ? ) { ids =>