Browse Source

server: Update Block model to support TPoS blocks

scalafmt-draft
Alexis Hernandez 7 years ago
parent
commit
735a19ea27
  1. 4
      server/app/com/xsn/explorer/models/Block.scala
  2. 24
      server/app/com/xsn/explorer/models/TransactionVOUT.scala
  3. 24
      server/app/com/xsn/explorer/models/rpc/ScriptPubKey.scala
  4. 23
      server/test/com/xsn/explorer/helpers/DataHelper.scala
  5. 34
      server/test/controllers/BlocksControllerSpec.scala
  6. 19
      server/test/controllers/TransactionsControllerSpec.scala

4
server/app/com/xsn/explorer/models/Block.scala

@ -25,7 +25,7 @@ case class Block(
bits: String,
chainwork: String,
difficulty: BigDecimal,
tposContract: Option[String]) {
tposContract: Option[TransactionId]) {
/**
* Every block until 75 is PoW.
@ -60,7 +60,7 @@ object Block {
(__ \ 'bits).read[String] and
(__ \ 'chainwork).read[String] and
(__ \ 'difficulty).read[BigDecimal] and
(__ \ 'tposcontract).readNullable[String]
(__ \ 'tposcontract).readNullable[TransactionId]
builder.apply { (hash, previous, next, root, transactions,
confirmations, size, height, version, time,

24
server/app/com/xsn/explorer/models/TransactionVOUT.scala

@ -1,32 +1,26 @@
package com.xsn.explorer.models
import com.xsn.explorer.models.rpc.ScriptPubKey
import play.api.libs.functional.syntax._
import play.api.libs.json.{JsObject, Reads, __}
import play.api.libs.json.{Reads, __}
case class TransactionVOUT(
value: BigDecimal,
n: Int,
scriptPubKeyType: String,
address: Option[Address])
scriptPubKey: Option[ScriptPubKey] = None) {
val address: Option[Address] = scriptPubKey.flatMap(_.addresses.headOption)
}
object TransactionVOUT {
implicit val reads: Reads[TransactionVOUT] = {
val builder = (__ \ 'value).read[BigDecimal] and
(__ \ 'n).read[Int] and
(__ \ 'scriptPubKey).read[JsObject].map { json =>
val t = (json \ "type").as[String]
val a = (json \ "addresses")
.asOpt[List[String]]
.flatMap(_.headOption)
.flatMap(Address.from)
(t, a)
}
(__ \ 'scriptPubKey).readNullable[ScriptPubKey]
builder.apply { (value, n, tuple) =>
val (scriptType, address) = tuple
TransactionVOUT(value, n, scriptType, address)
builder.apply { (value, n, script) =>
TransactionVOUT(value, n, script)
}
}
}

24
server/app/com/xsn/explorer/models/rpc/ScriptPubKey.scala

@ -0,0 +1,24 @@
package com.xsn.explorer.models.rpc
import com.xsn.explorer.models.Address
import play.api.libs.functional.syntax._
import play.api.libs.json.{Reads, __}
case class ScriptPubKey(
`type`: String,
asm: String,
addresses: List[Address]
)
object ScriptPubKey {
implicit val reads: Reads[ScriptPubKey] = {
val builder = (__ \ 'type).read[String] and
(__ \ 'asm).read[String] and
(__ \ 'addresses).readNullable[List[Address]].map(_ getOrElse List.empty)
builder.apply { (t, asm, addresses) =>
ScriptPubKey(t, asm, addresses)
}
}
}

23
server/test/com/xsn/explorer/helpers/DataHelper.scala

@ -0,0 +1,23 @@
package com.xsn.explorer.helpers
import com.xsn.explorer.models.rpc.ScriptPubKey
import com.xsn.explorer.models.{Address, TransactionId, TransactionVOUT}
object DataHelper {
def createAddress(string: String) = Address.from(string).get
def createTransactionId(string: String) = TransactionId.from(string).get
def createTransactionVOUT(n: Int, value: BigDecimal, scriptPubKey: ScriptPubKey) = {
TransactionVOUT(
n = n,
value = value,
scriptPubKey = Some(scriptPubKey))
}
def createScriptPubKey(scriptType: String, address: Address) = {
ScriptPubKey(scriptType, "", List(address))
}
}

34
server/test/controllers/BlocksControllerSpec.scala

@ -3,7 +3,7 @@ package controllers
import com.alexitc.playsonify.PublicErrorRenderer
import com.alexitc.playsonify.core.FutureApplicationResult
import com.xsn.explorer.errors.{BlockNotFoundError, TransactionNotFoundError}
import com.xsn.explorer.helpers.DummyXSNService
import com.xsn.explorer.helpers.{DataHelper, DummyXSNService}
import com.xsn.explorer.models._
import com.xsn.explorer.services.XSNService
import controllers.common.MyAPISpec
@ -16,6 +16,8 @@ import scala.concurrent.Future
class BlocksControllerSpec extends MyAPISpec {
import DataHelper._
// PoS block
val posBlock = createBlock(
hash = Blockhash.from("b72dd1655408e9307ef5874be20422ee71029333283e2360975bc6073bdb2b81").get,
@ -29,10 +31,10 @@ class BlocksControllerSpec extends MyAPISpec {
id = TransactionId.from("0834641a7d30d8a2d2b451617599670445ee94ed7736e146c13be260c576c641").get,
vin = TransactionVIN(TransactionId.from("585cec5009c8ca19e83e33d282a6a8de65eb2ca007b54d6572167703768967d9").get, 2),
vout = List(
TransactionVOUT(BigDecimal("0"), 0, "nonstandard", None),
TransactionVOUT(n = 1, value = BigDecimal("600"), scriptPubKeyType = "pubkeyhash", address = Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")),
TransactionVOUT(n = 2, value = BigDecimal("600"), scriptPubKeyType = "pubkeyhash", address = Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")),
TransactionVOUT(BigDecimal("10"), 3, "pubkeyhash", Some(Address.from("XnH3bC9NruJ4wnu4Dgi8F3wemmJtcxpKp6").get))
TransactionVOUT(n = 0, value = BigDecimal("0")),
createTransactionVOUT(1, BigDecimal(600), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL"))),
createTransactionVOUT(2, BigDecimal(600), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL"))),
createTransactionVOUT(3, BigDecimal(10), createScriptPubKey("pubkeyhash", createAddress("XnH3bC9NruJ4wnu4Dgi8F3wemmJtcxpKp6")))
)
)
@ -40,9 +42,9 @@ class BlocksControllerSpec extends MyAPISpec {
id = TransactionId.from("585cec5009c8ca19e83e33d282a6a8de65eb2ca007b54d6572167703768967d9").get,
vin = TransactionVIN(TransactionId.from("fd74206866fc4ed986d39084eb9f20de6cb324b028693f33d60897ac995fff4f").get, 2),
vout = List(
TransactionVOUT(BigDecimal("0"), 0, "nonstandard", None),
TransactionVOUT(BigDecimal("1"), 1, "pubkeyhash", Some(Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL").get)),
TransactionVOUT(BigDecimal("1000"), 2, "pubkeyhash", Some(Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL").get))
TransactionVOUT(BigDecimal("0"), 0, None),
createTransactionVOUT(1, BigDecimal(1), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL"))),
createTransactionVOUT(2, BigDecimal(1000), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")))
)
)
@ -59,9 +61,9 @@ class BlocksControllerSpec extends MyAPISpec {
id = TransactionId.from("0b761343c7be39116d5429953e0cfbf51bfe83400ab27d61084222451045116c").get,
vin = TransactionVIN(TransactionId.from("1860288a5a87c79e617f743af44600e050c28ddb7d929d93d43a9148e2ba6638").get, 1),
vout = List(
TransactionVOUT(BigDecimal("0"), 0, "nonstandard", None),
TransactionVOUT(n = 1, value = BigDecimal("292968.74570312"), scriptPubKeyType = "pubkeyhash", address = Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")),
TransactionVOUT(n = 2, value = BigDecimal("292968.74570312"), scriptPubKeyType = "pubkeyhash", address = Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL"))
TransactionVOUT(BigDecimal("0"), 0, None),
createTransactionVOUT(1, BigDecimal("292968.74570312"), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL"))),
createTransactionVOUT(2, BigDecimal("292968.74570312"), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")))
)
)
@ -69,16 +71,16 @@ class BlocksControllerSpec extends MyAPISpec {
id = TransactionId.from("1860288a5a87c79e617f743af44600e050c28ddb7d929d93d43a9148e2ba6638").get,
vin = TransactionVIN(TransactionId.from("ef157f5ec0b3a6cdf669ff799988ee94d9fa2af8adaf2408ae9e34b47310831f").get, 2),
vout = List(
TransactionVOUT(BigDecimal("0"), 0, "nonstandard", None),
TransactionVOUT(BigDecimal("585937.49140625"), 1, "pubkeyhash", Some(Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL").get)),
TransactionVOUT(BigDecimal("585937.49140625"), 2, "pubkeyhash", Some(Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL").get))
TransactionVOUT(BigDecimal("0"), 0, None),
createTransactionVOUT(1, BigDecimal("585937.49140625"), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL"))),
createTransactionVOUT(2, BigDecimal("585937.49140625"), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")))
)
)
// TPoS
val tposBlock = posBlock.copy(
hash = Blockhash.from("c6944a33e3e03eb0ccd350f1fc2d6e5f3bd1411e1efddc0990aa3243663b41b7").get,
tposContract = Some("7f2b5f25b0ae24a417633e4214827f930a69802c1c43d1fb2ff7b7075b2d1701"))
tposContract = Some(createTransactionId("7f2b5f25b0ae24a417633e4214827f930a69802c1c43d1fb2ff7b7075b2d1701")))
// PoW
val powBlock = posBlock.copy(
@ -93,7 +95,7 @@ class BlocksControllerSpec extends MyAPISpec {
id = TransactionId.from("67aa0bd8b9297ca6ee25a1e5c2e3a8dbbcc1e20eab76b6d1bdf9d69f8a5356b8").get,
vin = None,
vout = List(
TransactionVOUT(BigDecimal("76500000.00000000"), 0, "pubkey", Some(Address.from("XdJnCKYNwzCz8ATv8Eu75gonaHyfr9qXg9").get))
createTransactionVOUT(0, BigDecimal("76500000.00000000"), createScriptPubKey("pubkey", createAddress("XdJnCKYNwzCz8ATv8Eu75gonaHyfr9qXg9")))
)
)

19
server/test/controllers/TransactionsControllerSpec.scala

@ -3,7 +3,7 @@ package controllers
import com.alexitc.playsonify.PublicErrorRenderer
import com.alexitc.playsonify.core.FutureApplicationResult
import com.xsn.explorer.errors.TransactionNotFoundError
import com.xsn.explorer.helpers.DummyXSNService
import com.xsn.explorer.helpers.{DataHelper, DummyXSNService}
import com.xsn.explorer.models._
import com.xsn.explorer.services.XSNService
import controllers.common.MyAPISpec
@ -16,6 +16,8 @@ import scala.concurrent.Future
class TransactionsControllerSpec extends MyAPISpec {
import DataHelper._
val coinbaseTx: Transaction = Transaction(
id = TransactionId.from("024aba1d535cfe5dd3ea465d46a828a57b00e1df012d7a2d158e0f7484173f7c").get,
size = Size(98),
@ -25,7 +27,8 @@ class TransactionsControllerSpec extends MyAPISpec {
confirmations = Confirmations(5347),
vin = None,
vout = List(
TransactionVOUT(n = 0, address = Address.from("XdJnCKYNwzCz8ATv8Eu75gonaHyfr9qXg9"), value = 0, scriptPubKeyType = "pubkey"))
createTransactionVOUT(0, BigDecimal(0), createScriptPubKey("pubkey", createAddress("XdJnCKYNwzCz8ATv8Eu75gonaHyfr9qXg9")))
)
)
val nonCoinbaseTx: Transaction = Transaction(
@ -38,8 +41,9 @@ class TransactionsControllerSpec extends MyAPISpec {
vin = Some(
TransactionVIN(TransactionId.from("585cec5009c8ca19e83e33d282a6a8de65eb2ca007b54d6572167703768967d9").get, 2)),
vout = List(
TransactionVOUT(n = 1, value = BigDecimal("1171874.98281250"), scriptPubKeyType = "pubkeyhash", address = Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")),
TransactionVOUT(n = 2, value = BigDecimal("1171874.98281250"), scriptPubKeyType = "pubkeyhash", address = Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")))
createTransactionVOUT(1, BigDecimal("1171874.98281250"), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL"))),
createTransactionVOUT(2, BigDecimal("1171874.98281250"), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")))
)
)
val nonCoinbasePreviousTx: Transaction = Transaction(
@ -50,10 +54,11 @@ class TransactionsControllerSpec extends MyAPISpec {
blocktime = 1520314409,
confirmations = Confirmations(11239),
vin = Some(
TransactionVIN(TransactionId.from("fd74206866fc4ed986d39084eb9f20de6cb324b028693f33d60897ac995fff4f").get, 2)),
TransactionVIN(createTransactionId("fd74206866fc4ed986d39084eb9f20de6cb324b028693f33d60897ac995fff4f"), 2)),
vout = List(
TransactionVOUT(n = 1, value = BigDecimal("2343749.96562500"), scriptPubKeyType = "pubkeyhash", address = Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")),
TransactionVOUT(n = 2, value = BigDecimal("2343749.96562500"), scriptPubKeyType = "pubkeyhash", address = Address.from("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")))
createTransactionVOUT(1, BigDecimal("2343749.96562500"), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL"))),
createTransactionVOUT(2, BigDecimal("2343749.96562500"), createScriptPubKey("pubkeyhash", createAddress("XgEGH3y7RfeKEdn2hkYEvBnrnmGBr7zvjL")))
)
)
val customXSNService = new DummyXSNService {

Loading…
Cancel
Save