diff --git a/server/app/com/xsn/explorer/data/anorm/dao/BlockPostgresDAO.scala b/server/app/com/xsn/explorer/data/anorm/dao/BlockPostgresDAO.scala index 1ec0fa6..e46e8bf 100644 --- a/server/app/com/xsn/explorer/data/anorm/dao/BlockPostgresDAO.scala +++ b/server/app/com/xsn/explorer/data/anorm/dao/BlockPostgresDAO.scala @@ -20,15 +20,15 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI |INSERT INTO blocks | ( | 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 | ( | {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, - | height, version, time, median_time, nonce, bits, chainwork, difficulty + | height, version, time, median_time, nonce, bits, chainwork, difficulty, extraction_method """.stripMargin ).on( 'blockhash -> block.hash.string, @@ -44,7 +44,8 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI 'nonce -> block.nonce, 'bits -> block.bits, 'chainwork -> block.chainwork, - 'difficulty -> block.difficulty + 'difficulty -> block.difficulty, + 'extraction_method -> block.extractionMethod.entryName ).as(parseBlock.singleOpt) } @@ -59,7 +60,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI |SET next_blockhash = {next_blockhash} |WHERE blockhash = {blockhash} |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 ).on( 'blockhash -> blockhash.string, @@ -71,7 +72,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI SQL( """ |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 |WHERE blockhash = {blockhash} """.stripMargin @@ -84,7 +85,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI SQL( """ |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 |WHERE height = {height} """.stripMargin @@ -102,7 +103,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI SQL( s""" |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 |$orderBy |OFFSET {offset} @@ -131,7 +132,7 @@ class BlockPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLI |DELETE FROM blocks |WHERE blockhash = {blockhash} |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 ).on( "blockhash" -> blockhash.string diff --git a/server/app/com/xsn/explorer/data/anorm/parsers/BlockParsers.scala b/server/app/com/xsn/explorer/data/anorm/parsers/BlockParsers.scala index cc0fb63..47cfc24 100644 --- a/server/app/com/xsn/explorer/data/anorm/parsers/BlockParsers.scala +++ b/server/app/com/xsn/explorer/data/anorm/parsers/BlockParsers.scala @@ -25,6 +25,10 @@ object BlockParsers { .map(Blockhash.from) .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 parseHeight = int("height").map(Height.apply) val parseVersion = int("version") @@ -48,7 +52,8 @@ object BlockParsers { parseNonce ~ parseBits ~ parseChainwork ~ - parseDifficulty).map { + parseDifficulty ~ + parseExtractionMethod).map { case hash ~ nextBlockhash ~ @@ -63,7 +68,8 @@ object BlockParsers { nonce ~ bits ~ chainwork ~ - difficulty => + difficulty ~ + extractionMethod => Block( hash = hash, @@ -79,7 +85,8 @@ object BlockParsers { bits = bits, chainwork = chainwork, difficulty = difficulty, - version = version + version = version, + extractionMethod = extractionMethod ) } } diff --git a/server/app/com/xsn/explorer/models/persisted/Block.scala b/server/app/com/xsn/explorer/models/persisted/Block.scala index 4058bf5..73666cc 100644 --- a/server/app/com/xsn/explorer/models/persisted/Block.scala +++ b/server/app/com/xsn/explorer/models/persisted/Block.scala @@ -1,6 +1,7 @@ package com.xsn.explorer.models.persisted import com.xsn.explorer.models._ +import enumeratum._ case class Block( hash: Blockhash, @@ -16,4 +17,18 @@ case class Block( nonce: Long, bits: 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") + } +} diff --git a/server/app/com/xsn/explorer/services/LedgerSynchronizerService.scala b/server/app/com/xsn/explorer/services/LedgerSynchronizerService.scala index c757b41..5bb2eaa 100644 --- a/server/app/com/xsn/explorer/services/LedgerSynchronizerService.scala +++ b/server/app/com/xsn/explorer/services/LedgerSynchronizerService.scala @@ -162,7 +162,10 @@ class LedgerSynchronizerService @Inject() ( val result = for { rpcBlock <- xsnService.getBlock(blockhash).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) result.toFuture diff --git a/server/conf/evolutions/default/12.sql b/server/conf/evolutions/default/12.sql new file mode 100644 index 0000000..fa83692 --- /dev/null +++ b/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; diff --git a/server/test/com/xsn/explorer/helpers/BlockLoader.scala b/server/test/com/xsn/explorer/helpers/BlockLoader.scala index a32b6cd..d3cf466 100644 --- a/server/test/com/xsn/explorer/helpers/BlockLoader.scala +++ b/server/test/com/xsn/explorer/helpers/BlockLoader.scala @@ -3,7 +3,6 @@ package com.xsn.explorer.helpers import java.io.File import com.xsn.explorer.models._ -import io.scalaland.chimney.dsl._ import play.api.libs.json.{JsValue, Json} object BlockLoader { @@ -12,8 +11,7 @@ object BlockLoader { def get(blockhash: String): persisted.Block = { val rpcBlock = getRPC(blockhash) - - rpcBlock.into[persisted.Block].transform + Converters.toPersistedBlock(rpcBlock) } def getRPC(blockhash: String): rpc.Block = { @@ -33,7 +31,7 @@ object BlockLoader { def all(): List[persisted.Block] = { allRPC() - .map(_.into[persisted.Block].transform) + .map(Converters.toPersistedBlock) } def allRPC(): List[rpc.Block] = { diff --git a/server/test/com/xsn/explorer/helpers/Converters.scala b/server/test/com/xsn/explorer/helpers/Converters.scala index 021ae48..8c5e4df 100644 --- a/server/test/com/xsn/explorer/helpers/Converters.scala +++ b/server/test/com/xsn/explorer/helpers/Converters.scala @@ -8,6 +8,9 @@ import scala.language.implicitConversions object Converters { 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 } }