Skip to content

Commit

Permalink
move hash of Block and id of Transaction into case class parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
fluency03 committed Apr 26, 2018
1 parent b2b1a5f commit b1a7a30
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 51 deletions.
1 change: 0 additions & 1 deletion src/main/scala/com/fluency03/blockchain/api/package.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.fluency03.blockchain

import akka.http.scaladsl.model.{StatusCode, StatusCodes}
import com.fluency03.blockchain.core.{Block, Peer, Transaction}

package object api {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ trait BlockRoutes extends RoutesSupport {
post {
entity(as[Block]) { block =>
val blockCreated: Future[Message] = (blocksActor ? CreateBlock(block)).mapTo[Message]
onSuccess(blockCreated) {
case s: SuccessMsg => complete((StatusCodes.Created, s))
case f: FailureMsg => complete((StatusCodes.Conflict, f))
}
onSuccess(blockCreated) { respondOnCreation }
}
}
} ~
Expand All @@ -46,10 +43,7 @@ trait BlockRoutes extends RoutesSupport {
} ~
delete {
val blockDeleted: Future[Message] = (blocksActor ? DeleteBlock(hash)).mapTo[Message]
onSuccess(blockDeleted) {
case s: SuccessMsg => complete((StatusCodes.OK, s))
case f: FailureMsg => complete((StatusCodes.NotFound, f))
}
onSuccess(blockDeleted) { respondOnDeletion }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ 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.RouteDirectives.complete
import akka.pattern.ask
import com.fluency03.blockchain.api.{FailureMsg, Message, SuccessMsg}
import com.fluency03.blockchain.api.Message
import com.fluency03.blockchain.api.actors.BlockchainActor._
import com.fluency03.blockchain.core.Blockchain
import org.json4s.JsonAST.JValue

import scala.concurrent.Future

Expand All @@ -28,20 +26,12 @@ trait BlockchainRoutes extends RoutesSupport {
rejectEmptyResponse { complete(blockchain) }
} ~
post {
entity(as[JValue]) { _ =>
val blockchainCreated: Future[Message] = (blockchainActor ? CreateBlockchain).mapTo[Message]
onSuccess(blockchainCreated) {
case s: SuccessMsg => complete((StatusCodes.Created, s))
case f: FailureMsg => complete((StatusCodes.Conflict, f))
}
}
val blockchainCreated: Future[Message] = (blockchainActor ? CreateBlockchain).mapTo[Message]
onSuccess(blockchainCreated) { respondOnCreation }
} ~
delete {
val blockchainDeleted: Future[Message] = (blockchainActor ? DeleteBlockchain).mapTo[Message]
onSuccess(blockchainDeleted) {
case s: SuccessMsg => complete((StatusCodes.OK, s))
case f: FailureMsg => complete((StatusCodes.NotFound, f))
}
onSuccess(blockchainDeleted) { respondOnDeletion }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ trait NetworkRoutes extends RoutesSupport {
post {
entity(as[PeerSimple]) { peer =>
val peerCreated: Future[Message] = (networkActor ? CreatePeer(peer.name)).mapTo[Message]
onSuccess(peerCreated) {
case s: SuccessMsg => complete((StatusCodes.Created, s))
case f: FailureMsg => complete((StatusCodes.Conflict, f))
}
onSuccess(peerCreated) { respondOnCreation }
}
}
} ~
Expand All @@ -46,10 +43,7 @@ trait NetworkRoutes extends RoutesSupport {
} ~
delete {
val peerDeleted: Future[Message] = (networkActor ? DeletePeer(name)).mapTo[Message]
onSuccess(peerDeleted) {
case s: SuccessMsg => complete((StatusCodes.OK, s))
case f: FailureMsg => complete((StatusCodes.NotFound, f))
}
onSuccess(peerDeleted) { respondOnDeletion }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.fluency03.blockchain.api.routes

import akka.actor.ActorSystem
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.{RequestContext, StandardRoute}
import akka.http.scaladsl.server.directives.RouteDirectives.complete
import akka.util.Timeout
import com.fluency03.blockchain.api.JsonSupport
import com.fluency03.blockchain.api.{FailureMsg, JsonSupport, Message, SuccessMsg}

import scala.concurrent.Future
import scala.concurrent.duration._

trait RoutesSupport extends JsonSupport {
Expand All @@ -13,4 +17,14 @@ trait RoutesSupport extends JsonSupport {
// Required by the `ask` (?) method
implicit lazy val timeout: Timeout = Timeout(5.seconds) // usually we'd obtain the timeout from the system's configuration

def respondOnCreation(m: Message): StandardRoute = m match {
case s: SuccessMsg => complete((StatusCodes.Created, s))
case f: FailureMsg => complete((StatusCodes.Conflict, f))
}

def respondOnDeletion(m: Message): StandardRoute = m match {
case s: SuccessMsg => complete((StatusCodes.OK, s))
case f: FailureMsg => complete((StatusCodes.NotFound, f))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ trait TransactionRoutes extends RoutesSupport {
post {
entity(as[Transaction]) { tx =>
val txCreated: Future[Message] = (transActor ? CreateTransaction(tx)).mapTo[Message]
onSuccess(txCreated) {
case s: SuccessMsg => complete((StatusCodes.Created, s))
case f: FailureMsg => complete((StatusCodes.Conflict, f))
}
onSuccess(txCreated) { respondOnCreation }
}
}
} ~
Expand All @@ -46,10 +43,7 @@ trait TransactionRoutes extends RoutesSupport {
} ~
delete {
val txDeleted: Future[Message] = (transActor ? DeleteTransaction(id)).mapTo[Message]
onSuccess(txDeleted) {
case s: SuccessMsg => complete((StatusCodes.OK, s))
case f: FailureMsg => complete((StatusCodes.NotFound, f))
}
onSuccess(txDeleted) { respondOnDeletion }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,4 @@ package object routes {
}






}
10 changes: 6 additions & 4 deletions src/main/scala/com/fluency03/blockchain/core/Block.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package core

import com.fluency03.blockchain.core.BlockHeader.hashOfHeaderFields
import com.fluency03.blockchain.core.Transaction.createCoinbaseTx
import org.json4s.JsonAST.JObject
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods.{compact, render}
import org.json4s.{Extraction, JValue}
Expand All @@ -13,7 +12,7 @@ import org.json4s.{Extraction, JValue}
* @param header Header of current Block
* @param transactions Seq of Transactions included in current Block
*/
case class Block(header: BlockHeader, transactions: Seq[Transaction] = Seq()) {
case class Block(header: BlockHeader, transactions: Seq[Transaction], hash: String) {
lazy val index: Int = header.index
lazy val previousHash: String = header.previousHash
lazy val data: String = header.data
Expand All @@ -22,7 +21,7 @@ case class Block(header: BlockHeader, transactions: Seq[Transaction] = Seq()) {
lazy val difficulty: Int = header.difficulty
lazy val nonce: Int = header.nonce

lazy val hash: String = header.hash
// lazy val hash: String = header.hash

def nextTrial(): Block = Block(header.nextTrial(), transactions)

Expand All @@ -39,13 +38,16 @@ case class Block(header: BlockHeader, transactions: Seq[Transaction] = Seq()) {

def hasValidMerkleHash: Boolean = merkleHash == Merkle.computeRoot(transactions)

def toJson: JValue = ("header" -> header.toJson) ~ ("transactions" -> transactions.map(_.toJson)) ~ ("hash" -> hash)
def toJson: JValue = Extraction.decompose(this)

override def toString: String = compact(render(toJson))
}

object Block {

def apply(header: BlockHeader, transactions: Seq[Transaction] = Seq()): Block =
Block(header, transactions, header.hash)

def apply(
index: Int,
previousHash: String,
Expand Down
6 changes: 6 additions & 0 deletions src/main/scala/com/fluency03/blockchain/core/Blockchain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package core

import com.fluency03.blockchain.core.Blockchain._
import com.fluency03.blockchain.core.Block.canBeChained
import org.json4s.JsonDSL._
import org.json4s.{Extraction, JValue}
import org.json4s.native.JsonMethods.{compact, render}

/**
* Blockchain with difficulty and the chain of Blocks.
Expand Down Expand Up @@ -32,6 +35,9 @@ case class Blockchain(difficulty: Int = 4, chain: Seq[Block] = Seq(Block.genesis
case _ => isValidChain(chain)
}

def toJson: JValue = Extraction.decompose(this)

override def toString: String = compact(render(toJson))

}

Expand Down
13 changes: 10 additions & 3 deletions src/main/scala/com/fluency03/blockchain/core/Transaction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ case class Outpoint(id: String, index: Int)
case class TxIn(previousOut: Outpoint, signature: String)
case class TxOut(address: String, amount: Long)

case class Transaction(txIns: Seq[TxIn], txOuts: Seq[TxOut], timestamp: Long) {
lazy val id: String = hashOfTransaction(this)
case class Transaction(txIns: Seq[TxIn], txOuts: Seq[TxOut], timestamp: Long, id: String) {
// lazy val id: String = hashOfTransaction(this)

def addTxIn(in: TxIn): Transaction = Transaction(in +: txIns, txOuts, timestamp)

Expand All @@ -32,13 +32,16 @@ case class Transaction(txIns: Seq[TxIn], txOuts: Seq[TxOut], timestamp: Long) {

def removeTxOut(txOut: TxOut): Transaction = Transaction(txIns, txOuts.filter(_ != txOut), timestamp)

def toJson: JValue = Extraction.decompose(this).asInstanceOf[JObject] ~ ("id" -> id)
def toJson: JValue = Extraction.decompose(this)

override def toString: String = compact(render(toJson))
}

object Transaction {

def apply(txIns: Seq[TxIn], txOuts: Seq[TxOut], timestamp: Long): Transaction =
Transaction(txIns, txOuts, timestamp, hashOfTransaction(txIns, txOuts, timestamp))

lazy val COINBASE_AMOUNT: Int = 50

def createCoinbase(blockIndex: Int): TxIn = TxIn(Outpoint("", blockIndex), "")
Expand All @@ -53,6 +56,10 @@ object Transaction {
sha256Of(tx.txIns.map(tx => tx.previousOut.id + tx.previousOut.index).mkString,
tx.txOuts.map(tx => tx.address + tx.amount).mkString, tx.timestamp.toString)

def hashOfTransaction(txIns: Seq[TxIn], txOuts: Seq[TxOut], timestamp: Long): String =
sha256Of(txIns.map(tx => tx.previousOut.id + tx.previousOut.index).mkString,
txOuts.map(tx => tx.address + tx.amount).mkString, timestamp.toString)

def signTxIn(txId: String, txIn: TxIn, keyPair: KeyPair, unspentTxOuts: mutable.Map[Outpoint, TxOut]): Option[TxIn] =
signTxIn(txId.hex2Bytes, txIn, keyPair, unspentTxOuts)

Expand Down

0 comments on commit b1a7a30

Please sign in to comment.