Merge branch 'dev_wuwei1972' into dev_supply

# Conflicts:
#	build.sbt
#	conf/system.conf
#	scripts/example_deploy.js
#	src/main/scala/ContractAssetsTPL.scala
#	src/main/scala/Contractback.txt
#	src/main/scala/NewContract.scala
#	src/main/scala/rep/api/SwaggerDocService.scala
#	src/main/scala/rep/api/rest/RestActor.scala
#	src/main/scala/rep/api/rest/RestService.scala
#	src/main/scala/rep/app/conf/SystemProfile.scala
#	src/main/scala/rep/crypto/ECDSASign.scala
#	src/main/scala/rep/crypto/Sha256.scala
#	src/main/scala/rep/crypto/SignFunc.scala
#	src/main/scala/rep/log/EventActor.scala
#	src/main/scala/rep/network/PeerHelper.scala
#	src/main/scala/rep/network/cache/TransactionPool.scala
#	src/main/scala/rep/network/consensus/block/BlockHelper.scala
#	src/main/scala/rep/network/consensus/block/BlockModule.scala
#	src/main/scala/rep/network/consensus/endorse/EndorsementModule.scala
#	src/main/scala/rep/network/consensus/vote/CRFDVoter.scala
#	src/main/scala/rep/network/consensus/vote/CRFDVoterModule.scala
#	src/main/scala/rep/network/consensus/vote/VoterBase.scala
#	src/main/scala/rep/network/tools/PeerExtension.scala
#	src/main/scala/rep/sc/Sandbox.scala
#	src/main/scala/rep/sc/Shim.scala
#	src/main/scala/rep/sc/contract/Compiler.scala
#	src/main/scala/rep/sc/scalax/SandboxScala.scala
#	src/main/scala/rep/storage/cfg/StoreConfig.java
#	src/main/scala/rep/storage/test/testmap.scala
#	src/main/scala/rep/storage/util/pathUtil.java
#	src/main/scala/rep/utils/SerializeUtils.scala
#	src/test/scala/rep/sc/SandboxSpec.scala
This commit is contained in:
brightestboy 2018-07-27 14:58:41 +08:00
commit 3235d348fc
28 changed files with 732 additions and 184 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/bin/

View File

@ -62,7 +62,7 @@ libraryDependencies ++= Seq(
"de.heikoseeberger" % "akka-http-json4s_2.11" % "1.16.1",
"org.json4s" %% "json4s-native" % "3.5.4",
"org.json4s" %% "json4s-jackson" % "3.5.4",
"ch.megard" %% "akka-http-cors" % "0.2.2"
)

View File

