github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/p2p/discv5/topic_test.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // Copyright 2019 The go-aigar Authors 3 // This file is part of the go-aigar library. 4 // 5 // The go-aigar library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-aigar library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>. 17 18 package discv5 19 20 import ( 21 "encoding/binary" 22 "testing" 23 "time" 24 25 "github.com/AigarNetwork/aigar/common" 26 "github.com/AigarNetwork/aigar/common/mclock" 27 ) 28 29 func TestTopicRadius(t *testing.T) { 30 now := mclock.Now() 31 topic := Topic("qwerty") 32 rad := newTopicRadius(topic) 33 targetRad := (^uint64(0)) / 100 34 35 waitFn := func(addr common.Hash) time.Duration { 36 prefix := binary.BigEndian.Uint64(addr[0:8]) 37 dist := prefix ^ rad.topicHashPrefix 38 relDist := float64(dist) / float64(targetRad) 39 relTime := (1 - relDist/2) * 2 40 if relTime < 0 { 41 relTime = 0 42 } 43 return time.Duration(float64(targetWaitTime) * relTime) 44 } 45 46 bcnt := 0 47 cnt := 0 48 var sum float64 49 for cnt < 100 { 50 addr := rad.nextTarget(false).target 51 wait := waitFn(addr) 52 ticket := &ticket{ 53 topics: []Topic{topic}, 54 regTime: []mclock.AbsTime{mclock.AbsTime(wait)}, 55 node: &Node{nodeNetGuts: nodeNetGuts{sha: addr}}, 56 } 57 rad.adjustWithTicket(now, addr, ticketRef{ticket, 0}) 58 if rad.radius != maxRadius { 59 cnt++ 60 sum += float64(rad.radius) 61 } else { 62 bcnt++ 63 if bcnt > 500 { 64 t.Errorf("Radius did not converge in 500 iterations") 65 } 66 } 67 } 68 avgRel := sum / float64(cnt) / float64(targetRad) 69 if avgRel > 1.05 || avgRel < 0.95 { 70 t.Errorf("Average/target ratio is too far from 1 (%v)", avgRel) 71 } 72 }