@Test public void statistics() { BlockSynchronizer blockSynchronizer = new BlockSynchronizer(CHAIN_ID); List<Node> nodeList = new ArrayList<>(); for (int i = 0; i < 80; i++) { Node node = new Node(); node.setId("group1-" + i); node.setHeight(888L); node.setHash(NulsHash.calcHash("888".getBytes())); nodeList.add(node); } for (int i = 0; i < 20; i++) { Node node = new Node(); node.setId("group2-" + i); node.setHeight(888L); node.setHash(NulsHash.calcHash("sss".getBytes())); nodeList.add(node); } BlockDownloaderParams params = blockSynchronizer.statistics(nodeList, null); Assert.assertTrue(params.getNodes().size() == 80); nodeList.clear(); for (int i = 0; i < 79; i++) { Node node = new Node(); node.setId("group1-" + i); node.setHeight(888L); node.setHash(NulsHash.calcHash("888".getBytes())); nodeList.add(node); } for (int i = 0; i < 21; i++) { Node node = new Node(); node.setId("group2-" + i); node.setHeight(888L); node.setHash(NulsHash.calcHash("sss".getBytes())); nodeList.add(node); } params = blockSynchronizer.statistics(nodeList, null); Assert.assertTrue(params.getNodes().size() == 0); nodeList.clear(); for (int i = 0; i < 88; i++) { Node node = new Node(); node.setId("group1-" + i); node.setHeight(888L); node.setHash(NulsHash.calcHash("888".getBytes())); nodeList.add(node); } for (int i = 0; i < 6; i++) { Node node = new Node(); node.setId("group2-" + i); node.setHeight(888L); node.setHash(NulsHash.calcHash("sss".getBytes())); nodeList.add(node); } for (int i = 0; i < 6; i++) { Node node = new Node(); node.setId("group2-" + i); node.setHeight(666L); node.setHash(NulsHash.calcHash("666".getBytes())); nodeList.add(node); } params = blockSynchronizer.statistics(nodeList, null); Node node = params.getNodes().get(0); Assert.assertTrue(node.getHeight() == 888 && node.getHash().equals(NulsHash.calcHash("888".getBytes()))); }
BlockDownloaderParams statistics(List<Node> availableNodes, ChainContext context) { BlockDownloaderParams params = new BlockDownloaderParams(); List<Node> filterAvailableNodes = filterNodes(availableNodes, context); params.setAvailableNodesCount(filterAvailableNodes.size()); if (filterAvailableNodes.isEmpty()) { return params; } String key = ""; int count = 0; Map<String, List<Node>> nodeMap = new HashMap<>(filterAvailableNodes.size()); Map<String, Integer> countMap = new HashMap<>(filterAvailableNodes.size()); for (Node node : filterAvailableNodes) { String tempKey = node.getHash().toHex() + node.getHeight(); if (countMap.containsKey(tempKey)) { countMap.put(tempKey, countMap.get(tempKey) + 1); } else { countMap.put(tempKey, 1); } if (nodeMap.containsKey(tempKey)) { List<Node> nodes = nodeMap.get(tempKey); nodes.add(node); } else { nodeMap.put(tempKey, Lists.newArrayList(node)); } } for (Map.Entry<String, Integer> entry : countMap.entrySet()) { Integer value = entry.getValue(); if (value > count) { count = value; key = entry.getKey(); } } ChainParameters parameters = context.getParameters(); double div = DoubleUtils.div(count, filterAvailableNodes.size(), 2); byte percent = calculateConsistencyNodePercent(parameters.getConsistencyNodePercent(), filterAvailableNodes.size()); if (div * 100 < percent) { return params; } List<Node> nodeList = nodeMap.get(key); params.setNodes(nodeList); Map<String, Node> statusMap = new ConcurrentHashMap<>(); nodeList.forEach(e -> statusMap.put(e.getId(), e)); params.setNodeMap(statusMap); Node node = nodeList.get(0); params.setNetLatestHash(node.getHash()); params.setNetLatestHeight(node.getHeight()); StampedLock lock = context.getLock(); long stamp = lock.tryOptimisticRead(); try { for (; ; stamp = lock.readLock()) { if (stamp == 0L) { continue; } params.setLocalLatestHeight(context.getLatestHeight()); params.setLocalLatestHash(context.getLatestBlock().getHeader().getHash()); if (!lock.validate(stamp)) { continue; } return params; } } finally { if (StampedLock.isReadLockStamp(stamp)) { lock.unlockRead(stamp); } } }
BlockSynchronizer implements Runnable { BlockDownloaderParams statistics(List<Node> availableNodes, ChainContext context) { BlockDownloaderParams params = new BlockDownloaderParams(); List<Node> filterAvailableNodes = filterNodes(availableNodes, context); params.setAvailableNodesCount(filterAvailableNodes.size()); if (filterAvailableNodes.isEmpty()) { return params; } String key = ""; int count = 0; Map<String, List<Node>> nodeMap = new HashMap<>(filterAvailableNodes.size()); Map<String, Integer> countMap = new HashMap<>(filterAvailableNodes.size()); for (Node node : filterAvailableNodes) { String tempKey = node.getHash().toHex() + node.getHeight(); if (countMap.containsKey(tempKey)) { countMap.put(tempKey, countMap.get(tempKey) + 1); } else { countMap.put(tempKey, 1); } if (nodeMap.containsKey(tempKey)) { List<Node> nodes = nodeMap.get(tempKey); nodes.add(node); } else { nodeMap.put(tempKey, Lists.newArrayList(node)); } } for (Map.Entry<String, Integer> entry : countMap.entrySet()) { Integer value = entry.getValue(); if (value > count) { count = value; key = entry.getKey(); } } ChainParameters parameters = context.getParameters(); double div = DoubleUtils.div(count, filterAvailableNodes.size(), 2); byte percent = calculateConsistencyNodePercent(parameters.getConsistencyNodePercent(), filterAvailableNodes.size()); if (div * 100 < percent) { return params; } List<Node> nodeList = nodeMap.get(key); params.setNodes(nodeList); Map<String, Node> statusMap = new ConcurrentHashMap<>(); nodeList.forEach(e -> statusMap.put(e.getId(), e)); params.setNodeMap(statusMap); Node node = nodeList.get(0); params.setNetLatestHash(node.getHash()); params.setNetLatestHeight(node.getHeight()); StampedLock lock = context.getLock(); long stamp = lock.tryOptimisticRead(); try { for (; ; stamp = lock.readLock()) { if (stamp == 0L) { continue; } params.setLocalLatestHeight(context.getLatestHeight()); params.setLocalLatestHash(context.getLatestBlock().getHeader().getHash()); if (!lock.validate(stamp)) { continue; } return params; } } finally { if (StampedLock.isReadLockStamp(stamp)) { lock.unlockRead(stamp); } } } }
BlockSynchronizer implements Runnable { BlockDownloaderParams statistics(List<Node> availableNodes, ChainContext context) { BlockDownloaderParams params = new BlockDownloaderParams(); List<Node> filterAvailableNodes = filterNodes(availableNodes, context); params.setAvailableNodesCount(filterAvailableNodes.size()); if (filterAvailableNodes.isEmpty()) { return params; } String key = ""; int count = 0; Map<String, List<Node>> nodeMap = new HashMap<>(filterAvailableNodes.size()); Map<String, Integer> countMap = new HashMap<>(filterAvailableNodes.size()); for (Node node : filterAvailableNodes) { String tempKey = node.getHash().toHex() + node.getHeight(); if (countMap.containsKey(tempKey)) { countMap.put(tempKey, countMap.get(tempKey) + 1); } else { countMap.put(tempKey, 1); } if (nodeMap.containsKey(tempKey)) { List<Node> nodes = nodeMap.get(tempKey); nodes.add(node); } else { nodeMap.put(tempKey, Lists.newArrayList(node)); } } for (Map.Entry<String, Integer> entry : countMap.entrySet()) { Integer value = entry.getValue(); if (value > count) { count = value; key = entry.getKey(); } } ChainParameters parameters = context.getParameters(); double div = DoubleUtils.div(count, filterAvailableNodes.size(), 2); byte percent = calculateConsistencyNodePercent(parameters.getConsistencyNodePercent(), filterAvailableNodes.size()); if (div * 100 < percent) { return params; } List<Node> nodeList = nodeMap.get(key); params.setNodes(nodeList); Map<String, Node> statusMap = new ConcurrentHashMap<>(); nodeList.forEach(e -> statusMap.put(e.getId(), e)); params.setNodeMap(statusMap); Node node = nodeList.get(0); params.setNetLatestHash(node.getHash()); params.setNetLatestHeight(node.getHeight()); StampedLock lock = context.getLock(); long stamp = lock.tryOptimisticRead(); try { for (; ; stamp = lock.readLock()) { if (stamp == 0L) { continue; } params.setLocalLatestHeight(context.getLatestHeight()); params.setLocalLatestHash(context.getLatestBlock().getHeader().getHash()); if (!lock.validate(stamp)) { continue; } return params; } } finally { if (StampedLock.isReadLockStamp(stamp)) { lock.unlockRead(stamp); } } } BlockSynchronizer(int chainId); }
BlockSynchronizer implements Runnable { BlockDownloaderParams statistics(List<Node> availableNodes, ChainContext context) { BlockDownloaderParams params = new BlockDownloaderParams(); List<Node> filterAvailableNodes = filterNodes(availableNodes, context); params.setAvailableNodesCount(filterAvailableNodes.size()); if (filterAvailableNodes.isEmpty()) { return params; } String key = ""; int count = 0; Map<String, List<Node>> nodeMap = new HashMap<>(filterAvailableNodes.size()); Map<String, Integer> countMap = new HashMap<>(filterAvailableNodes.size()); for (Node node : filterAvailableNodes) { String tempKey = node.getHash().toHex() + node.getHeight(); if (countMap.containsKey(tempKey)) { countMap.put(tempKey, countMap.get(tempKey) + 1); } else { countMap.put(tempKey, 1); } if (nodeMap.containsKey(tempKey)) { List<Node> nodes = nodeMap.get(tempKey); nodes.add(node); } else { nodeMap.put(tempKey, Lists.newArrayList(node)); } } for (Map.Entry<String, Integer> entry : countMap.entrySet()) { Integer value = entry.getValue(); if (value > count) { count = value; key = entry.getKey(); } } ChainParameters parameters = context.getParameters(); double div = DoubleUtils.div(count, filterAvailableNodes.size(), 2); byte percent = calculateConsistencyNodePercent(parameters.getConsistencyNodePercent(), filterAvailableNodes.size()); if (div * 100 < percent) { return params; } List<Node> nodeList = nodeMap.get(key); params.setNodes(nodeList); Map<String, Node> statusMap = new ConcurrentHashMap<>(); nodeList.forEach(e -> statusMap.put(e.getId(), e)); params.setNodeMap(statusMap); Node node = nodeList.get(0); params.setNetLatestHash(node.getHash()); params.setNetLatestHeight(node.getHeight()); StampedLock lock = context.getLock(); long stamp = lock.tryOptimisticRead(); try { for (; ; stamp = lock.readLock()) { if (stamp == 0L) { continue; } params.setLocalLatestHeight(context.getLatestHeight()); params.setLocalLatestHash(context.getLatestBlock().getHeader().getHash()); if (!lock.validate(stamp)) { continue; } return params; } } finally { if (StampedLock.isReadLockStamp(stamp)) { lock.unlockRead(stamp); } } } BlockSynchronizer(int chainId); static void syn(int chainId); int getChainId(); void setChainId(int chainId); synchronized boolean isRunning(); synchronized void setRunning(boolean running); @Override void run(); }
BlockSynchronizer implements Runnable { BlockDownloaderParams statistics(List<Node> availableNodes, ChainContext context) { BlockDownloaderParams params = new BlockDownloaderParams(); List<Node> filterAvailableNodes = filterNodes(availableNodes, context); params.setAvailableNodesCount(filterAvailableNodes.size()); if (filterAvailableNodes.isEmpty()) { return params; } String key = ""; int count = 0; Map<String, List<Node>> nodeMap = new HashMap<>(filterAvailableNodes.size()); Map<String, Integer> countMap = new HashMap<>(filterAvailableNodes.size()); for (Node node : filterAvailableNodes) { String tempKey = node.getHash().toHex() + node.getHeight(); if (countMap.containsKey(tempKey)) { countMap.put(tempKey, countMap.get(tempKey) + 1); } else { countMap.put(tempKey, 1); } if (nodeMap.containsKey(tempKey)) { List<Node> nodes = nodeMap.get(tempKey); nodes.add(node); } else { nodeMap.put(tempKey, Lists.newArrayList(node)); } } for (Map.Entry<String, Integer> entry : countMap.entrySet()) { Integer value = entry.getValue(); if (value > count) { count = value; key = entry.getKey(); } } ChainParameters parameters = context.getParameters(); double div = DoubleUtils.div(count, filterAvailableNodes.size(), 2); byte percent = calculateConsistencyNodePercent(parameters.getConsistencyNodePercent(), filterAvailableNodes.size()); if (div * 100 < percent) { return params; } List<Node> nodeList = nodeMap.get(key); params.setNodes(nodeList); Map<String, Node> statusMap = new ConcurrentHashMap<>(); nodeList.forEach(e -> statusMap.put(e.getId(), e)); params.setNodeMap(statusMap); Node node = nodeList.get(0); params.setNetLatestHash(node.getHash()); params.setNetLatestHeight(node.getHeight()); StampedLock lock = context.getLock(); long stamp = lock.tryOptimisticRead(); try { for (; ; stamp = lock.readLock()) { if (stamp == 0L) { continue; } params.setLocalLatestHeight(context.getLatestHeight()); params.setLocalLatestHash(context.getLatestBlock().getHeader().getHash()); if (!lock.validate(stamp)) { continue; } return params; } } finally { if (StampedLock.isReadLockStamp(stamp)) { lock.unlockRead(stamp); } } } BlockSynchronizer(int chainId); static void syn(int chainId); int getChainId(); void setChainId(int chainId); synchronized boolean isRunning(); synchronized void setRunning(boolean running); @Override void run();  }