From a334864e38b8db3e7953fcd1c130cb08a0cbed35 Mon Sep 17 00:00:00 2001 From: Alexis Hernandez Date: Sun, 17 Feb 2019 23:28:46 -0700 Subject: [PATCH] server: allow to get block extractionMethod from the BlockService --- .../xsn/explorer/services/BlockService.scala | 25 +++++++++++++++++++ .../explorer/services/logic/BlockLogic.scala | 14 ++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/server/app/com/xsn/explorer/services/BlockService.scala b/server/app/com/xsn/explorer/services/BlockService.scala index f493db4..9b0cf19 100644 --- a/server/app/com/xsn/explorer/services/BlockService.scala +++ b/server/app/com/xsn/explorer/services/BlockService.scala @@ -101,6 +101,31 @@ class BlockService @Inject() ( result.toFuture } + def extractionMethod(block: rpc.Block): FutureApplicationResult[BlockExtractionMethod] = { + if (block.tposContract.isDefined) { + Future.successful(Good(BlockExtractionMethod.TrustlessProofOfStake)) + } else if (block.transactions.isEmpty) { + Future.successful(Good(BlockExtractionMethod.ProofOfWork)) + } else { + isPoS(block) + .toFutureOr + .map { + case true => BlockExtractionMethod.ProofOfStake + case false => BlockExtractionMethod.ProofOfWork + } + .toFuture + } + } + + private def isPoS(block: rpc.Block): FutureApplicationResult[Boolean] = { + val result = for { + coinbaseTxid <- blockLogic.getCoinbase(block).toFutureOr + coinbase <- xsnService.getTransaction(coinbaseTxid).toFutureOr + } yield blockLogic.isPoS(block, coinbase) + + result.toFuture + } + private def getBlockRewards(block: Block): FutureApplicationResult[BlockRewards] = { if (block.transactions.isEmpty) { Future.successful(Bad(BlockRewardsNotFoundError).accumulating) diff --git a/server/app/com/xsn/explorer/services/logic/BlockLogic.scala b/server/app/com/xsn/explorer/services/logic/BlockLogic.scala index 33b794d..872b2ca 100644 --- a/server/app/com/xsn/explorer/services/logic/BlockLogic.scala +++ b/server/app/com/xsn/explorer/services/logic/BlockLogic.scala @@ -1,7 +1,7 @@ package com.xsn.explorer.services.logic import com.alexitc.playsonify.core.ApplicationResult -import com.xsn.explorer.errors.{BlockNotFoundError, BlockhashFormatError} +import com.xsn.explorer.errors.{BlockNotFoundError, BlockhashFormatError, TransactionNotFoundError} import com.xsn.explorer.models._ import com.xsn.explorer.models.rpc.{Block, Transaction} import com.xsn.explorer.models.values.{Address, Blockhash, TransactionId} @@ -20,6 +20,12 @@ class BlockLogic { Or.from(maybe, One(BlockNotFoundError)) } + def getCoinbase(block: Block): ApplicationResult[TransactionId] = { + val maybe = block.transactions.headOption + + Or.from(maybe, One(TransactionNotFoundError)) + } + /** * Get the coinstake transaction id for the given block. * @@ -144,4 +150,10 @@ class BlockLogic { Good(TPoSBlockRewards(ownerReward, merchantReward, masternodeRewardMaybe)) } + + def isPoS(block: rpc.Block, coinbase: rpc.Transaction): Boolean = { + block.nonce == 0 && + coinbase.vin.isEmpty && + coinbase.vout.flatMap(_.address).isEmpty + } }