@ -70,14 +70,18 @@ akka.http {
system {
//api是否开启
//如果是单机多节点测试模式Repchain则选择0默认节点1会开启
ws_enable = 0//api 0,不开启;1,开启
ws_enable = 1//api 0,不开启;1,开启
//交易生产方式
trans_create_type = 0 //0,手动;1,自动
trans_create_type = 1 //0,手动;1,自动
//是否进行TPS测试
statistic_enable = 0 // 0,unable;able
httpServicePort = 8081//http服务的端口号默认为8081
checkCertValidate = 0//设置是否检查证书的有效性默认为0 0=不校验1=校验
contractOperationMode = 0//设置合约的运行方式0=debug方式1=deploy默认为debug方式如果发布部署必须使用deploy方式。
block {
//块内交易的最大数量
trans_num_limit = 50
@ -98,7 +102,7 @@ system {
transaction {
//辅助自动创建交易的间隔
tran_create_dur = 50 //millis
tran_create_dur = 100 //millis
//最大交易缓存量
max_cache_num = 10000
}

View File

@ -14,12 +14,9 @@
* limitations under the License.
*/
import org.json4s._
import org.json4s.jackson.JsonMethods._
import rep.sc.contract._
import scala.reflect.ManifestFactory.classType
/**
* 资产管理合约

View File

@ -14,12 +14,10 @@
* limitations under the License.
*/
import org.json4s._
import org.json4s.jackson.JsonMethods._
import rep.sc.contract._
import scala.reflect.ManifestFactory.classType
import rep.storage.FakeStorage.Key
/**
* 资产管理合约

View File

@ -178,35 +178,23 @@ class RestActor extends Actor with ModuleHelper with RepLogging {
val sig = txr.signature.toByteArray
val tOutSig1 = txr.withSignature(ByteString.EMPTY)
val tOutSig = tOutSig1.withMetadata(ByteString.EMPTY)
val peercert = ECDSASign.getCertByBitcoinAddr(txr.cert.toStringUtf8) // 从信任列表中取得证书
// TODO 把节点证书存放在worldstate中然后再取出来还原看是否和节点证书一样
// val certF = CertificateFactory.getInstance("X.509")
// val kvcer = certF.generateCertificate(new ByteArrayInputStream(cer.get)) // 从kv中获得相应的证书
// val cid = txr.payload.get.chaincodeID.get.name
val cid = ChaincodeID.fromAscii(txr.chaincodeID.toStringUtf8).name
val certKey = WorldStateKeyPreFix + cid + "_" + PRE_CERT + txr.cert.toStringUtf8
val cert = Option(sr.Get(certKey)) // 从worldstate中取证书,用户注册好像是以前缀形式写进去的
try {
if (peercert != None) {
//TODO 验证签名
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), peercert.get.getPublicKey) match {
try{
var cert = ECDSASign.getCertWithCheck(txr.cert.toStringUtf8,certKey,pe.getSysTag)
if(cert != None){
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), cert.get.getPublicKey) match {
case true =>
case false => throw new RuntimeException("验证签名出错")
}
} else if (cert != None){
if (new String(cert.get) == "null") {
throw new RuntimeException("该用户证书已注销")
}
val kvcert = SerializeUtils.deserialise(cert.get).asInstanceOf[Certificate] //rep序列化与反序列化字节数组
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), kvcert.getPublicKey) match {
case true =>
// ImpDataPreloadMgr.Free(pe.getSysTag, "preload")
case false => throw new RuntimeException("验证签名出错")
}
} else {
//TODO 没有找到证书的情况下是直接抛出错误
}else{
throw new RuntimeException("没有证书")
}
}catch{
case e : RuntimeException => throw e
}
try {
val future = sandbox ? PreTransaction(txr)
val result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
val rv = result
@ -242,6 +230,8 @@ class RestActor extends Actor with ModuleHelper with RepLogging {
val result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
val rv = result
ImpDataPreloadMgr.Free(pe.getDBTag,t.txid)
rv.err match {
case None =>
//预执行正常,提交并广播交易

View File

@ -43,15 +43,27 @@ object SystemProfile {
private[this] var _MAX_CATCH_TRANS_NUM: Int = 0//交易最多缓存数量
private[this] var _DISKSPACE_ALARM_NUM:Long=0//磁盘剩余空间预警 单位=M
private[this] var _SERVERPORT:Int=8081//http服务的端口默认为8081
private[this] var _CHECKCERTVALIDATE:Int=0//是否检查证书的有效性0不检查1检查
private[this] var _CONTRACTOPERATIONMODE = 0//设置合约的运行方式0=debug方式1=deploy默认为debug方式如果发布部署必须使用deploy方式
private def SERVERPORT :Int = _SERVERPORT
private def CHECKCERTVALIDATE:Int = _CHECKCERTVALIDATE
private def DISKSPACE_ALARM_NUM :Long = _DISKSPACE_ALARM_NUM
private def CONTRACTOPERATIONMODE:Int=_CONTRACTOPERATIONMODE
private def SERVERPORT_=(value: Int): Unit = {
_SERVERPORT = value
}
private def CHECKCERTVALIDATE_=(value: Int): Unit = {
_CHECKCERTVALIDATE = value
}
private def CONTRACTOPERATIONMODE_=(value: Int): Unit = {
_CONTRACTOPERATIONMODE = value
}
private def DISKSPACE_ALARM_NUM_=(value: Long): Unit = {
_DISKSPACE_ALARM_NUM = value
@ -116,6 +128,8 @@ object SystemProfile {
TRANS_CREATE_TYPE_=(config.getInt("system.trans_create_type"))
DISKSPACE_ALARM_NUM_=(config.getInt("system.diskspaceManager.diskspacealarm"))
SERVERPORT_=(config.getInt("system.httpServicePort"))
CHECKCERTVALIDATE_=(config.getInt("system.checkCertValidate"))
CONTRACTOPERATIONMODE_=(config.getInt("system.contractOperationMode"))
}
@ -137,4 +151,8 @@ object SystemProfile {
def getDiskSpaceAlarm = DISKSPACE_ALARM_NUM
def getHttpServicePort = SERVERPORT
def getCheckCertValidate = CHECKCERTVALIDATE
def getContractOperationMode = CONTRACTOPERATIONMODE
}

View File

@ -18,11 +18,11 @@ package rep.crypto
import java.security._
import java.io._
import java.security.cert.{ Certificate, CertificateFactory }
import rep.app.conf.SystemProfile
import com.google.protobuf.ByteString
import fastparse.utils.Base64
import rep.utils.SerializeUtils
import rep.storage._
import scala.collection.mutable
import com.fasterxml.jackson.core.Base64Variants
import java.security.cert.X509Certificate
@ -128,7 +128,14 @@ object ECDSASign extends ECDSASign {
* @return
*/
def getCertByBitcoinAddr(addr: String): Option[Certificate] = {
trustkeysPubAddrMap.get(addr)
var tmpcert = trustkeysPubAddrMap.get(addr)
if(checkCertificate(new java.util.Date(), tmpcert.get)){
tmpcert
}else{
throw new RuntimeException("证书已经过期")
}
}
/**
@ -172,8 +179,11 @@ object ECDSASign extends ECDSASign {
def getKeyPair(alias: String): (PrivateKey, PublicKey, Array[Byte]) = {
val sk = keyStore(alias).getKey(alias, password(alias).toCharArray)
val cert = keyStore(alias).getCertificate(alias)
// (sk.asInstanceOf[PrivateKey], cert.getPublicKey(), cert.getEncoded)
(sk.asInstanceOf[PrivateKey], cert.getPublicKey(), SerializeUtils.serialise(cert))
if(checkCertificate(new java.util.Date(), cert)){
(sk.asInstanceOf[PrivateKey], cert.getPublicKey(), SerializeUtils.serialise(cert))
}else{
throw new RuntimeException("证书已经过期")
}
}
/**
@ -346,4 +356,67 @@ class ECDSASign extends SignFunc {
s2.verify(signature)
}
def getCertWithCheck(certAddr:String,certKey:String,sysTag:String):Option[java.security.cert.Certificate]={
val cert = ECDSASign.getCertByBitcoinAddr(certAddr)
if(cert != None) {
if(checkCertificate(new java.util.Date(), cert.get)){
cert
}else{
throw new RuntimeException("证书已经过期")
}
}else{
if(certKey == null || sysTag == null){
throw new RuntimeException("没有证书")
}else{
try{
val sr: ImpDataAccess = ImpDataAccess.GetDataAccess(sysTag)
val cert = Option(sr.Get(certKey))
if (cert != None){
if (new String(cert.get) == "null") {
throw new RuntimeException("用户证书已经注销")
}else{
val kvcert = SerializeUtils.deserialise(cert.get).asInstanceOf[Certificate]
if(kvcert != null){
if(checkCertificate(new java.util.Date(), kvcert)){
Some(kvcert)
}else{
throw new RuntimeException("证书已经过期")
}
}else{
throw new RuntimeException("证书内容错误")
}
}
}else{
throw new RuntimeException("没有证书")
}
}catch{
case e : Exception =>throw new RuntimeException("证书获取过程中发生错误",e)
}
}
}
}
def checkCertificate(date:java.util.Date, cert:Certificate):Boolean={
var isValid :Boolean = false
var start = System.currentTimeMillis()
try {
if(SystemProfile.getCheckCertValidate == 0){
isValid = true
}else if(SystemProfile.getCheckCertValidate == 1){
if(cert.isInstanceOf[X509Certificate]){
var x509cert :X509Certificate = cert.asInstanceOf[X509Certificate]
x509cert.checkValidity(date)
isValid = true
}
}else{
isValid = true
}
} catch{
case e : Exception => isValid = false
}
var end = System.currentTimeMillis()
//println("check cert validate,spent time="+(end-start))
isValid;
}
}

View File

@ -19,16 +19,24 @@ import com.google.protobuf.ByteString
/**
* @author c4w
* modify by jiangbuyun
*/
object Sha256 extends CryptographicHash{
override val DigestSize: Int = 32
def hash(input: Array[Byte]): Array[Byte] = MessageDigest.getInstance("SHA-256").digest(input)
def hashstr(input: Array[Byte]):String ={
BytesHex.bytes2hex(hash(input))
}
def hashstr(input: String):String ={
val iptb = ByteString.copyFromUtf8(input)
BytesHex.bytes2hex(hash(iptb.toByteArray()))
}
def hashToBytes(input: String):Array[Byte] ={
val iptb = ByteString.copyFromUtf8(input)
hash(iptb.toByteArray())
}
}

View File

@ -23,4 +23,5 @@ import java.security._
trait SignFunc {
def sign(privateKey: PrivateKey, message: Array[Byte]): Array[Byte]
def verify(signature: Array[Byte], message: Array[Byte], publicKey: PublicKey): Boolean
def getCertWithCheck(certAddr:String,certKey:String,sysTag:String):Option[java.security.cert.Certificate]
}

View File

@ -123,11 +123,15 @@ object PeerHelper {
}
t = t.withTxid(txid)
//Signature
val (priKey, pubKey, cert) = ECDSASign.getKeyPair(nodeName)
t = t.withCert(ByteString.copyFromUtf8(ECDSASign.getBitcoinAddrByCert(cert)))
//Get signature with tx hashinclude cert
val sig = ECDSASign.sign(priKey,getTxHash(t))
t = t.withSignature(ByteString.copyFrom(sig))
try{
val (priKey, pubKey, cert) = ECDSASign.getKeyPair(nodeName)
t = t.withCert(ByteString.copyFromUtf8(ECDSASign.getBitcoinAddrByCert(cert)))
//Get signature with tx hashinclude cert
val sig = ECDSASign.sign(priKey,getTxHash(t))
t = t.withSignature(ByteString.copyFrom(sig))
}catch{
case e:RuntimeException => throw e
}
t
}
@ -191,13 +195,17 @@ class PeerHelper(name: String) extends ModuleBase(name) {
case TickInvoke =>
//invoke
// val cname = t.payload.get.chaincodeID.get.name
val t2 = transactionCreator(pe.getSysTag,rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
"", li1 ,List(),"", Option(chaincode),rep.protos.peer.ChaincodeSpec.CodeType.CODE_JAVASCRIPT)
//getActorRef(ActorType.TRANSACTION_POOL) ! t2
val t3 = transactionCreator(pe.getSysTag,rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
"", "transfer" ,Seq(li2),"", Option(chaincode),rep.protos.peer.ChaincodeSpec.CodeType.CODE_JAVASCRIPT)
getActorRef(ActorType.TRANSACTION_POOL) ! t3
scheduler.scheduleOnce(SystemProfile.getTranCreateDur.millis, self, TickInvoke)
try{
val t2 = transactionCreator(pe.getSysTag,rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
"", li1 ,List(),"", Option(chaincode),rep.protos.peer.ChaincodeSpec.CodeType.CODE_JAVASCRIPT)
//getActorRef(ActorType.TRANSACTION_POOL) ! t2
val t3 = transactionCreator(pe.getSysTag,rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
"", "transfer" ,Seq(li2),"", Option(chaincode),rep.protos.peer.ChaincodeSpec.CodeType.CODE_JAVASCRIPT)
getActorRef(ActorType.TRANSACTION_POOL) ! t3
scheduler.scheduleOnce(SystemProfile.getTranCreateDur.millis, self, TickInvoke)
}catch{
case e:RuntimeException => throw e
}
// println(sdf.format(System.currentTimeMillis())+" ########## "+pe.getSysTag+" ************* ")
}
}

View File

@ -74,45 +74,26 @@ class TransactionPool(moduleName: String) extends ModuleBase(moduleName) {
var result = false
val sig = t.signature.toByteArray
val tOutSig = t.withSignature(ByteString.EMPTY)
val certTx = ECDSASign.getCertByBitcoinAddr(t.cert.toStringUtf8)
certTx.getOrElse(None) match {
case None =>
val cid = ChaincodeID.fromAscii(t.chaincodeID.toStringUtf8).name
val certKey = WorldStateKeyPreFix + cid + "_" + "CERT_" + t.cert.toStringUtf8 // 普通用户证书的key
val cert = Option(dataaccess.Get(certKey)) // 从worldstate中取证书,用户注册是以前缀形式写进去的
cert.getOrElse(None) match {
case None => resultMsg = s"The transaction(${t.txid}) is not trusted"
case _ =>
if (new String(cert.get) == "null") {
throw new RuntimeException("该用户证书已注销")
}
//验证签名和内容hash
val kvcert = SerializeUtils.deserialise(cert.get).asInstanceOf[Certificate] //rep序列化与反序列化字节数组
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), kvcert.getPublicKey) match {
case true =>
val cid = ChaincodeID.fromAscii(t.chaincodeID.toStringUtf8).name
val certKey = WorldStateKeyPreFix + cid + "_" + "CERT_" + t.cert.toStringUtf8 // 普通用户证书的key
try{
var cert = ECDSASign.getCertWithCheck(t.cert.toStringUtf8,certKey,pe.getSysTag)
if(cert != None){
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), cert.get.getPublicKey) match {
case true =>
dataAccess.getBlockByTxId(t.txid) match {
case null => result = true
case _ => resultMsg = s"The transaction(${t.txid}) is duplicated with txid"
}
case false => resultMsg = s"The transaction(${t.txid}) is not completed"
}
}
}else{
throw new RuntimeException("没有证书")
}
case _ =>
val alias = ECDSASign.getAliasByCert(certTx.get).getOrElse(None)
alias match {
case None => resultMsg = s"The transaction(${t.txid}) is not trusted"
case _ =>
//验证签名和内容hash
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), certTx.get.getPublicKey) match {
case false => resultMsg = s"The transaction(${t.txid}) is not completed"
case true =>
dataAccess.getBlockByTxId(t.txid) match {
case null => result = true
case _ => resultMsg = s"The transaction(${t.txid}) is duplicated with txid"
}
}
}
}
}catch{
case e : RuntimeException => throw e
}
CheckedTransactionResult(result, resultMsg)
}

