Browse Source

server: Add extraction_method column to the blocks table

Defaults to PoW, a migration is required to set the correct values.
master
Alexis Hernandez 6 years ago
parent
commit
21399f3c99
  1. 19
      server/app/com/xsn/explorer/data/anorm/dao/BlockPostgresDAO.scala
  2. 13
      server/app/com/xsn/explorer/data/anorm/parsers/BlockParsers.scala
  3. 17
      server/app/com/xsn/explorer/models/persisted/Block.scala
  4. 5
      server/app/com/xsn/explorer/services/LedgerSynchronizerService.scala
  5. 15
      server/conf/evolutions/default/12.sql
  6. 6
      server/test/com/xsn/explorer/helpers/BlockLoader.scala
  7. 5
      server/test/com/xsn/explorer/helpers/Converters.scala

19
server/app/com/xsn/explorer/data/anorm/dao/BlockPostgresDAO.scala

@ -20,15 +20,15 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI
|INSERT INTO blocks |INSERT INTO blocks
| ( | (
| blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size, | blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size,
| height, version, time, median_time, nonce, bits, chainwork, difficulty | height, version, time, median_time, nonce, bits, chainwork, difficulty, extraction_method
| ) | )
|VALUES |VALUES
| ( | (
| {blockhash}, {previous_blockhash}, {next_blockhash}, {tpos_contract}, {merkle_root}, {size}, | {blockhash}, {previous_blockhash}, {next_blockhash}, {tpos_contract}, {merkle_root}, {size},
| {height}, {version}, {time}, {median_time}, {nonce}, {bits}, {chainwork}, {difficulty} | {height}, {version}, {time}, {median_time}, {nonce}, {bits}, {chainwork}, {difficulty}, {extraction_method}::BLOCK_EXTRACTION_METHOD_TYPE
| ) | )
|RETURNING blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size, |RETURNING blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size,
| height, version, time, median_time, nonce, bits, chainwork, difficulty | height, version, time, median_time, nonce, bits, chainwork, difficulty, extraction_method
""".stripMargin """.stripMargin
).on( ).on(
'blockhash -> block.hash.string, 'blockhash -> block.hash.string,
@ -44,7 +44,8 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI
'nonce -> block.nonce, 'nonce -> block.nonce,
'bits -> block.bits, 'bits -> block.bits,
'chainwork -> block.chainwork, 'chainwork -> block.chainwork,
'difficulty -> block.difficulty 'difficulty -> block.difficulty,
'extraction_method -> block.extractionMethod.entryName
).as(parseBlock.singleOpt) ).as(parseBlock.singleOpt)
} }
@ -59,7 +60,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI
|SET next_blockhash = {next_blockhash} |SET next_blockhash = {next_blockhash}
|WHERE blockhash = {blockhash} |WHERE blockhash = {blockhash}
|RETURNING blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size, |RETURNING blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size,
| height, version, time, median_time, nonce, bits, chainwork, difficulty | height, version, time, median_time, nonce, bits, chainwork, difficulty, extraction_method
""".stripMargin """.stripMargin
).on( ).on(
'blockhash -> blockhash.string, 'blockhash -> blockhash.string,
@ -71,7 +72,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI
SQL( SQL(
""" """
|SELECT blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size, |SELECT blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size,
| height, version, time, median_time, nonce, bits, chainwork, difficulty | height, version, time, median_time, nonce, bits, chainwork, difficulty, extraction_method
|FROM blocks |FROM blocks
|WHERE blockhash = {blockhash} |WHERE blockhash = {blockhash}
""".stripMargin """.stripMargin
@ -84,7 +85,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI
SQL( SQL(
""" """
|SELECT blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size, |SELECT blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size,
| height, version, time, median_time, nonce, bits, chainwork, difficulty | height, version, time, median_time, nonce, bits, chainwork, difficulty, extraction_method
|FROM blocks |FROM blocks
|WHERE height = {height} |WHERE height = {height}
""".stripMargin """.stripMargin
@ -102,7 +103,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI
SQL( SQL(
s""" s"""
|SELECT blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size, |SELECT blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size,
| height, version, time, median_time, nonce, bits, chainwork, difficulty | height, version, time, median_time, nonce, bits, chainwork, difficulty, extraction_method
|FROM blocks |FROM blocks
|$orderBy |$orderBy
|OFFSET {offset} |OFFSET {offset}
@ -131,7 +132,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI
|DELETE FROM blocks |DELETE FROM blocks
|WHERE blockhash = {blockhash} |WHERE blockhash = {blockhash}
|RETURNING blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size, |RETURNING blockhash, previous_blockhash, next_blockhash, tpos_contract, merkle_root, size,
| height, version, time, median_time, nonce, bits, chainwork, difficulty | height, version, time, median_time, nonce, bits, chainwork, difficulty, extraction_method
""".stripMargin """.stripMargin
).on( ).on(
"blockhash" -> blockhash.string "blockhash" -> blockhash.string

13
server/app/com/xsn/explorer/data/anorm/parsers/BlockParsers.scala

@ -25,6 +25,10 @@ object BlockParsers {
.map(Blockhash.from) .map(Blockhash.from)
.map { _.getOrElse(throw new RuntimeException("corrupted merkle_root")) } .map { _.getOrElse(throw new RuntimeException("corrupted merkle_root")) }
val parseExtractionMethod = str("extraction_method")
.map(Block.ExtractionMethod.withNameInsensitiveOption)
.map { _.getOrElse(throw new RuntimeException("corrupted extraction_method")) }
val parseSize = int("size").map(Size.apply) val parseSize = int("size").map(Size.apply)
val parseHeight = int("height").map(Height.apply) val parseHeight = int("height").map(Height.apply)
val parseVersion = int("version") val parseVersion = int("version")
@ -48,7 +52,8 @@ object BlockParsers {
parseNonce ~ parseNonce ~
parseBits ~ parseBits ~
parseChainwork ~ parseChainwork ~
parseDifficulty).map { parseDifficulty ~
parseExtractionMethod).map {
case hash ~ case hash ~
nextBlockhash ~ nextBlockhash ~
@ -63,7 +68,8 @@ object BlockParsers {
nonce ~ nonce ~
bits ~ bits ~
chainwork ~ chainwork ~
difficulty => difficulty ~
extractionMethod =>
Block( Block(
hash = hash, hash = hash,
@ -79,7 +85,8 @@ object BlockParsers {
bits = bits, bits = bits,
chainwork = chainwork, chainwork = chainwork,
difficulty = difficulty, difficulty = difficulty,
version = version version = version,
extractionMethod = extractionMethod
) )
} }
} }

17
server/app/com/xsn/explorer/models/persisted/Block.scala

@ -1,6 +1,7 @@
package com.xsn.explorer.models.persisted package com.xsn.explorer.models.persisted
import com.xsn.explorer.models._ import com.xsn.explorer.models._
import enumeratum._
case class Block( case class Block(
hash: Blockhash, hash: Blockhash,
@ -16,4 +17,18 @@ case class Block(
nonce: Long, nonce: Long,
bits: String, bits: String,
chainwork: String, chainwork: String,
difficulty: BigDecimal) difficulty: BigDecimal,
extractionMethod: Block.ExtractionMethod)
object Block {
sealed abstract class ExtractionMethod(override val entryName: String) extends EnumEntry
object ExtractionMethod extends Enum[ExtractionMethod] {
val values = findValues
final case object ProofOfWork extends ExtractionMethod("PoW")
final case object ProofOfStake extends ExtractionMethod("PoS")
final case object TrustlessProofOfStake extends ExtractionMethod("TPoS")
}
}

5
server/app/com/xsn/explorer/services/LedgerSynchronizerService.scala

@ -162,7 +162,10 @@ class LedgerSynchronizerService @Inject() (
val result = for { val result = for {
rpcBlock <- xsnService.getBlock(blockhash).toFutureOr rpcBlock <- xsnService.getBlock(blockhash).toFutureOr
transactions <- transactionRPCService.getTransactions(rpcBlock.transactions).toFutureOr transactions <- transactionRPCService.getTransactions(rpcBlock.transactions).toFutureOr
block = rpcBlock.into[Block].transform block = rpcBlock
.into[Block]
.withFieldConst(_.extractionMethod, Block.ExtractionMethod.ProofOfWork) // TODO: Get proper method
.transform
} yield (block, transactions) } yield (block, transactions)
result.toFuture result.toFuture

15
server/conf/evolutions/default/12.sql

@ -0,0 +1,15 @@
# --- !Ups
CREATE TYPE BLOCK_EXTRACTION_METHOD_TYPE AS ENUM ('PoW', 'PoS', 'TPoS');
ALTER TABLE blocks
ADD COLUMN extraction_method BLOCK_EXTRACTION_METHOD_TYPE NOT NULL DEFAULT 'PoW';
# --- !Downs
ALTER TABLE blocks
DROP COLUMN extraction_method;
DROP TYPE BLOCK_EXTRACTION_METHOD_TYPE;

6
server/test/com/xsn/explorer/helpers/BlockLoader.scala

@ -3,7 +3,6 @@ package com.xsn.explorer.helpers
import java.io.File import java.io.File
import com.xsn.explorer.models._ import com.xsn.explorer.models._
import io.scalaland.chimney.dsl._
import play.api.libs.json.{JsValue, Json} import play.api.libs.json.{JsValue, Json}
object BlockLoader { object BlockLoader {
@ -12,8 +11,7 @@ object BlockLoader {
def get(blockhash: String): persisted.Block = { def get(blockhash: String): persisted.Block = {
val rpcBlock = getRPC(blockhash) val rpcBlock = getRPC(blockhash)
Converters.toPersistedBlock(rpcBlock)
rpcBlock.into[persisted.Block].transform
} }
def getRPC(blockhash: String): rpc.Block = { def getRPC(blockhash: String): rpc.Block = {
@ -33,7 +31,7 @@ object BlockLoader {
def all(): List[persisted.Block] = { def all(): List[persisted.Block] = {
allRPC() allRPC()
.map(_.into[persisted.Block].transform) .map(Converters.toPersistedBlock)
} }
def allRPC(): List[rpc.Block] = { def allRPC(): List[rpc.Block] = {

5
server/test/com/xsn/explorer/helpers/Converters.scala

@ -8,6 +8,9 @@ import scala.language.implicitConversions
object Converters { object Converters {
implicit def toPersistedBlock(rpcBlock: rpc.Block): persisted.Block = { implicit def toPersistedBlock(rpcBlock: rpc.Block): persisted.Block = {
rpcBlock.into[persisted.Block].transform rpcBlock
.into[persisted.Block]
.withFieldConst(_.extractionMethod, persisted.Block.ExtractionMethod.ProofOfWork) // TODO: Detect method
.transform
} }
} }

Loading…
Cancel
Save