Browse Source

server: Extract the BlockValidator from the BlockLogic

bitcoin
Alexis Hernandez 6 years ago
parent
commit
a723a6501c
  1. 27
      server/app/com/xsn/explorer/services/BlockService.scala
  2. 9
      server/app/com/xsn/explorer/services/logic/BlockLogic.scala
  3. 12
      server/app/com/xsn/explorer/services/validators/BlockhashValidator.scala
  4. 13
      server/app/com/xsn/explorer/services/validators/package.scala
  5. 3
      server/test/com/xsn/explorer/services/LedgerSynchronizerServiceSpec.scala

27
server/app/com/xsn/explorer/services/BlockService.scala

@ -7,16 +7,17 @@ import com.alexitc.playsonify.models.pagination.{Limit, Offset, PaginatedQuery}
import com.alexitc.playsonify.validators.PaginatedQueryValidator
import com.xsn.explorer.cache.BlockHeaderCache
import com.xsn.explorer.data.async.BlockFutureDataHandler
import com.xsn.explorer.errors.{BlockRewardsNotFoundError, BlockhashFormatError}
import com.xsn.explorer.errors.BlockRewardsNotFoundError
import com.xsn.explorer.models._
import com.xsn.explorer.models.persisted.BlockHeader
import com.xsn.explorer.models.rpc.{Block, TransactionVIN}
import com.xsn.explorer.models.values.{Blockhash, Height}
import com.xsn.explorer.parsers.OrderingConditionParser
import com.xsn.explorer.services.logic.{BlockLogic, TransactionLogic}
import com.xsn.explorer.services.validators.BlockhashValidator
import com.xsn.explorer.util.Extensions.FutureOrExt
import javax.inject.Inject
import org.scalactic.{Bad, Good, One, Or}
import org.scalactic.{Bad, Good}
import play.api.libs.json.{JsValue, Writes}
import scala.concurrent.{ExecutionContext, Future}
@ -25,6 +26,7 @@ class BlockService @Inject() (
xsnService: XSNService,
blockDataHandler: BlockFutureDataHandler,
paginatedQueryValidator: PaginatedQueryValidator,
blockhashValidator: BlockhashValidator,
blockLogic: BlockLogic,
transactionLogic: TransactionLogic,
orderingConditionParser: OrderingConditionParser,
@ -40,13 +42,10 @@ class BlockService @Inject() (
implicit writes: Writes[BlockHeader]): FutureApplicationResult[JsValue] = {
val result = for {
lastSeenHash <- {
lastSeenHashString
.map(Blockhash.from)
.map { txid => Or.from(txid, One(BlockhashFormatError)).map(Option.apply) }
.getOrElse(Good(Option.empty))
.toFutureOr
}
lastSeenHash <- lastSeenHashString
.map { string => blockhashValidator.validate(string).map(Option.apply) }
.getOrElse(Good(None))
.toFutureOr
_ <- paginatedQueryValidator.validate(PaginatedQuery(Offset(0), limit), maxHeadersPerQuery).toFutureOr
orderingCondition <- orderingConditionParser.parseReuslt(orderingConditionString).toFutureOr
@ -75,10 +74,7 @@ class BlockService @Inject() (
def getRawBlock(blockhashString: String): FutureApplicationResult[JsValue] = {
val result = for {
blockhash <- blockLogic
.getBlockhash(blockhashString)
.toFutureOr
blockhash <- blockhashValidator.validate(blockhashString).toFutureOr
block <- xsnService.getRawBlock(blockhash).toFutureOr
} yield block
@ -96,10 +92,7 @@ class BlockService @Inject() (
def getDetails(blockhashString: String): FutureApplicationResult[BlockDetails] = {
val result = for {
blockhash <- blockLogic
.getBlockhash(blockhashString)
.toFutureOr
blockhash <- blockhashValidator.validate(blockhashString).toFutureOr
details <- getDetailsPrivate(blockhash).toFutureOr
} yield details

9
server/app/com/xsn/explorer/services/logic/BlockLogic.scala

@ -1,19 +1,14 @@
package com.xsn.explorer.services.logic
import com.alexitc.playsonify.core.ApplicationResult
import com.xsn.explorer.errors.{BlockNotFoundError, BlockhashFormatError, TransactionNotFoundError}
import com.xsn.explorer.errors.{BlockNotFoundError, TransactionNotFoundError}
import com.xsn.explorer.models._
import com.xsn.explorer.models.rpc.{Block, Transaction}
import com.xsn.explorer.models.values.{Address, Blockhash, TransactionId}
import com.xsn.explorer.models.values.{Address, TransactionId}
import org.scalactic.{Bad, Good, One, Or}
class BlockLogic {
def getBlockhash(string: String): ApplicationResult[Blockhash] = {
val maybe = Blockhash.from(string)
Or.from(maybe, One(BlockhashFormatError))
}
def getPoWTransactionId(block: Block): ApplicationResult[TransactionId] = {
val maybe = block.transactions.headOption

12
server/app/com/xsn/explorer/services/validators/BlockhashValidator.scala

@ -0,0 +1,12 @@
package com.xsn.explorer.services.validators
import com.alexitc.playsonify.core.ApplicationResult
import com.xsn.explorer.errors.BlockhashFormatError
import com.xsn.explorer.models.values.Blockhash
class BlockhashValidator {
def validate(string: String): ApplicationResult[Blockhash] = {
optional(string, BlockhashFormatError)(Blockhash.from)
}
}

13
server/app/com/xsn/explorer/services/validators/package.scala

@ -0,0 +1,13 @@
package com.xsn.explorer.services
import com.alexitc.playsonify.core.ApplicationResult
import com.alexitc.playsonify.models.ApplicationError
import org.scalactic.{One, Or}
package object validators {
def optional[T](string: String, error: ApplicationError)(builder: String => Option[T]): ApplicationResult[T] = {
val maybe = builder(string)
Or.from(maybe, One(error))
}
}

3
server/test/com/xsn/explorer/services/LedgerSynchronizerServiceSpec.scala

@ -13,7 +13,7 @@ import com.xsn.explorer.models.rpc.Block
import com.xsn.explorer.models.values.{Blockhash, Height}
import com.xsn.explorer.parsers.{OrderingConditionParser, TransactionOrderingParser}
import com.xsn.explorer.services.logic.{BlockLogic, TransactionLogic}
import com.xsn.explorer.services.validators.AddressValidator
import com.xsn.explorer.services.validators.{AddressValidator, BlockhashValidator}
import org.scalactic.{Bad, Good, One, Or}
import org.scalatest.BeforeAndAfter
import org.scalatest.concurrent.ScalaFutures
@ -223,6 +223,7 @@ class LedgerSynchronizerServiceSpec extends PostgresDataHandlerSpec with BeforeA
xsnService,
new BlockFutureDataHandler(blockDataHandler)(Executors.databaseEC),
new PaginatedQueryValidator,
new BlockhashValidator,
new BlockLogic,
new TransactionLogic,
new OrderingConditionParser,

Loading…
Cancel
Save