You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.9 KiB
93 lines
2.9 KiB
package com.xsn.explorer.services
|
|
|
|
import javax.inject.Inject
|
|
|
|
import com.alexitc.playsonify.core.FutureApplicationResult
|
|
import com.alexitc.playsonify.core.FutureOr.Implicits.{FutureOps, OrOps}
|
|
import com.xsn.explorer.errors.{BlockNotFoundError, TPoSBlockNotSupportedError}
|
|
import com.xsn.explorer.models._
|
|
import com.xsn.explorer.services.logic.{BlockLogic, TransactionLogic}
|
|
import org.scalactic.Bad
|
|
|
|
import scala.concurrent.{ExecutionContext, Future}
|
|
|
|
class BlockService @Inject() (
|
|
xsnService: XSNService,
|
|
blockLogic: BlockLogic,
|
|
transactionLogic: TransactionLogic)(
|
|
implicit ec: ExecutionContext) {
|
|
|
|
def getDetails(blockhashString: String): FutureApplicationResult[BlockDetails] = {
|
|
val result = for {
|
|
blockhash <- blockLogic
|
|
.getBlockhash(blockhashString)
|
|
.toFutureOr
|
|
block <- xsnService
|
|
.getBlock(blockhash)
|
|
.toFutureOr
|
|
|
|
rewards <- getBlockRewards(block).toFutureOr
|
|
} yield BlockDetails(block, rewards)
|
|
|
|
result.toFuture
|
|
}
|
|
|
|
private def getBlockRewards(block: Block): FutureApplicationResult[BlockRewards] = {
|
|
if (block.isPoW) {
|
|
getPoWBlockRewards(block)
|
|
} else if (block.isPoS) {
|
|
getPoSBlockRewards(block)
|
|
} else {
|
|
getTPoSBlockRewards(block)
|
|
}
|
|
}
|
|
|
|
private def getPoWBlockRewards(block: Block): FutureApplicationResult[PoWBlockRewards] = {
|
|
val result = for {
|
|
txid <- blockLogic.getPoWTransactionId(block).toFutureOr
|
|
// TODO: handle tx not found
|
|
tx <- xsnService.getTransaction(txid).toFutureOr
|
|
vout <- transactionLogic.getVOUT(0, tx, BlockNotFoundError).toFutureOr
|
|
address <- transactionLogic.getAddress(vout, BlockNotFoundError).toFutureOr
|
|
} yield PoWBlockRewards(BlockReward(address, vout.value))
|
|
|
|
result.toFuture
|
|
}
|
|
|
|
private def getPoSBlockRewards(block: Block): FutureApplicationResult[PoSBlockRewards] = {
|
|
val result = for {
|
|
coinstakeTxId <- blockLogic
|
|
.getCoinstakeTransactionId(block)
|
|
.toFutureOr
|
|
coinstakeTx <- xsnService
|
|
.getTransaction(coinstakeTxId)
|
|
.toFutureOr
|
|
coinstakeTxVIN <- transactionLogic
|
|
.getVIN(coinstakeTx, BlockNotFoundError)
|
|
.toFutureOr
|
|
|
|
previousToCoinstakeTx <- xsnService
|
|
.getTransaction(coinstakeTxVIN.txid)
|
|
.toFutureOr
|
|
previousToCoinstakeVOUT <- transactionLogic
|
|
.getVOUT(coinstakeTxVIN, previousToCoinstakeTx, BlockNotFoundError)
|
|
.toFutureOr
|
|
|
|
coinstakeAddress <- transactionLogic
|
|
.getAddress(previousToCoinstakeVOUT, BlockNotFoundError)
|
|
.toFutureOr
|
|
|
|
rewards <- blockLogic
|
|
.getPoSRewards(coinstakeTx, coinstakeAddress, previousToCoinstakeVOUT.value)
|
|
.toFutureOr
|
|
} yield rewards
|
|
|
|
result.toFuture
|
|
}
|
|
|
|
// TODO: Complete it
|
|
private def getTPoSBlockRewards(block: Block): FutureApplicationResult[BlockRewards] = {
|
|
val result = Bad(TPoSBlockNotSupportedError).accumulating
|
|
Future.successful(result)
|
|
}
|
|
}
|
|
|