From eceee020a0d9273db4dfcc189cf6cbfcc75a070b Mon Sep 17 00:00:00 2001 From: fluency03 Date: Sat, 28 Apr 2018 00:42:43 +0100 Subject: [PATCH] add test for allTransAreValid --- .../com/fluency03/blockchain/core/Block.scala | 4 --- .../com/fluency03/blockchain/CryptoTest.scala | 2 ++ .../fluency03/blockchain/core/BlockTest.scala | 35 ++++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/scala/com/fluency03/blockchain/core/Block.scala b/src/main/scala/com/fluency03/blockchain/core/Block.scala index 183bdde..e562c19 100644 --- a/src/main/scala/com/fluency03/blockchain/core/Block.scala +++ b/src/main/scala/com/fluency03/blockchain/core/Block.scala @@ -41,10 +41,6 @@ case class Block(header: BlockHeader, transactions: Seq[Transaction], hash: Stri def hasValidHeaderHash: Boolean = hash == header.hash def allTransAreValid(uTxOs: mutable.Map[Outpoint, TxOut]): Boolean = allTransValidOf(transactions, index, uTxOs) -// transactions match { -// case Nil => false -// case init :+ last => validateCoinbaseTx(last, index) && init.forall(tx => tx.isValid(uTxOs)) -// } def noDuplicateTxIn(): Boolean = noDuplicateTxInOf(transactions) diff --git a/src/test/scala/com/fluency03/blockchain/CryptoTest.scala b/src/test/scala/com/fluency03/blockchain/CryptoTest.scala index d44053e..477a4e4 100644 --- a/src/test/scala/com/fluency03/blockchain/CryptoTest.scala +++ b/src/test/scala/com/fluency03/blockchain/CryptoTest.scala @@ -18,6 +18,8 @@ class CryptoTest extends FlatSpec with Matchers { generatePublicKey(pair.getPrivate) shouldEqual pair.getPublic recoverPublicKey(publicKeyToHex(pair.getPublic)) shouldEqual pair.getPublic recoverPrivateKey(privateKeyToHex(pair.getPrivate)) shouldEqual pair.getPrivate + recoverPublicKey(pair.getPublic.toHex) shouldEqual pair.getPublic + recoverPrivateKey(pair.getPrivate.toHex) shouldEqual pair.getPrivate } diff --git a/src/test/scala/com/fluency03/blockchain/core/BlockTest.scala b/src/test/scala/com/fluency03/blockchain/core/BlockTest.scala index 2aee42d..47a4f2b 100644 --- a/src/test/scala/com/fluency03/blockchain/core/BlockTest.scala +++ b/src/test/scala/com/fluency03/blockchain/core/BlockTest.scala @@ -1,14 +1,17 @@ package com.fluency03.blockchain package core +import java.security.KeyPair + import com.fluency03.blockchain.core.BlockHeader.hashOfBlockHeader -import com.fluency03.blockchain.core.Transaction.createCoinbaseTx +import com.fluency03.blockchain.core.Transaction.{COINBASE_AMOUNT, createCoinbaseTx, signTxIn, updateUTxOs} import org.json4s.JValue import org.json4s.JsonAST.{JArray, JInt, JObject, JString} import org.json4s.JsonDSL._ import org.json4s.native.JsonMethods.parse import org.scalatest.{FlatSpec, Matchers} +import scala.collection.mutable import scala.io.Source class BlockTest extends FlatSpec with Matchers { @@ -145,5 +148,35 @@ class BlockTest extends FlatSpec with Matchers { parse(newBlock.toString) shouldEqual json } + "allTransAreValid" should "check whether all transactions of a Block are valid." in { + val uTxOs: mutable.Map[Outpoint, TxOut] = mutable.Map.empty[Outpoint, TxOut] + genesis.allTransAreValid(uTxOs) shouldEqual true + + val pair1 = Crypto.generateKeyPair() + val address1 = pair1.getPublic.toHex + + val ts = getCurrentTimestamp + val tx: Transaction = Transaction( + Seq(TxIn(Outpoint(genesis.transactions.head.id, 0), "")), + Seq(TxOut(address1, COINBASE_AMOUNT)), + ts) + + val nextBlock = Block.mineNextBlock(genesis, "This is next Block!", ts, genesis.difficulty, Seq(tx)) + nextBlock.allTransAreValid(uTxOs) shouldEqual false + + val uTxOs2 = updateUTxOs(genesis.transactions, uTxOs.toMap) + uTxOs ++= uTxOs2 + nextBlock.allTransAreValid(uTxOs) shouldEqual false + + val genesisPrivate: String = Source.fromResource("private-key").getLines.mkString + val keyPair = new KeyPair(Crypto.recoverPublicKey(genesisMiner), Crypto.recoverPrivateKey(genesisPrivate)) + val signedTxIns = tx.txIns.map(txIn => signTxIn(tx.id.hex2Bytes, txIn, keyPair, uTxOs)).filter(_.isDefined).map(_.get) + signedTxIns.length shouldEqual tx.txIns.length + val signedTx = Transaction(signedTxIns, Seq(TxOut(address1, COINBASE_AMOUNT)), ts) + + val validNewBlock = Block.mineNextBlock(genesis, "This is next Block!", ts, genesis.difficulty, + Seq(signedTx, createCoinbaseTx(1, address1, ts))) + validNewBlock.allTransAreValid(uTxOs) shouldEqual true + } }