mirror of
https://gitee.com/BTAJL/repchain.git
synced 2024-12-03 04:08:40 +08:00
修改抽签算法,通过伪随机数生成出块人随机序列。
This commit is contained in:
parent
76c4199fc4
commit
356a6713c2
@ -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())
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
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){
|
||||
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,25 @@ 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
|
||||
//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)
|
||||
|
||||
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
|
||||
}
|
||||
candidate.toSet
|
||||
//candidate.toSet
|
||||
candidate
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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}")
|
||||
}
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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]
|
||||
|
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)
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user