diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java index 9027034ccc7..3c83bc51e47 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java @@ -87,6 +87,18 @@ private boolean check(PeerConnection peer, SyncBlockChainMessage msg) throws P2p private LinkedList getLostBlockIds(List blockIds) throws P2pException { + BlockId unForkId = getUnForkId(blockIds); + LinkedList ids = getBlockIds(unForkId.getNum()); + + if (ids.isEmpty() || !unForkId.equals(ids.peekFirst())) { + unForkId = getUnForkId(blockIds); + ids = getBlockIds(unForkId.getNum()); + } + + return ids; + } + + private BlockId getUnForkId(List blockIds) throws P2pException { BlockId unForkId = null; for (int i = blockIds.size() - 1; i >= 0; i--) { if (tronNetDelegate.containBlockInMainChain(blockIds.get(i))) { @@ -99,13 +111,17 @@ private LinkedList getLostBlockIds(List blockIds) throws P2pEx throw new P2pException(TypeEnum.SYNC_FAILED, "unForkId is null"); } + return unForkId; + } + + private LinkedList getBlockIds(Long unForkNum) throws P2pException { BlockId headID = tronNetDelegate.getHeadBlockId(); long headNum = headID.getNum(); - long len = Math.min(headNum, unForkId.getNum() + NetConstants.SYNC_FETCH_BATCH_NUM); + long len = Math.min(headNum, unForkNum + NetConstants.SYNC_FETCH_BATCH_NUM); LinkedList ids = new LinkedList<>(); - for (long i = unForkId.getNum(); i <= len; i++) { + for (long i = unForkNum; i <= len; i++) { if (i == headNum) { ids.add(headID); } else { diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java index 2dbad09c655..53375ec7815 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java @@ -2,6 +2,7 @@ import java.io.File; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.util.ArrayList; @@ -64,6 +65,21 @@ public void testProcessMessage() throws Exception { method.setAccessible(true); boolean f = (boolean)method.invoke(handler, peer, message); Assert.assertTrue(!f); + + Method method1 = handler.getClass().getDeclaredMethod( + "getLostBlockIds", List.class); + method1.setAccessible(true); + try { + method1.invoke(handler, blockIds); + } catch (InvocationTargetException e) { + Assert.assertEquals("unForkId is null", e.getTargetException().getMessage()); + } + + Method method2 = handler.getClass().getDeclaredMethod( + "getBlockIds", Long.class); + method2.setAccessible(true); + List list = (List) method2.invoke(handler, 0L); + Assert.assertEquals(1, list.size()); } @After