diff --git a/server/app/com/xsn/explorer/models/StatisticsDetails.scala b/server/app/com/xsn/explorer/models/StatisticsDetails.scala index d69b085..b928e85 100644 --- a/server/app/com/xsn/explorer/models/StatisticsDetails.scala +++ b/server/app/com/xsn/explorer/models/StatisticsDetails.scala @@ -2,7 +2,7 @@ package com.xsn.explorer.models import play.api.libs.json._ -case class StatisticsDetails(statistics: Statistics, masternodes: Option[Int]) +case class StatisticsDetails(statistics: Statistics, masternodes: Option[Int], difficulty: Option[BigDecimal]) object StatisticsDetails { @@ -14,7 +14,8 @@ object StatisticsDetails { val extras = List( "totalSupply" -> obj.statistics.totalSupply.map(JsNumber.apply), "circulatingSupply" -> obj.statistics.circulatingSupply.map(JsNumber.apply), - "masternodes" -> obj.masternodes.map(c => JsNumber.apply(c)) + "masternodes" -> obj.masternodes.map(c => JsNumber.apply(c)), + "difficulty" -> obj.difficulty.map(c => JsNumber.apply(c)) ).flatMap { case (key, maybe) => maybe.map(key -> _) } diff --git a/server/app/com/xsn/explorer/services/StatisticsService.scala b/server/app/com/xsn/explorer/services/StatisticsService.scala index 7f6c65c..29f6683 100644 --- a/server/app/com/xsn/explorer/services/StatisticsService.scala +++ b/server/app/com/xsn/explorer/services/StatisticsService.scala @@ -18,6 +18,7 @@ class StatisticsService @Inject() ( def getStatistics(): FutureApplicationResult[StatisticsDetails] = { val dbStats = statisticsFutureDataHandler.getStatistics() val rpcStats = xsnService.getMasternodeCount() + val difficulty = xsnService.getDifficulty() val result = for { stats <- dbStats.toFutureOr @@ -25,7 +26,11 @@ class StatisticsService @Inject() ( case Good(count) => Good(Some(count)) case Bad(_) => Good(None) }.toFutureOr - } yield StatisticsDetails(stats, count) + diff <- difficulty.map { + case Good(difficulty) => Good(Some(difficulty)) + case Bad(_) => Good(None) + }.toFutureOr + } yield StatisticsDetails(stats, count, diff) result.toFuture } diff --git a/server/app/com/xsn/explorer/services/XSNService.scala b/server/app/com/xsn/explorer/services/XSNService.scala index 075e04d..8bef929 100644 --- a/server/app/com/xsn/explorer/services/XSNService.scala +++ b/server/app/com/xsn/explorer/services/XSNService.scala @@ -37,6 +37,8 @@ trait XSNService { def getMasternodeCount(): FutureApplicationResult[Int] + def getDifficulty(): FutureApplicationResult[BigDecimal] + def getMasternodes(): FutureApplicationResult[List[rpc.Masternode]] def getMasternode(ipAddress: IPAddress): FutureApplicationResult[rpc.Masternode] @@ -288,6 +290,28 @@ class XSNServiceRPCImpl @Inject() ( } } + override def getDifficulty(): FutureApplicationResult[BigDecimal] = { + val body = s""" + |{ + | "jsonrpc": "1.0", + | "method": "getdifficulty", + | "params": [] + |} + |""".stripMargin + + server + .post(body) + .map { response => + val maybe = getResult[BigDecimal](response) + maybe.getOrElse { + logger.warn(s"Unexpected response from XSN Server, status = ${response.status}, response = ${response.body}") + + Bad(XSNUnexpectedResponseError).accumulating + } + } + } + + override def getMasternodes(): FutureApplicationResult[List[rpc.Masternode]] = { val body = s""" |{ diff --git a/server/test/com/xsn/explorer/helpers/DummyXSNService.scala b/server/test/com/xsn/explorer/helpers/DummyXSNService.scala index 06ab5ae..8bc3099 100644 --- a/server/test/com/xsn/explorer/helpers/DummyXSNService.scala +++ b/server/test/com/xsn/explorer/helpers/DummyXSNService.scala @@ -19,6 +19,7 @@ class DummyXSNService extends XSNService { override def getLatestBlock(): FutureApplicationResult[rpc.Block] = ??? override def getServerStatistics(): FutureApplicationResult[rpc.ServerStatistics] = ??? override def getMasternodeCount(): FutureApplicationResult[Int] = ??? + override def getDifficulty(): FutureApplicationResult[BigDecimal] = ??? override def getMasternodes(): FutureApplicationResult[List[rpc.Masternode]] = ??? override def getMasternode(ipAddress: IPAddress): FutureApplicationResult[Masternode] = ??? override def getUnspentOutputs(address: Address): FutureApplicationResult[JsValue] = ??? diff --git a/server/test/com/xsn/explorer/services/XSNServiceRPCImplSpec.scala b/server/test/com/xsn/explorer/services/XSNServiceRPCImplSpec.scala index f1a6512..82bd9f5 100644 --- a/server/test/com/xsn/explorer/services/XSNServiceRPCImplSpec.scala +++ b/server/test/com/xsn/explorer/services/XSNServiceRPCImplSpec.scala @@ -459,6 +459,21 @@ class XSNServiceRPCImplSpec extends WordSpec with MustMatchers with ScalaFutures } } + "getDifficulty" should { + "return the difficulty" in { + val content = "129.1827211827212" + + val responseBody = createRPCSuccessfulResponse(Json.parse(content)) + val json = Json.parse(responseBody) + + mockRequest(request, response)(200, json) + + whenReady(service.getDifficulty()) { result => + result mustEqual Good(129.1827211827212) + } + } + } + "getMasternodes" should { "return the masternodes" in { val content = diff --git a/server/test/controllers/StatisticsControllerSpec.scala b/server/test/controllers/StatisticsControllerSpec.scala index e9b5f68..1e7c431 100644 --- a/server/test/controllers/StatisticsControllerSpec.scala +++ b/server/test/controllers/StatisticsControllerSpec.scala @@ -28,6 +28,9 @@ class StatisticsControllerSpec extends MyAPISpec { override def getMasternodeCount(): FutureApplicationResult[Int] = { Future.successful(Good(1000)) } + override def getDifficulty(): FutureApplicationResult[BigDecimal] = { + Future.successful(Good(129.1827211827212)) + } } override val application = guiceApplicationBuilder @@ -46,6 +49,7 @@ class StatisticsControllerSpec extends MyAPISpec { (json \ "totalSupply").as[BigDecimal] mustEqual stats.totalSupply.get (json \ "circulatingSupply").as[BigDecimal] mustEqual stats.circulatingSupply.get (json \ "masternodes").as[Int] mustEqual 1000 + (json \ "difficulty").as[BigDecimal] mustEqual 129.1827211827212 } } }