View File

@ -28,6 +28,7 @@ import rep.storage._
import java.security.cert.{ Certificate}
import rep.network.PeerHelper
import rep.utils.SerializeUtils
import scala.util.control.Breaks
/**
@ -45,9 +46,13 @@ object BlockHelper {
* @return
*/
def endorseBlock(blkHash:Array[Byte], alise:String):Endorsement ={
val (priK, pubK, cert) = ECDSASign.getKeyPair(alise)
Endorsement(ByteString.copyFromUtf8(ECDSASign.getBitcoinAddrByCert(cert)),
try{
val (priK, pubK, cert) = ECDSASign.getKeyPair(alise)
Endorsement(ByteString.copyFromUtf8(ECDSASign.getBitcoinAddrByCert(cert)),
ByteString.copyFrom(ECDSASign.sign(priK, blkHash)))
}catch{
case e:RuntimeException => throw e
}
}
/**
@ -57,16 +62,21 @@ object BlockHelper {
*/
def checkBlockContent(endor:Endorsement, blkHash: Array[Byte]): Boolean = {
//获取出块人的背书信息
val certTx = ECDSASign.getCertByBitcoinAddr(endor.endorser.toStringUtf8)
if(certTx.getOrElse(None)!=None){
// val certTx = SerializeUtils.deserialise(endor.endorser.toByteArray).asInstanceOf[Certificate]
val alias = ECDSASign.getAliasByCert(certTx.get).getOrElse(None)
if (alias == None) false
else {
ECDSASign.verify(endor.signature.toByteArray, blkHash, certTx.get.getPublicKey)
}
try{
val certTx = ECDSASign.getCertByBitcoinAddr(endor.endorser.toStringUtf8)
if(certTx.getOrElse(None)!=None){
// val certTx = SerializeUtils.deserialise(endor.endorser.toByteArray).asInstanceOf[Certificate]
val alias = ECDSASign.getAliasByCert(certTx.get).getOrElse(None)
if (alias == None) false
else {
ECDSASign.verify(endor.signature.toByteArray, blkHash, certTx.get.getPublicKey)
}
}
else false
}catch{
case e : RuntimeException => false
}
else false
}
//用于对交易对签名验证
@ -76,33 +86,19 @@ object BlockHelper {
val sig = t.signature.toByteArray
val tOutSig1 = t.withSignature(ByteString.EMPTY)
val tOutSig = tOutSig1.withMetadata(ByteString.EMPTY)
val certTx = ECDSASign.getCertByBitcoinAddr(t.cert.toStringUtf8)
certTx.getOrElse(None) match {
case None =>
try{
val cid = ChaincodeID.fromAscii(t.chaincodeID.toStringUtf8).name
val certKey = IdxPrefix.WorldStateKeyPreFix + cid + "_" + "CERT_" + t.cert.toStringUtf8 // 普通用户证书的key
val cert = Option(dataAccess.Get(certKey)) // 从worldstate中取证书,用户注册是以前缀形式写进去的
cert.getOrElse(None) match {
case None => resultMsg = s"The transaction(${t.txid}) is not trusted"
case _ =>
if (new String(cert.get) == "null") {
//throw new RuntimeException("该用户证书已注销")
resultMsg = "该用户证书已注销"
}
//验证签名和内容hash
val kvcert = SerializeUtils.deserialise(cert.get).asInstanceOf[Certificate] //rep序列化与反序列化字节数组
result = ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), kvcert.getPublicKey)
var cert = ECDSASign.getCertWithCheck(t.cert.toStringUtf8,certKey,dataAccess.getSystemName)
if(cert != None){
result = ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), cert.get.getPublicKey)
}else{
resultMsg = s"The transaction(${t.txid}) is not trusted"
}
case _ =>
val alias = ECDSASign.getAliasByCert(certTx.get).getOrElse(None)
alias match {
case None => resultMsg = s"The transaction(${t.txid}) is not trusted"
case _ =>
//验证签名和内容hash
result = ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), certTx.get.getPublicKey)
}
}
//CheckedTransactionResult(result, resultMsg)
}catch{
case e : RuntimeException => resultMsg = s"The transaction(${t.txid}) is not trusted${e.getMessage}"
}
result
}
@ -170,4 +166,70 @@ object BlockHelper {
Sha256.hashstr(blk.toByteArray)
}
def isEndorserListSorted(srclist : Array[Endorsement]):Int={
var b : Int = 0
if (srclist == null || srclist.length < 2){
b
}else{
if(srclist(0).endorser.toStringUtf8() < srclist(1).endorser.toStringUtf8() ){//升序
b = 1
}else{//降序
b = -1
}
val loopbreak = new Breaks
loopbreak.breakable(
for (i <- 1 to srclist.length-1){
if(b == 1 && srclist(i).endorser.toStringUtf8() < srclist(i-1).endorser.toStringUtf8()){
b = 0
loopbreak.break
}
if(b == -1 && srclist(i).endorser.toStringUtf8() > srclist(i-1).endorser.toStringUtf8()){
b = 0
loopbreak.break
}
}
)
}
b
}
def main(args: Array[String]): Unit = {
var eas = new Array[Endorsement](4)
var e1 = new Endorsement()
e1 = e1.withEndorser(ByteString.copyFromUtf8("sdfsdfseqqooqoq"))
e1 = e1.withSignature(ByteString.copyFromUtf8("sdfsdfseqqooqoq"))
var e2 = new Endorsement()
e2 = e2.withEndorser(ByteString.copyFromUtf8("hkg"))
e2 = e2.withSignature(ByteString.copyFromUtf8("hkg"))
var e3 = new Endorsement()
e3 = e3.withEndorser(ByteString.copyFromUtf8("wre"))
e3 = e3.withSignature(ByteString.copyFromUtf8("wre"))
var e4 = new Endorsement()
e4 = e4.withEndorser(ByteString.copyFromUtf8("yiu"))
e4 = e4.withSignature(ByteString.copyFromUtf8("yiu"))
eas(0) = e4
eas(1) = e1
eas(2) = e2
eas(3) = e3
if(isEndorserListSorted(eas) == -1 || isEndorserListSorted(eas) == 0){
println("not sorted")
}else{
println("sorted")
}
var tmpeas = eas.sortWith((endorser_left,endorser_right)=> endorser_left.endorser.toStringUtf8() < endorser_right.endorser.toStringUtf8())
if(isEndorserListSorted(tmpeas) == -1 || isEndorserListSorted(tmpeas) == 0){
println("not sorted")
}else{
println("sorted")
}
}
}

