diff --git a/server/app/com/xsn/explorer/models/Block.scala b/server/app/com/xsn/explorer/models/Block.scala index 7976e30..14cb582 100644 --- a/server/app/com/xsn/explorer/models/Block.scala +++ b/server/app/com/xsn/explorer/models/Block.scala @@ -11,8 +11,8 @@ import play.api.libs.json._ */ case class Block( hash: Blockhash, - previousBlockhash: Blockhash, - nextBlockhash: Blockhash, + previousBlockhash: Option[Blockhash], // first block doesn't have a previous block + nextBlockhash: Option[Blockhash], // last block doesn't have a next block merkleRoot: Blockhash, transactions: List[TransactionId], confirmations: Confirmations, @@ -24,14 +24,30 @@ case class Block( nonce: Int, bits: String, chainwork: String, - difficulty: BigDecimal -) + difficulty: BigDecimal, + tposContract: Option[String]) { + + /** + * Every block until 75 is PoW. + */ + def isPoW: Boolean = height.int <= 75 + + /** + * From block 76, we have just PoW or TPoS + */ + def isPoS: Boolean = !isPoW && tposContract.isEmpty + + /** + * TPoS blocks need a tposcontract + */ + def isTPoS: Boolean = !isPoW && tposContract.nonEmpty +} object Block { implicit val reads: Reads[Block] = { val builder = (__ \ 'hash).read[Blockhash] and - (__ \ 'previousblockhash).read[Blockhash] and - (__ \ 'nextblockhash).read[Blockhash] and + (__ \ 'previousblockhash).readNullable[Blockhash] and + (__ \ 'nextblockhash).readNullable[Blockhash] and (__ \ 'merkleroot).read[Blockhash] and (__ \ 'tx).read[List[TransactionId]] and (__ \ 'confirmations).read[Confirmations] and @@ -43,16 +59,17 @@ object Block { (__ \ 'nonce).read[Int] and (__ \ 'bits).read[String] and (__ \ 'chainwork).read[String] and - (__ \ 'difficulty).read[BigDecimal] + (__ \ 'difficulty).read[BigDecimal] and + (__ \ 'tposcontract).readNullable[String] builder.apply { (hash, previous, next, root, transactions, confirmations, size, height, version, time, - medianTime, nonce, bits, chainwork, difficulty) => + medianTime, nonce, bits, chainwork, difficulty, tposContract) => Block( hash, previous, next, root, transactions, confirmations, size, height, version, time, - medianTime, nonce, bits, chainwork, difficulty) + medianTime, nonce, bits, chainwork, difficulty, tposContract) } } diff --git a/server/test/controllers/BlocksControllerSpec.scala b/server/test/controllers/BlocksControllerSpec.scala index 97ddc7a..03cc5b5 100644 --- a/server/test/controllers/BlocksControllerSpec.scala +++ b/server/test/controllers/BlocksControllerSpec.scala @@ -139,8 +139,8 @@ class BlocksControllerSpec extends MyAPISpec { (jsonBlock \ "merkleRoot").as[Blockhash] mustEqual block.merkleRoot (jsonBlock \ "version").as[Long] mustEqual block.version (jsonBlock \ "nonce").as[Int] mustEqual block.nonce - (jsonBlock \ "previousBlockhash").as[Blockhash] mustEqual block.previousBlockhash - (jsonBlock \ "nextBlockhash").as[Blockhash] mustEqual block.nextBlockhash + (jsonBlock \ "previousBlockhash").asOpt[Blockhash] mustEqual block.previousBlockhash + (jsonBlock \ "nextBlockhash").asOpt[Blockhash] mustEqual block.nextBlockhash val jsonCoinstake = (jsonRewards \ "coinstake").as[JsValue] (jsonCoinstake \ "address").as[String] mustEqual "XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL" @@ -173,8 +173,8 @@ class BlocksControllerSpec extends MyAPISpec { (jsonBlock \ "merkleRoot").as[Blockhash] mustEqual block.merkleRoot (jsonBlock \ "version").as[Long] mustEqual block.version (jsonBlock \ "nonce").as[Int] mustEqual block.nonce - (jsonBlock \ "previousBlockhash").as[Blockhash] mustEqual block.previousBlockhash - (jsonBlock \ "nextBlockhash").as[Blockhash] mustEqual block.nextBlockhash + (jsonBlock \ "previousBlockhash").asOpt[Blockhash] mustEqual block.previousBlockhash + (jsonBlock \ "nextBlockhash").asOpt[Blockhash] mustEqual block.nextBlockhash val jsonCoinstake = (jsonRewards \ "coinstake").as[JsValue] (jsonCoinstake \ "address").as[String] mustEqual "XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL" @@ -245,8 +245,9 @@ class BlocksControllerSpec extends MyAPISpec { bits = "1d011212", chainwork = "00000000000000000000000000000000000000000000000000000084c71ff420", difficulty = BigDecimal("0.9340526210769362"), - previousBlockhash = Blockhash.from("000003dc4c2fc449dededaaad6efc33ce1b64b88a060652dc47edc63d6d6b524").get, - nextBlockhash = Blockhash.from("000000125c06cedf38b07bff174bdb61027935dbcb34831d28cff40bedb519d5").get + previousBlockhash = Some(Blockhash.from("000003dc4c2fc449dededaaad6efc33ce1b64b88a060652dc47edc63d6d6b524").get), + nextBlockhash = Some(Blockhash.from("000000125c06cedf38b07bff174bdb61027935dbcb34831d28cff40bedb519d5").get), + tposContract = None ) } }