github.com/braveheart12/insolar-09-08-19@v0.8.7/network/controller/bootstrap/helper.go (about) 1 /* 2 * The Clear BSD License 3 * 4 * Copyright (c) 2019 Insolar Technologies 5 * 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: 9 * 10 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 11 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 12 * Neither the name of Insolar Technologies nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 * 14 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 * 16 */ 17 18 package bootstrap 19 20 import ( 21 "crypto/rand" 22 "fmt" 23 "math" 24 "sort" 25 26 "github.com/insolar/insolar/core" 27 "github.com/insolar/insolar/network" 28 "github.com/insolar/insolar/network/utils" 29 "github.com/pkg/errors" 30 ) 31 32 const nonceSize int = 128 33 34 // CheckShortIDCollision returns true if NodeKeeper already contains node with such ShortID 35 func CheckShortIDCollision(keeper network.NodeKeeper, id core.ShortNodeID) bool { 36 return keeper.GetActiveNodeByShortID(id) != nil 37 } 38 39 // GenerateShortID correct ShortID of the node so it does not conflict with existing active node list 40 func GenerateShortID(keeper network.NodeKeeper, nodeID core.RecordRef) core.ShortNodeID { 41 shortID := utils.GenerateShortID(nodeID) 42 if !CheckShortIDCollision(keeper, shortID) { 43 return shortID 44 } 45 return regenerateShortID(keeper, shortID) 46 } 47 48 func regenerateShortID(keeper network.NodeKeeper, shortID core.ShortNodeID) core.ShortNodeID { 49 activeNodes := keeper.GetActiveNodes() 50 shortIDs := make([]core.ShortNodeID, len(activeNodes)) 51 for i, activeNode := range activeNodes { 52 shortIDs[i] = activeNode.ShortID() 53 } 54 sort.Slice(shortIDs, func(i, j int) bool { 55 return shortIDs[i] < shortIDs[j] 56 }) 57 return generateNonConflictingID(shortIDs, shortID) 58 } 59 60 func generateNonConflictingID(sortedSlice []core.ShortNodeID, conflictingID core.ShortNodeID) core.ShortNodeID { 61 index := sort.Search(len(sortedSlice), func(i int) bool { 62 return sortedSlice[i] >= conflictingID 63 }) 64 result := conflictingID 65 repeated := false 66 for { 67 if result == math.MaxUint32 { 68 if !repeated { 69 repeated = true 70 result = 0 71 index = 0 72 } else { 73 panic("[ generateNonConflictingID ] shortID overflow twice") 74 } 75 } 76 index++ 77 result++ 78 if index >= len(sortedSlice) || result != sortedSlice[index] { 79 return result 80 } 81 } 82 } 83 84 func RemoveOrigin(discoveryNodes []core.DiscoveryNode, origin core.RecordRef) []core.DiscoveryNode { 85 for i, discoveryNode := range discoveryNodes { 86 if origin.Equal(*discoveryNode.GetNodeRef()) { 87 return append(discoveryNodes[:i], discoveryNodes[i+1:]...) 88 } 89 } 90 return discoveryNodes 91 } 92 93 func FindDiscovery(cert core.Certificate, ref core.RecordRef) core.DiscoveryNode { 94 bNodes := cert.GetDiscoveryNodes() 95 for _, discoveryNode := range bNodes { 96 if ref.Equal(*discoveryNode.GetNodeRef()) { 97 return discoveryNode 98 } 99 } 100 return nil 101 } 102 103 func Xor(first, second []byte) []byte { 104 if len(second) < len(first) { 105 temp := second 106 second = first 107 first = temp 108 } 109 result := make([]byte, len(second)) 110 for i, d := range second { 111 result[i] = first[i%len(first)] ^ d 112 } 113 return result 114 } 115 116 func GenerateNonce() (Nonce, error) { 117 buffer := [nonceSize]byte{} 118 l, err := rand.Read(buffer[:]) 119 if err != nil { 120 return nil, errors.Wrapf(err, "error generating nonce") 121 } 122 if l != nonceSize { 123 return nil, errors.New(fmt.Sprintf("GenerateNonce: generated size %d does equal to required size %d", l, nonceSize)) 124 } 125 return buffer[:], nil 126 }