Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
5d339b7
make merge method private
catena2w Nov 16, 2015
357b0fb
headoption, 32 bytes puz
kushti Nov 17, 2015
d541cc8
BlockchainBuilder.scala
kushti Nov 17, 2015
9bec7f9
Merkle reimplementation
catena2w Nov 16, 2015
f1630bd
Merge branch 'perma' of github.com:ScorexProject/Scorex-Lagonaki into…
catena2w Nov 17, 2015
ea01db7
Merge branch 'master' of github.com:ScorexProject/Scorex-Lagonaki int…
catena2w Nov 17, 2015
157e312
Fix exceptions on JVM shutdown
catena2w Nov 18, 2015
0cac591
Reformat code
catena2w Nov 18, 2015
01504fb
Merge branch 'master' of github.com:ScorexProject/Scorex-Lagonaki int…
catena2w Nov 18, 2015
db851bf
More merkle test
catena2w Nov 18, 2015
e4f8db7
Fix testApp
catena2w Nov 18, 2015
01314d2
Start work only when miners are ready
catena2w Nov 18, 2015
8ca0fb5
Save calculated hash values
catena2w Nov 18, 2015
ecb49e5
Don't recreate existing Tree
catena2w Nov 18, 2015
eef33d5
TestApp refactoring
catena2w Nov 19, 2015
2cd93ad
MapDBStorage refactoring
catena2w Nov 19, 2015
f9622a9
merkle tree index is Long
catena2w Nov 19, 2015
1a472e8
Put different levels to different files
catena2w Nov 19, 2015
af46a97
unused imports, formatting, styling
kushti Nov 19, 2015
bf0a83d
if-else braces
kushti Nov 19, 2015
6be7e07
code simplification
kushti Nov 19, 2015
0877cbe
not used vals fix
kushti Nov 19, 2015
2a747db
unused commented code removed
kushti Nov 19, 2015
d117aa9
Merge branch 'master' into perma
kushti Nov 19, 2015
134d626
MapDBStorage refactoring
catena2w Nov 23, 2015
ad574b7
Rename MapDBStorage
catena2w Nov 23, 2015
e99b67c
Miners keep their data in mapDB storage
catena2w Nov 23, 2015
014b251
Ask segments from other miners first
catena2w Nov 23, 2015
975200f
Commit only when need
catena2w Nov 23, 2015
de39ba4
Move constants to config
catena2w Nov 24, 2015
bd9eb68
Refactoring
catena2w Nov 24, 2015
849c110
fast Merkle tree tests
catena2w Nov 24, 2015
00f077d
implicit settings
catena2w Nov 24, 2015
83d1da3
rename config file
catena2w Nov 25, 2015
54e389f
pass data storage to miner
catena2w Nov 25, 2015
70b5ea7
Refactor
catena2w Nov 25, 2015
45b61fb
Calc puz from last block
catena2w Nov 25, 2015
5defa81
Perma consensus
catena2w Nov 26, 2015
6d84ee0
Serialization of data blocks
catena2w Nov 26, 2015
e85d657
Use serialization
catena2w Nov 26, 2015
c0da600
Check genesis block
catena2w Nov 26, 2015
a13273c
Is valid block
catena2w Nov 26, 2015
6cd8161
New block generation
catena2w Nov 26, 2015
99048ec
unused import, formatting
kushti Nov 27, 2015
5177046
Merge branch 'master' of github.com:ScorexProject/Scorex-Lagonaki int…
catena2w Nov 27, 2015
d332150
Merge branch 'perma' of github.com:ScorexProject/Scorex-Lagonaki into…
catena2w Nov 27, 2015
3ef1904
Try from block generation
catena2w Nov 27, 2015
bd4b7eb
Create storage folder
catena2w Nov 27, 2015
f9d523e
Hash function from config
catena2w Nov 27, 2015
eab0d9b
Test initialization of dataset
catena2w Nov 27, 2015
fe24051
Score for genesis block
catena2w Nov 27, 2015
93dadf8
Difficulty should be bigint
catena2w Nov 27, 2015
60338b7
Equals block score for all blocks
catena2w Nov 27, 2015
1be31ba
Difficulty algo
catena2w Nov 27, 2015
6d5bf0d
Rename difficulty => target
catena2w Nov 28, 2015
18d7e63
Move constants to config
catena2w Nov 28, 2015
7145ff5
Use nonce size = hash.valueSize
catena2w Nov 28, 2015
f3fd7b4
more debug
catena2w Nov 28, 2015
533c49e
Move average delay to parent ConsensusModule trait
catena2w Nov 28, 2015
81edc6e
Some consensus API
catena2w Nov 28, 2015
d95bd35
Move Json serialization to separate trait
catena2w Nov 28, 2015
ccb28c0
Serialize Array[Byte]
catena2w Nov 28, 2015
221013d
Puz to API route
catena2w Nov 29, 2015
d2836e1
Move average delay to blockchain
catena2w Nov 29, 2015
5583e01
Blocks delay to API
catena2w Nov 29, 2015
68da425
binary serialization
catena2w Nov 29, 2015
a522205
externalizing constants, formatting
kushti Dec 1, 2015
1318c2c
FieldName
kushti Dec 1, 2015
896e8b2
Proofs binary parsing
catena2w Nov 30, 2015
9222ede
PublicKeyLength = EllipticCurveImpl.KeyLength
kushti Dec 1, 2015
e54442e
Merge branch 'master' into perma
kushti Dec 1, 2015
7dd1fed
formatting
kushti Dec 1, 2015
566ca17
Permanent block generation
catena2w Dec 1, 2015
af23f58
Merge remote-tracking branch 'origin/perma' into perma
kushti Dec 1, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scorex-basics/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ libraryDependencies ++=
Dependencies.akka ++
Dependencies.spray ++
Dependencies.testKit ++
Dependencies.db ++
Dependencies.logging ++ Seq(
"org.whispersystems" % "curve25519-java" % "+",
"commons-net" % "commons-net" % "3.+"
Expand Down
44 changes: 26 additions & 18 deletions scorex-basics/src/main/scala/scorex/block/Block.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ import scorex.utils.ScorexLogging
import scala.util.{Failure, Try}

/**
* A block is a an atomic piece of data network participates are agreed on.
*
* A block has:
* - transactions data: a sequence of transactions, where a transaction is an atomic state update.
* Some metadata is possible as well(transactions Merkle tree root, state Merkle tree root etc).
*
* - consensus data to check whether block was generated by a right party in a right way. E.g.
* "baseTarget" & "generatorSignature" fields in the Nxt block structure, nonce & difficulty in the
* Bitcoin block structure.
*
* - a signature(s) of a block generator(s)
*
* - additional data: block structure version no, timestamp etc
*/

trait Block {
* A block is a an atomic piece of data network participates are agreed on.
*
* A block has:
* - transactions data: a sequence of transactions, where a transaction is an atomic state update.
* Some metadata is possible as well(transactions Merkle tree root, state Merkle tree root etc).
*
* - consensus data to check whether block was generated by a right party in a right way. E.g.
* "baseTarget" & "generatorSignature" fields in the Nxt block structure, nonce & difficulty in the
* Bitcoin block structure.
*
* - a signature(s) of a block generator(s)
*
* - additional data: block structure version no, timestamp etc
*/

trait Block extends ScorexLogging {
type ConsensusDataType
type TransactionDataType

Expand Down Expand Up @@ -79,13 +79,21 @@ trait Block {

lazy val bytesWithoutSignature = bytes.dropRight(EllipticCurveImpl.SignatureLength)

def isValid =
consensusModule.isValid(this) &&
def isValid: Boolean = {
val v = consensusModule.isValid(this) &&
transactionModule.isValid(this) &&
transactionModule.history.contains(referenceField.value) &&
EllipticCurveImpl.verify(signerDataField.value.signature,
bytesWithoutSignature,
signerDataField.value.generator.publicKey)
if (!v) log.debug(
s"Block checks: ${consensusModule.isValid(this)} && ${transactionModule.isValid(this)} && " +
s"${transactionModule.history.contains(referenceField.value)} && " +
EllipticCurveImpl.verify(signerDataField.value.signature, bytesWithoutSignature,
signerDataField.value.generator.publicKey)
)
v
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future


trait ConsensusModule[ConsensusBlockData] extends BlockProcessingModule[ConsensusBlockData]{
trait ConsensusModule[ConsensusBlockData] extends BlockProcessingModule[ConsensusBlockData] {

def isValid[TT](block: Block)(implicit transactionModule: TransactionModule[TT]): Boolean

/**
* Fees could go to a single miner(forger) usually, but can go to many parties, e.g. see
* Meni Rosenfeld's Proof-of-Activity proposal http://eprint.iacr.org/2014/452.pdf
*/
* Fees could go to a single miner(forger) usually, but can go to many parties, e.g. see
* Meni Rosenfeld's Proof-of-Activity proposal http://eprint.iacr.org/2014/452.pdf
*/
def feesDistribution(block: Block): Map[Account, Long]

/**
* Get block producers(miners/forgers). Usually one miner produces a block, but in some proposals not
* (see e.g. Meni Rosenfeld's Proof-of-Activity paper http://eprint.iacr.org/2014/452.pdf)
* @param block
* @return
*/
* Get block producers(miners/forgers). Usually one miner produces a block, but in some proposals not
* (see e.g. Meni Rosenfeld's Proof-of-Activity paper http://eprint.iacr.org/2014/452.pdf)
* @param block
* @return
*/
def generators(block: Block): Seq[Account]

def blockScore(block: Block)(implicit transactionModule: TransactionModule[_]): BigInt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ import java.security.MessageDigest
trait CryptographicHash {
import CryptographicHash._

val ValueSize: Int //in bytes
val DigestSize: Int //in bytes

def hash(input: Message): Digest

def hash(input: String): Digest = hash(input.getBytes)

def doubleHash(input: Message): Digest = hash(hash(input))
}

Expand All @@ -37,7 +39,7 @@ object CryptographicHash {
* Hashing functions implementation with sha256 impl from Java SDK
*/
object Sha256 extends CryptographicHash {
override val ValueSize = 32
override val DigestSize = 32

override def hash(input: Array[Byte]) = MessageDigest.getInstance("SHA-256").digest(input)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package scorex.crypto.ads.merkle

import play.api.libs.json._
import scorex.crypto.CryptographicHash._
import scorex.crypto.ads.merkle.TreeStorage.Position
import scorex.crypto.{Base58, CryptographicHash, Sha256}

import scala.annotation.tailrec

/**
* @param data - data block
* @param merklePath - merkle path, complementary to data block
*/
case class AuthDataBlock[Block](data: Block, merklePath: Seq[Digest]) {

def check[HashImpl <: CryptographicHash](index: Position, rootHash: Digest)
(hashFunction: HashImpl = Sha256): Boolean = {

@tailrec
def calculateHash(idx: Position, nodeHash: Digest, path: Seq[Digest]): Digest = {
val hash = if (idx % 2 == 0)
hashFunction.hash(nodeHash ++ path.head)
else
hashFunction.hash(path.head ++ nodeHash)

if (path.size == 1)
hash
else
calculateHash(idx / 2, hash, path.tail)
}

if (merklePath.nonEmpty)
calculateHash(index, hashFunction.hash(data.asInstanceOf[Message]), merklePath) sameElements rootHash
else
false
}
}

object AuthDataBlock {

implicit def authDataBlockReads[T](implicit fmt: Reads[T]): Reads[AuthDataBlock[T]] = new Reads[AuthDataBlock[T]] {
def reads(json: JsValue): JsResult[AuthDataBlock[T]] = JsSuccess(AuthDataBlock[T](
(json \ "data").get match {
case JsString(ts) =>
Base58.decode(ts).get.asInstanceOf[T]
case _ =>
throw new RuntimeException("Data MUST be a string")
},
(json \ "merklePath").get match {
case JsArray(ts) => ts.map { t =>
t match {
case JsString(digest) =>
Base58.decode(digest)
case m =>
throw new RuntimeException("MerklePath MUST be array of strings" + m + " given")
}
}.map(_.get)
case m =>
throw new RuntimeException("MerklePath MUST be a list " + m + " given")
}
))
}

implicit def authDataBlockWrites[T](implicit fmt: Writes[T]): Writes[AuthDataBlock[T]] = new Writes[AuthDataBlock[T]] {
def writes(ts: AuthDataBlock[T]) = JsObject(Seq(
"data" -> JsString(Base58.encode(ts.data.asInstanceOf[Array[Byte]])),
"merklePath" -> JsArray(
ts.merklePath.map(digest => JsString(Base58.encode(digest)))
)
))
}
}

Loading