Coverage Summary for Class: DistanceCalculator (co.rsk.net.discovery.table)
Class |
Class, %
|
Method, %
|
Line, %
|
DistanceCalculator |
0%
(0/1)
|
0%
(0/4)
|
0%
(0/21)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2017 RSK Labs Ltd.
4 *
5 * This program 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 * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package co.rsk.net.discovery.table;
20
21 import co.rsk.net.NodeID;
22 import org.ethereum.crypto.HashUtil;
23
24 /**
25 * Calculates the distance between 2 nodes
26 */
27 public class DistanceCalculator {
28 private final int maxDistance;
29
30 public DistanceCalculator(int maxDistance) {
31 this.maxDistance = maxDistance;
32 }
33
34 /**
35 * The distance is calculated as the Most Significant Bit (MSB) position
36 * of the XOR between the keccak256(keccak256(nodeId)) of the 2 nodes
37 * @param node1 id
38 * @param node2 id
39 * @return The distance between 2 nodes
40 */
41 public int calculateDistance(NodeID node1, NodeID node2) {
42 byte[] nodeId1 = HashUtil.keccak256(HashUtil.keccak256(node1.getID()));
43 byte[] nodeId2 = HashUtil.keccak256(HashUtil.keccak256(node2.getID()));
44 byte[] result = new byte[nodeId1.length];
45
46 for (int i = 0; i < result.length; i++) {
47 result[i] = (byte) (((int) nodeId1[i]) ^ ((int) nodeId2[i]));
48 }
49
50 return msbPosition(result);
51 }
52
53 /**
54 *
55 * @param result
56 * @return The MSB position of the XOR result.
57 */
58 private int msbPosition(byte[] result) {
59 int distance = this.maxDistance;
60
61 for (byte b : result) {
62 if (b == 0) {
63 distance -= 8;
64 } else {
65 distance -= positionsToMove(b);
66 return distance;
67 }
68 }
69
70 return distance;
71 }
72
73 private int positionsToMove(byte b) {
74 int count = 0;
75
76 for (int i = 7; i >= 0; i--) {
77 if (((b & 0xff)& (1 << i)) == 0) {
78 count++;
79 } else {
80 return count;
81 }
82 }
83
84 return count;
85 }
86 }