From 356a6713c29b5f35ece27aaafad7c38f912f26e7 Mon Sep 17 00:00:00 2001 From: wuwei1972 Date: Sat, 14 Jul 2018 20:53:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8A=BD=E7=AD=BE=E7=AE=97?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E9=80=9A=E8=BF=87=E4=BC=AA=E9=9A=8F=E6=9C=BA?= =?UTF-8?q?=E6=95=B0=E7=94=9F=E6=88=90=E5=87=BA=E5=9D=97=E4=BA=BA=E9=9A=8F?= =?UTF-8?q?=E6=9C=BA=E5=BA=8F=E5=88=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/scala/rep/crypto/Sha256.scala | 7 + .../network/consensus/vote/CRFDVoter.scala | 78 ++++--- .../consensus/vote/CRFDVoterModule.scala | 10 +- .../network/consensus/vote/VoterBase.scala | 4 +- .../rep/network/tools/PeerExtension.scala | 2 +- .../rep/storage/test/testRandomVote.scala | 207 ++++++++++++++++++ src/main/scala/rep/storage/util/pathUtil.java | 21 ++ 7 files changed, 295 insertions(+), 34 deletions(-) create mode 100644 src/main/scala/rep/storage/test/testRandomVote.scala diff --git a/src/main/scala/rep/crypto/Sha256.scala b/src/main/scala/rep/crypto/Sha256.scala index f6bb56df..32fbfad4 100644 --- a/src/main/scala/rep/crypto/Sha256.scala +++ b/src/main/scala/rep/crypto/Sha256.scala @@ -19,6 +19,7 @@ import com.google.protobuf.ByteString /** * @author c4w + * modify by jiangbuyun */ object Sha256 extends CryptographicHash{ override val DigestSize: Int = 32 @@ -26,9 +27,15 @@ object Sha256 extends CryptographicHash{ 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()) + } } \ No newline at end of file diff --git a/src/main/scala/rep/network/consensus/vote/CRFDVoter.scala b/src/main/scala/rep/network/consensus/vote/CRFDVoter.scala index 0b59aced..7355a397 100644 --- a/src/main/scala/rep/network/consensus/vote/CRFDVoter.scala +++ b/src/main/scala/rep/network/consensus/vote/CRFDVoter.scala @@ -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){ 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= 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 = 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.toSet + candidate } } + } diff --git a/src/main/scala/rep/network/consensus/vote/CRFDVoterModule.scala b/src/main/scala/rep/network/consensus/vote/CRFDVoterModule.scala index 4b2df4d0..7a991c7f 100644 --- a/src/main/scala/rep/network/consensus/vote/CRFDVoterModule.scala +++ b/src/main/scala/rep/network/consensus/vote/CRFDVoterModule.scala @@ -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}") } diff --git a/src/main/scala/rep/network/consensus/vote/VoterBase.scala b/src/main/scala/rep/network/consensus/vote/VoterBase.scala index 2af96442..b88e59d9 100644 --- a/src/main/scala/rep/network/consensus/vote/VoterBase.scala +++ b/src/main/scala/rep/network/consensus/vote/VoterBase.scala @@ -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] } diff --git a/src/main/scala/rep/network/tools/PeerExtension.scala b/src/main/scala/rep/network/tools/PeerExtension.scala index 441c6d81..df3a0b8f 100644 --- a/src/main/scala/rep/network/tools/PeerExtension.scala +++ b/src/main/scala/rep/network/tools/PeerExtension.scala @@ -260,7 +260,7 @@ class PeerExtensionImpl extends Extension { } } - def resetCandidator(nds: Set[ String ]): Unit = { + def resetCandidator(nds: Array[ String ]): Unit = { candidatorLock.lock() try{ candidator = immutable.TreeMap.empty[String,String] diff --git a/src/main/scala/rep/storage/test/testRandomVote.scala b/src/main/scala/rep/storage/test/testRandomVote.scala new file mode 100644 index 00000000..3a42dbe4 --- /dev/null +++ b/src/main/scala/rep/storage/test/testRandomVote.scala @@ -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= 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) + } +} + diff --git a/src/main/scala/rep/storage/util/pathUtil.java b/src/main/scala/rep/storage/util/pathUtil.java index 04fa90f2..41e2be1e 100644 --- a/src/main/scala/rep/storage/util/pathUtil.java +++ b/src/main/scala/rep/storage/util/pathUtil.java @@ -119,4 +119,25 @@ 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; + } }