mirror of
https://gitee.com/BTAJL/repchain.git
synced 2024-12-03 20:28:35 +08:00
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:
commit
3235d348fc
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/bin/
|
@ -62,7 +62,7 @@ libraryDependencies ++= Seq(
|
|||||||
"de.heikoseeberger" % "akka-http-json4s_2.11" % "1.16.1",
|
"de.heikoseeberger" % "akka-http-json4s_2.11" % "1.16.1",
|
||||||
"org.json4s" %% "json4s-native" % "3.5.4",
|
"org.json4s" %% "json4s-native" % "3.5.4",
|
||||||
"org.json4s" %% "json4s-jackson" % "3.5.4",
|
"org.json4s" %% "json4s-jackson" % "3.5.4",
|
||||||
|
|
||||||
"ch.megard" %% "akka-http-cors" % "0.2.2"
|
"ch.megard" %% "akka-http-cors" % "0.2.2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -70,14 +70,18 @@ akka.http {
|
|||||||
system {
|
system {
|
||||||
//api是否开启
|
//api是否开启
|
||||||
//如果是单机多节点测试模式(Repchain,则选择0,默认节点1会开启)
|
//如果是单机多节点测试模式(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测试
|
//是否进行TPS测试
|
||||||
statistic_enable = 0 // 0,unable;able
|
statistic_enable = 0 // 0,unable;able
|
||||||
|
|
||||||
httpServicePort = 8081//http服务的端口号,默认为8081
|
httpServicePort = 8081//http服务的端口号,默认为8081
|
||||||
|
|
||||||
|
checkCertValidate = 0//设置是否检查证书的有效性,默认为0 0=不校验,1=校验
|
||||||
|
|
||||||
|
contractOperationMode = 0//设置合约的运行方式,0=debug方式,1=deploy,默认为debug方式,如果发布部署,必须使用deploy方式。
|
||||||
|
|
||||||
block {
|
block {
|
||||||
//块内交易的最大数量
|
//块内交易的最大数量
|
||||||
trans_num_limit = 50
|
trans_num_limit = 50
|
||||||
@ -98,7 +102,7 @@ system {
|
|||||||
|
|
||||||
transaction {
|
transaction {
|
||||||
//辅助自动创建交易的间隔
|
//辅助自动创建交易的间隔
|
||||||
tran_create_dur = 50 //millis
|
tran_create_dur = 100 //millis
|
||||||
//最大交易缓存量
|
//最大交易缓存量
|
||||||
max_cache_num = 10000
|
max_cache_num = 10000
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import org.json4s._
|
import org.json4s._
|
||||||
import org.json4s.jackson.JsonMethods._
|
import org.json4s.jackson.JsonMethods._
|
||||||
import rep.sc.contract._
|
import rep.sc.contract._
|
||||||
import scala.reflect.ManifestFactory.classType
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 资产管理合约
|
* 资产管理合约
|
||||||
|
@ -14,12 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import org.json4s._
|
import org.json4s._
|
||||||
import org.json4s.jackson.JsonMethods._
|
import org.json4s.jackson.JsonMethods._
|
||||||
import rep.sc.contract._
|
import rep.sc.contract._
|
||||||
import scala.reflect.ManifestFactory.classType
|
import rep.storage.FakeStorage.Key
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 资产管理合约
|
* 资产管理合约
|
||||||
|
@ -178,35 +178,23 @@ class RestActor extends Actor with ModuleHelper with RepLogging {
|
|||||||
val sig = txr.signature.toByteArray
|
val sig = txr.signature.toByteArray
|
||||||
val tOutSig1 = txr.withSignature(ByteString.EMPTY)
|
val tOutSig1 = txr.withSignature(ByteString.EMPTY)
|
||||||
val tOutSig = tOutSig1.withMetadata(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 cid = ChaincodeID.fromAscii(txr.chaincodeID.toStringUtf8).name
|
||||||
val certKey = WorldStateKeyPreFix + cid + "_" + PRE_CERT + txr.cert.toStringUtf8
|
val certKey = WorldStateKeyPreFix + cid + "_" + PRE_CERT + txr.cert.toStringUtf8
|
||||||
val cert = Option(sr.Get(certKey)) // 从worldstate中取证书,用户注册好像是以前缀形式写进去的
|
try{
|
||||||
try {
|
var cert = ECDSASign.getCertWithCheck(txr.cert.toStringUtf8,certKey,pe.getSysTag)
|
||||||
if (peercert != None) {
|
if(cert != None){
|
||||||
//TODO 验证签名
|
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), cert.get.getPublicKey) match {
|
||||||
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), peercert.get.getPublicKey) match {
|
|
||||||
case true =>
|
case true =>
|
||||||
case false => throw new RuntimeException("验证签名出错")
|
case false => throw new RuntimeException("验证签名出错")
|
||||||
}
|
}
|
||||||
} else if (cert != None){
|
}else{
|
||||||
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 没有找到证书的情况下,是直接抛出错误
|
|
||||||
throw new RuntimeException("没有证书")
|
throw new RuntimeException("没有证书")
|
||||||
}
|
}
|
||||||
|
}catch{
|
||||||
|
case e : RuntimeException => throw e
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
val future = sandbox ? PreTransaction(txr)
|
val future = sandbox ? PreTransaction(txr)
|
||||||
val result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
|
val result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
|
||||||
val rv = result
|
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 result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
|
||||||
val rv = result
|
val rv = result
|
||||||
|
|
||||||
|
ImpDataPreloadMgr.Free(pe.getDBTag,t.txid)
|
||||||
|
|
||||||
rv.err match {
|
rv.err match {
|
||||||
case None =>
|
case None =>
|
||||||
//预执行正常,提交并广播交易
|
//预执行正常,提交并广播交易
|
||||||
|
@ -43,15 +43,27 @@ object SystemProfile {
|
|||||||
private[this] var _MAX_CATCH_TRANS_NUM: Int = 0//交易最多缓存数量
|
private[this] var _MAX_CATCH_TRANS_NUM: Int = 0//交易最多缓存数量
|
||||||
private[this] var _DISKSPACE_ALARM_NUM:Long=0//磁盘剩余空间预警 单位=M
|
private[this] var _DISKSPACE_ALARM_NUM:Long=0//磁盘剩余空间预警 单位=M
|
||||||
private[this] var _SERVERPORT:Int=8081//http服务的端口,默认为8081
|
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 SERVERPORT :Int = _SERVERPORT
|
||||||
|
private def CHECKCERTVALIDATE:Int = _CHECKCERTVALIDATE
|
||||||
private def DISKSPACE_ALARM_NUM :Long = _DISKSPACE_ALARM_NUM
|
private def DISKSPACE_ALARM_NUM :Long = _DISKSPACE_ALARM_NUM
|
||||||
|
private def CONTRACTOPERATIONMODE:Int=_CONTRACTOPERATIONMODE
|
||||||
|
|
||||||
|
|
||||||
private def SERVERPORT_=(value: Int): Unit = {
|
private def SERVERPORT_=(value: Int): Unit = {
|
||||||
_SERVERPORT = value
|
_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 = {
|
private def DISKSPACE_ALARM_NUM_=(value: Long): Unit = {
|
||||||
_DISKSPACE_ALARM_NUM = value
|
_DISKSPACE_ALARM_NUM = value
|
||||||
@ -116,6 +128,8 @@ object SystemProfile {
|
|||||||
TRANS_CREATE_TYPE_=(config.getInt("system.trans_create_type"))
|
TRANS_CREATE_TYPE_=(config.getInt("system.trans_create_type"))
|
||||||
DISKSPACE_ALARM_NUM_=(config.getInt("system.diskspaceManager.diskspacealarm"))
|
DISKSPACE_ALARM_NUM_=(config.getInt("system.diskspaceManager.diskspacealarm"))
|
||||||
SERVERPORT_=(config.getInt("system.httpServicePort"))
|
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 getDiskSpaceAlarm = DISKSPACE_ALARM_NUM
|
||||||
|
|
||||||
def getHttpServicePort = SERVERPORT
|
def getHttpServicePort = SERVERPORT
|
||||||
|
|
||||||
|
def getCheckCertValidate = CHECKCERTVALIDATE
|
||||||
|
|
||||||
|
def getContractOperationMode = CONTRACTOPERATIONMODE
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,11 @@ package rep.crypto
|
|||||||
import java.security._
|
import java.security._
|
||||||
import java.io._
|
import java.io._
|
||||||
import java.security.cert.{ Certificate, CertificateFactory }
|
import java.security.cert.{ Certificate, CertificateFactory }
|
||||||
|
import rep.app.conf.SystemProfile
|
||||||
import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
import fastparse.utils.Base64
|
import fastparse.utils.Base64
|
||||||
import rep.utils.SerializeUtils
|
import rep.utils.SerializeUtils
|
||||||
|
import rep.storage._
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import com.fasterxml.jackson.core.Base64Variants
|
import com.fasterxml.jackson.core.Base64Variants
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
@ -128,7 +128,14 @@ object ECDSASign extends ECDSASign {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def getCertByBitcoinAddr(addr: String): Option[Certificate] = {
|
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]) = {
|
def getKeyPair(alias: String): (PrivateKey, PublicKey, Array[Byte]) = {
|
||||||
val sk = keyStore(alias).getKey(alias, password(alias).toCharArray)
|
val sk = keyStore(alias).getKey(alias, password(alias).toCharArray)
|
||||||
val cert = keyStore(alias).getCertificate(alias)
|
val cert = keyStore(alias).getCertificate(alias)
|
||||||
// (sk.asInstanceOf[PrivateKey], cert.getPublicKey(), cert.getEncoded)
|
if(checkCertificate(new java.util.Date(), cert)){
|
||||||
(sk.asInstanceOf[PrivateKey], cert.getPublicKey(), SerializeUtils.serialise(cert))
|
(sk.asInstanceOf[PrivateKey], cert.getPublicKey(), SerializeUtils.serialise(cert))
|
||||||
|
}else{
|
||||||
|
throw new RuntimeException("证书已经过期")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -346,4 +356,67 @@ class ECDSASign extends SignFunc {
|
|||||||
s2.verify(signature)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -19,16 +19,24 @@ import com.google.protobuf.ByteString
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author c4w
|
* @author c4w
|
||||||
|
* modify by jiangbuyun
|
||||||
*/
|
*/
|
||||||
object Sha256 extends CryptographicHash{
|
object Sha256 extends CryptographicHash{
|
||||||
override val DigestSize: Int = 32
|
override val DigestSize: Int = 32
|
||||||
def hash(input: Array[Byte]): Array[Byte] = MessageDigest.getInstance("SHA-256").digest(input)
|
def hash(input: Array[Byte]): Array[Byte] = MessageDigest.getInstance("SHA-256").digest(input)
|
||||||
|
|
||||||
def hashstr(input: Array[Byte]):String ={
|
def hashstr(input: Array[Byte]):String ={
|
||||||
BytesHex.bytes2hex(hash(input))
|
BytesHex.bytes2hex(hash(input))
|
||||||
}
|
}
|
||||||
|
|
||||||
def hashstr(input: String):String ={
|
def hashstr(input: String):String ={
|
||||||
val iptb = ByteString.copyFromUtf8(input)
|
val iptb = ByteString.copyFromUtf8(input)
|
||||||
BytesHex.bytes2hex(hash(iptb.toByteArray()))
|
BytesHex.bytes2hex(hash(iptb.toByteArray()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def hashToBytes(input: String):Array[Byte] ={
|
||||||
|
val iptb = ByteString.copyFromUtf8(input)
|
||||||
|
hash(iptb.toByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -23,4 +23,5 @@ import java.security._
|
|||||||
trait SignFunc {
|
trait SignFunc {
|
||||||
def sign(privateKey: PrivateKey, message: Array[Byte]): Array[Byte]
|
def sign(privateKey: PrivateKey, message: Array[Byte]): Array[Byte]
|
||||||
def verify(signature: Array[Byte], message: Array[Byte], publicKey: PublicKey): Boolean
|
def verify(signature: Array[Byte], message: Array[Byte], publicKey: PublicKey): Boolean
|
||||||
|
def getCertWithCheck(certAddr:String,certKey:String,sysTag:String):Option[java.security.cert.Certificate]
|
||||||
}
|
}
|
@ -123,11 +123,15 @@ object PeerHelper {
|
|||||||
}
|
}
|
||||||
t = t.withTxid(txid)
|
t = t.withTxid(txid)
|
||||||
//Signature
|
//Signature
|
||||||
val (priKey, pubKey, cert) = ECDSASign.getKeyPair(nodeName)
|
try{
|
||||||
t = t.withCert(ByteString.copyFromUtf8(ECDSASign.getBitcoinAddrByCert(cert)))
|
val (priKey, pubKey, cert) = ECDSASign.getKeyPair(nodeName)
|
||||||
//Get signature with tx hash(include cert)
|
t = t.withCert(ByteString.copyFromUtf8(ECDSASign.getBitcoinAddrByCert(cert)))
|
||||||
val sig = ECDSASign.sign(priKey,getTxHash(t))
|
//Get signature with tx hash(include cert)
|
||||||
t = t.withSignature(ByteString.copyFrom(sig))
|
val sig = ECDSASign.sign(priKey,getTxHash(t))
|
||||||
|
t = t.withSignature(ByteString.copyFrom(sig))
|
||||||
|
}catch{
|
||||||
|
case e:RuntimeException => throw e
|
||||||
|
}
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,13 +195,17 @@ class PeerHelper(name: String) extends ModuleBase(name) {
|
|||||||
case TickInvoke =>
|
case TickInvoke =>
|
||||||
//invoke
|
//invoke
|
||||||
// val cname = t.payload.get.chaincodeID.get.name
|
// val cname = t.payload.get.chaincodeID.get.name
|
||||||
val t2 = transactionCreator(pe.getSysTag,rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
|
try{
|
||||||
"", li1 ,List(),"", Option(chaincode),rep.protos.peer.ChaincodeSpec.CodeType.CODE_JAVASCRIPT)
|
val t2 = transactionCreator(pe.getSysTag,rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
|
||||||
//getActorRef(ActorType.TRANSACTION_POOL) ! t2
|
"", li1 ,List(),"", Option(chaincode),rep.protos.peer.ChaincodeSpec.CodeType.CODE_JAVASCRIPT)
|
||||||
val t3 = transactionCreator(pe.getSysTag,rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
|
//getActorRef(ActorType.TRANSACTION_POOL) ! t2
|
||||||
"", "transfer" ,Seq(li2),"", Option(chaincode),rep.protos.peer.ChaincodeSpec.CodeType.CODE_JAVASCRIPT)
|
val t3 = transactionCreator(pe.getSysTag,rep.protos.peer.Transaction.Type.CHAINCODE_INVOKE,
|
||||||
getActorRef(ActorType.TRANSACTION_POOL) ! t3
|
"", "transfer" ,Seq(li2),"", Option(chaincode),rep.protos.peer.ChaincodeSpec.CodeType.CODE_JAVASCRIPT)
|
||||||
scheduler.scheduleOnce(SystemProfile.getTranCreateDur.millis, self, TickInvoke)
|
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+" ************* ")
|
// println(sdf.format(System.currentTimeMillis())+" ########## "+pe.getSysTag+" ************* ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,45 +74,26 @@ class TransactionPool(moduleName: String) extends ModuleBase(moduleName) {
|
|||||||
var result = false
|
var result = false
|
||||||
val sig = t.signature.toByteArray
|
val sig = t.signature.toByteArray
|
||||||
val tOutSig = t.withSignature(ByteString.EMPTY)
|
val tOutSig = t.withSignature(ByteString.EMPTY)
|
||||||
val certTx = ECDSASign.getCertByBitcoinAddr(t.cert.toStringUtf8)
|
val cid = ChaincodeID.fromAscii(t.chaincodeID.toStringUtf8).name
|
||||||
certTx.getOrElse(None) match {
|
val certKey = WorldStateKeyPreFix + cid + "_" + "CERT_" + t.cert.toStringUtf8 // 普通用户证书的key
|
||||||
case None =>
|
try{
|
||||||
val cid = ChaincodeID.fromAscii(t.chaincodeID.toStringUtf8).name
|
var cert = ECDSASign.getCertWithCheck(t.cert.toStringUtf8,certKey,pe.getSysTag)
|
||||||
val certKey = WorldStateKeyPreFix + cid + "_" + "CERT_" + t.cert.toStringUtf8 // 普通用户证书的key
|
if(cert != None){
|
||||||
val cert = Option(dataaccess.Get(certKey)) // 从worldstate中取证书,用户注册是以前缀形式写进去的
|
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), cert.get.getPublicKey) match {
|
||||||
cert.getOrElse(None) match {
|
case true =>
|
||||||
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 =>
|
|
||||||
dataAccess.getBlockByTxId(t.txid) match {
|
dataAccess.getBlockByTxId(t.txid) match {
|
||||||
case null => result = true
|
case null => result = true
|
||||||
case _ => resultMsg = s"The transaction(${t.txid}) is duplicated with txid"
|
case _ => resultMsg = s"The transaction(${t.txid}) is duplicated with txid"
|
||||||
}
|
}
|
||||||
case false => resultMsg = s"The transaction(${t.txid}) is not completed"
|
case false => resultMsg = s"The transaction(${t.txid}) is not completed"
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
throw new RuntimeException("没有证书")
|
||||||
}
|
}
|
||||||
case _ =>
|
}catch{
|
||||||
val alias = ECDSASign.getAliasByCert(certTx.get).getOrElse(None)
|
case e : RuntimeException => throw e
|
||||||
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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckedTransactionResult(result, resultMsg)
|
CheckedTransactionResult(result, resultMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import rep.storage._
|
|||||||
import java.security.cert.{ Certificate}
|
import java.security.cert.{ Certificate}
|
||||||
import rep.network.PeerHelper
|
import rep.network.PeerHelper
|
||||||
import rep.utils.SerializeUtils
|
import rep.utils.SerializeUtils
|
||||||
|
import scala.util.control.Breaks
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,9 +46,13 @@ object BlockHelper {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def endorseBlock(blkHash:Array[Byte], alise:String):Endorsement ={
|
def endorseBlock(blkHash:Array[Byte], alise:String):Endorsement ={
|
||||||
val (priK, pubK, cert) = ECDSASign.getKeyPair(alise)
|
try{
|
||||||
Endorsement(ByteString.copyFromUtf8(ECDSASign.getBitcoinAddrByCert(cert)),
|
val (priK, pubK, cert) = ECDSASign.getKeyPair(alise)
|
||||||
|
Endorsement(ByteString.copyFromUtf8(ECDSASign.getBitcoinAddrByCert(cert)),
|
||||||
ByteString.copyFrom(ECDSASign.sign(priK, blkHash)))
|
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 = {
|
def checkBlockContent(endor:Endorsement, blkHash: Array[Byte]): Boolean = {
|
||||||
//获取出块人的背书信息
|
//获取出块人的背书信息
|
||||||
val certTx = ECDSASign.getCertByBitcoinAddr(endor.endorser.toStringUtf8)
|
try{
|
||||||
if(certTx.getOrElse(None)!=None){
|
val certTx = ECDSASign.getCertByBitcoinAddr(endor.endorser.toStringUtf8)
|
||||||
// val certTx = SerializeUtils.deserialise(endor.endorser.toByteArray).asInstanceOf[Certificate]
|
if(certTx.getOrElse(None)!=None){
|
||||||
val alias = ECDSASign.getAliasByCert(certTx.get).getOrElse(None)
|
// val certTx = SerializeUtils.deserialise(endor.endorser.toByteArray).asInstanceOf[Certificate]
|
||||||
if (alias == None) false
|
val alias = ECDSASign.getAliasByCert(certTx.get).getOrElse(None)
|
||||||
else {
|
if (alias == None) false
|
||||||
ECDSASign.verify(endor.signature.toByteArray, blkHash, certTx.get.getPublicKey)
|
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 sig = t.signature.toByteArray
|
||||||
val tOutSig1 = t.withSignature(ByteString.EMPTY)
|
val tOutSig1 = t.withSignature(ByteString.EMPTY)
|
||||||
val tOutSig = tOutSig1.withMetadata(ByteString.EMPTY)
|
val tOutSig = tOutSig1.withMetadata(ByteString.EMPTY)
|
||||||
val certTx = ECDSASign.getCertByBitcoinAddr(t.cert.toStringUtf8)
|
|
||||||
certTx.getOrElse(None) match {
|
try{
|
||||||
case None =>
|
|
||||||
val cid = ChaincodeID.fromAscii(t.chaincodeID.toStringUtf8).name
|
val cid = ChaincodeID.fromAscii(t.chaincodeID.toStringUtf8).name
|
||||||
val certKey = IdxPrefix.WorldStateKeyPreFix + cid + "_" + "CERT_" + t.cert.toStringUtf8 // 普通用户证书的key
|
val certKey = IdxPrefix.WorldStateKeyPreFix + cid + "_" + "CERT_" + t.cert.toStringUtf8 // 普通用户证书的key
|
||||||
val cert = Option(dataAccess.Get(certKey)) // 从worldstate中取证书,用户注册是以前缀形式写进去的
|
var cert = ECDSASign.getCertWithCheck(t.cert.toStringUtf8,certKey,dataAccess.getSystemName)
|
||||||
cert.getOrElse(None) match {
|
if(cert != None){
|
||||||
case None => resultMsg = s"The transaction(${t.txid}) is not trusted"
|
result = ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), cert.get.getPublicKey)
|
||||||
case _ =>
|
}else{
|
||||||
if (new String(cert.get) == "null") {
|
resultMsg = s"The transaction(${t.txid}) is not trusted"
|
||||||
//throw new RuntimeException("该用户证书已注销")
|
|
||||||
resultMsg = "该用户证书已注销"
|
|
||||||
}
|
|
||||||
//验证签名和内容hash
|
|
||||||
val kvcert = SerializeUtils.deserialise(cert.get).asInstanceOf[Certificate] //rep序列化与反序列化字节数组
|
|
||||||
result = ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), kvcert.getPublicKey)
|
|
||||||
}
|
}
|
||||||
case _ =>
|
}catch{
|
||||||
val alias = ECDSASign.getAliasByCert(certTx.get).getOrElse(None)
|
case e : RuntimeException => resultMsg = s"The transaction(${t.txid}) is not trusted${e.getMessage}"
|
||||||
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)
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,4 +166,70 @@ object BlockHelper {
|
|||||||
Sha256.hashstr(blk.toByteArray)
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -410,6 +410,10 @@ class BlockModule(moduleName: String) extends ModuleBase(moduleName) {
|
|||||||
if(blc.previousBlockHash.toStringUtf8() != pe.getCurrentBlockHash){
|
if(blc.previousBlockHash.toStringUtf8() != pe.getCurrentBlockHash){
|
||||||
resetVoteEnv
|
resetVoteEnv
|
||||||
}else{
|
}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
|
//广播这个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()}")
|
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,
|
mediator ! Publish(Topic.Block, new ConfirmedBlock(blc, dataaccess.getBlockChainInfo().height + 1,
|
||||||
@ -431,7 +435,7 @@ class BlockModule(moduleName: String) extends ModuleBase(moduleName) {
|
|||||||
//TODO kami 这是一个非常耗时的工作?后续需要完善
|
//TODO kami 这是一个非常耗时的工作?后续需要完善
|
||||||
if (!BlockHelper.checkBlockContent(endorse, Sha256.hash(blkOutEndorse.toByteArray))) isEndorsed = false
|
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,
|
logTime("New block, start to store", CRFD_STEP._13_NEW_BLK_START_STORE,
|
||||||
getActorRef(ActorType.STATISTIC_COLLECTION))
|
getActorRef(ActorType.STATISTIC_COLLECTION))
|
||||||
//c4w 广播接收到block事件
|
//c4w 广播接收到block事件
|
||||||
@ -452,9 +456,8 @@ class BlockModule(moduleName: String) extends ModuleBase(moduleName) {
|
|||||||
logMsg(LOG_TYPE.INFO, "New block, store opt over ...")
|
logMsg(LOG_TYPE.INFO, "New block, store opt over ...")
|
||||||
logTime("New block, store opt over", CRFD_STEP._14_NEW_BLK_STORE_END,
|
logTime("New block, store opt over", CRFD_STEP._14_NEW_BLK_STORE_END,
|
||||||
getActorRef(ActorType.STATISTIC_COLLECTION))
|
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()}")
|
else logMsg(LOG_TYPE.WARN, s"The num of endorsement in block is not enough. Sender : ${sender()}")
|
||||||
|
|
||||||
|
@ -73,7 +73,29 @@ class EndorsementModule(moduleName: String) extends ModuleBase(moduleName) {
|
|||||||
)
|
)
|
||||||
r
|
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)={
|
private def endorseForWork(blk:Block, actRef: ActorRef,blkidentifier:String)={
|
||||||
val dbinstancename = "endorse_"+blk.transactions.head.txid
|
val dbinstancename = "endorse_"+blk.transactions.head.txid
|
||||||
val preload: ImpDataPreload = ImpDataPreloadMgr.GetImpDataPreload(pe.getSysTag,dbinstancename)
|
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 blkData = blk.withConsensusMetadata(Seq())
|
||||||
val blkInfo = Sha256.hash(blkData.toByteArray)
|
val blkInfo = Sha256.hash(blkData.toByteArray)
|
||||||
if (BlockHelper.checkBlockContent(blk.consensusMetadata.head, blkInfo)) {
|
if (BlockHelper.checkBlockContent(blk.consensusMetadata.head, blkInfo)) {
|
||||||
if(verifyTransSign(blk.transactions)){
|
if(!hasRepeatOfTrans(blk.transactions)){
|
||||||
if(preload.VerifyForEndorsement(blk)){
|
if(verifyTransSign(blk.transactions)){
|
||||||
logMsg(LOG_TYPE.WARN, s"Block endorse success,current height=${pe.getCacheHeight()},identifier=${blkidentifier}")
|
if(preload.VerifyForEndorsement(blk)){
|
||||||
actRef ! EndorsedBlock(true, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
|
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{
|
sendEvent(EventType.PUBLISH_INFO, mediator, selfAddr, Topic.Block, Event.Action.ENDORSEMENT)
|
||||||
logMsg(LOG_TYPE.WARN, "Transcation preload failed,Block endorse failed")
|
}else{
|
||||||
actRef! EndorsedBlock(false, blkData, BlockHelper.endorseBlock(blkInfo, pe.getSysTag),blkidentifier)
|
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{
|
}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))
|
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}")
|
logMsg(LOG_TYPE.WARN, s"Block endorse finish,current height=${pe.getCacheHeight()},identifier=${blkidentifier}")
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -17,6 +17,7 @@ package rep.network.consensus.vote
|
|||||||
|
|
||||||
import rep.crypto.Sha256
|
import rep.crypto.Sha256
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
import rep.storage.util.pathUtil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统默认
|
* 系统默认
|
||||||
@ -28,23 +29,50 @@ import scala.collection.mutable
|
|||||||
*/
|
*/
|
||||||
//TODO kami 应该在init的时候载入一个实现函数或者类。然后调用方法。写的更通用一些
|
//TODO kami 应该在init的时候载入一个实现函数或者类。然后调用方法。写的更通用一些
|
||||||
trait CRFDVoter extends VoterBase {
|
trait CRFDVoter extends VoterBase {
|
||||||
|
case class randomNumber(var number:Long,var generateSerial:Int,var sortPos:Int)
|
||||||
override def blocker(nodes: Set[String], position:Int): Option[String] = {
|
|
||||||
//if (nodes.nonEmpty&&position<nodes.size) Option(nodes.head) else None
|
override def blocker(nodes: Array[String], position:Int): String = {
|
||||||
if(nodes.nonEmpty){
|
if(nodes.nonEmpty){
|
||||||
var pos = position
|
var pos = position
|
||||||
if(position >= nodes.size){
|
if(position >= nodes.size){
|
||||||
pos = position % nodes.size
|
pos = position % nodes.size
|
||||||
}
|
}
|
||||||
val a = nodes.toList
|
nodes(pos)
|
||||||
Option(a(pos))
|
|
||||||
}else{
|
}else{
|
||||||
None
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def candidators(nodes: Set[String], seed: Array[Byte]): Set[String] = {
|
private def getRandomList(seed:Long,candidatorLen:Int,candidatorTotal:Int):Array[randomNumber]={
|
||||||
var nodesSeq = nodes.toSeq.sortBy(f=>(f.toString()))//nodes.toSeq
|
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
|
var len = nodes.size / 2 + 1
|
||||||
val min_len = 4
|
val min_len = 4
|
||||||
len = if(len<min_len){
|
len = if(len<min_len){
|
||||||
@ -53,27 +81,21 @@ trait CRFDVoter extends VoterBase {
|
|||||||
}
|
}
|
||||||
else len
|
else len
|
||||||
if(len<4){
|
if(len<4){
|
||||||
Set.empty
|
null
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
var candidate = mutable.Seq.empty[String]
|
var candidate = new Array[String](len)
|
||||||
var index = 0
|
var hashSeed:Long = pathUtil.bytesToInt(seed)
|
||||||
var hashSeed = seed
|
var randomList = getRandomList(hashSeed,len,nodes.size)
|
||||||
|
//PrintRandomArray(randomList)
|
||||||
while (candidate.size < len) {
|
println(randomList(0).sortPos)
|
||||||
if (index >= hashSeed.size) {
|
for(j<-0 to len-1){
|
||||||
hashSeed = Sha256.hash(hashSeed)
|
var e = randomList(j)
|
||||||
index = 0
|
candidate(j) = nodesSeq(e.sortPos)
|
||||||
}
|
|
||||||
//应该按位来计算
|
|
||||||
if ((hashSeed(index) & 1) == 1) {
|
|
||||||
candidate = (candidate :+ nodesSeq(index % (nodesSeq.size)))
|
|
||||||
nodesSeq = (nodesSeq.toSet - nodesSeq(index % (nodesSeq.size))).toSeq
|
|
||||||
}
|
|
||||||
index += 1
|
|
||||||
}
|
}
|
||||||
candidate.toSet
|
candidate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ class CRFDVoterModule(moduleName: String) extends ModuleBase(moduleName) with CR
|
|||||||
|
|
||||||
def rnd = ThreadLocalRandom.current
|
def rnd = ThreadLocalRandom.current
|
||||||
|
|
||||||
var candidatorCur = Set.empty[ String ]
|
var candidatorCur : Array[ String ] = null
|
||||||
|
|
||||||
var isWaiting = false
|
var isWaiting = false
|
||||||
|
|
||||||
@ -167,15 +167,15 @@ class CRFDVoterModule(moduleName: String) extends ModuleBase(moduleName) with CR
|
|||||||
val seed = pe.getVoteBlockHash//pe.getCurrentBlockHash
|
val seed = pe.getVoteBlockHash//pe.getCurrentBlockHash
|
||||||
|
|
||||||
candidatorCur = candidators(SystemCertList.getSystemCertList, Sha256.hash(seed))
|
candidatorCur = candidators(SystemCertList.getSystemCertList, Sha256.hash(seed))
|
||||||
if (!candidatorCur.isEmpty) {
|
if (candidatorCur != null) {
|
||||||
pe.resetCandidator(candidatorCur)
|
pe.resetCandidator(candidatorCur)
|
||||||
if(pe.getCacheHeight() >= 1){
|
if(pe.getCacheHeight() >= 1){
|
||||||
val blo = blocker(candidatorCur, pe.getBlker_index)
|
val blo = blocker(candidatorCur, pe.getBlker_index)
|
||||||
if (blo != None) {
|
if (blo != null) {
|
||||||
pe.resetBlocker(blo.get)
|
pe.resetBlocker(blo)
|
||||||
//暂时只找到该方法能够明确标识一个在网络中(有网络地址)的节点,后续发现好方法可以完善
|
//暂时只找到该方法能够明确标识一个在网络中(有网络地址)的节点,后续发现好方法可以完善
|
||||||
logMsg(LOG_TYPE.INFO, s"Select in getCacheHeight=${pe.getCacheHeight()} Candidates : ${candidatorCur} ~ Blocker : ${blo},currenthash=${pe.getCurrentBlockHash},index=${pe.getBlker_index}")
|
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, "")
|
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}")
|
logMsg(LOG_TYPE.INFO, s"Select in getCacheHeight=${pe.getCacheHeight()} Candidates : ${candidatorCur} ,send Create cmd~ Blocker : ${blo},currenthash=${pe.getCurrentBlockHash},index=${pe.getBlker_index}")
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ trait VoterBase {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//def blocker[T](nodes:Set[T], position:Int):Option[T]
|
//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
|
* @return
|
||||||
*/
|
*/
|
||||||
//def candidators[T](nodes:Set[T], seed:Array[Byte]):Set[T]
|
//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]
|
||||||
}
|
}
|
||||||
|
@ -259,8 +259,8 @@ class PeerExtensionImpl extends Extension {
|
|||||||
candidatorLock.unlock()
|
candidatorLock.unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def resetCandidator(nds: Set[ String ]): Unit = {
|
def resetCandidator(nds: Array[ String ]): Unit = {
|
||||||
candidatorLock.lock()
|
candidatorLock.lock()
|
||||||
try{
|
try{
|
||||||
candidator = immutable.TreeMap.empty[String,String]
|
candidator = immutable.TreeMap.empty[String,String]
|
||||||
|
@ -100,7 +100,7 @@ abstract class Sandbox(cid:String) extends Actor with RepLogging{
|
|||||||
sender ! tr
|
sender ! tr
|
||||||
//交易预处理请求,指定接收者
|
//交易预处理请求,指定接收者
|
||||||
case PreTransaction(t:Transaction) =>
|
case PreTransaction(t:Transaction) =>
|
||||||
val tr = doTransaction(t,null,null)
|
val tr = doTransaction(t,null,t.txid)
|
||||||
shim.rollback()
|
shim.rollback()
|
||||||
sender ! tr
|
sender ! tr
|
||||||
//恢复chainCode,不回消息
|
//恢复chainCode,不回消息
|
||||||
|
@ -213,12 +213,15 @@ class Shim(system: ActorSystem, cid: String) {
|
|||||||
val sig = tx.signature.toByteArray
|
val sig = tx.signature.toByteArray
|
||||||
val tOutSig1 = tx.withSignature(ByteString.EMPTY)
|
val tOutSig1 = tx.withSignature(ByteString.EMPTY)
|
||||||
val tOutSig = tOutSig1.withMetadata(ByteString.EMPTY)
|
val tOutSig = tOutSig1.withMetadata(ByteString.EMPTY)
|
||||||
val peercer = ECDSASign.getCertByBitcoinAddr(bitcoinaddr)
|
|
||||||
if (peercer == None)
|
try{
|
||||||
throw new Exception(NOT_PERR_CERT)
|
val peercer = ECDSASign.getCertByBitcoinAddr(bitcoinaddr)
|
||||||
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), peercer.get.getPublicKey) match {
|
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), peercer.get.getPublicKey) match {
|
||||||
case true =>
|
case true =>
|
||||||
case false => throw new Exception("节点签名验证错误")
|
case false => throw new Exception("节点签名验证错误")
|
||||||
|
}
|
||||||
|
}catch{
|
||||||
|
case e : RuntimeException => throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +28,10 @@ import org.json4s._
|
|||||||
import org.json4s.jackson.JsonMethods._
|
import org.json4s.jackson.JsonMethods._
|
||||||
import rep.crypto.Sha256
|
import rep.crypto.Sha256
|
||||||
|
|
||||||
|
import rep.app.conf.SystemProfile
|
||||||
import scala.reflect.runtime.currentMirror
|
import scala.reflect.runtime.currentMirror
|
||||||
import scala.tools.reflect.ToolBox
|
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{
|
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 合约代码主体部分
|
* @param pcode 合约代码主体部分
|
||||||
* @cid 合约类唯一标识
|
* @cid 合约类唯一标识
|
||||||
@ -61,7 +68,7 @@ class Compiler(targetDir: Option[File], bDebug:Boolean) {
|
|||||||
//反射工具对象
|
//反射工具对象
|
||||||
val tb = currentMirror.mkToolBox()
|
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 {
|
val target = targetDir match {
|
||||||
case Some(dir) => AbstractFile.getDirectory(dir)
|
case Some(dir) => AbstractFile.getDirectory(dir)
|
||||||
|
@ -156,13 +156,13 @@ public class StoreConfig {
|
|||||||
|
|
||||||
public long getFreeDiskSpace(){
|
public long getFreeDiskSpace(){
|
||||||
String bpath = this.getBlockPath();
|
String bpath = this.getBlockPath();
|
||||||
/*try {
|
try {
|
||||||
if(pathUtil.FileExists(bpath) == -1){
|
if(pathUtil.FileExists(bpath) == -1){
|
||||||
pathUtil.MkdirAll(bpath);
|
pathUtil.MkdirAll(bpath);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}*/
|
}
|
||||||
File f = new File(bpath);
|
File f = new File(bpath);
|
||||||
long l = f.getFreeSpace();
|
long l = f.getFreeSpace();
|
||||||
return l;
|
return l;
|
||||||
|
207
src/main/scala/rep/storage/test/testRandomVote.scala
Normal file
207
src/main/scala/rep/storage/test/testRandomVote.scala
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -256,9 +256,21 @@ def testTreeMapclear{
|
|||||||
|
|
||||||
println(tm)
|
println(tm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class myobject(txid:String,name:String)
|
||||||
|
|
||||||
def main(args: Array[String]): Unit = {
|
def main(args: Array[String]): Unit = {
|
||||||
//testTreeMap
|
//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)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -119,4 +119,40 @@ public class pathUtil {
|
|||||||
}
|
}
|
||||||
return l;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ object SerializeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Json对象反序列化,由于没有给出造型类型,无法胜任复杂对象
|
* Json对象反序列化
|
||||||
* @param bytes
|
* @param bytes
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -116,7 +116,7 @@ class SandboxSpec(_system: ActorSystem)
|
|||||||
val dbTag = "1"
|
val dbTag = "1"
|
||||||
//加载合约脚本
|
//加载合约脚本
|
||||||
// val s1 = scala.io.Source.fromFile("src/main/scala/ContractAssetsTPL.scala")
|
// 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 l1 = try s1.mkString finally s1.close()
|
||||||
|
|
||||||
//val clazz = Compiler.compilef(l1,null)
|
//val clazz = Compiler.compilef(l1,null)
|
||||||
@ -197,4 +197,90 @@ class SandboxSpec(_system: ActorSystem)
|
|||||||
re3 should be("transfer ok")
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user