View File

@ -410,6 +410,10 @@ class BlockModule(moduleName: String) extends ModuleBase(moduleName) {
if(blc.previousBlockHash.toStringUtf8() != pe.getCurrentBlockHash){
resetVoteEnv
}else{
//调整确认块中的共识数据的顺序
var consensus = blc.consensusMetadata.toArray[Endorsement]
var tmpconsensus = consensus.sortWith((endorser_left,endorser_right)=> endorser_left.endorser.toStringUtf8() < endorser_right.endorser.toStringUtf8())
blc = blc.withConsensusMetadata(tmpconsensus)
//广播这个block
logMsg(LOG_TYPE.INFO, s"new block,nodename=${pe.getSysTag},transaction size=${blc.transactions.size},identifier=${this.blkidentifier_str},${blkidentifier},current height=${dataaccess.getBlockChainInfo().height},previoushash=${blc.previousBlockHash.toStringUtf8()}")
mediator ! Publish(Topic.Block, new ConfirmedBlock(blc, dataaccess.getBlockChainInfo().height + 1,
@ -431,7 +435,7 @@ class BlockModule(moduleName: String) extends ModuleBase(moduleName) {
//TODO kami 这是一个非常耗时的工作后续需要完善
if (!BlockHelper.checkBlockContent(endorse, Sha256.hash(blkOutEndorse.toByteArray))) isEndorsed = false
}
if (isEndorsed) {
if (isEndorsed && BlockHelper.isEndorserListSorted(endors.toArray[Endorsement])==1) {
logTime("New block, start to store", CRFD_STEP._13_NEW_BLK_START_STORE,
getActorRef(ActorType.STATISTIC_COLLECTION))
//c4w 广播接收到block事件
@ -452,9 +456,8 @@ class BlockModule(moduleName: String) extends ModuleBase(moduleName) {
logMsg(LOG_TYPE.INFO, "New block, store opt over ...")
logTime("New block, store opt over", CRFD_STEP._14_NEW_BLK_STORE_END,
getActorRef(ActorType.STATISTIC_COLLECTION))
}
else logMsg(LOG_TYPE.WARN, s"The block endorsement info is wrong. Sender : ${sender()}")
else logMsg(LOG_TYPE.WARN, s"The block endorsement info is wrong or endorser sort error. Sender : ${sender()}")
}
else logMsg(LOG_TYPE.WARN, s"The num of endorsement in block is not enough. Sender : ${sender()}")

View File

@ -73,7 +73,29 @@ class EndorsementModule(moduleName: String) extends ModuleBase(moduleName) {
)
r
}
private def hasRepeatOfTrans(trans:Seq[Transaction]):Boolean={
var isRepeat : Boolean = false
val aliaslist = trans.distinct
if(aliaslist.size != trans.size){
isRepeat = true
}else{
val sr: ImpDataAccess = ImpDataAccess.GetDataAccess(pe.getSysTag)
val loopbreak = new Breaks
loopbreak.breakable(
trans.foreach(f=>{
if(sr.getBlockByTxId(f.txid) != null){
isRepeat = true
loopbreak.break
}
})
)
}
isRepeat
}
private def endorseForWork(blk:Block, actRef: ActorRef,blkidentifier:String)={
val dbinstancename = "endorse_"+blk.transactions.head.txid
val preload: ImpDataPreload = ImpDataPreloadMgr.GetImpDataPreload(pe.getSysTag,dbinstancename)
@ -81,21 +103,30 @@ class EndorsementModule(moduleName: String) extends ModuleBase(moduleName) {
val blkData = blk.withConsensusMetadata(Seq())
val blkInfo = Sha256.hash(blkData.toByteArray)
if (BlockHelper.checkBlockContent(blk.consensusMetadata.head, blkInfo)) {
if(verifyTransSign(blk.transactions)){
if(preload.VerifyForEndorsement(blk)){
logMsg(LOG_TYPE.WARN, s"Block endorse success,current height=${pe.getCacheHeight()},identifier=${blkidentifier}")
actRef ! EndorsedBlock(true, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
//广播发送背书信息的事件(背书成功)
sendEvent(EventType.PUBLISH_INFO, mediator, selfAddr, Topic.Block, Event.Action.ENDORSEMENT)
}else{
logMsg(LOG_TYPE.WARN, "Transcation preload failed,Block endorse failed")
actRef! EndorsedBlock(false, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
}
if(!hasRepeatOfTrans(blk.transactions)){
if(verifyTransSign(blk.transactions)){
if(preload.VerifyForEndorsement(blk)){
logMsg(LOG_TYPE.WARN, s"Block endorse success,current height=${pe.getCacheHeight()},identifier=${blkidentifier}")
actRef ! EndorsedBlock(true, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
//广播发送背书信息的事件(背书成功)
sendEvent(EventType.PUBLISH_INFO, mediator, selfAddr, Topic.Block, Event.Action.ENDORSEMENT)
}else{
logMsg(LOG_TYPE.WARN, "Transcation preload failed,Block endorse failed")
actRef! EndorsedBlock(false, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
}
}else{
logMsg(LOG_TYPE.WARN, "Transcation Certification vertified failed")
actRef! EndorsedBlock(false, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
}
}else{
logMsg(LOG_TYPE.WARN, "Transcation Certification vertified failed")
logMsg(LOG_TYPE.WARN, "Transcation vertified failed,found same Transcation")
actRef! EndorsedBlock(false, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
}
}
else logMsg(LOG_TYPE.WARN, "Blocker Certification vertified failed")
else {
logMsg(LOG_TYPE.WARN, "Blocker Certification vertified failed")
actRef! EndorsedBlock(false, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
}
logTime("Endorse end", CRFD_STEP._9_ENDORSE_END, getActorRef(ActorType.STATISTIC_COLLECTION))
logMsg(LOG_TYPE.WARN, s"Block endorse finish,current height=${pe.getCacheHeight()},identifier=${blkidentifier}")
} catch {

View File

@ -17,6 +17,7 @@ package rep.network.consensus.vote
import rep.crypto.Sha256
import scala.collection.mutable
import rep.storage.util.pathUtil
/**
* 系统默认
@ -28,23 +29,50 @@ import scala.collection.mutable
*/
//TODO kami 应该在init的时候载入一个实现函数或者类然后调用方法写的更通用一些
trait CRFDVoter extends VoterBase {
override def blocker(nodes: Set[String], position:Int): Option[String] = {
//if (nodes.nonEmpty&&position<nodes.size) Option(nodes.head) else None
case class randomNumber(var number:Long,var generateSerial:Int,var sortPos:Int)
override def blocker(nodes: Array[String], position:Int): String = {
if(nodes.nonEmpty){
var pos = position
if(position >= nodes.size){
pos = position % nodes.size
}
val a = nodes.toList
Option(a(pos))
nodes(pos)
}else{
None
null
}
}
override def candidators(nodes: Set[String], seed: Array[Byte]): Set[String] = {
var nodesSeq = nodes.toSeq.sortBy(f=>(f.toString()))//nodes.toSeq
private def getRandomList(seed:Long,candidatorLen:Int,candidatorTotal:Int):Array[randomNumber]={
val m = 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2
val a = 2045
val b = 1
var randomArray = new Array[randomNumber](candidatorTotal)
var hashSeed = seed.abs
for(i<-0 to candidatorTotal-1){
var tmpSeed = (a * hashSeed + b) % m
tmpSeed = tmpSeed.abs
if(tmpSeed == hashSeed) tmpSeed = tmpSeed + 1
hashSeed = tmpSeed
var randomobj = new randomNumber(hashSeed,i,-1)
randomArray(i) = randomobj
}
randomArray = randomArray.sortWith(
(randomNumber_left,randomNumber_right)=> randomNumber_left.number < randomNumber_right.number)
for(i<-0 to randomArray.size-1){
randomArray(i).sortPos = i
}
randomArray = randomArray.sortWith(
(randomNumber_left,randomNumber_right)=> randomNumber_left.generateSerial < randomNumber_right.generateSerial)
randomArray
}
override def candidators(nodes: Set[String], seed: Array[Byte]): Array[String] = {
var nodesSeq = nodes.toSeq.sortBy(f=>(f.toString()))
var len = nodes.size / 2 + 1
val min_len = 4
len = if(len<min_len){
@ -53,27 +81,21 @@ trait CRFDVoter extends VoterBase {
}
else len
if(len<4){
Set.empty
null
}
else{
var candidate = mutable.Seq.empty[String]
var index = 0
var hashSeed = seed
while (candidate.size < len) {
if (index >= hashSeed.size) {
hashSeed = Sha256.hash(hashSeed)
index = 0
}
//应该按位来计算
if ((hashSeed(index) & 1) == 1) {
candidate = (candidate :+ nodesSeq(index % (nodesSeq.size)))
nodesSeq = (nodesSeq.toSet - nodesSeq(index % (nodesSeq.size))).toSeq
}
index += 1
var candidate = new Array[String](len)
var hashSeed:Long = pathUtil.bytesToInt(seed)
var randomList = getRandomList(hashSeed,len,nodes.size)
//PrintRandomArray(randomList)
println(randomList(0).sortPos)
for(j<-0 to len-1){
var e = randomList(j)
candidate(j) = nodesSeq(e.sortPos)
}
candidate.toSet
candidate
}
}
}

View File

@ -78,7 +78,7 @@ class CRFDVoterModule(moduleName: String) extends ModuleBase(moduleName) with CR
def rnd = ThreadLocalRandom.current
var candidatorCur = Set.empty[ String ]
var candidatorCur : Array[ String ] = null
var isWaiting = false
@ -167,15 +167,15 @@ class CRFDVoterModule(moduleName: String) extends ModuleBase(moduleName) with CR
val seed = pe.getVoteBlockHash//pe.getCurrentBlockHash
candidatorCur = candidators(SystemCertList.getSystemCertList, Sha256.hash(seed))
if (!candidatorCur.isEmpty) {
if (candidatorCur != null) {
pe.resetCandidator(candidatorCur)
if(pe.getCacheHeight() >= 1){
val blo = blocker(candidatorCur, pe.getBlker_index)
if (blo != None) {
pe.resetBlocker(blo.get)
if (blo != null) {
pe.resetBlocker(blo)
//暂时只找到该方法能够明确标识一个在网络中有网络地址的节点后续发现好方法可以完善
logMsg(LOG_TYPE.INFO, s"Select in getCacheHeight=${pe.getCacheHeight()} Candidates : ${candidatorCur} ~ Blocker : ${blo},currenthash=${pe.getCurrentBlockHash},index=${pe.getBlker_index}")
if (pe.getSysTag == blo.get.toString()) {
if (pe.getSysTag == blo) {
getActorRef(ActorType.BLOCK_MODULE) ! (BlockEvent.CREATE_BLOCK, "")
logMsg(LOG_TYPE.INFO, s"Select in getCacheHeight=${pe.getCacheHeight()} Candidates : ${candidatorCur} ,send Create cmd~ Blocker : ${blo},currenthash=${pe.getCurrentBlockHash},index=${pe.getBlker_index}")
}

View File

@ -35,7 +35,7 @@ trait VoterBase {
* @return
*/
//def blocker[T](nodes:Set[T], position:Int):Option[T]
def blocker(nodes:Set[String], position:Int):Option[String]
def blocker(nodes:Array[String], position:Int):String
/**
* 获取候选人节点
@ -45,5 +45,5 @@ trait VoterBase {
* @return
*/
//def candidators[T](nodes:Set[T], seed:Array[Byte]):Set[T]
def candidators(nodes:Set[String], seed:Array[Byte]):Set[String]
def candidators(nodes:Set[String], seed:Array[Byte]):Array[String]
}

View File

@ -259,8 +259,8 @@ class PeerExtensionImpl extends Extension {
candidatorLock.unlock()
}
}
def resetCandidator(nds: Set[ String ]): Unit = {
def resetCandidator(nds: Array[ String ]): Unit = {
candidatorLock.lock()
try{
candidator = immutable.TreeMap.empty[String,String]

View File

@ -100,7 +100,7 @@ abstract class Sandbox(cid:String) extends Actor with RepLogging{
sender ! tr
//交易预处理请求指定接收者
case PreTransaction(t:Transaction) =>
val tr = doTransaction(t,null,null)
val tr = doTransaction(t,null,t.txid)
shim.rollback()
sender ! tr
//恢复chainCode,不回消息

View File

@ -213,12 +213,15 @@ class Shim(system: ActorSystem, cid: String) {
val sig = tx.signature.toByteArray
val tOutSig1 = tx.withSignature(ByteString.EMPTY)
val tOutSig = tOutSig1.withMetadata(ByteString.EMPTY)
val peercer = ECDSASign.getCertByBitcoinAddr(bitcoinaddr)
if (peercer == None)
throw new Exception(NOT_PERR_CERT)
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), peercer.get.getPublicKey) match {
case true =>
case false => throw new Exception("节点签名验证错误")
try{
val peercer = ECDSASign.getCertByBitcoinAddr(bitcoinaddr)
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), peercer.get.getPublicKey) match {
case true =>
case false => throw new Exception("节点签名验证错误")
}
}catch{
case e : RuntimeException => throw e
}
}

View File

@ -28,9 +28,10 @@ import org.json4s._
import org.json4s.jackson.JsonMethods._
import rep.crypto.Sha256
import rep.app.conf.SystemProfile
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
import scala.util.matching.Regex
import rep.storage.util.pathUtil
/**
* 动态编译工具类的伴生对象提供静态方法
@ -38,7 +39,13 @@ import scala.util.matching.Regex
*/
object Compiler{
//建立动态编译工具类实例
val cp = new Compiler(None, true)
val contractOperationMode = SystemProfile.getContractOperationMode
var isDebug = true
contractOperationMode match{
case 0 => isDebug = true
case 1 => isDebug = false
}
val cp = new Compiler(None, isDebug)
/** 根据传入的合约代码,以及指定的合约类唯一标识,生成合约类,并动态编译
* @param pcode 合约代码主体部分
* @cid 合约类唯一标识
@ -61,7 +68,7 @@ class Compiler(targetDir: Option[File], bDebug:Boolean) {
//反射工具对象
val tb = currentMirror.mkToolBox()
//源文件路径
val path_source = if(bDebug) getSourcePath else null
val path_source = if(bDebug) getSourcePath else pathUtil.getPath("custom_contract")
//目标文件路径
val target = targetDir match {
case Some(dir) => AbstractFile.getDirectory(dir)

View File

@ -156,13 +156,13 @@ public class StoreConfig {
public long getFreeDiskSpace(){
String bpath = this.getBlockPath();
/*try {
try {
if(pathUtil.FileExists(bpath) == -1){
pathUtil.MkdirAll(bpath);
}
} catch (Exception e) {
e.printStackTrace();
}*/
}
File f = new File(bpath);
long l = f.getFreeSpace();
return l;

View File

@ -0,0 +1,207 @@
package rep.storage.test
import scala.collection.mutable
import rep.crypto.Sha256
import rep.storage.util.pathUtil
object testRandomVote {
case class randomstatis(listsize:Int,clist:scala.collection.mutable.ArrayBuffer[String])
case class randomNumber(var number:Long,var generateSerial:Int,var sortPos:Int)
var statisvar:randomstatis = null
var statis:Array[Int] = null
def getRandomList(seed:Long,candidatorLen:Int,candidatorTotal:Int):Array[randomNumber]={
val m = 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2
val a = 2045
val b = 1
var randomArray = new Array[randomNumber](candidatorTotal)
var hashSeed = seed.abs
for(i<-0 to candidatorTotal-1){
var tmpSeed = (a * hashSeed + b) % m
tmpSeed = tmpSeed.abs
if(tmpSeed == hashSeed) tmpSeed = tmpSeed + 1
hashSeed = tmpSeed
var randomobj = new randomNumber(hashSeed,i,-1)
randomArray(i) = randomobj
}
randomArray = randomArray.sortWith(
(randomNumber_left,randomNumber_right)=> randomNumber_left.number < randomNumber_right.number)
for(i<-0 to randomArray.size-1){
randomArray(i).sortPos = i
}
randomArray = randomArray.sortWith(
(randomNumber_left,randomNumber_right)=> randomNumber_left.generateSerial < randomNumber_right.generateSerial)
randomArray
}
def PrintRandomArray(ra : Array[randomNumber])={
if(ra == null) println("no data,input is null")
if(ra.size == 0) println("no data, input length is zero")
for(i<-0 to (ra.length-1)){
println("randomnumber="+ra(i).number+",generateSerial="+ra(i).generateSerial+",sortpos="+ra(i).sortPos+"|||")
}
}
def getRandomString(length:Int):String={
val str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var random=new util.Random()
var sb=new StringBuffer()
for( i<-0 to length-1){
val number= random.nextInt(62)
sb.append(str.charAt(number))
}
sb.toString()
}
def getRandomSha256String(length:Int): Array[Byte]={
val s = getRandomString(length)
//println(Sha256.hashstr(s))
Sha256.hashToBytes(s)
}
def findIndex(indexs:Array[Int],idx:Int):Boolean={
var b = false
for( i<-0 to indexs.length-1){
if(indexs(i) == idx){
b = true
}
}
b
}
def candidators(nodes: Set[String], seed: Array[Byte]): Array[String] = {
var nodesSeq = nodes.toSeq.sortBy(f=>(Integer.parseInt(f.toString())))
var len = nodes.size / 2 + 1
val min_len = 4
len = if(len<min_len){
if(nodes.size < min_len) nodes.size
else min_len
}
else len
if(len<4){
null
}
else{
//var candidate = mutable.Seq.empty[String]
var candidate = new Array[String](len)
var hashSeed:Long = pathUtil.bytesToInt(seed)
var randomList = getRandomList(hashSeed,len,nodes.size)
//PrintRandomArray(randomList)
println(randomList(0).sortPos)
for(j<-0 to len-1){
var e = randomList(j)
//candidate = (candidate :+ nodesSeq(e.sortPos))
candidate(j) = nodesSeq(e.sortPos)
}
//candidate.toSet
candidate
}
}
def blocker(nodes: Array[String], position:Int): String = {
if(nodes.nonEmpty){
var pos = position
if(position >= nodes.size){
pos = position % nodes.size
}
val a = nodes.toList
nodes(pos)
}else{
null
}
}
def getStableNodes(length:Int) :Set[String] = {
var source = Set.empty[String]
for(i <- 0 to length-1){
source += i.toString()
}
source
}
def checkblker(nodecount:Int,pos:Int)={
val c = getStableNodes(nodecount)
val hashbytes = getRandomSha256String(500)
val cs = candidators(c, hashbytes)
val blo = blocker(cs, pos)
//statisvar.clist += blo.toString()
//println(cs.toString()+"\t"+blo.toString())
val idx = Integer.parseInt(blo)
statis(idx) = statis(idx) + 1
//println(blo.toString())
}
def testRandomBlocker(count:Int,nodes:Int,pos:Int){
//statisvar = new randomstatis(count,new scala.collection.mutable.ArrayBuffer[String](count))
statis = new Array[Int](nodes)
for(i<-0 to count-1){
checkblker(nodes,pos)
}
//println(statisvar.clist.toString())
for(j<-0 to statis.length-1) print(","+"blocker="+j+"("+statis(j).toString()+")")
}
def printRandom(size:Int){
for(j<-0 to 1000){
val istr = getRandomSha256String(500)
var i = pathUtil.bytesToInt(istr)
if(i < 0){
i = i.abs
}
println("\t"+i % size)
}
}
def testPrintRandomArray(len:Int,size:Int){
for(j<-0 to 1000){
val istr = getRandomSha256String(500)
var seed = pathUtil.bytesToInt(istr)
var ra = getRandomList(seed,len,size)
PrintRandomArray(ra)
println("-------------------")
}
}
def printRandomlist(size:Int){
val m = 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2//43112609
val a = 2045//12477 // a = 4p + 1 3119
val b = 1//4667 // b = 2q + 1 2333
var tmpstatis = new Array[Int](size)
val istr = getRandomSha256String(500)
var l = pathUtil.bytesToInt(istr)
if(l < 0){
l = l.abs
}
for(i<-0 to 1000){
l = a*l+b
if(l < 0) l = l.abs
tmpstatis(l % size) = tmpstatis(l % size) +1
println("\t"+l % size)
}
for(j<-0 to tmpstatis.length-1)
print(","+tmpstatis(j))
}
def main(args: Array[String]): Unit = {
//println(pathUtil.IsPrime(2333))
testRandomBlocker(100000,5,0)
//printRandom(4)
//printRandomlist(30)
//testPrintRandomArray(16,30)
}
}

View File

@ -256,9 +256,21 @@ def testTreeMapclear{
println(tm)
}
case class myobject(txid:String,name:String)
def main(args: Array[String]): Unit = {
//testTreeMap
testTreeMapclear
//testTreeMapclear
var as = new Array[myobject](5)
as(0) = new myobject("1","name1")
as(1) = new myobject("2","name2")
as(2) = new myobject("3","name3")
as(3) = new myobject("2","name2")
as(4) = new myobject("5","name5")
val tmp = as.distinct
println("tmpsize="+tmp.length+",assize="+as.length)
}
}

View File

@ -119,4 +119,40 @@ public class pathUtil {
}
return l;
}
public static int bytesToInt(byte[] inputs){
if(inputs == null) return 0;
if(inputs.length < 4) return 0;
return (inputs[0] & 0xff) << 24
| (inputs[1] & 0xff) << 16
| (inputs[2] & 0xff) << 8
| (inputs[3] & 0xff) << 0 ;
}
public static boolean IsPrime(int n){
if (n <= 3) {
return n > 1;
}
for(int i=2;i<=Math.sqrt(n);i++){
if(n%i == 0)
return false;
}
return true;
}
public static String getPath(String spath) {
String p = spath;
try {
File f = new File(spath);
if(!f.exists()){
MkdirAll(f.getAbsolutePath());
}
p = f.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
}
return p;
}
}

View File

@ -63,7 +63,7 @@ object SerializeUtils {
}
/**
* Json对象反序列化,由于没有给出造型类型,无法胜任复杂对象
* Json对象反序列化
* @param bytes
* @return
*/

View File

@ -116,7 +116,7 @@ class SandboxSpec(_system: ActorSystem)
val dbTag = "1"
//加载合约脚本
// val s1 = scala.io.Source.fromFile("src/main/scala/ContractAssetsTPL.scala")
val s1 = scala.io.Source.fromFile("src/main/scala/rep/sc/tpl/NewContract.scala")
val s1 = scala.io.Source.fromFile("src/main/scala/NewContract.scala")
val l1 = try s1.mkString finally s1.close()
//val clazz = Compiler.compilef(l1,null)
@ -197,4 +197,90 @@ class SandboxSpec(_system: ActorSystem)
re3 should be("transfer ok")
}
}
//JavaScript的合约实现同一个合约串行执行测试
"sandbox" should "process trasactions Synchronously" in {
val sysName = "1"
//建立PeerManager实例是为了调用transactionCreator(需要用到密钥签名)无他
val f1 =
"""
var Thread = Java.type("java.lang.Thread");
function waitprint(span,output) {
Thread.sleep(span);
print(output);
return output
}
"""
val s1 =
"""
waitprint(5000,"FirstPrint");
"""
val s2 =
"""
waitprint(5,"SecondPrint");
"""
val probe = TestProbe()
val db = ImpDataAccess.GetDataAccess(sysName)
var sandbox = system.actorOf(TransProcessor.props("sandbox", "", probe.ref))
//deploy
val t1 = transactionCreator(sysName, rep.protos.peer.Transaction.Type.CHAINCODE_DEPLOY,
"", "", List(), f1, None)
val msg_send1 = new DoTransaction(t1, probe.ref, "")
probe.send(sandbox, msg_send1)
val msg_recv1 = probe.expectMsgType[Sandbox.DoTransactionResult](10000.seconds)
//invoke
val cname = t1.payload.get.chaincodeID.get.name
val t2 = transactionCreator(sysName, rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
"", s1, List(), "", Option(cname))
val msg_send2 = new DoTransaction(t2, probe.ref, "")
probe.send(sandbox, msg_send2)
val msg_recv2 = probe.expectMsgType[Sandbox.DoTransactionResult](10000.seconds)
val rv2 = msg_recv2.r.asInstanceOf[JValue]
val re2 = rv2.extract[String]
re2 should be("FirstPrint")
val t3 = transactionCreator(sysName, rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
"", s2, List(), "", Option(cname))
val msg_send3 = new DoTransaction(t3, probe.ref, "")
probe.send(sandbox, msg_send3)
val msg_recv3 = probe.expectMsgType[Sandbox.DoTransactionResult](10000.seconds)
val rv3 = msg_recv3.r.asInstanceOf[JValue]
rv3.extract[String] should be("SecondPrint")
}
//在合约脚本中访问正在处理的签名交易测试
"sandbox scripts" should "can access the Trasaction being processed" in {
val sysName = "1"
val f1 =
"""
print(tx);
"""
val s1 =
"""
r=tx;
"""
val probe = TestProbe()
val db = ImpDataAccess.GetDataAccess(sysName)
var sandbox = system.actorOf(TransProcessor.props("sandbox", "", probe.ref))
//deploy
val t1 = transactionCreator(sysName, rep.protos.peer.Transaction.Type.CHAINCODE_DEPLOY,
"", "", List(), f1, None)
val msg_send1 = new DoTransaction(t1, probe.ref, "")
probe.send(sandbox, msg_send1)
val msg_recv1 = probe.expectMsgType[Sandbox.DoTransactionResult](10000.seconds)
//invoke
val cname = t1.payload.get.chaincodeID.get.name
val t2 = transactionCreator(sysName, rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
"", s1, List(), "", Option(cname))
val msg_send2 = new DoTransaction(t2, probe.ref, "")
probe.send(sandbox, msg_send2)
val msg_recv2 = probe.expectMsgType[Sandbox.DoTransactionResult](10000.seconds)
val rv2 = msg_recv2.r.asInstanceOf[JValue]
val re2 = rv2.extract[Transaction]
re2.txid should be(t2.txid)
}
}