SyncQueueImpl implements SyncQueueIfc { List<HeaderElement> getLongestChain() { Map<ByteArrayWrapper, HeaderElement> lastValidatedGen = headers.get(darkZoneNum); assert lastValidatedGen.size() == 1; HeaderElement lastHeader = lastValidatedGen.values().iterator().next(); Map<byte[], HeaderElement> chainedParents = new ByteArrayMap<>(); chainedParents.put(lastHeader.header.getHash(), lastHeader); for(long curNum = darkZoneNum + 1; ; curNum++) { Map<byte[], HeaderElement> chainedBlocks = new ByteArrayMap<>(); Map<ByteArrayWrapper, HeaderElement> curLevel = headers.get(curNum); if (curLevel == null) break; for (HeaderElement element : curLevel.values()) { if (chainedParents.containsKey(element.header.getHeader().getParentHash())) { chainedBlocks.put(element.header.getHash(), element); } } if (chainedBlocks.isEmpty()) break; chainedParents = chainedBlocks; } List<HeaderElement> ret = new ArrayList<>(); for (HeaderElement el = chainedParents.values().iterator().next(); el != lastHeader.getParent(); el = el.getParent()) { ret.add(0, el); } return ret; } SyncQueueImpl(List<Block> initBlocks);  SyncQueueImpl(Blockchain bc);  SyncQueueImpl(Blockchain bc, Long endBlockNumber); @Override synchronized List<HeadersRequest> requestHeaders(int maxSize, int maxRequests, int maxTotalHeaders); @Override synchronized List<BlockHeaderWrapper> addHeaders(Collection<BlockHeaderWrapper> headers); @Override synchronized ValidatedHeaders addHeadersAndValidate(Collection<BlockHeaderWrapper> headers); @Override synchronized int getHeadersCount(); @Override synchronized BlocksRequest requestBlocks(int maxSize); @Override synchronized List<Block> addBlocks(Collection<Block> blocks); synchronized List<Block> pollBlocks(); SyncQueueImpl withParentHeaderValidator(DependentBlockHeaderRule validator);  }
@Test public void testLongLongestChain() { List<Block> randomChain = TestUtils.getRandomAltChain(new byte[32], 0, 10500, 3); SyncQueueImpl syncQueue = new SyncQueueImpl(randomChain); assert syncQueue.getLongestChain().size() == 10500; }
@Test public void testWideLongestChain() { List<Block> randomChain = TestUtils.getRandomAltChain(new byte[32], 0, 100, 100); SyncQueueImpl syncQueue = new SyncQueueImpl(randomChain); assert syncQueue.getLongestChain().size() == 100; }
@Test public void testGapedLongestChain() { List<Block> randomChain = TestUtils.getRandomAltChain(new byte[32], 0, 100, 5); Iterator<Block> it = randomChain.iterator(); while (it.hasNext()) { if (it.next().getHeader().getNumber() == 15) it.remove(); } SyncQueueImpl syncQueue = new SyncQueueImpl(randomChain); assert syncQueue.getLongestChain().size() == 15; }
@Test public void testFirstBlockGapedLongestChain() { List<Block> randomChain = TestUtils.getRandomAltChain(new byte[32], 0, 100, 5); Iterator<Block> it = randomChain.iterator(); while (it.hasNext()) { if (it.next().getHeader().getNumber() == 1) it.remove(); } SyncQueueImpl syncQueue = new SyncQueueImpl(randomChain); assert syncQueue.getLongestChain().size() == 1; }
@Test(expected = AssertionError.class) public void testZeroBlockGapedLongestChain() { List<Block> randomChain = TestUtils.getRandomAltChain(new byte[32], 0, 100, 5); Iterator<Block> it = randomChain.iterator(); while (it.hasNext()) { if (it.next().getHeader().getNumber() == 0) it.remove(); } SyncQueueImpl syncQueue = new SyncQueueImpl(randomChain); syncQueue.getLongestChain().size(); }
@Test public void testNoParentGapeLongestChain() { List<Block> randomChain = TestUtils.getRandomAltChain(new byte[32], 0, 100, 5); Iterator<Block> it = randomChain.iterator(); List<Block> blockSaver = new ArrayList<>(); while (it.hasNext()) { Block block = it.next(); if (block.getHeader().getNumber() == 15) { blockSaver.add(block); it.remove(); } } randomChain.addAll(blockSaver); SyncQueueImpl syncQueue = new SyncQueueImpl(randomChain); assert syncQueue.getLongestChain().size() == 100; List<Block> randomChain2 = TestUtils.getRandomAltChain(new byte[32], 0, 100, 5); Iterator<Block> it2 = randomChain2.iterator(); List<Block> blockSaver2 = new ArrayList<>(); while (it2.hasNext()) { Block block = it2.next(); if (block.getHeader().getNumber() == 15) { blockSaver2.add(block); } } for (int i = 0; i < 5; ++i) { randomChain.remove(randomChain.size() - 1); } assert blockSaver2.size() == 5; randomChain.addAll(blockSaver2); assert new SyncQueueImpl(randomChain).getLongestChain().size() == 15; }