From 4d0f502c0d24da1eb5b3348af0c265275d210f4c Mon Sep 17 00:00:00 2001 From: jiangbuyun Date: Sun, 24 Jul 2022 15:55:53 +0800 Subject: [PATCH] =?UTF-8?q?repchain2.0-update88:=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=A4=E6=98=93=E6=8E=A5=E6=94=B6=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E4=BA=A4=E6=98=93=E5=A4=A7=E5=B0=8F=E3=80=81?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E4=BA=A4=E6=98=93=E6=98=AF=E5=90=A6=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E3=80=81=E6=A3=80=E6=9F=A5=E4=BA=A4=E6=98=93=E7=AD=BE?= =?UTF-8?q?=E5=90=8D=E3=80=81=E6=A0=B9=E6=8D=AE=E9=85=8D=E7=BD=AE=E9=A1=B9?= =?UTF-8?q?=E7=A1=AE=E5=AE=9A=E4=BA=A4=E6=98=93=E6=98=AF=E5=90=A6=E9=A2=84?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=EF=BC=8C=E6=9C=80=E5=90=8E=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=A1=AE=E5=AE=9A=E4=BA=A4=E6=98=93=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E5=B9=BF=E6=92=AD=EF=BC=8C=E4=B8=8D=E5=B9=BF=E6=92=AD?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E5=8A=A0=E5=85=A5=E8=87=AA=E8=BA=AB=E4=BA=A4?= =?UTF-8?q?=E6=98=93=E6=B1=A0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/scala/rep/api/rest/RestActor.scala | 66 ++++++++++++++----- .../tools/transpool/PoolOfTransaction.scala | 15 +++++ 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/main/scala/rep/api/rest/RestActor.scala b/src/main/scala/rep/api/rest/RestActor.scala index 294cba2c..ef3e7151 100644 --- a/src/main/scala/rep/api/rest/RestActor.scala +++ b/src/main/scala/rep/api/rest/RestActor.scala @@ -17,6 +17,7 @@ package rep.api.rest import akka.util.Timeout + import scala.concurrent.duration._ import rep.crypto._ import org.json4s._ @@ -25,12 +26,19 @@ import akka.actor.Props import rep.log.RepLogger import rep.network.base.ModuleBase import rep.network.consensus.byzantium.ConsensusCondition -import rep.proto.rc2.{ActionResult, ChaincodeId, Event, Transaction} +import rep.network.module.ModuleActorType +import rep.proto.rc2.{ActionResult, ChaincodeId, Event, Transaction, TransactionResult} +import rep.sc.Sandbox.DoTransactionResult +import rep.sc.TypeOfSender import rep.storage.chain.block.BlockSearcher import rep.storage.db.factory.DBFactory import rep.utils.GlobalUtils.EventType import rep.utils.{MessageToJson, SerializeUtils} +import scala.concurrent.Await +import akka.pattern.ask +import rep.sc.SandboxDispatcher.DoTransaction + /** * RestActor伴生object,包含可接受的传入消息定义,以及处理的返回结果定义。 * 以及用于建立Tranaction,检索Tranaction的静态方法 @@ -184,6 +192,24 @@ class RestActor(moduleName: String) extends ModuleBase(moduleName) { } } + private def sendTransaction(t:Transaction):Unit={ + //预执行正常,提交并广播交易 + if (config.isBroadcastTransaction) { + mediator ! Publish(Topic.Transaction, t) + sendEvent(EventType.PUBLISH_INFO, mediator, pe.getSysTag, Topic.Transaction, Event.Action.TRANSACTION) + sender ! PostResult(t.id, None, None) + }else{ + val pool = pe.getRepChainContext.getTransactionPool + if(!pool.hasOverflowed){ + pool.addTransactionToCache(t) + sendEvent(EventType.PUBLISH_INFO, mediator, pe.getSysTag, Topic.Transaction, Event.Action.TRANSACTION) + sender ! PostResult(t.id, None, None) + }else{ + sender ! PostResult(t.id, None, Option("code=901,reason=交易池已经满了")) + } + } + } + // 先检查交易大小,然后再检查交易是否已存在,再去验证签名,如果没有问题,则广播 def preTransaction(t: Transaction): Unit = { val tranLimitSize = config.getBlockMaxLength / 3 @@ -191,23 +217,33 @@ class RestActor(moduleName: String) extends ModuleBase(moduleName) { sender ! PostResult(t.id, None, Option(s"交易大小超出限制: ${tranLimitSize},请重新检查")) } else if (!this.consensusCondition.CheckWorkConditionOfSystem(pe.getRepChainContext.getNodeMgr.getStableNodes.size)) { sender ! PostResult(t.id, None, Option("共识节点数目太少,暂时无法处理交易")) + } else if (pe.getRepChainContext.getTransactionPool.isExistInCache(t.id) || sr.isExistTransactionByTxId(t.id)) { + sender ! PostResult(t.id, None, Option(s"交易ID重复, ID为:${t.id}")) } else { try { - //if (pe.getTransPoolMgr.getTransLength() < SystemProfile.getMaxCacheTransNum) { - - //pe.getTransPoolMgr.putTran(t,pe.getSysTag) - - if (config.isBroadcastTransaction) { - mediator ! Publish(Topic.Transaction, t) + val sig = t.signature.get.signature.toByteArray + val tOutSig = t.clearSignature + val certId = t.signature.get.certId.get + if (pe.getRepChainContext.getSignTool.verify(sig, tOutSig.toByteArray, certId)) { + RepLogger.info(RepLogger.Business_Logger, s"验证签名成功,txid: ${t.id},creditCode: ${t.signature.get.getCertId.creditCode}, certName: ${t.signature.get.getCertId.certName}") + if (pe.getRepChainContext.getConfig.hasPreloadOfApi) { + val future = pe.getActorRef(ModuleActorType.ActorType.transactiondispatcher) ? DoTransaction(Array(t).toSeq, "api_" + t.id, TypeOfSender.FromAPI) + val result = Await.result(future, timeout.duration).asInstanceOf[Seq[TransactionResult]] + val rv = result(0).err + rv.get.code match { + case 0 => + sendTransaction(t) + case _ => + //预执行异常,废弃交易,向api调用者发送异常 + sender ! PostResult(t.id, None, Option("code="+rv.get.code+",reason="+rv.get.reason)) + } + } else { + sendTransaction(t) + } + } else { + RepLogger.info(RepLogger.Business_Logger, s"验证签名出错,txid: ${t.id},creditCode: ${t.signature.get.getCertId.creditCode}, certName: ${t.signature.get.getCertId.certName}") + sender ! PostResult(t.id, None, Option("验证签名出错")) } - sendEvent(EventType.PUBLISH_INFO, mediator, pe.getSysTag, Topic.Transaction, Event.Action.TRANSACTION) - - - sender ! PostResult(t.id, None, None) - /*} else { - // 交易缓存池已满,不可继续提交交易 - sender ! PostResult(t.id, None, Option(s"交易缓存池已满,容量为${pe.getTransPoolMgr.getTransLength()},不可继续提交交易")) - }*/ } catch { case e: Exception => sender ! PostResult(t.id, None, Option(e.getMessage)) diff --git a/src/main/scala/rep/network/tools/transpool/PoolOfTransaction.scala b/src/main/scala/rep/network/tools/transpool/PoolOfTransaction.scala index 6cca78da..c5cd5a1c 100644 --- a/src/main/scala/rep/network/tools/transpool/PoolOfTransaction.scala +++ b/src/main/scala/rep/network/tools/transpool/PoolOfTransaction.scala @@ -142,6 +142,21 @@ class PoolOfTransaction(ctx:RepChainSystemContext) { r } + /** + * @author jiangbuyun + * @version 2.0 + * @since 2022-04-15 + * @category 根据交易Id检查交易是否已经出块 + * @param tid:String 交易Id + * @return 交易已经出块返回true,否则false + * */ + def isExistInCache(tid:String):Boolean={ + var r = false + if(this.transactionCaches.containsKey(tid)){ + r = true + } + r + } /** * @author jiangbuyun * @version 2.0