github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/p2p/discv5/topic_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:44</date>
    10  //</624342657878986752>
    11  
    12  
    13  package discv5
    14  
    15  import (
    16  	"encoding/binary"
    17  	"testing"
    18  	"time"
    19  
    20  	"github.com/ethereum/go-ethereum/common"
    21  	"github.com/ethereum/go-ethereum/common/mclock"
    22  )
    23  
    24  func TestTopicRadius(t *testing.T) {
    25  	now := mclock.Now()
    26  	topic := Topic("qwerty")
    27  	rad := newTopicRadius(topic)
    28  	targetRad := (^uint64(0)) / 100
    29  
    30  	waitFn := func(addr common.Hash) time.Duration {
    31  		prefix := binary.BigEndian.Uint64(addr[0:8])
    32  		dist := prefix ^ rad.topicHashPrefix
    33  		relDist := float64(dist) / float64(targetRad)
    34  		relTime := (1 - relDist/2) * 2
    35  		if relTime < 0 {
    36  			relTime = 0
    37  		}
    38  		return time.Duration(float64(targetWaitTime) * relTime)
    39  	}
    40  
    41  	bcnt := 0
    42  	cnt := 0
    43  	var sum float64
    44  	for cnt < 100 {
    45  		addr := rad.nextTarget(false).target
    46  		wait := waitFn(addr)
    47  		ticket := &ticket{
    48  			topics:  []Topic{topic},
    49  			regTime: []mclock.AbsTime{mclock.AbsTime(wait)},
    50  			node:    &Node{nodeNetGuts: nodeNetGuts{sha: addr}},
    51  		}
    52  		rad.adjustWithTicket(now, addr, ticketRef{ticket, 0})
    53  		if rad.radius != maxRadius {
    54  			cnt++
    55  			sum += float64(rad.radius)
    56  		} else {
    57  			bcnt++
    58  			if bcnt > 500 {
    59  				t.Errorf("Radius did not converge in 500 iterations")
    60  			}
    61  		}
    62  	}
    63  	avgRel := sum / float64(cnt) / float64(targetRad)
    64  	if avgRel > 1.05 || avgRel < 0.95 {
    65  		t.Errorf("Average/target ratio is too far from 1 (%v)", avgRel)
    66  	}
    67  }
    68