mirror of
https://gitee.com/BTAJL/repchain.git
synced 2024-12-05 05:08:29 +08:00
1、增加get接口:获取目前系统接收到的交易总数;
2、增加post接口:1)通过高度2)通过txid获取所在块的时间戳(交易入块时间); 3、修改查询交易入块时间的接口,增加utc时间(13位的ms级)
This commit is contained in:
parent
0af717c136
commit
9b2dc19031
@ -42,6 +42,7 @@ import akka.actor.Props
|
||||
import rep.crypto.cert.SignTool
|
||||
import rep.protos.peer.ActionResult
|
||||
import rep.app.conf.SystemProfile
|
||||
import rep.log.RepLogger
|
||||
import rep.network.base.ModuleBase
|
||||
import rep.sc.TypeOfSender
|
||||
import rep.sc.SandboxDispatcher.DoTransaction
|
||||
@ -60,12 +61,14 @@ object RestActor {
|
||||
case object ChainInfo
|
||||
case object NodeNumber
|
||||
case object TransNumber
|
||||
case object AcceptedTransNumber
|
||||
|
||||
case class SystemStart(cout: Int)
|
||||
case class SystemStop(from: Int, to: Int)
|
||||
|
||||
case class BlockId(bid: String)
|
||||
case class BlockHeight(h: Int)
|
||||
case class BlockTime(createTime: String, createTimeUtc: String)
|
||||
case class BlockTimeForHeight(h:Long)
|
||||
case class BlockTimeForTxid(txid:String)
|
||||
case class BlockHeightStream(h: Int)
|
||||
@ -159,6 +162,7 @@ class RestActor(moduleName: String) extends ModuleBase(moduleName) {
|
||||
sender ! PostResult(t.id, None, Option(s"transactionId is exists, the transaction is \n ${JsonFormat.toJson(st.get)}"))
|
||||
case None =>
|
||||
if (SignTool.verify(sig, tOutSig.toByteArray, certId, pe.getSysTag)) {
|
||||
// RepLogger.info(RepLogger.Business_Logger, s"验证签名成功,txid: ${t.id},creditCode: ${t.signature.get.getCertId.creditCode}, certName: ${t.signature.get.getCertId.certName}")
|
||||
val future = pe.getActorRef(ActorType.transactiondispatcher) ? DoTransaction(t, "api_" + t.id, TypeOfSender.FromAPI)
|
||||
val result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
|
||||
val rv = result
|
||||
@ -248,7 +252,7 @@ class RestActor(moduleName: String) extends ModuleBase(moduleName) {
|
||||
val r = bb match {
|
||||
case null => QueryResult(None)
|
||||
case _ =>
|
||||
QueryResult(Option(JsonMethods.parse(string2JsonInput("{"+"\"createtime\":\""+bb+"\"}"))))
|
||||
QueryResult(Option(JsonMethods.parse(bb)))
|
||||
}
|
||||
sender ! r
|
||||
|
||||
@ -257,7 +261,7 @@ class RestActor(moduleName: String) extends ModuleBase(moduleName) {
|
||||
val r = bb match {
|
||||
case null => QueryResult(None)
|
||||
case _ =>
|
||||
QueryResult(Option(JsonMethods.parse(string2JsonInput("{"+"\"createtime\":\""+bb+"\"}"))))
|
||||
QueryResult(Option(JsonMethods.parse(bb)))
|
||||
}
|
||||
sender ! r
|
||||
|
||||
@ -318,11 +322,14 @@ class RestActor(moduleName: String) extends ModuleBase(moduleName) {
|
||||
val rs = "{\"consensusnodes\":\""+stablenode+"\",\"nodes\":\""+snode+"\"}"
|
||||
sender ! QueryResult(Option(JsonMethods.parse(string2JsonInput(rs))))
|
||||
|
||||
case TransNumber =>
|
||||
case TransNumber =>
|
||||
val num = pe.getTransPoolMgr.getTransLength()
|
||||
val rs = "{\"numberofcache\":\""+num+"\"}"
|
||||
sender ! QueryResult(Option(JsonMethods.parse(string2JsonInput(rs))))
|
||||
|
||||
|
||||
|
||||
case AcceptedTransNumber =>
|
||||
val num = sr.getBlockChainInfo.height + pe.getTransPoolMgr.getTransLength()
|
||||
val rs = "{\"acceptedNumber\":\""+num+"\"}"
|
||||
sender ! QueryResult(Option(JsonMethods.parse(string2JsonInput(rs))))
|
||||
}
|
||||
}
|
@ -16,8 +16,8 @@
|
||||
|
||||
package rep.api.rest
|
||||
|
||||
import scala.concurrent.{ ExecutionContext, Future }
|
||||
import akka.actor.{ ActorRef, ActorSelection }
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import akka.actor.{ActorRef, ActorSelection}
|
||||
import akka.util.Timeout
|
||||
import akka.http.scaladsl.model.Uri.Path.Segment
|
||||
import akka.http.scaladsl.server.Directives
|
||||
@ -30,29 +30,26 @@ import Directives._
|
||||
import rep.sc.Sandbox.SandboxException
|
||||
import rep.sc.Sandbox._
|
||||
import rep.sc.Shim._
|
||||
|
||||
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
|
||||
import rep.protos.peer._
|
||||
import rep.api.rest.RestActor._
|
||||
import spray.json.DefaultJsonProtocol._
|
||||
import org.json4s.{ DefaultFormats, Formats, jackson }
|
||||
|
||||
import org.json4s.{DefaultFormats, Formats, jackson}
|
||||
import akka.http.scaladsl.server.Directives
|
||||
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
|
||||
import spray.json._
|
||||
|
||||
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport
|
||||
import akka.http.scaladsl.model.{ ContentTypes, HttpCharsets, MediaTypes }
|
||||
import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshaller }
|
||||
import akka.http.scaladsl.model.{ContentTypes, HttpCharsets, MediaTypes}
|
||||
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
|
||||
|
||||
import scala.xml.NodeSeq
|
||||
|
||||
import rep.log.RepLogger
|
||||
|
||||
/**
|
||||
* 获得区块链的概要信息
|
||||
* @author c4w
|
||||
*/
|
||||
* 获得区块链的概要信息
|
||||
*
|
||||
* @author c4w
|
||||
*/
|
||||
@Api(value = "/chaininfo", description = "获得当前区块链信息", produces = "application/json")
|
||||
@Path("chaininfo")
|
||||
class ChainService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
@ -62,11 +59,12 @@ class ChainService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import Json4sSupport._
|
||||
|
||||
implicit val serialization = jackson.Serialization // or native.Serialization
|
||||
implicit val formats = DefaultFormats
|
||||
implicit val timeout = Timeout(20.seconds)
|
||||
|
||||
val route = getBlockChainInfo ~ getNodeNumber ~ getCacheTransNumber
|
||||
val route = getBlockChainInfo ~ getNodeNumber ~ getCacheTransNumber ~ getAcceptedTransNumber
|
||||
|
||||
@ApiOperation(value = "返回块链信息", notes = "", nickname = "getChainInfo", httpMethod = "GET")
|
||||
@ApiResponses(Array(
|
||||
@ -94,7 +92,7 @@ class ChainService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Path("/getcachetransnumber")
|
||||
@ApiOperation(value = "返回系统缓存交易数量", notes = "", nickname = "getCacheTransNumber", httpMethod = "GET")
|
||||
@ApiResponses(Array(
|
||||
@ -108,26 +106,46 @@ class ChainService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/getAcceptedTransNumber")
|
||||
@ApiOperation(value = "返回系统接收到的交易数量", notes = "", nickname = "getAcceptedTransNumber", httpMethod = "GET")
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "返回系统接收到的交易数量", response = classOf[QueryResult])))
|
||||
def getAcceptedTransNumber =
|
||||
path("chaininfo" / "getAcceptedTransNumber") {
|
||||
get {
|
||||
extractClientIP { ip =>
|
||||
RepLogger.debug(RepLogger.APIAccess_Logger, s"remoteAddr=${ip} get number of accepted")
|
||||
complete {
|
||||
(ra ? AcceptedTransNumber).mapTo[QueryResult]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定区块的详细信息
|
||||
* @author c4w
|
||||
*/
|
||||
* 获得指定区块的详细信息
|
||||
*
|
||||
* @author c4w
|
||||
*/
|
||||
|
||||
@Api(value = "/block", description = "获得区块数据", produces = "application/json")
|
||||
@Path("block")
|
||||
class BlockService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
extends Directives {
|
||||
|
||||
import akka.pattern.ask
|
||||
import scala.concurrent.duration._
|
||||
|
||||
implicit val timeout = Timeout(20.seconds)
|
||||
|
||||
import Json4sSupport._
|
||||
|
||||
implicit val serialization = jackson.Serialization // or native.Serialization
|
||||
implicit val formats = DefaultFormats
|
||||
|
||||
val route = getBlockById ~ getBlockByHeight ~ getBlockStreamByHeight ~ getBlockTimeOfCreate ~ getBlockTimeOfTransaction
|
||||
val route = getBlockById ~ getBlockByHeight ~ getBlockByHeightToo ~ getBlockStreamByHeight ~ getBlockTimeOfCreate ~ getBlockTimeOfTxrByTxid ~ getBlockTimeOfTransaction
|
||||
|
||||
@Path("/hash/{blockId}")
|
||||
@ApiOperation(value = "返回指定id的区块", notes = "", nickname = "getBlockById", httpMethod = "GET")
|
||||
@ -151,7 +169,7 @@ class BlockService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
new ApiImplicitParam(name = "blockHeight", value = "区块高度", required = true, dataType = "int", paramType = "path")))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "返回区块json内容", response = classOf[QueryResult])))
|
||||
def getBlockByHeight =
|
||||
def getBlockByHeightToo =
|
||||
path("block" / Segment) { blockHeight =>
|
||||
get {
|
||||
extractClientIP { ip =>
|
||||
@ -163,6 +181,25 @@ class BlockService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/blockHeight")
|
||||
@ApiOperation(value = "返回指定高度的区块", notes = "", nickname = "getBlockByHeight", httpMethod = "POST")
|
||||
@ApiImplicitParams(Array(
|
||||
new ApiImplicitParam(name = "height", value = "区块高度", required = true, dataType = "String", paramType = "body")))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "返回区块json内容", response = classOf[QueryResult])))
|
||||
def getBlockByHeight =
|
||||
path("block" / "blockHeight") {
|
||||
post {
|
||||
entity(as[Map[String, Int]]) { blockQuery =>
|
||||
complete {
|
||||
(ra ? BlockHeight(blockQuery("height"))).mapTo[QueryResult]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Path("/blocktime/{blockHeight}")
|
||||
@ApiOperation(value = "返回指定高度的区块的出块时间", notes = "", nickname = "getBlockTimeOfCreate", httpMethod = "GET")
|
||||
@ApiImplicitParams(Array(
|
||||
@ -170,7 +207,7 @@ class BlockService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "返回指定高度的区块的出块时间", response = classOf[QueryResult])))
|
||||
def getBlockTimeOfCreate =
|
||||
path("block" /"blocktime"/ Segment) { blockHeight =>
|
||||
path("block" / "blocktime" / Segment) { blockHeight =>
|
||||
get {
|
||||
extractClientIP { ip =>
|
||||
RepLogger.debug(RepLogger.APIAccess_Logger, s"remoteAddr=${ip} get block time for Height,block height=${blockHeight}")
|
||||
@ -180,7 +217,7 @@ class BlockService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
//complete { (ra ? BlockHeight(blockHeight.toInt)).mapTo[QueryResult] }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Path("/blocktimeoftran/{transid}")
|
||||
@ApiOperation(value = "返回指定交易的入块时间", notes = "", nickname = "getBlockTimeOfTransaction", httpMethod = "GET")
|
||||
@ApiImplicitParams(Array(
|
||||
@ -198,7 +235,23 @@ class BlockService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
//complete { (ra ? BlockHeight(blockHeight.toInt)).mapTo[QueryResult] }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Path("/blocktimeoftran")
|
||||
@ApiOperation(value = "返回指定交易的入块时间", notes = "", nickname = "getBlockTimeOfTransaction", httpMethod = "POST")
|
||||
@ApiImplicitParams(Array(
|
||||
new ApiImplicitParam(name = "txid", value = "交易id", required = true, dataType = "String", paramType = "body")))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "返回指定交易的入块时间", response = classOf[QueryResult])))
|
||||
def getBlockTimeOfTxrByTxid=
|
||||
path("block" / "blocktimeoftran") {
|
||||
post {
|
||||
entity(as[Map[String, String]]) { trans =>
|
||||
complete { (ra ? BlockTimeForTxid(trans("txid"))).mapTo[QueryResult] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/stream/{blockHeight}")
|
||||
@ApiOperation(value = "返回指定高度的区块字节流", notes = "", nickname = "getBlockStreamByHeight", httpMethod = "GET")
|
||||
@ApiImplicitParams(Array(
|
||||
@ -217,9 +270,10 @@ class BlockService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定交易的详细信息,提交签名交易
|
||||
* @author c4w
|
||||
*/
|
||||
* 获得指定交易的详细信息,提交签名交易
|
||||
*
|
||||
* @author c4w
|
||||
*/
|
||||
@Api(value = "/transaction", description = "获得交易数据", consumes = "application/json,application/xml", produces = "application/json,application/xml")
|
||||
@Path("transaction")
|
||||
class TransactionService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
@ -230,11 +284,12 @@ class TransactionService(ra: ActorRef)(implicit executionContext: ExecutionConte
|
||||
import java.io.FileInputStream
|
||||
|
||||
implicit val timeout = Timeout(20.seconds)
|
||||
|
||||
import Json4sSupport._
|
||||
import ScalaXmlSupport._
|
||||
import akka.stream.scaladsl.FileIO
|
||||
import akka.util.ByteString
|
||||
import java.nio.file.{ Paths, Files }
|
||||
import java.nio.file.{Paths, Files}
|
||||
import akka.stream.scaladsl.Framing
|
||||
|
||||
implicit val serialization = jackson.Serialization // or native.Serialization
|
||||
@ -279,7 +334,7 @@ class TransactionService(ra: ActorRef)(implicit executionContext: ExecutionConte
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Path("/stream/{transactionId}")
|
||||
@ApiOperation(value = "返回指定id的交易字节流", notes = "", nickname = "getTransactionStream", httpMethod = "GET", produces = "application/octet-stream")
|
||||
|
@ -67,7 +67,8 @@ object RepChain_Multi {
|
||||
var nodes = Set.empty[ClusterSystem]
|
||||
nodes += sys1
|
||||
|
||||
for (i <- 1 to 9) {
|
||||
// 可以根据自己的需要将nodelist.length改成对应的节点数
|
||||
for (i <- 1 to nodelist.length) {
|
||||
Thread.sleep(2000)
|
||||
val sysN = new ClusterSystem(nodelist(i), InitType.MULTI_INIT, true)
|
||||
sysN.init
|
||||
|
@ -20,6 +20,7 @@ import rep.storage.block._
|
||||
import rep.storage.leveldb._
|
||||
import rep.storage.cfg._
|
||||
import rep.protos.peer._
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
import com.google.protobuf.ByteString
|
||||
import com.fasterxml.jackson.core.Base64Variants
|
||||
@ -29,7 +30,10 @@ import org.json4s.jackson.JsonMethods
|
||||
import rep.sc.Shim._
|
||||
import rep.utils._
|
||||
import java.io._
|
||||
|
||||
import rep.api.rest.RestActor.BlockTime
|
||||
import rep.protos.peer.OperLog
|
||||
|
||||
import scala.collection.mutable._
|
||||
import rep.network.consensus.util.BlockHelp
|
||||
import rep.log.RepLogger
|
||||
@ -38,6 +42,7 @@ import rep.storage.util.pathUtil
|
||||
import rep.log.RepTimeTracer
|
||||
import rep.app.conf.SystemProfile
|
||||
import rep.crypto.cert.certCache
|
||||
|
||||
import scala.util.control.Breaks._
|
||||
|
||||
/**
|
||||
@ -393,7 +398,7 @@ class ImpDataAccess private (SystemName: String) extends IDataAccess(SystemName)
|
||||
* @return 返回出块时间
|
||||
*/
|
||||
override def getBlockTimeOfTxid(txid: String): String = {
|
||||
this.getBlockTime4Block(this.getBlock4ObjectByTxId(txid))
|
||||
SerializeUtils.toJson(this.getBlockTime4Block(this.getBlock4ObjectByTxId(txid)))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -405,18 +410,21 @@ class ImpDataAccess private (SystemName: String) extends IDataAccess(SystemName)
|
||||
* @return 返回出块时间
|
||||
*/
|
||||
def getBlockTimeOfHeight(h: Long): String = {
|
||||
this.getBlockTime4Block(this.getBlock4ObjectByHeight(h))
|
||||
SerializeUtils.toJson(this.getBlockTime4Block(this.getBlock4ObjectByHeight(h)))
|
||||
}
|
||||
|
||||
private def getBlockTime4Block(b: Block): String = {
|
||||
var rs = ""
|
||||
private def getBlockTime4Block(b: Block): BlockTime = {
|
||||
var rs = BlockTime("", "")
|
||||
if (b != null && b.endorsements != null && b.endorsements.length >= 1) {
|
||||
val signer = b.endorsements(0)
|
||||
val date = new java.util.Date(signer.tmLocal.get.seconds * 1000);
|
||||
val formatstr = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
formatstr.setTimeZone(java.util.TimeZone.getTimeZone("ETC/GMT-8"))
|
||||
val tmpstr = formatstr.format(date)
|
||||
rs = tmpstr + "."+signer.tmLocal.get.nanos/1000000
|
||||
val createTime = tmpstr + "."+signer.tmLocal.get.nanos/1000000
|
||||
// 13位,毫秒精度级(utc时间)
|
||||
val createTimeUtc = String.valueOf(signer.tmLocal.get.seconds * 1000 - 8 * 3600 * 1000)
|
||||
rs = BlockTime(createTime, createTimeUtc)
|
||||
}
|
||||
rs
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user