From ff69595ca0ef7a30bc7eab62279b4e1fd656a026 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Mon, 1 Jul 2024 15:04:55 +0800 Subject: [PATCH 01/42] test(CI): add test-retry plugin for test Mitigate flaky tests by retrying tests when they fail. --- framework/build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/framework/build.gradle b/framework/build.gradle index 8c4fbfc4583..a297faed7a9 100644 --- a/framework/build.gradle +++ b/framework/build.gradle @@ -1,4 +1,5 @@ plugins { + id "org.gradle.test-retry" version "1.5.9" id "org.sonarqube" version "2.6" id "com.gorylenko.gradle-git-properties" version "2.4.1" } @@ -113,6 +114,10 @@ run { } test { + retry { + maxRetries = 5 + maxFailures = 20 + } testLogging { exceptionFormat = 'full' } From 496d64dd1226356c2b3cab1aeed53ff6b94ad3f6 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Thu, 18 Jul 2024 15:39:19 +0800 Subject: [PATCH 02/42] feat(version): update version to 4.7.6 --- framework/src/main/java/org/tron/program/Version.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/program/Version.java b/framework/src/main/java/org/tron/program/Version.java index eb21aa292f7..601f555a234 100644 --- a/framework/src/main/java/org/tron/program/Version.java +++ b/framework/src/main/java/org/tron/program/Version.java @@ -4,7 +4,7 @@ public class Version { public static final String VERSION_NAME = "GreatVoyage-v4.7.4-44-g8720e06a6"; public static final String VERSION_CODE = "18306"; - private static final String VERSION = "4.7.5"; + private static final String VERSION = "4.7.6"; public static String getVersion() { return VERSION; From 0dc7a3f01bb56220f7a3028ce30ee3636daf1682 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Mon, 24 Jun 2024 09:53:57 +0800 Subject: [PATCH 03/42] feat(net) : optimize the isIdle method --- .../src/main/java/org/tron/core/net/peer/PeerConnection.java | 2 +- .../test/java/org/tron/core/net/peer/PeerConnectionTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index 4fac50b82c7..e66f708b543 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -167,7 +167,7 @@ public void setBlockBothHave(BlockId blockId) { } public boolean isIdle() { - return advInvRequest.isEmpty() && syncBlockRequested.isEmpty() && syncChainRequested == null; + return syncBlockRequested.isEmpty() && syncChainRequested == null; } public void sendMessage(Message message) { diff --git a/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java b/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java index 9db5230ed45..2eaebb2715e 100644 --- a/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java +++ b/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java @@ -78,7 +78,7 @@ public void testIsIdle() { Long time = System.currentTimeMillis(); peerConnection.getAdvInvRequest().put(item, time); f = peerConnection.isIdle(); - Assert.assertTrue(!f); + Assert.assertTrue(f); peerConnection.getAdvInvRequest().clear(); f = peerConnection.isIdle(); From ddbe8f10b32f5e0df3239a7ad66e0f63d9353fb7 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Mon, 1 Jul 2024 14:20:07 +0800 Subject: [PATCH 04/42] feat(net): add isSyncIdle method --- .../tron/core/net/peer/PeerConnection.java | 4 +++ .../core/net/service/sync/SyncService.java | 4 +-- .../core/net/peer/PeerConnectionTest.java | 32 ++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index e66f708b543..1c7560559e1 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -167,6 +167,10 @@ public void setBlockBothHave(BlockId blockId) { } public boolean isIdle() { + return advInvRequest.isEmpty() && isSyncIdle(); + } + + public boolean isSyncIdle() { return syncBlockRequested.isEmpty() && syncChainRequested == null; } diff --git a/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java b/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java index 9453700df0d..8c673977962 100644 --- a/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java +++ b/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java @@ -134,7 +134,7 @@ public void processBlock(PeerConnection peer, BlockMessage blockMessage) { blockJustReceived.put(blockMessage, peer); } handleFlag = true; - if (peer.isIdle()) { + if (peer.isSyncIdle()) { if (peer.getRemainNum() > 0 && peer.getSyncBlockToFetch().size() <= syncFetchBatchNum) { syncNext(peer); @@ -226,7 +226,7 @@ private BlockId getBlockIdByNum(long num) throws P2pException { private void startFetchSyncBlock() { HashMap> send = new HashMap<>(); tronNetDelegate.getActivePeer().stream() - .filter(peer -> peer.isNeedSyncFromPeer() && peer.isIdle()) + .filter(peer -> peer.isNeedSyncFromPeer() && peer.isSyncIdle()) .filter(peer -> peer.isFetchAble()) .forEach(peer -> { if (!send.containsKey(peer)) { diff --git a/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java b/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java index 2eaebb2715e..5a67cd8f609 100644 --- a/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java +++ b/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java @@ -78,7 +78,7 @@ public void testIsIdle() { Long time = System.currentTimeMillis(); peerConnection.getAdvInvRequest().put(item, time); f = peerConnection.isIdle(); - Assert.assertTrue(f); + Assert.assertTrue(!f); peerConnection.getAdvInvRequest().clear(); f = peerConnection.isIdle(); @@ -98,6 +98,36 @@ public void testIsIdle() { Assert.assertTrue(!f); } + @Test + public void testIsSyncIdle() { + PeerConnection peerConnection = new PeerConnection(); + boolean f = peerConnection.isSyncIdle(); + Assert.assertTrue(f); + + Item item = new Item(Sha256Hash.ZERO_HASH, Protocol.Inventory.InventoryType.TRX); + Long time = System.currentTimeMillis(); + peerConnection.getAdvInvRequest().put(item, time); + f = peerConnection.isSyncIdle(); + Assert.assertTrue(f); + + peerConnection.getAdvInvRequest().clear(); + f = peerConnection.isSyncIdle(); + Assert.assertTrue(f); + + BlockCapsule.BlockId blockId = new BlockCapsule.BlockId(); + peerConnection.getSyncBlockRequested().put(blockId, time); + f = peerConnection.isSyncIdle(); + Assert.assertTrue(!f); + + peerConnection.getSyncBlockRequested().clear(); + f = peerConnection.isSyncIdle(); + Assert.assertTrue(f); + + peerConnection.setSyncChainRequested(new Pair<>(new LinkedList<>(), time)); + f = peerConnection.isSyncIdle(); + Assert.assertTrue(!f); + } + @Test public void testOnConnect() { PeerConnection peerConnection = new PeerConnection(); From 0779c0091cac1b184b6c5755ebd844b63661497a Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Tue, 25 Jun 2024 18:53:38 +0800 Subject: [PATCH 05/42] feat(net): optimize fetch inventory message check logic --- .../FetchInvDataMsgHandler.java | 4 +++ .../FetchInvDataMsgHandlerTest.java | 35 +++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 5e797c084b3..5415ea435e3 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -164,6 +164,10 @@ private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) thr throw new P2pException(TypeEnum.BAD_MESSAGE, "minBlockNum: " + minBlockNum + ", blockNum: " + blockNum); } + if (blockNum > peer.getLastSyncBlockId().getNum()) { + throw new P2pException(TypeEnum.BAD_MESSAGE, + "maxBlockNum: " + peer.getLastSyncBlockId().getNum() + ", blockNum: " + blockNum); + } if (peer.getSyncBlockIdCache().getIfPresent(hash) != null) { throw new P2pException(TypeEnum.BAD_MESSAGE, new BlockId(hash).getString() + " is exist"); diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java index 404d275276a..5fd6d6725ba 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java @@ -21,8 +21,6 @@ import org.tron.core.net.service.adv.AdvService; import org.tron.protos.Protocol; - - public class FetchInvDataMsgHandlerTest { @Test @@ -62,4 +60,37 @@ public void testProcessMessage() throws Exception { new FetchInvDataMessage(blockIds, Protocol.Inventory.InventoryType.BLOCK)); Assert.assertNotNull(syncBlockIdCache.getIfPresent(blockId)); } + + @Test + public void testSyncFetchCheck() { + BlockCapsule.BlockId blockId = new BlockCapsule.BlockId(Sha256Hash.ZERO_HASH, 10000L); + List blockIds = new LinkedList<>(); + blockIds.add(blockId); + FetchInvDataMessage msg = + new FetchInvDataMessage(blockIds, Protocol.Inventory.InventoryType.BLOCK); + + PeerConnection peer = Mockito.mock(PeerConnection.class); + Mockito.when(peer.isNeedSyncFromUs()).thenReturn(true); + Cache advInvSpread = CacheBuilder.newBuilder().maximumSize(100) + .expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); + Mockito.when(peer.getAdvInvSpread()).thenReturn(advInvSpread); + + FetchInvDataMsgHandler fetchInvDataMsgHandler = new FetchInvDataMsgHandler(); + + try { + Mockito.when(peer.getLastSyncBlockId()) + .thenReturn(new BlockCapsule.BlockId(Sha256Hash.ZERO_HASH, 1000L)); + fetchInvDataMsgHandler.processMessage(peer, msg); + } catch (Exception e) { + Assert.assertEquals(e.getMessage(), "maxBlockNum: 1000, blockNum: 10000"); + } + + try { + Mockito.when(peer.getLastSyncBlockId()) + .thenReturn(new BlockCapsule.BlockId(Sha256Hash.ZERO_HASH, 20000L)); + fetchInvDataMsgHandler.processMessage(peer, msg); + } catch (Exception e) { + Assert.assertEquals(e.getMessage(), "minBlockNum: 16000, blockNum: 10000"); + } + } } From fdbfa17e1d99a5627fc8863e719889ff38ab7537 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Fri, 21 Jun 2024 10:01:55 +0800 Subject: [PATCH 06/42] feat(net) : optimizing the sortPeers method --- .../org/tron/core/net/peer/PeerManager.java | 6 +++- .../tron/core/net/peer/PeerManagerTest.java | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerManager.java b/framework/src/main/java/org/tron/core/net/peer/PeerManager.java index 537f2083691..442e0a3fab1 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerManager.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerManager.java @@ -94,7 +94,11 @@ private static void remove(PeerConnection peerConnection) { } public static synchronized void sortPeers() { - peers.sort(Comparator.comparingDouble(c -> c.getChannel().getAvgLatency())); + try { + peers.sort(Comparator.comparingDouble(c -> c.getChannel().getAvgLatency())); + } catch (Exception e) { + logger.warn("Sort peers failed. {}", e.getMessage()); + } } public static PeerConnection getPeerConnection(Channel channel) { diff --git a/framework/src/test/java/org/tron/core/net/peer/PeerManagerTest.java b/framework/src/test/java/org/tron/core/net/peer/PeerManagerTest.java index a6151da6d1c..b8c03de1029 100644 --- a/framework/src/test/java/org/tron/core/net/peer/PeerManagerTest.java +++ b/framework/src/test/java/org/tron/core/net/peer/PeerManagerTest.java @@ -135,4 +135,32 @@ public void testGetPeers() throws Exception { Assert.assertEquals(2, peers.size()); } + @Test + public void testSortPeers() throws Exception { + PeerConnection p1 = new PeerConnection(); + PeerConnection p2 = new PeerConnection(); + + List peers = new ArrayList<>(); + peers.add(p1); + peers.add(p2); + + Field field = PeerManager.class.getDeclaredField("peers"); + field.setAccessible(true); + field.set(PeerManager.class, Collections.synchronizedList(peers)); + + PeerManager.sortPeers(); + + Channel c1 = new Channel(); + c1.updateAvgLatency(100000L); + ReflectUtils.setFieldValue(p1, "channel", c1); + + Channel c2 = new Channel(); + c2.updateAvgLatency(1000L); + ReflectUtils.setFieldValue(p2, "channel", c2); + + PeerManager.sortPeers(); + + Assert.assertEquals(PeerManager.getPeers().get(0), p2); + } + } From ea14933e02ec001650196c3113b1ee9889007b28 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Mon, 1 Jul 2024 14:44:09 +0800 Subject: [PATCH 07/42] feat(net): use comparingLong method for sortPeers --- framework/src/main/java/org/tron/core/net/peer/PeerManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerManager.java b/framework/src/main/java/org/tron/core/net/peer/PeerManager.java index 442e0a3fab1..f564b90f3ed 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerManager.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerManager.java @@ -95,7 +95,7 @@ private static void remove(PeerConnection peerConnection) { public static synchronized void sortPeers() { try { - peers.sort(Comparator.comparingDouble(c -> c.getChannel().getAvgLatency())); + peers.sort(Comparator.comparingLong(c -> c.getChannel().getAvgLatency())); } catch (Exception e) { logger.warn("Sort peers failed. {}", e.getMessage()); } From 3b3b6686b9e79fd7d02cbad42a4cbee8f3725dbd Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 18 Jul 2024 16:30:20 +0800 Subject: [PATCH 08/42] initial commit of test isolated --- .../java/org/tron/core/ChainBaseManager.java | 5 + .../common/parameter/CommonParameter.java | 3 + .../src/main/java/org/tron/core/Constant.java | 2 + .../java/org/tron/core/config/args/Args.java | 4 + .../main/java/org/tron/core/db/Manager.java | 1 + .../org/tron/core/net/TronNetService.java | 8 +- .../net/messagehandler/BlockMsgHandler.java | 1 + .../ChainInventoryMsgHandler.java | 1 + .../FetchInvDataMsgHandler.java | 1 + .../messagehandler/InventoryMsgHandler.java | 3 + .../SyncBlockChainMsgHandler.java | 2 +- .../tron/core/net/peer/PeerConnection.java | 5 + .../service/effective/ResilienceService.java | 170 ++++++++++++++++ .../src/main/resources/config-localtest.conf | 1 + framework/src/main/resources/config.conf | 1 + .../net/services/ResilienceServiceTest.java | 182 ++++++++++++++++++ framework/src/test/resources/args-test.conf | 1 + .../src/test/resources/config-localtest.conf | 1 + framework/src/test/resources/config-test.conf | 1 + 19 files changed, 391 insertions(+), 2 deletions(-) create mode 100644 framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java create mode 100644 framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java diff --git a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java index e43d442534a..d148021f6c4 100644 --- a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java +++ b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java @@ -244,6 +244,10 @@ public class ChainBaseManager { @Setter private long lowestBlockNum = -1; // except num = 0. + @Getter + @Setter + private long latestSaveBlockTime; + // for test only public List getWitnesses() { return witnessScheduleStore.getActiveWitnesses(); @@ -381,6 +385,7 @@ private void init() { this.lowestBlockNum = this.blockIndexStore.getLimitNumber(1, 1).stream() .map(BlockId::getNum).findFirst().orElse(0L); this.nodeType = getLowestBlockNum() > 1 ? NodeType.LITE : NodeType.FULL; + this.latestSaveBlockTime = System.currentTimeMillis(); } public void shutdown() { diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index 22159063333..62ed12d856c 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -333,6 +333,9 @@ public class CommonParameter { public boolean isOpenFullTcpDisconnect; @Getter @Setter + public int inactiveThreshold; + @Getter + @Setter public boolean nodeDetectEnable; @Getter @Setter diff --git a/common/src/main/java/org/tron/core/Constant.java b/common/src/main/java/org/tron/core/Constant.java index 0e634d3ef7d..da3b2b1becc 100644 --- a/common/src/main/java/org/tron/core/Constant.java +++ b/common/src/main/java/org/tron/core/Constant.java @@ -198,6 +198,8 @@ public class Constant { public static final String NODE_IS_OPEN_FULL_TCP_DISCONNECT = "node.isOpenFullTcpDisconnect"; + public static final String NODE_INACTIVE_THRESHOLD = "node.inactiveThreshold"; + public static final String NODE_DETECT_ENABLE = "node.nodeDetectEnable"; public static final String NODE_MAX_TRANSACTION_PENDING_SIZE = "node.maxTransactionPendingSize"; diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 422efefaed8..7b089530a41 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -173,6 +173,7 @@ public static void clearParam() { PARAMETER.receiveTcpMinDataLength = 2048; PARAMETER.isOpenFullTcpDisconnect = false; PARAMETER.nodeDetectEnable = false; + PARAMETER.inactiveThreshold = 600; PARAMETER.supportConstant = false; PARAMETER.debug = false; PARAMETER.minTimeRatio = 0.0; @@ -845,6 +846,9 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.nodeDetectEnable = config.hasPath(Constant.NODE_DETECT_ENABLE) && config.getBoolean(Constant.NODE_DETECT_ENABLE); + PARAMETER.inactiveThreshold = config.hasPath(Constant.NODE_INACTIVE_THRESHOLD) + ? config.getInt(Constant.NODE_INACTIVE_THRESHOLD) : 600; + PARAMETER.maxTransactionPendingSize = config.hasPath(Constant.NODE_MAX_TRANSACTION_PENDING_SIZE) ? config.getInt(Constant.NODE_MAX_TRANSACTION_PENDING_SIZE) : 2000; diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index ef2f5c81124..66aeccdda39 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -1384,6 +1384,7 @@ public void updateDynamicProperties(BlockCapsule block) { (chainBaseManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber() - chainBaseManager.getDynamicPropertiesStore().getLatestSolidifiedBlockNum() + 1)); + chainBaseManager.setLatestSaveBlockTime(System.currentTimeMillis()); Metrics.gaugeSet(MetricKeys.Gauge.HEADER_HEIGHT, block.getNum()); Metrics.gaugeSet(MetricKeys.Gauge.HEADER_TIME, block.getTimeStamp()); } diff --git a/framework/src/main/java/org/tron/core/net/TronNetService.java b/framework/src/main/java/org/tron/core/net/TronNetService.java index 03becf5d4e9..5b99f94c0db 100644 --- a/framework/src/main/java/org/tron/core/net/TronNetService.java +++ b/framework/src/main/java/org/tron/core/net/TronNetService.java @@ -22,6 +22,7 @@ import org.tron.core.net.peer.PeerStatusCheck; import org.tron.core.net.service.adv.AdvService; import org.tron.core.net.service.effective.EffectiveCheckService; +import org.tron.core.net.service.effective.ResilienceService; import org.tron.core.net.service.fetchblock.FetchBlockService; import org.tron.core.net.service.nodepersist.NodePersistService; import org.tron.core.net.service.relay.RelayService; @@ -50,6 +51,9 @@ public class TronNetService { @Autowired private PeerStatusCheck peerStatusCheck; + @Autowired + private ResilienceService resilienceService; + @Autowired private TransactionsMsgHandler transactionsMsgHandler; @@ -88,6 +92,7 @@ public void start() { advService.init(); syncService.init(); peerStatusCheck.init(); + resilienceService.init(); transactionsMsgHandler.init(); fetchBlockService.init(); nodePersistService.init(); @@ -110,6 +115,7 @@ public void close() { nodePersistService.close(); advService.close(); syncService.close(); + resilienceService.close(); peerStatusCheck.close(); transactionsMsgHandler.close(); fetchBlockService.close(); @@ -177,7 +183,7 @@ private P2pConfig updateConfig(P2pConfig config) { config.setMaxConnectionsWithSameIp(parameter.getMaxConnectionsWithSameIp()); config.setPort(parameter.getNodeListenPort()); config.setNetworkId(parameter.getNodeP2pVersion()); - config.setDisconnectionPolicyEnable(parameter.isOpenFullTcpDisconnect()); + config.setDisconnectionPolicyEnable(false); config.setNodeDetectEnable(parameter.isNodeDetectEnable()); config.setDiscoverEnable(parameter.isNodeDiscoveryEnable()); if (StringUtils.isEmpty(config.getIp()) && hasIpv4Stack(NetUtil.getAllLocalAddress())) { diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 926ed1a01ca..547f96036cb 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -76,6 +76,7 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep if (!fastForward && !peer.isRelayPeer()) { check(peer, blockMessage); } + peer.setLastActiveTime(System.currentTimeMillis()); if (peer.getSyncBlockRequested().containsKey(blockId)) { peer.getSyncBlockRequested().remove(blockId); diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index bd2e428418c..4f99deb146b 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -142,6 +142,7 @@ private void check(PeerConnection peer, ChainInventoryMessage msg) throws P2pExc + msg.getRemainNum() + " > futureMaxNum: " + maxFutureNum); } } + peer.setLastActiveTime(System.currentTimeMillis()); } } diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 5e797c084b3..2c4e94a66fa 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -171,6 +171,7 @@ private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) thr peer.getSyncBlockIdCache().put(hash, System.currentTimeMillis()); } } + peer.setLastActiveTime(System.currentTimeMillis()); } } diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index a8ad8d0ec73..5e303bd3d6f 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -39,6 +39,9 @@ public void processMessage(PeerConnection peer, TronMessage msg) { Item item = new Item(id, type); peer.getAdvInvReceive().put(item, System.currentTimeMillis()); advService.addInv(item); + if (type.equals(InventoryType.BLOCK) && peer.getAdvInvSpread().getIfPresent(item) == null) { + peer.setLastActiveTime(System.currentTimeMillis()); + } } } 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 958ebfe5561..e03e039ac4d 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 @@ -33,7 +33,7 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep peer.disconnect(Protocol.ReasonCode.BAD_PROTOCOL); return; } - + peer.setLastActiveTime(System.currentTimeMillis()); long remainNum = 0; List summaryChainIds = syncBlockChainMessage.getBlockIds(); diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index 4fac50b82c7..66903e7c64e 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -79,6 +79,10 @@ public class PeerConnection { @Setter private ByteString address; + @Getter + @Setter + private long lastActiveTime; + @Getter @Setter private TronState tronState = TronState.INIT; @@ -159,6 +163,7 @@ public void setChannel(Channel channel) { this.isRelayPeer = true; } this.nodeStatistics = TronStatsManager.getNodeStatistics(channel.getInetAddress()); + lastActiveTime = System.currentTimeMillis(); } public void setBlockBothHave(BlockId blockId) { diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java new file mode 100644 index 00000000000..bdf5892f260 --- /dev/null +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -0,0 +1,170 @@ +package org.tron.core.net.service.effective; + +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; +import org.tron.common.parameter.CommonParameter; +import org.tron.core.ChainBaseManager; +import org.tron.core.config.args.Args; +import org.tron.core.net.TronNetDelegate; +import org.tron.core.net.peer.PeerConnection; +import org.tron.protos.Protocol.ReasonCode; + +@Slf4j(topic = "net") +@Component +public class ResilienceService { + + private final long inactiveThreshold = + CommonParameter.getInstance().getInactiveThreshold() * 1000L; + public static final long blockNotChangeThreshold = 90 * 1000L; + + //when node is isolated, retention percent peers will not be disconnected + public static final double retentionPercent = 0.8; + private static final int initialDelay = 300; + private final String esName = "resilience-service"; + + @Autowired + private TronNetDelegate tronNetDelegate; + + @Autowired + private ChainBaseManager chainBaseManager; + + private ScheduledExecutorService executor; + + public void init() { + executor = ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); + + if (Args.getInstance().isOpenFullTcpDisconnect) { + executor.scheduleWithFixedDelay(() -> { + try { + disconnectRandom(); + } catch (Exception e) { + logger.error("DisconnectRandom node failed", e); + } + }, initialDelay, 60, TimeUnit.SECONDS); + } else { + logger.info("OpenFullTcpDisconnect is disabled"); + } + + executor.scheduleWithFixedDelay(() -> { + try { + disconnectLan(); + } catch (Exception e) { + logger.error("DisconnectLan node failed", e); + } + }, initialDelay, 10, TimeUnit.SECONDS); + + executor.scheduleWithFixedDelay(() -> { + try { + disconnectIsolated2(); + } catch (Exception e) { + logger.error("DisconnectIsolated node failed", e); + } + }, initialDelay, 30, TimeUnit.SECONDS); + } + + private void disconnectRandom() { + int peerSize = tronNetDelegate.getActivePeer().size(); + if (peerSize >= CommonParameter.getInstance().getMaxConnections()) { + long now = System.currentTimeMillis(); + List peers = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.isDisconnect()) + .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) + .filter(peer -> !peer.getChannel().isTrustPeer()) + .collect(Collectors.toList()); + if (!peers.isEmpty()) { + int index = new Random().nextInt(peers.size()); + disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION); + } + } + } + + private void disconnectLan() { + if (isLanNode()) { + // disconnect from the node that has keep inactive for more than inactiveThreshold + // and its lastActiveTime is smallest + int peerSize = tronNetDelegate.getActivePeer().size(); + if (peerSize >= CommonParameter.getInstance().getMinConnections()) { + long now = System.currentTimeMillis(); + Optional one = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.isDisconnect()) + .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) + .filter(peer -> !peer.getChannel().isTrustPeer()) + .min(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); + + one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); + } + } + } + + private void disconnectIsolated2() { + if (isIsolateLand2()) { + logger.info("Node is isolated, try to disconnect from peers"); + int peerSize = tronNetDelegate.getActivePeer().size(); + + //disconnect from the node whose lastActiveTime is smallest + if (peerSize >= CommonParameter.getInstance().getMinActiveConnections()) { + Optional one = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.isDisconnect()) + .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(peer -> peer.getChannel().isActive()) + .min(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); + + one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); + } + + //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection + peerSize = tronNetDelegate.getActivePeer().size(); + int threshold = (int) (CommonParameter.getInstance().getMaxConnections() * retentionPercent); + if (peerSize > threshold) { + int disconnectSize = peerSize - threshold; + List peers = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.isDisconnect()) + .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(peer -> !peer.getChannel().isActive()) + .sorted(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)) + .collect(Collectors.toList()); + + if (peers.size() > disconnectSize) { + peers = peers.subList(0, disconnectSize); + } + peers.forEach(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); + } + } + } + + private boolean isLanNode() { + int peerSize = tronNetDelegate.getActivePeer().size(); + int activePeerSize = (int) tronNetDelegate.getActivePeer().stream() + .filter(peer -> peer.getChannel().isActive()) + .count(); + return peerSize > 0 && peerSize == activePeerSize; + } + + private boolean isIsolateLand2() { + int advPeerCount = (int) tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) + .count(); + long diff = System.currentTimeMillis() - chainBaseManager.getLatestSaveBlockTime(); + return advPeerCount >= 1 && diff >= blockNotChangeThreshold; + } + + private void disconnectFromPeer(PeerConnection peer, ReasonCode reasonCode) { + int inactiveSeconds = (int) ((System.currentTimeMillis() - peer.getLastActiveTime()) / 1000); + logger.info("Disconnect from peer {}, inactive seconds {}", peer.getInetSocketAddress(), + inactiveSeconds); + peer.disconnect(reasonCode); + } + + public void close() { + ExecutorServiceManager.shutdownAndAwaitTermination(executor, esName); + } +} diff --git a/framework/src/main/resources/config-localtest.conf b/framework/src/main/resources/config-localtest.conf index f1ac104c9ed..e1c0d55b002 100644 --- a/framework/src/main/resources/config-localtest.conf +++ b/framework/src/main/resources/config-localtest.conf @@ -99,6 +99,7 @@ node { # check the peer data transfer ,disconnect factor isOpenFullTcpDisconnect = true + inactiveThreshold = 600 p2p { version = 333 # 11111: mainnet; 20180622: testnet diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index 78427c30f87..3b4a2b64968 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -180,6 +180,7 @@ node { minParticipationRate = 15 isOpenFullTcpDisconnect = false + inactiveThreshold = 600 p2p { version = 11111 # 11111: mainnet; 20180622: testnet diff --git a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java new file mode 100644 index 00000000000..a8b8e04d3cb --- /dev/null +++ b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java @@ -0,0 +1,182 @@ +package org.tron.core.net.services; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.spy; + +import io.netty.channel.ChannelHandlerContext; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.HashSet; +import java.util.Set; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mockito; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.utils.ReflectUtils; +import org.tron.core.ChainBaseManager; +import org.tron.core.Constant; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerManager; +import org.tron.core.net.service.effective.ResilienceService; +import org.tron.p2p.connection.Channel; + +public class ResilienceServiceTest { + + protected TronApplicationContext context; + private ResilienceService service; + private ChainBaseManager chainBaseManager; + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Before + public void init() throws IOException { + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + chainBaseManager = context.getBean(ChainBaseManager.class); + service = context.getBean(ResilienceService.class); + } + + @Test + public void testDisconnectRandom() { + int maxConnection = 30; + Assert.assertEquals(maxConnection, Args.getInstance().getMaxConnections()); + clearPeers(); + Assert.assertEquals(0, PeerManager.getPeers().size()); + + for (int i = 0; i < maxConnection; i++) { + InetSocketAddress inetSocketAddress = new InetSocketAddress("201.0.0." + i, 10001); + Channel c1 = spy(Channel.class); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress.getAddress()); + ReflectUtils.setFieldValue(c1, "ctx", spy(ChannelHandlerContext.class)); + Mockito.doNothing().when(c1).send((byte[]) any()); + + PeerManager.add(context, c1); + } + ReflectUtils.invokeMethod(service, "disconnectRandom"); + Assert.assertEquals(maxConnection, PeerManager.getPeers().size()); + + PeerConnection p1 = PeerManager.getPeers().get(1); + p1.setLastActiveTime( + System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 1000); + PeerConnection p2 = PeerManager.getPeers().get(10); + p2.setLastActiveTime( + System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 2000); + + ReflectUtils.invokeMethod(service, "disconnectRandom"); + Assert.assertEquals(maxConnection - 1, PeerManager.getPeers().size()); + } + + @Test + public void testDisconnectLan() { + int minConnection = 8; + Assert.assertEquals(minConnection, Args.getInstance().getMinConnections()); + clearPeers(); + Assert.assertEquals(0, PeerManager.getPeers().size()); + + for (int i = 0; i < 9; i++) { + InetSocketAddress inetSocketAddress = new InetSocketAddress("201.0.0." + i, 10001); + Channel c1 = spy(Channel.class); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress.getAddress()); + ReflectUtils.setFieldValue(c1, "isActive", true); + ReflectUtils.setFieldValue(c1, "ctx", spy(ChannelHandlerContext.class)); + Mockito.doNothing().when(c1).send((byte[]) any()); + + PeerManager.add(context, c1); + } + + Assert.assertEquals(9, PeerManager.getPeers().size()); + + boolean isLan = ReflectUtils.invokeMethod(service, "isLanNode"); + Assert.assertTrue(isLan); + + PeerConnection p1 = PeerManager.getPeers().get(1); + InetSocketAddress address1 = p1.getChannel().getInetSocketAddress(); + p1.setLastActiveTime( + System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 1000); + PeerConnection p2 = PeerManager.getPeers().get(2); + InetSocketAddress address2 = p2.getChannel().getInetSocketAddress(); + p2.setLastActiveTime( + System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 2000); + + ReflectUtils.invokeMethod(service, "disconnectLan"); + Assert.assertEquals(8, PeerManager.getPeers().size()); + Set addressSet = new HashSet<>(); + PeerManager.getPeers() + .forEach(p -> addressSet.add(p.getChannel().getInetSocketAddress())); + Assert.assertTrue(addressSet.contains(address1)); + Assert.assertFalse(addressSet.contains(address2)); + + ReflectUtils.invokeMethod(service, "disconnectLan"); + Assert.assertEquals(7, PeerManager.getPeers().size()); + addressSet.clear(); + PeerManager.getPeers() + .forEach(p -> addressSet.add(p.getChannel().getInetSocketAddress())); + Assert.assertFalse(addressSet.contains(address1)); + + ReflectUtils.invokeMethod(service, "disconnectLan"); + Assert.assertEquals(7, PeerManager.getPeers().size()); + } + + @Test + public void testDisconnectIsolated2() { + int maxConnection = 30; + Assert.assertEquals(maxConnection, Args.getInstance().getMaxConnections()); + clearPeers(); + Assert.assertEquals(0, PeerManager.getPeers().size()); + + int addSize = (int) (maxConnection * ResilienceService.retentionPercent) + 2; //26 + for (int i = 0; i < addSize; i++) { + InetSocketAddress inetSocketAddress = new InetSocketAddress("201.0.0." + i, 10001); + Channel c1 = spy(Channel.class); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress.getAddress()); + // 1 ~ 3 is active, 4 ~ 26 is not active + ReflectUtils.setFieldValue(c1, "isActive", i <= 2); + ReflectUtils.setFieldValue(c1, "ctx", spy(ChannelHandlerContext.class)); + Mockito.doNothing().when(c1).send((byte[]) any()); + + PeerManager.add(context, c1); + } + PeerManager.getPeers().get(10).setNeedSyncFromUs(false); + PeerManager.getPeers().get(10).setNeedSyncFromPeer(false); + chainBaseManager.setLatestSaveBlockTime( + System.currentTimeMillis() - ResilienceService.blockNotChangeThreshold - 100L); + boolean isIsolated = ReflectUtils.invokeMethod(service, "isIsolateLand2"); + Assert.assertTrue(isIsolated); + + ReflectUtils.invokeMethod(service, "disconnectIsolated2"); + int activeNodeSize = (int) PeerManager.getPeers().stream() + .filter(p -> p.getChannel().isActive()) + .count(); + int passiveSize = (int) PeerManager.getPeers().stream() + .filter(p -> !p.getChannel().isActive()) + .count(); + Assert.assertEquals(2, activeNodeSize); + Assert.assertEquals((int) (maxConnection * ResilienceService.retentionPercent), + activeNodeSize + passiveSize); + Assert.assertEquals((int) (maxConnection * ResilienceService.retentionPercent), + PeerManager.getPeers().size()); + } + + private void clearPeers() { + for (PeerConnection p : PeerManager.getPeers()) { + PeerManager.remove(p.getChannel()); + } + } + + @After + public void destroy() { + Args.clearParam(); + context.destroy(); + } +} \ No newline at end of file diff --git a/framework/src/test/resources/args-test.conf b/framework/src/test/resources/args-test.conf index 91913dfe32e..2d0c54c1d28 100644 --- a/framework/src/test/resources/args-test.conf +++ b/framework/src/test/resources/args-test.conf @@ -92,6 +92,7 @@ node { maxConnections = 30 minConnections = 8 minActiveConnections = 3 + inactiveThreshold = 600 p2p { version = 43 # 43: testnet; 101: debug diff --git a/framework/src/test/resources/config-localtest.conf b/framework/src/test/resources/config-localtest.conf index d7f573fe90e..e56318fea1a 100644 --- a/framework/src/test/resources/config-localtest.conf +++ b/framework/src/test/resources/config-localtest.conf @@ -96,6 +96,7 @@ node { # check the peer data transfer ,disconnect factor isOpenFullTcpDisconnect = true + inactiveThreshold = 600 p2p { version = 333 # 11111: mainnet; 20180622: testnet diff --git a/framework/src/test/resources/config-test.conf b/framework/src/test/resources/config-test.conf index db24bb2a8a0..19a8be9e25f 100644 --- a/framework/src/test/resources/config-test.conf +++ b/framework/src/test/resources/config-test.conf @@ -100,6 +100,7 @@ node { # nodeId = e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c # } ] + inactiveThreshold = 600 p2p { version = 43 # 43: testnet; 101: debug From 6466458ffe58e2ac985cac4c4da0bacf464a147d Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 18 Jul 2024 16:45:28 +0800 Subject: [PATCH 09/42] init commit of set_block_both_have2 --- .../org/tron/core/net/messagehandler/BlockMsgHandler.java | 7 +++++++ .../main/java/org/tron/core/net/peer/PeerConnection.java | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 926ed1a01ca..dc886517476 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -151,6 +151,13 @@ private void processBlock(PeerConnection peer, BlockCapsule block) throws P2pExc try { tronNetDelegate.processBlock(block, false); witnessProductBlockService.validWitnessProductTwoBlock(block); + + Item item = new Item(blockId, InventoryType.BLOCK); + tronNetDelegate.getActivePeer().forEach(p -> { + if (p.getAdvInvReceive().getIfPresent(item) != null) { + p.setBlockBothHave(blockId); + } + }); } catch (Exception e) { logger.warn("Process adv block {} from peer {} failed. reason: {}", blockId, peer.getInetAddress(), e.getMessage()); diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index 4fac50b82c7..30d7d8f5c4f 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -225,7 +225,8 @@ public String log() { channel.getInetSocketAddress(), (now - channel.getStartTime()) / Constant.ONE_THOUSAND, channel.getAvgLatency(), - fastForwardBlock != null ? fastForwardBlock.getNum() : blockBothHave.getNum(), + fastForwardBlock != null ? fastForwardBlock.getNum() : String.format("%d [%ds]", + blockBothHave.getNum(), (System.currentTimeMillis() - blockBothHaveUpdateTime) / 1000), isNeedSyncFromPeer(), isNeedSyncFromUs(), syncBlockToFetch.size(), From 6a08ac635f93a24715bae04107b990e3b2564380 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Mon, 1 Jul 2024 12:09:22 +0800 Subject: [PATCH 10/42] test(MerkleTree): ignore testConcurrent This is an unstable concurrent unit test. --- .../test/java/org/tron/core/capsule/utils/MerkleTreeTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/framework/src/test/java/org/tron/core/capsule/utils/MerkleTreeTest.java b/framework/src/test/java/org/tron/core/capsule/utils/MerkleTreeTest.java index 3662fb524b8..910b1adba67 100644 --- a/framework/src/test/java/org/tron/core/capsule/utils/MerkleTreeTest.java +++ b/framework/src/test/java/org/tron/core/capsule/utils/MerkleTreeTest.java @@ -8,6 +8,7 @@ import java.util.stream.IntStream; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -185,6 +186,7 @@ public void testAnyHashNum() { } @Test + @Ignore public void testConcurrent() { Sha256Hash root1 = Sha256Hash.wrap( ByteString.fromHex("6cb38b4f493db8bacf26123cd4253bbfc530c708b97b3747e782f64097c3c482")); From f5961f412d1f0d8789e438bd02ada2217cee5d05 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 19 Jul 2024 13:00:55 +0800 Subject: [PATCH 11/42] add testcase testProcessBlock for BlockMsgHandler --- .../messagehandler/BlockMsgHandlerTest.java | 51 +++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java index 8154d01aded..56f023417aa 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java @@ -1,26 +1,33 @@ package org.tron.core.net.messagehandler; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import com.google.common.collect.ImmutableList; import com.google.protobuf.ByteString; - import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.InetSocketAddress; +import java.util.ArrayList; import java.util.List; import javax.annotation.Resource; - import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.Mockito; import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.config.Parameter; import org.tron.core.config.args.Args; import org.tron.core.exception.P2pException; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.adv.BlockMessage; import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerConnection; @@ -41,9 +48,8 @@ public class BlockMsgHandlerTest extends BaseTest { */ @BeforeClass public static void init() { - Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, + Args.setParam(new String[] {"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); - } @Before @@ -123,4 +129,41 @@ public void testProcessMessage() { logger.error("error", e); } } + + @Test + public void testProcessBlock() { + TronNetDelegate tronNetDelegate = Mockito.mock(TronNetDelegate.class); + + try { + Field field = handler.getClass().getDeclaredField("tronNetDelegate"); + field.setAccessible(true); + field.set(handler, tronNetDelegate); + + BlockCapsule blockCapsule0 = new BlockCapsule(1, + Sha256Hash.wrap(ByteString + .copyFrom(ByteArray + .fromHexString( + "9938a342238077182498b464ac0292229938a342238077182498b464ac029222"))), + 1234, + ByteString.copyFrom("1234567".getBytes())); + + peer.getAdvInvReceive() + .put(new Item(blockCapsule0.getBlockId(), InventoryType.BLOCK), System.currentTimeMillis()); + + Mockito.doReturn(true).when(tronNetDelegate).validBlock(any(BlockCapsule.class)); + Mockito.doReturn(true).when(tronNetDelegate).containBlock(any(BlockId.class)); + Mockito.doReturn(blockCapsule0.getBlockId()).when(tronNetDelegate).getHeadBlockId(); + Mockito.doNothing().when(tronNetDelegate).processBlock(any(BlockCapsule.class), anyBoolean()); + List peers = new ArrayList<>(); + peers.add(peer); + Mockito.doReturn(peers).when(tronNetDelegate).getActivePeer(); + + Method method = handler.getClass() + .getDeclaredMethod("processBlock", PeerConnection.class, BlockCapsule.class); + method.setAccessible(true); + method.invoke(handler, peer, blockCapsule0); + } catch (Exception e) { + Assert.fail(); + } + } } From 6706d83196547d828e08b80962dfb687ca52958a Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 19 Jul 2024 13:04:21 +0800 Subject: [PATCH 12/42] add testcase testProcessBlock for BlockMsgHandler --- .../org/tron/core/net/messagehandler/BlockMsgHandlerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java index 56f023417aa..48e7d730520 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java @@ -148,7 +148,8 @@ public void testProcessBlock() { ByteString.copyFrom("1234567".getBytes())); peer.getAdvInvReceive() - .put(new Item(blockCapsule0.getBlockId(), InventoryType.BLOCK), System.currentTimeMillis()); + .put(new Item(blockCapsule0.getBlockId(), InventoryType.BLOCK), + System.currentTimeMillis()); Mockito.doReturn(true).when(tronNetDelegate).validBlock(any(BlockCapsule.class)); Mockito.doReturn(true).when(tronNetDelegate).containBlock(any(BlockId.class)); From 90a6e8f3adf5d1c60e860c202c9086243a00911e Mon Sep 17 00:00:00 2001 From: tomatoishealthy Date: Tue, 14 May 2024 14:26:45 +0800 Subject: [PATCH 13/42] fix(http/metric): change endpoint variable from member to local --- .../java/org/tron/core/services/filter/HttpInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java b/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java index 2cce8272dd5..8b43cfef642 100644 --- a/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java +++ b/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java @@ -18,7 +18,6 @@ @Slf4j(topic = "httpInterceptor") public class HttpInterceptor implements Filter { - private String endpoint; private final int HTTP_SUCCESS = 200; private final int HTTP_BAD_REQUEST = 400; private final int HTTP_NOT_ACCEPTABLE = 406; @@ -29,6 +28,7 @@ public void init(FilterConfig filterConfig) { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { + String endpoint = MetricLabels.UNDEFINED; try { if (!(request instanceof HttpServletRequest)) { chain.doFilter(request, response); From e6703860a69bcef69ab36ba41b1361c253a46c22 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Mon, 22 Jul 2024 15:39:26 +0800 Subject: [PATCH 14/42] set lastactivetime in P2pEventHandlerImpl --- .../java/org/tron/core/net/P2pEventHandlerImpl.java | 5 +++++ .../tron/core/net/messagehandler/BlockMsgHandler.java | 1 - .../net/messagehandler/ChainInventoryMsgHandler.java | 1 - .../net/messagehandler/SyncBlockChainMsgHandler.java | 1 - .../java/org/tron/core/net/peer/PeerConnection.java | 2 +- .../core/net/service/effective/ResilienceService.java | 10 ++++------ framework/src/main/resources/config-localtest.conf | 2 +- framework/src/main/resources/config.conf | 2 +- framework/src/test/resources/args-test.conf | 2 +- framework/src/test/resources/config-localtest.conf | 2 +- framework/src/test/resources/config-test.conf | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java index 7518b1347a7..c38ddc8c439 100644 --- a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java +++ b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java @@ -19,6 +19,7 @@ import org.tron.core.net.message.PbftMessageFactory; import org.tron.core.net.message.TronMessage; import org.tron.core.net.message.TronMessageFactory; +import org.tron.core.net.message.adv.FetchInvDataMessage; import org.tron.core.net.message.adv.InventoryMessage; import org.tron.core.net.message.base.DisconnectMessage; import org.tron.core.net.message.handshake.HelloMessage; @@ -38,6 +39,7 @@ import org.tron.p2p.P2pEventHandler; import org.tron.p2p.connection.Channel; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.Inventory.InventoryType; import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") @@ -183,9 +185,11 @@ private void processMessage(PeerConnection peer, byte[] data) { break; case SYNC_BLOCK_CHAIN: syncBlockChainMsgHandler.processMessage(peer, msg); + peer.setLastActiveTime(System.currentTimeMillis()); break; case BLOCK_CHAIN_INVENTORY: chainInventoryMsgHandler.processMessage(peer, msg); + peer.setLastActiveTime(System.currentTimeMillis()); break; case INVENTORY: inventoryMsgHandler.processMessage(peer, msg); @@ -195,6 +199,7 @@ private void processMessage(PeerConnection peer, byte[] data) { break; case BLOCK: blockMsgHandler.processMessage(peer, msg); + peer.setLastActiveTime(System.currentTimeMillis()); break; case TRXS: transactionsMsgHandler.processMessage(peer, msg); diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 547f96036cb..926ed1a01ca 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -76,7 +76,6 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep if (!fastForward && !peer.isRelayPeer()) { check(peer, blockMessage); } - peer.setLastActiveTime(System.currentTimeMillis()); if (peer.getSyncBlockRequested().containsKey(blockId)) { peer.getSyncBlockRequested().remove(blockId); diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java index 4f99deb146b..bd2e428418c 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandler.java @@ -142,7 +142,6 @@ private void check(PeerConnection peer, ChainInventoryMessage msg) throws P2pExc + msg.getRemainNum() + " > futureMaxNum: " + maxFutureNum); } } - peer.setLastActiveTime(System.currentTimeMillis()); } } 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 e03e039ac4d..f575253c50c 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 @@ -33,7 +33,6 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep peer.disconnect(Protocol.ReasonCode.BAD_PROTOCOL); return; } - peer.setLastActiveTime(System.currentTimeMillis()); long remainNum = 0; List summaryChainIds = syncBlockChainMessage.getBlockIds(); diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index 66903e7c64e..5981f46ae41 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -81,7 +81,7 @@ public class PeerConnection { @Getter @Setter - private long lastActiveTime; + private volatile long lastActiveTime; @Getter @Setter diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index bdf5892f260..166b0eb9cf6 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -22,14 +22,16 @@ @Component public class ResilienceService { - private final long inactiveThreshold = + private static final long inactiveThreshold = CommonParameter.getInstance().getInactiveThreshold() * 1000L; public static final long blockNotChangeThreshold = 90 * 1000L; //when node is isolated, retention percent peers will not be disconnected public static final double retentionPercent = 0.8; private static final int initialDelay = 300; - private final String esName = "resilience-service"; + private static final String esName = "resilience-service"; + private final ScheduledExecutorService executor = ExecutorServiceManager + .newSingleThreadScheduledExecutor(esName); @Autowired private TronNetDelegate tronNetDelegate; @@ -37,11 +39,7 @@ public class ResilienceService { @Autowired private ChainBaseManager chainBaseManager; - private ScheduledExecutorService executor; - public void init() { - executor = ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); - if (Args.getInstance().isOpenFullTcpDisconnect) { executor.scheduleWithFixedDelay(() -> { try { diff --git a/framework/src/main/resources/config-localtest.conf b/framework/src/main/resources/config-localtest.conf index e1c0d55b002..50e7539c1d0 100644 --- a/framework/src/main/resources/config-localtest.conf +++ b/framework/src/main/resources/config-localtest.conf @@ -99,7 +99,7 @@ node { # check the peer data transfer ,disconnect factor isOpenFullTcpDisconnect = true - inactiveThreshold = 600 + inactiveThreshold = 600 //seconds p2p { version = 333 # 11111: mainnet; 20180622: testnet diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index 3b4a2b64968..f9fc2dd673d 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -180,7 +180,7 @@ node { minParticipationRate = 15 isOpenFullTcpDisconnect = false - inactiveThreshold = 600 + inactiveThreshold = 600 //seconds p2p { version = 11111 # 11111: mainnet; 20180622: testnet diff --git a/framework/src/test/resources/args-test.conf b/framework/src/test/resources/args-test.conf index 2d0c54c1d28..cf5d0b8d718 100644 --- a/framework/src/test/resources/args-test.conf +++ b/framework/src/test/resources/args-test.conf @@ -92,7 +92,7 @@ node { maxConnections = 30 minConnections = 8 minActiveConnections = 3 - inactiveThreshold = 600 + inactiveThreshold = 600 //seconds p2p { version = 43 # 43: testnet; 101: debug diff --git a/framework/src/test/resources/config-localtest.conf b/framework/src/test/resources/config-localtest.conf index e56318fea1a..1d7ae09af7c 100644 --- a/framework/src/test/resources/config-localtest.conf +++ b/framework/src/test/resources/config-localtest.conf @@ -96,7 +96,7 @@ node { # check the peer data transfer ,disconnect factor isOpenFullTcpDisconnect = true - inactiveThreshold = 600 + inactiveThreshold = 600 //seconds p2p { version = 333 # 11111: mainnet; 20180622: testnet diff --git a/framework/src/test/resources/config-test.conf b/framework/src/test/resources/config-test.conf index 19a8be9e25f..62337f02fc5 100644 --- a/framework/src/test/resources/config-test.conf +++ b/framework/src/test/resources/config-test.conf @@ -100,7 +100,7 @@ node { # nodeId = e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c # } ] - inactiveThreshold = 600 + inactiveThreshold = 600 //seconds p2p { version = 43 # 43: testnet; 101: debug From 735bccb64a2fc41fe64b15b1e5f502b10fe68bd0 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 23 Jul 2024 12:36:50 +0800 Subject: [PATCH 15/42] add updateLastActiveTime --- .../tron/core/net/P2pEventHandlerImpl.java | 25 ++++++++++++++++--- .../FetchInvDataMsgHandler.java | 1 - .../core/net/P2pEventHandlerImplTest.java | 21 ++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java index c38ddc8c439..0100dc443d9 100644 --- a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java +++ b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java @@ -185,11 +185,9 @@ private void processMessage(PeerConnection peer, byte[] data) { break; case SYNC_BLOCK_CHAIN: syncBlockChainMsgHandler.processMessage(peer, msg); - peer.setLastActiveTime(System.currentTimeMillis()); break; case BLOCK_CHAIN_INVENTORY: chainInventoryMsgHandler.processMessage(peer, msg); - peer.setLastActiveTime(System.currentTimeMillis()); break; case INVENTORY: inventoryMsgHandler.processMessage(peer, msg); @@ -199,7 +197,6 @@ private void processMessage(PeerConnection peer, byte[] data) { break; case BLOCK: blockMsgHandler.processMessage(peer, msg); - peer.setLastActiveTime(System.currentTimeMillis()); break; case TRXS: transactionsMsgHandler.processMessage(peer, msg); @@ -210,6 +207,7 @@ private void processMessage(PeerConnection peer, byte[] data) { default: throw new P2pException(P2pException.TypeEnum.NO_SUCH_MESSAGE, msg.getType().toString()); } + updateLastActiveTime(peer, msg); } catch (Exception e) { processException(peer, msg, e); } finally { @@ -225,6 +223,27 @@ private void processMessage(PeerConnection peer, byte[] data) { } } + private void updateLastActiveTime(PeerConnection peer, TronMessage msg) { + MessageTypes type = msg.getType(); + + boolean flag = false; + switch (type) { + case SYNC_BLOCK_CHAIN: + case BLOCK_CHAIN_INVENTORY: + case BLOCK: + flag = true; + break; + case FETCH_INV_DATA: + flag = ((FetchInvDataMessage) msg).getInventoryType().equals(InventoryType.BLOCK); + break; + default: + break; + } + if (flag) { + peer.setLastActiveTime(System.currentTimeMillis()); + } + } + private void processException(PeerConnection peer, TronMessage msg, Exception ex) { Protocol.ReasonCode code; diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java index 2c4e94a66fa..5e797c084b3 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandler.java @@ -171,7 +171,6 @@ private void check(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) thr peer.getSyncBlockIdCache().put(hash, System.currentTimeMillis()); } } - peer.setLastActiveTime(System.currentTimeMillis()); } } diff --git a/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java b/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java index 0008ec315d5..7a3dc30cb86 100644 --- a/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java +++ b/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java @@ -12,10 +12,13 @@ import org.tron.common.utils.Sha256Hash; import org.tron.core.Constant; import org.tron.core.config.args.Args; +import org.tron.core.net.message.TronMessage; +import org.tron.core.net.message.adv.FetchInvDataMessage; import org.tron.core.net.message.adv.InventoryMessage; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.service.statistics.PeerStatistics; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.Inventory.InventoryType; public class P2pEventHandlerImplTest { @@ -108,4 +111,22 @@ public void testProcessInventoryMessage() throws Exception { Assert.assertEquals(300, count); } + + @Test + public void testUpdateLastActiveTime() throws Exception { + String[] a = new String[0]; + Args.setParam(a, Constant.TESTNET_CONF); + + PeerConnection peer = new PeerConnection(); + P2pEventHandlerImpl p2pEventHandler = new P2pEventHandlerImpl(); + + Method method = p2pEventHandler.getClass() + .getDeclaredMethod("updateLastActiveTime", PeerConnection.class, TronMessage.class); + method.setAccessible(true); + + long t1 = System.currentTimeMillis(); + FetchInvDataMessage message = new FetchInvDataMessage(new ArrayList<>(), InventoryType.BLOCK); + method.invoke(p2pEventHandler, peer, message); + Assert.assertTrue(peer.getLastActiveTime() >= t1); + } } From 343c5f6a041646296cc363274c25e90b89d929cb Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 23 Jul 2024 14:41:55 +0800 Subject: [PATCH 16/42] optimize log method of PeerConnection --- .../src/main/java/org/tron/core/net/peer/PeerConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index 30d7d8f5c4f..d30ed92d830 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -226,7 +226,7 @@ public String log() { (now - channel.getStartTime()) / Constant.ONE_THOUSAND, channel.getAvgLatency(), fastForwardBlock != null ? fastForwardBlock.getNum() : String.format("%d [%ds]", - blockBothHave.getNum(), (System.currentTimeMillis() - blockBothHaveUpdateTime) / 1000), + blockBothHave.getNum(), (now - blockBothHaveUpdateTime) / Constant.ONE_THOUSAND), isNeedSyncFromPeer(), isNeedSyncFromUs(), syncBlockToFetch.size(), From a718006c257e2879d5d007e42a80d038947bc57e Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 25 Jul 2024 16:07:42 +0800 Subject: [PATCH 17/42] catch exception of sort peers --- .../core/net/service/effective/ResilienceService.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 166b0eb9cf6..ffac784fd55 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -119,7 +119,8 @@ private void disconnectIsolated2() { one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); } - //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection + //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection, + //so new peers can come in peerSize = tronNetDelegate.getActivePeer().size(); int threshold = (int) (CommonParameter.getInstance().getMaxConnections() * retentionPercent); if (peerSize > threshold) { @@ -128,8 +129,13 @@ private void disconnectIsolated2() { .filter(peer -> !peer.isDisconnect()) .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> !peer.getChannel().isActive()) - .sorted(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)) .collect(Collectors.toList()); + try { + peers.sort(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); + } catch (Exception e) { + logger.warn("Sort peers failed: {}", e.getMessage()); + return; + } if (peers.size() > disconnectSize) { peers = peers.subList(0, disconnectSize); From 14fda8faecad2a1021a59e4999e1563a8f238c59 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 25 Jul 2024 16:47:15 +0800 Subject: [PATCH 18/42] catch exception min of peers --- .../service/effective/ResilienceService.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index ffac784fd55..fbbb2855934 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -92,12 +92,12 @@ private void disconnectLan() { int peerSize = tronNetDelegate.getActivePeer().size(); if (peerSize >= CommonParameter.getInstance().getMinConnections()) { long now = System.currentTimeMillis(); - Optional one = tronNetDelegate.getActivePeer().stream() + List peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> !peer.isDisconnect()) .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) .filter(peer -> !peer.getChannel().isTrustPeer()) - .min(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); - + .collect(Collectors.toList()); + Optional one = getEarliestPeer(peers); one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); } } @@ -110,12 +110,13 @@ private void disconnectIsolated2() { //disconnect from the node whose lastActiveTime is smallest if (peerSize >= CommonParameter.getInstance().getMinActiveConnections()) { - Optional one = tronNetDelegate.getActivePeer().stream() + List peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> !peer.isDisconnect()) .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> peer.getChannel().isActive()) - .min(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); + .collect(Collectors.toList()); + Optional one = getEarliestPeer(peers); one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); } @@ -133,7 +134,7 @@ private void disconnectIsolated2() { try { peers.sort(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); } catch (Exception e) { - logger.warn("Sort peers failed: {}", e.getMessage()); + logger.warn("Sort disconnectIsolated2 peers failed: {}", e.getMessage()); return; } @@ -145,6 +146,17 @@ private void disconnectIsolated2() { } } + private Optional getEarliestPeer(List pees) { + Optional one = Optional.empty(); + try { + one = pees.stream() + .min(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); + } catch (Exception e) { + logger.warn("Get earliest peer failed: {}", e.getMessage()); + } + return one; + } + private boolean isLanNode() { int peerSize = tronNetDelegate.getActivePeer().size(); int activePeerSize = (int) tronNetDelegate.getActivePeer().stream() From d6faee8bdfc69588f4b20bd90d2e73e8c1c083fe Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Wed, 31 Jul 2024 12:10:08 +0800 Subject: [PATCH 19/42] feat(monitor): add tcp out traffic and udp in traffic statistics --- .../service/statistics/TronStatsManager.java | 8 +++++ .../net/services/TronStatsManagerTest.java | 36 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/framework/src/main/java/org/tron/core/net/service/statistics/TronStatsManager.java b/framework/src/main/java/org/tron/core/net/service/statistics/TronStatsManager.java index caac3f7f325..99e12834ced 100644 --- a/framework/src/main/java/org/tron/core/net/service/statistics/TronStatsManager.java +++ b/framework/src/main/java/org/tron/core/net/service/statistics/TronStatsManager.java @@ -63,11 +63,19 @@ private void work() { Metrics.histogramObserve(MetricKeys.Histogram.TCP_BYTES, stats.getTcpInSize() - TCP_TRAFFIC_IN, MetricLabels.Histogram.TRAFFIC_IN); + MetricsUtil.meterMark(MetricsKey.NET_TCP_OUT_TRAFFIC, stats.getTcpOutSize() - TCP_TRAFFIC_OUT); + Metrics.histogramObserve(MetricKeys.Histogram.TCP_BYTES, + stats.getTcpOutSize() - TCP_TRAFFIC_OUT, + MetricLabels.Histogram.TRAFFIC_OUT); + + MetricsUtil.meterMark(MetricsKey.NET_UDP_IN_TRAFFIC, + stats.getUdpInSize() - UDP_TRAFFIC_IN); Metrics.histogramObserve(MetricKeys.Histogram.UDP_BYTES, stats.getUdpInSize() - UDP_TRAFFIC_IN, MetricLabels.Histogram.TRAFFIC_IN); + MetricsUtil.meterMark(MetricsKey.NET_UDP_OUT_TRAFFIC, stats.getUdpOutSize() - UDP_TRAFFIC_OUT); Metrics.histogramObserve(MetricKeys.Histogram.UDP_BYTES, diff --git a/framework/src/test/java/org/tron/core/net/services/TronStatsManagerTest.java b/framework/src/test/java/org/tron/core/net/services/TronStatsManagerTest.java index 369955f4e7f..a940a14d392 100644 --- a/framework/src/test/java/org/tron/core/net/services/TronStatsManagerTest.java +++ b/framework/src/test/java/org/tron/core/net/services/TronStatsManagerTest.java @@ -1,5 +1,7 @@ package org.tron.core.net.services; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -24,4 +26,38 @@ public void testOnDisconnect() { Assert.assertEquals(Protocol.ReasonCode.UNKNOWN, statistics.getDisconnectReason()); } + @Test + public void testWork() throws Exception { + TronStatsManager manager = new TronStatsManager(); + Field field1 = manager.getClass().getDeclaredField("TCP_TRAFFIC_IN"); + field1.setAccessible(true); + field1.set(manager, 1L); + + Field field2 = manager.getClass().getDeclaredField("TCP_TRAFFIC_OUT"); + field2.setAccessible(true); + field2.set(manager, 1L); + + Field field3 = manager.getClass().getDeclaredField("UDP_TRAFFIC_IN"); + field3.setAccessible(true); + field3.set(manager, 1L); + + Field field4 = manager.getClass().getDeclaredField("UDP_TRAFFIC_OUT"); + field4.setAccessible(true); + field4.set(manager, 1L); + + Assert.assertEquals(field1.get(manager), 1L); + Assert.assertEquals(field2.get(manager), 1L); + Assert.assertEquals(field3.get(manager), 1L); + Assert.assertEquals(field4.get(manager), 1L); + + Method method = manager.getClass().getDeclaredMethod("work"); + method.setAccessible(true); + method.invoke(manager); + + Assert.assertEquals(field1.get(manager), 0L); + Assert.assertEquals(field2.get(manager), 0L); + Assert.assertEquals(field3.get(manager), 0L); + Assert.assertEquals(field4.get(manager), 0L); + } + } From 81bb50bd0190e2289d2d17d5ac12acf6a65e5f0e Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 7 Aug 2024 16:50:40 +0800 Subject: [PATCH 20/42] add some log for isolated2 disconnection --- .../tron/core/net/peer/PeerConnection.java | 2 ++ .../service/effective/ResilienceService.java | 20 +++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index da97f74c241..24f43e1f3fa 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -230,6 +230,7 @@ public String log() { + "syncBlockRequestedSize:%d\n" + "remainNum:%d\n" + "syncChainRequested:%d\n" + + "inactiveSeconds:%d\n" + "blockInProcess:%d\n", channel.getInetSocketAddress(), (now - channel.getStartTime()) / Constant.ONE_THOUSAND, @@ -244,6 +245,7 @@ public String log() { remainNum, requested == null ? 0 : (now - requested.getValue()) / Constant.ONE_THOUSAND, + (now - lastActiveTime) / Constant.ONE_THOUSAND, syncBlockInProcess.size()); } diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index fbbb2855934..83ddc56655f 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -80,7 +80,7 @@ private void disconnectRandom() { .collect(Collectors.toList()); if (!peers.isEmpty()) { int index = new Random().nextInt(peers.size()); - disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION); + disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION, "random"); } } } @@ -98,14 +98,14 @@ private void disconnectLan() { .filter(peer -> !peer.getChannel().isTrustPeer()) .collect(Collectors.toList()); Optional one = getEarliestPeer(peers); - one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); + one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "lan node")); } } } private void disconnectIsolated2() { if (isIsolateLand2()) { - logger.info("Node is isolated, try to disconnect from peers"); + logger.warn("Node is isolated, try to disconnect from peers"); int peerSize = tronNetDelegate.getActivePeer().size(); //disconnect from the node whose lastActiveTime is smallest @@ -117,7 +117,8 @@ private void disconnectIsolated2() { .collect(Collectors.toList()); Optional one = getEarliestPeer(peers); - one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); + one.ifPresent( + peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and active")); } //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection, @@ -141,7 +142,10 @@ private void disconnectIsolated2() { if (peers.size() > disconnectSize) { peers = peers.subList(0, disconnectSize); } - peers.forEach(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL)); + logger.info("All peer Size:{}, avail:{}, disconnectSize:{}, ", peerSize, peers.size(), + disconnectSize); + peers.forEach( + peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and passive")); } } } @@ -173,10 +177,10 @@ private boolean isIsolateLand2() { return advPeerCount >= 1 && diff >= blockNotChangeThreshold; } - private void disconnectFromPeer(PeerConnection peer, ReasonCode reasonCode) { + private void disconnectFromPeer(PeerConnection peer, ReasonCode reasonCode, String cause) { int inactiveSeconds = (int) ((System.currentTimeMillis() - peer.getLastActiveTime()) / 1000); - logger.info("Disconnect from peer {}, inactive seconds {}", peer.getInetSocketAddress(), - inactiveSeconds); + logger.info("Disconnect from peer {}, inactive seconds {}, cause: {}", + peer.getInetSocketAddress(), inactiveSeconds, cause); peer.disconnect(reasonCode); } From 0d21388fc0cdb91e2613bddd24a5d5cf72118f7e Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 7 Aug 2024 17:11:29 +0800 Subject: [PATCH 21/42] add log of candidate disconnect size when node is isolated --- .../tron/core/net/service/effective/ResilienceService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 83ddc56655f..5544f6ede03 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -138,12 +138,12 @@ private void disconnectIsolated2() { logger.warn("Sort disconnectIsolated2 peers failed: {}", e.getMessage()); return; } - + int candidateSize = peers.size(); if (peers.size() > disconnectSize) { peers = peers.subList(0, disconnectSize); } - logger.info("All peer Size:{}, avail:{}, disconnectSize:{}, ", peerSize, peers.size(), - disconnectSize); + logger.info("All peer Size:{}, plan size:{}, candidate size:{}, real size:{}", peerSize, + disconnectSize, candidateSize, peers.size()); peers.forEach( peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and passive")); } From 0acc84b252d9c1fbbc24c563997682c23922268b Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 9 Aug 2024 18:29:35 +0800 Subject: [PATCH 22/42] set blockNotChangeThreshold from 90 to 60 seconds --- .../java/org/tron/core/config/args/Args.java | 3 + .../service/effective/ResilienceService.java | 117 +++++++++--------- 2 files changed, 63 insertions(+), 57 deletions(-) diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 7b089530a41..00142733f74 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -848,6 +848,9 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.inactiveThreshold = config.hasPath(Constant.NODE_INACTIVE_THRESHOLD) ? config.getInt(Constant.NODE_INACTIVE_THRESHOLD) : 600; + if (PARAMETER.inactiveThreshold < 1) { + PARAMETER.inactiveThreshold = 1; + } PARAMETER.maxTransactionPendingSize = config.hasPath(Constant.NODE_MAX_TRANSACTION_PENDING_SIZE) ? config.getInt(Constant.NODE_MAX_TRANSACTION_PENDING_SIZE) : 2000; diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 5544f6ede03..73ca16da743 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -24,7 +24,7 @@ public class ResilienceService { private static final long inactiveThreshold = CommonParameter.getInstance().getInactiveThreshold() * 1000L; - public static final long blockNotChangeThreshold = 90 * 1000L; + public static final long blockNotChangeThreshold = 60 * 1000L; //when node is isolated, retention percent peers will not be disconnected public static final double retentionPercent = 0.8; @@ -86,67 +86,69 @@ private void disconnectRandom() { } private void disconnectLan() { - if (isLanNode()) { - // disconnect from the node that has keep inactive for more than inactiveThreshold - // and its lastActiveTime is smallest - int peerSize = tronNetDelegate.getActivePeer().size(); - if (peerSize >= CommonParameter.getInstance().getMinConnections()) { - long now = System.currentTimeMillis(); - List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> !peer.isDisconnect()) - .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) - .filter(peer -> !peer.getChannel().isTrustPeer()) - .collect(Collectors.toList()); - Optional one = getEarliestPeer(peers); - one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "lan node")); - } + if (!isLanNode()) { + return; + } + // disconnect from the node that has keep inactive for more than inactiveThreshold + // and its lastActiveTime is smallest + int peerSize = tronNetDelegate.getActivePeer().size(); + if (peerSize >= CommonParameter.getInstance().getMinConnections()) { + long now = System.currentTimeMillis(); + List peers = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.isDisconnect()) + .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) + .filter(peer -> !peer.getChannel().isTrustPeer()) + .collect(Collectors.toList()); + Optional one = getEarliestPeer(peers); + one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "lan node")); } } private void disconnectIsolated2() { - if (isIsolateLand2()) { - logger.warn("Node is isolated, try to disconnect from peers"); - int peerSize = tronNetDelegate.getActivePeer().size(); - - //disconnect from the node whose lastActiveTime is smallest - if (peerSize >= CommonParameter.getInstance().getMinActiveConnections()) { - List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> !peer.isDisconnect()) - .filter(peer -> !peer.getChannel().isTrustPeer()) - .filter(peer -> peer.getChannel().isActive()) - .collect(Collectors.toList()); - - Optional one = getEarliestPeer(peers); - one.ifPresent( - peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and active")); - } + if (!isIsolateLand2()) { + return; + } + logger.warn("Node is isolated, try to disconnect from peers"); + int peerSize = tronNetDelegate.getActivePeer().size(); - //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection, - //so new peers can come in - peerSize = tronNetDelegate.getActivePeer().size(); - int threshold = (int) (CommonParameter.getInstance().getMaxConnections() * retentionPercent); - if (peerSize > threshold) { - int disconnectSize = peerSize - threshold; - List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> !peer.isDisconnect()) - .filter(peer -> !peer.getChannel().isTrustPeer()) - .filter(peer -> !peer.getChannel().isActive()) - .collect(Collectors.toList()); - try { - peers.sort(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); - } catch (Exception e) { - logger.warn("Sort disconnectIsolated2 peers failed: {}", e.getMessage()); - return; - } - int candidateSize = peers.size(); - if (peers.size() > disconnectSize) { - peers = peers.subList(0, disconnectSize); - } - logger.info("All peer Size:{}, plan size:{}, candidate size:{}, real size:{}", peerSize, - disconnectSize, candidateSize, peers.size()); - peers.forEach( - peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and passive")); + //disconnect from the node whose lastActiveTime is smallest + if (peerSize >= CommonParameter.getInstance().getMinActiveConnections()) { + List peers = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.isDisconnect()) + .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(peer -> peer.getChannel().isActive()) + .collect(Collectors.toList()); + + Optional one = getEarliestPeer(peers); + one.ifPresent( + peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and active")); + } + + //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection, + //so new peers can come in + peerSize = tronNetDelegate.getActivePeer().size(); + int threshold = (int) (CommonParameter.getInstance().getMaxConnections() * retentionPercent); + if (peerSize > threshold) { + int disconnectSize = peerSize - threshold; + List peers = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.isDisconnect()) + .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(peer -> !peer.getChannel().isActive()) + .collect(Collectors.toList()); + try { + peers.sort(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); + } catch (Exception e) { + logger.warn("Sort disconnectIsolated2 peers failed: {}", e.getMessage()); + return; + } + int candidateSize = peers.size(); + if (peers.size() > disconnectSize) { + peers = peers.subList(0, disconnectSize); } + logger.info("All peer Size:{}, plan size:{}, candidate size:{}, real size:{}", peerSize, + disconnectSize, candidateSize, peers.size()); + peers.forEach( + peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and passive")); } } @@ -166,7 +168,8 @@ private boolean isLanNode() { int activePeerSize = (int) tronNetDelegate.getActivePeer().stream() .filter(peer -> peer.getChannel().isActive()) .count(); - return peerSize > 0 && peerSize == activePeerSize; + return peerSize > CommonParameter.getInstance().getMinActiveConnections() + && peerSize == activePeerSize; } private boolean isIsolateLand2() { From 0fc9acb83fc1eb044b2592aa71a19cca12f24908 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 9 Aug 2024 20:15:57 +0800 Subject: [PATCH 23/42] remove the condition of peer.isDisconnect --- .../tron/core/net/service/effective/ResilienceService.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 73ca16da743..d48c84a4562 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -74,7 +74,6 @@ private void disconnectRandom() { if (peerSize >= CommonParameter.getInstance().getMaxConnections()) { long now = System.currentTimeMillis(); List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> !peer.isDisconnect()) .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) .filter(peer -> !peer.getChannel().isTrustPeer()) .collect(Collectors.toList()); @@ -95,7 +94,6 @@ private void disconnectLan() { if (peerSize >= CommonParameter.getInstance().getMinConnections()) { long now = System.currentTimeMillis(); List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> !peer.isDisconnect()) .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) .filter(peer -> !peer.getChannel().isTrustPeer()) .collect(Collectors.toList()); @@ -114,7 +112,6 @@ private void disconnectIsolated2() { //disconnect from the node whose lastActiveTime is smallest if (peerSize >= CommonParameter.getInstance().getMinActiveConnections()) { List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> !peer.isDisconnect()) .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> peer.getChannel().isActive()) .collect(Collectors.toList()); @@ -131,7 +128,6 @@ private void disconnectIsolated2() { if (peerSize > threshold) { int disconnectSize = peerSize - threshold; List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> !peer.isDisconnect()) .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> !peer.getChannel().isActive()) .collect(Collectors.toList()); From 0f7c7f4695fbdd74d4f34576625dfd53eb42d6ca Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 13 Aug 2024 15:18:22 +0800 Subject: [PATCH 24/42] don't disconnect with syncing node when random disconnect --- .../org/tron/core/net/service/effective/ResilienceService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index d48c84a4562..c44f39b4dbd 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -76,6 +76,7 @@ private void disconnectRandom() { List peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) .collect(Collectors.toList()); if (!peers.isEmpty()) { int index = new Random().nextInt(peers.size()); From 7bdae3265360c0b22082c00ed43b37b7950fe3d5 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 13 Aug 2024 16:34:23 +0800 Subject: [PATCH 25/42] add DisConnectCause --- .../service/effective/ResilienceService.java | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index c44f39b4dbd..8d39372d003 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -80,7 +80,8 @@ private void disconnectRandom() { .collect(Collectors.toList()); if (!peers.isEmpty()) { int index = new Random().nextInt(peers.size()); - disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION, "random"); + disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION, + DisConnectCause.RANDOM_ELIMINATION); } } } @@ -99,7 +100,8 @@ private void disconnectLan() { .filter(peer -> !peer.getChannel().isTrustPeer()) .collect(Collectors.toList()); Optional one = getEarliestPeer(peers); - one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "lan node")); + one.ifPresent( + peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, DisConnectCause.LAN_NODE)); } } @@ -118,8 +120,8 @@ private void disconnectIsolated2() { .collect(Collectors.toList()); Optional one = getEarliestPeer(peers); - one.ifPresent( - peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and active")); + one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, + DisConnectCause.ISOLATE2_ACTIVE)); } //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection, @@ -144,8 +146,8 @@ private void disconnectIsolated2() { } logger.info("All peer Size:{}, plan size:{}, candidate size:{}, real size:{}", peerSize, disconnectSize, candidateSize, peers.size()); - peers.forEach( - peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, "isolate2 and passive")); + peers.forEach(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, + DisConnectCause.ISOLATE2_PASSIVE)); } } @@ -177,13 +179,21 @@ private boolean isIsolateLand2() { return advPeerCount >= 1 && diff >= blockNotChangeThreshold; } - private void disconnectFromPeer(PeerConnection peer, ReasonCode reasonCode, String cause) { + private void disconnectFromPeer(PeerConnection peer, ReasonCode reasonCode, + DisConnectCause cause) { int inactiveSeconds = (int) ((System.currentTimeMillis() - peer.getLastActiveTime()) / 1000); logger.info("Disconnect from peer {}, inactive seconds {}, cause: {}", peer.getInetSocketAddress(), inactiveSeconds, cause); peer.disconnect(reasonCode); } + private enum DisConnectCause { + RANDOM_ELIMINATION, + LAN_NODE, + ISOLATE2_ACTIVE, + ISOLATE2_PASSIVE, + } + public void close() { ExecutorServiceManager.shutdownAndAwaitTermination(executor, esName); } From ffbb69e0c8880a772935be8101dfd78190a49cec Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 13 Aug 2024 16:35:12 +0800 Subject: [PATCH 26/42] add DisConnectCause --- .../net/service/effective/ResilienceService.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 8d39372d003..ac54c5b8b4e 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -81,7 +81,7 @@ private void disconnectRandom() { if (!peers.isEmpty()) { int index = new Random().nextInt(peers.size()); disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION, - DisConnectCause.RANDOM_ELIMINATION); + DisconnectCause.RANDOM_ELIMINATION); } } } @@ -101,7 +101,7 @@ private void disconnectLan() { .collect(Collectors.toList()); Optional one = getEarliestPeer(peers); one.ifPresent( - peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, DisConnectCause.LAN_NODE)); + peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, DisconnectCause.LAN_NODE)); } } @@ -121,7 +121,7 @@ private void disconnectIsolated2() { Optional one = getEarliestPeer(peers); one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, - DisConnectCause.ISOLATE2_ACTIVE)); + DisconnectCause.ISOLATE2_ACTIVE)); } //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection, @@ -147,7 +147,7 @@ private void disconnectIsolated2() { logger.info("All peer Size:{}, plan size:{}, candidate size:{}, real size:{}", peerSize, disconnectSize, candidateSize, peers.size()); peers.forEach(peer -> disconnectFromPeer(peer, ReasonCode.BAD_PROTOCOL, - DisConnectCause.ISOLATE2_PASSIVE)); + DisconnectCause.ISOLATE2_PASSIVE)); } } @@ -180,14 +180,14 @@ private boolean isIsolateLand2() { } private void disconnectFromPeer(PeerConnection peer, ReasonCode reasonCode, - DisConnectCause cause) { + DisconnectCause cause) { int inactiveSeconds = (int) ((System.currentTimeMillis() - peer.getLastActiveTime()) / 1000); logger.info("Disconnect from peer {}, inactive seconds {}, cause: {}", peer.getInetSocketAddress(), inactiveSeconds, cause); peer.disconnect(reasonCode); } - private enum DisConnectCause { + private enum DisconnectCause { RANDOM_ELIMINATION, LAN_NODE, ISOLATE2_ACTIVE, From abf8c42d9f27b8ee67ef4fb3a210d45300d89768 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 13 Aug 2024 17:46:30 +0800 Subject: [PATCH 27/42] change the condition of isLanNode --- .../org/tron/core/net/service/effective/ResilienceService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index ac54c5b8b4e..6375995c853 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -167,7 +167,7 @@ private boolean isLanNode() { int activePeerSize = (int) tronNetDelegate.getActivePeer().stream() .filter(peer -> peer.getChannel().isActive()) .count(); - return peerSize > CommonParameter.getInstance().getMinActiveConnections() + return peerSize >= CommonParameter.getInstance().getMinActiveConnections() && peerSize == activePeerSize; } From 40cb055466aa4b7cbc1c49365a78dfe3145cf653 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 13 Aug 2024 18:02:49 +0800 Subject: [PATCH 28/42] don't disconnect with syncing peer if i am lan node --- .../org/tron/core/net/service/effective/ResilienceService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 6375995c853..b0806457a4b 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -97,6 +97,7 @@ private void disconnectLan() { long now = System.currentTimeMillis(); List peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) + .filter(peer -> !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) .filter(peer -> !peer.getChannel().isTrustPeer()) .collect(Collectors.toList()); Optional one = getEarliestPeer(peers); From 14a07509108a979e14c14ebecf46fe414324a3b9 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 14 Aug 2024 15:14:23 +0800 Subject: [PATCH 29/42] modify testcase of ResilienceServiceTest --- .../tron/core/net/services/ResilienceServiceTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java index a8b8e04d3cb..cc09fb45c28 100644 --- a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java @@ -61,6 +61,10 @@ public void testDisconnectRandom() { PeerManager.add(context, c1); } + for (PeerConnection peer : PeerManager.getPeers()) { + peer.setNeedSyncFromPeer(false); + peer.setNeedSyncFromUs(false); + } ReflectUtils.invokeMethod(service, "disconnectRandom"); Assert.assertEquals(maxConnection, PeerManager.getPeers().size()); @@ -93,7 +97,10 @@ public void testDisconnectLan() { PeerManager.add(context, c1); } - + for (PeerConnection peer : PeerManager.getPeers()) { + peer.setNeedSyncFromPeer(false); + peer.setNeedSyncFromUs(false); + } Assert.assertEquals(9, PeerManager.getPeers().size()); boolean isLan = ReflectUtils.invokeMethod(service, "isLanNode"); From 471b522ed2b83dc4cf0d5ff11fab28e0d7f1306b Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 15 Aug 2024 13:26:26 +0800 Subject: [PATCH 30/42] use the condition: active size >= min active size in isolate2 --- .../core/net/service/effective/ResilienceService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index b0806457a4b..53e20d45fd1 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -111,10 +111,12 @@ private void disconnectIsolated2() { return; } logger.warn("Node is isolated, try to disconnect from peers"); - int peerSize = tronNetDelegate.getActivePeer().size(); //disconnect from the node whose lastActiveTime is smallest - if (peerSize >= CommonParameter.getInstance().getMinActiveConnections()) { + int activePeerSize = (int) tronNetDelegate.getActivePeer().stream() + .filter(peer -> peer.getChannel().isActive()) + .count(); + if (activePeerSize >= CommonParameter.getInstance().getMinActiveConnections()) { List peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> peer.getChannel().isActive()) @@ -127,7 +129,7 @@ private void disconnectIsolated2() { //disconnect from some passive nodes, make sure retention nodes' num <= 0.8 * maxConnection, //so new peers can come in - peerSize = tronNetDelegate.getActivePeer().size(); + int peerSize = tronNetDelegate.getActivePeer().size(); int threshold = (int) (CommonParameter.getInstance().getMaxConnections() * retentionPercent); if (peerSize > threshold) { int disconnectSize = peerSize - threshold; From 553fbb451ae42eef65ad3b8c2040a86bbe188741 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 16 Aug 2024 11:06:11 +0800 Subject: [PATCH 31/42] change varible name from lastActiveTime to lastInteractiveTime --- .../java/org/tron/core/net/P2pEventHandlerImpl.java | 7 +++---- .../core/net/messagehandler/InventoryMsgHandler.java | 2 +- .../java/org/tron/core/net/peer/PeerConnection.java | 6 +++--- .../core/net/service/effective/ResilienceService.java | 11 ++++++----- .../org/tron/core/net/P2pEventHandlerImplTest.java | 4 ++-- .../tron/core/net/services/ResilienceServiceTest.java | 8 ++++---- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java index 0100dc443d9..795c90b4edd 100644 --- a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java +++ b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java @@ -40,7 +40,6 @@ import org.tron.p2p.connection.Channel; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Inventory.InventoryType; -import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") @Component @@ -207,7 +206,7 @@ private void processMessage(PeerConnection peer, byte[] data) { default: throw new P2pException(P2pException.TypeEnum.NO_SUCH_MESSAGE, msg.getType().toString()); } - updateLastActiveTime(peer, msg); + updateLastInteractiveTime(peer, msg); } catch (Exception e) { processException(peer, msg, e); } finally { @@ -223,7 +222,7 @@ private void processMessage(PeerConnection peer, byte[] data) { } } - private void updateLastActiveTime(PeerConnection peer, TronMessage msg) { + private void updateLastInteractiveTime(PeerConnection peer, TronMessage msg) { MessageTypes type = msg.getType(); boolean flag = false; @@ -240,7 +239,7 @@ private void updateLastActiveTime(PeerConnection peer, TronMessage msg) { break; } if (flag) { - peer.setLastActiveTime(System.currentTimeMillis()); + peer.setLastInteractiveTime(System.currentTimeMillis()); } } diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java index 5e303bd3d6f..e8783b25e95 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java @@ -40,7 +40,7 @@ public void processMessage(PeerConnection peer, TronMessage msg) { peer.getAdvInvReceive().put(item, System.currentTimeMillis()); advService.addInv(item); if (type.equals(InventoryType.BLOCK) && peer.getAdvInvSpread().getIfPresent(item) == null) { - peer.setLastActiveTime(System.currentTimeMillis()); + peer.setLastInteractiveTime(System.currentTimeMillis()); } } } diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index 24f43e1f3fa..2e08e105bed 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -81,7 +81,7 @@ public class PeerConnection { @Getter @Setter - private volatile long lastActiveTime; + private volatile long lastInteractiveTime; @Getter @Setter @@ -163,7 +163,7 @@ public void setChannel(Channel channel) { this.isRelayPeer = true; } this.nodeStatistics = TronStatsManager.getNodeStatistics(channel.getInetAddress()); - lastActiveTime = System.currentTimeMillis(); + lastInteractiveTime = System.currentTimeMillis(); } public void setBlockBothHave(BlockId blockId) { @@ -245,7 +245,7 @@ public String log() { remainNum, requested == null ? 0 : (now - requested.getValue()) / Constant.ONE_THOUSAND, - (now - lastActiveTime) / Constant.ONE_THOUSAND, + (now - lastInteractiveTime) / Constant.ONE_THOUSAND, syncBlockInProcess.size()); } diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 53e20d45fd1..67c22616bed 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -74,7 +74,7 @@ private void disconnectRandom() { if (peerSize >= CommonParameter.getInstance().getMaxConnections()) { long now = System.currentTimeMillis(); List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) + .filter(peer -> now - peer.getLastInteractiveTime() >= inactiveThreshold) .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) .collect(Collectors.toList()); @@ -96,7 +96,7 @@ private void disconnectLan() { if (peerSize >= CommonParameter.getInstance().getMinConnections()) { long now = System.currentTimeMillis(); List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> now - peer.getLastActiveTime() >= inactiveThreshold) + .filter(peer -> now - peer.getLastInteractiveTime() >= inactiveThreshold) .filter(peer -> !peer.isNeedSyncFromPeer() && !peer.isNeedSyncFromUs()) .filter(peer -> !peer.getChannel().isTrustPeer()) .collect(Collectors.toList()); @@ -138,7 +138,7 @@ private void disconnectIsolated2() { .filter(peer -> !peer.getChannel().isActive()) .collect(Collectors.toList()); try { - peers.sort(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); + peers.sort(Comparator.comparing(PeerConnection::getLastInteractiveTime, Long::compareTo)); } catch (Exception e) { logger.warn("Sort disconnectIsolated2 peers failed: {}", e.getMessage()); return; @@ -158,7 +158,7 @@ private Optional getEarliestPeer(List pees) { Optional one = Optional.empty(); try { one = pees.stream() - .min(Comparator.comparing(PeerConnection::getLastActiveTime, Long::compareTo)); + .min(Comparator.comparing(PeerConnection::getLastInteractiveTime, Long::compareTo)); } catch (Exception e) { logger.warn("Get earliest peer failed: {}", e.getMessage()); } @@ -184,7 +184,8 @@ private boolean isIsolateLand2() { private void disconnectFromPeer(PeerConnection peer, ReasonCode reasonCode, DisconnectCause cause) { - int inactiveSeconds = (int) ((System.currentTimeMillis() - peer.getLastActiveTime()) / 1000); + int inactiveSeconds = (int) ((System.currentTimeMillis() - peer.getLastInteractiveTime()) + / 1000); logger.info("Disconnect from peer {}, inactive seconds {}, cause: {}", peer.getInetSocketAddress(), inactiveSeconds, cause); peer.disconnect(reasonCode); diff --git a/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java b/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java index 7a3dc30cb86..27b98f4a441 100644 --- a/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java +++ b/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java @@ -113,7 +113,7 @@ public void testProcessInventoryMessage() throws Exception { } @Test - public void testUpdateLastActiveTime() throws Exception { + public void testUpdateLastInteractiveTime() throws Exception { String[] a = new String[0]; Args.setParam(a, Constant.TESTNET_CONF); @@ -127,6 +127,6 @@ public void testUpdateLastActiveTime() throws Exception { long t1 = System.currentTimeMillis(); FetchInvDataMessage message = new FetchInvDataMessage(new ArrayList<>(), InventoryType.BLOCK); method.invoke(p2pEventHandler, peer, message); - Assert.assertTrue(peer.getLastActiveTime() >= t1); + Assert.assertTrue(peer.getLastInteractiveTime() >= t1); } } diff --git a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java index cc09fb45c28..2558e089b7e 100644 --- a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java @@ -69,10 +69,10 @@ public void testDisconnectRandom() { Assert.assertEquals(maxConnection, PeerManager.getPeers().size()); PeerConnection p1 = PeerManager.getPeers().get(1); - p1.setLastActiveTime( + p1.setLastInteractiveTime( System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 1000); PeerConnection p2 = PeerManager.getPeers().get(10); - p2.setLastActiveTime( + p2.setLastInteractiveTime( System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 2000); ReflectUtils.invokeMethod(service, "disconnectRandom"); @@ -108,11 +108,11 @@ public void testDisconnectLan() { PeerConnection p1 = PeerManager.getPeers().get(1); InetSocketAddress address1 = p1.getChannel().getInetSocketAddress(); - p1.setLastActiveTime( + p1.setLastInteractiveTime( System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 1000); PeerConnection p2 = PeerManager.getPeers().get(2); InetSocketAddress address2 = p2.getChannel().getInetSocketAddress(); - p2.setLastActiveTime( + p2.setLastInteractiveTime( System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 2000); ReflectUtils.invokeMethod(service, "disconnectLan"); From 1a7abf39a691670ab0a55de7594c17109800e9bb Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 16 Aug 2024 11:53:23 +0800 Subject: [PATCH 32/42] fix the testcase of testUpdateLastInteractiveTime --- .../test/java/org/tron/core/net/P2pEventHandlerImplTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java b/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java index 27b98f4a441..e0c816a537a 100644 --- a/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java +++ b/framework/src/test/java/org/tron/core/net/P2pEventHandlerImplTest.java @@ -121,7 +121,7 @@ public void testUpdateLastInteractiveTime() throws Exception { P2pEventHandlerImpl p2pEventHandler = new P2pEventHandlerImpl(); Method method = p2pEventHandler.getClass() - .getDeclaredMethod("updateLastActiveTime", PeerConnection.class, TronMessage.class); + .getDeclaredMethod("updateLastInteractiveTime", PeerConnection.class, TronMessage.class); method.setAccessible(true); long t1 = System.currentTimeMillis(); From 31b5d46e8dba8c800550cc57136c881da7e3f34c Mon Sep 17 00:00:00 2001 From: fyyhtx <72650068+fyyhtx@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:40:46 +0800 Subject: [PATCH 33/42] Add transaction expiration time check before execution (#1) feat(net): add transaction expiration time check before execution --- .../tron/core/capsule/TransactionCapsule.java | 9 +++ .../src/main/java/org/tron/core/Wallet.java | 1 + .../org/tron/core/net/TronNetDelegate.java | 8 ++ .../TransactionsMsgHandler.java | 5 ++ .../tron/core/db/TransactionExpireTest.java | 79 ++++++++++++++++--- .../TransactionsMsgHandlerTest.java | 43 ++++++++++ .../core/net/services/AdvServiceTest.java | 20 ++++- 7 files changed, 151 insertions(+), 14 deletions(-) diff --git a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java index c0a0fa4d88c..2b5e8b98596 100755 --- a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java @@ -59,6 +59,7 @@ import org.tron.core.exception.P2pException; import org.tron.core.exception.PermissionException; import org.tron.core.exception.SignatureFormatException; +import org.tron.core.exception.TransactionExpirationException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.store.AccountStore; import org.tron.core.store.DynamicPropertiesStore; @@ -869,4 +870,12 @@ public void removeRedundantRet() { this.transaction = transactionBuilder.build(); } } + + public void checkExpiration(long nextSlotTime) throws TransactionExpirationException { + if (getExpiration() < nextSlotTime) { + throw new TransactionExpirationException(String.format( + "Transaction expiration time is %d, but next slot time is %d", + getExpiration(), nextSlotTime)); + } + } } diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 9d7eb75df1b..769274e8f2a 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -549,6 +549,7 @@ public GrpcAPI.Return broadcastTransaction(Transaction signedTransaction) { throw new ContractValidateException(ActuatorConstant.CONTRACT_NOT_EXIST); } TransactionMessage message = new TransactionMessage(trx.getInstance().toByteArray()); + trx.checkExpiration(tronNetDelegate.getNextBlockSlotTime()); dbManager.pushTransaction(trx); int num = tronNetService.fastBroadcastTransaction(message); if (num == 0 && minEffectiveConnection != 0) { diff --git a/framework/src/main/java/org/tron/core/net/TronNetDelegate.java b/framework/src/main/java/org/tron/core/net/TronNetDelegate.java index cd9c8f01d8b..a6f9812a2d7 100644 --- a/framework/src/main/java/org/tron/core/net/TronNetDelegate.java +++ b/framework/src/main/java/org/tron/core/net/TronNetDelegate.java @@ -380,4 +380,12 @@ public boolean isBlockUnsolidified() { return headNum - solidNum >= maxUnsolidifiedBlocks; } + public long getNextBlockSlotTime() { + long slotCount = 1; + if (chainBaseManager.getDynamicPropertiesStore().getStateFlag() == 1) { + slotCount += chainBaseManager.getDynamicPropertiesStore().getMaintenanceSkipSlots(); + } + return chainBaseManager.getDynamicPropertiesStore().getLatestBlockHeaderTimestamp() + + slotCount * BLOCK_PRODUCED_INTERVAL; + } } diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index 665381b31a8..0c58fe08cd6 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -13,6 +13,7 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; +import org.tron.core.exception.TransactionExpirationException; import org.tron.core.net.TronNetDelegate; import org.tron.core.net.message.TronMessage; import org.tron.core.net.message.adv.TransactionMessage; @@ -128,6 +129,7 @@ private void handleTransaction(PeerConnection peer, TransactionMessage trx) { } try { + trx.getTransactionCapsule().checkExpiration(tronNetDelegate.getNextBlockSlotTime()); tronNetDelegate.pushTransaction(trx.getTransactionCapsule()); advService.broadcast(trx); } catch (P2pException e) { @@ -137,6 +139,9 @@ private void handleTransaction(PeerConnection peer, TransactionMessage trx) { peer.setBadPeer(true); peer.disconnect(ReasonCode.BAD_TX); } + } catch (TransactionExpirationException e) { + logger.warn("{}. trx: {}, peer: {}", + e.getMessage(), trx.getMessageId(), peer.getInetAddress()); } catch (Exception e) { logger.error("Trx {} from peer {} process failed", trx.getMessageId(), peer.getInetAddress(), e); diff --git a/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java b/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java index 5243405b7e6..5193f4128cd 100644 --- a/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java +++ b/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java @@ -50,19 +50,6 @@ public void init() throws IOException { context = new TronApplicationContext(DefaultConfig.class); wallet = context.getBean(Wallet.class); dbManager = context.getBean(Manager.class); - - blockCapsule = new BlockCapsule( - 1, - Sha256Hash.wrap(ByteString.copyFrom( - ByteArray.fromHexString( - "0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b81"))), - 1, - ByteString.copyFromUtf8("testAddress")); - dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(blockCapsule.getNum()); - dbManager.getDynamicPropertiesStore() - .saveLatestBlockHeaderTimestamp(blockCapsule.getTimeStamp()); - dbManager.updateRecentBlock(blockCapsule); - initLocalWitness(); } private void initLocalWitness() { @@ -81,6 +68,19 @@ public void removeDb() { @Test public void testExpireTransaction() { + blockCapsule = new BlockCapsule( + 1, + Sha256Hash.wrap(ByteString.copyFrom( + ByteArray.fromHexString( + "0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b81"))), + 1, + ByteString.copyFromUtf8("testAddress")); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(blockCapsule.getNum()); + dbManager.getDynamicPropertiesStore() + .saveLatestBlockHeaderTimestamp(blockCapsule.getTimeStamp()); + dbManager.updateRecentBlock(blockCapsule); + initLocalWitness(); + TransferContract transferContract = TransferContract.newBuilder() .setAmount(1L) .setOwnerAddress(ByteString.copyFrom(Args.getLocalWitnesses() @@ -101,8 +101,61 @@ public void testExpireTransaction() { Assert.assertEquals(response_code.TRANSACTION_EXPIRATION_ERROR, result.getCode()); } + @Test + public void testExpireTransactionNew() { + blockCapsule = new BlockCapsule( + 1, + Sha256Hash.wrap(ByteString.copyFrom( + ByteArray.fromHexString( + "0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b81"))), + System.currentTimeMillis(), + ByteString.copyFromUtf8("testAddress")); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(blockCapsule.getNum()); + dbManager.getDynamicPropertiesStore() + .saveLatestBlockHeaderTimestamp(blockCapsule.getTimeStamp()); + dbManager.updateRecentBlock(blockCapsule); + initLocalWitness(); + byte[] address = Args.getLocalWitnesses() + .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine()); + ByteString addressByte = ByteString.copyFrom(address); + AccountCapsule accountCapsule = + new AccountCapsule(Protocol.Account.newBuilder().setAddress(addressByte).build()); + accountCapsule.setBalance(1000_000_000L); + dbManager.getChainBaseManager().getAccountStore() + .put(accountCapsule.createDbKey(), accountCapsule); + + TransferContract transferContract = TransferContract.newBuilder() + .setAmount(1L) + .setOwnerAddress(addressByte) + .setToAddress(ByteString.copyFrom(ByteArray.fromHexString( + (Wallet.getAddressPreFixString() + "A389132D6639FBDA4FBC8B659264E6B7C90DB086")))) + .build(); + TransactionCapsule transactionCapsule = + new TransactionCapsule(transferContract, ContractType.TransferContract); + transactionCapsule.setReference(blockCapsule.getNum(), blockCapsule.getBlockId().getBytes()); + + transactionCapsule.setExpiration(System.currentTimeMillis()); + transactionCapsule.sign(ByteArray.fromHexString(Args.getLocalWitnesses().getPrivateKey())); + + GrpcAPI.Return result = wallet.broadcastTransaction(transactionCapsule.getInstance()); + Assert.assertEquals(response_code.TRANSACTION_EXPIRATION_ERROR, result.getCode()); + } + @Test public void testTransactionApprovedList() { + blockCapsule = new BlockCapsule( + 1, + Sha256Hash.wrap(ByteString.copyFrom( + ByteArray.fromHexString( + "0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b81"))), + 1, + ByteString.copyFromUtf8("testAddress")); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(blockCapsule.getNum()); + dbManager.getDynamicPropertiesStore() + .saveLatestBlockHeaderTimestamp(blockCapsule.getTimeStamp()); + dbManager.updateRecentBlock(blockCapsule); + initLocalWitness(); + byte[] address = Args.getLocalWitnesses() .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine()); TransferContract transferContract = TransferContract.newBuilder() diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java index 47ffde30ac3..e1865543443 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java @@ -6,13 +6,18 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; + +import lombok.Getter; import org.joda.time.DateTime; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; import org.tron.common.BaseTest; +import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.ByteArray; import org.tron.core.Constant; import org.tron.core.config.args.Args; @@ -75,10 +80,48 @@ public void testProcessMessage() { transactionsMsgHandler.processMessage(peer, new TransactionsMessage(transactionList)); Assert.assertNull(advInvRequest.get(item)); //Thread.sleep(10); + transactionsMsgHandler.close(); + BlockingQueue smartContractQueue = + new LinkedBlockingQueue(2); + smartContractQueue.offer(new TrxEvent(null, null)); + smartContractQueue.offer(new TrxEvent(null, null)); + Field field1 = TransactionsMsgHandler.class.getDeclaredField("smartContractQueue"); + field1.setAccessible(true); + field1.set(transactionsMsgHandler, smartContractQueue); + Protocol.Transaction trx1 = TvmTestUtils.generateTriggerSmartContractAndGetTransaction( + ByteArray.fromHexString("121212a9cf"), + ByteArray.fromHexString("121212a9cf"), + ByteArray.fromHexString("123456"), + 100, 100000000, 0, 0); + Map advInvRequest1 = new ConcurrentHashMap<>(); + Item item1 = new Item(new TransactionMessage(trx1).getMessageId(), + Protocol.Inventory.InventoryType.TRX); + advInvRequest1.put(item1, 0L); + Mockito.when(peer.getAdvInvRequest()).thenReturn(advInvRequest1); + List transactionList1 = new ArrayList<>(); + transactionList1.add(trx1); + transactionsMsgHandler.processMessage(peer, new TransactionsMessage(transactionList1)); + Assert.assertNull(advInvRequest.get(item1)); } catch (Exception e) { Assert.fail(); } finally { transactionsMsgHandler.close(); } } + + class TrxEvent { + + @Getter + private PeerConnection peer; + @Getter + private TransactionMessage msg; + @Getter + private long time; + + public TrxEvent(PeerConnection peer, TransactionMessage msg) { + this.peer = peer; + this.msg = msg; + this.time = System.currentTimeMillis(); + } + } } diff --git a/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java b/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java index d79b54f6f45..5eda8561236 100644 --- a/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.net.InetSocketAddress; + +import com.google.protobuf.Any; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -105,12 +107,28 @@ private void testBroadcast() { } private void testTrxBroadcast() { - Protocol.Transaction trx = Protocol.Transaction.newBuilder().build(); + Protocol.Transaction trx = Protocol.Transaction.newBuilder() + .setRawData( + Protocol.Transaction.raw.newBuilder() + .setRefBlockNum(1) + .setExpiration(System.currentTimeMillis() + 3000).build()).build(); CommonParameter.getInstance().setValidContractProtoThreadNum(1); TransactionMessage msg = new TransactionMessage(trx); service.broadcast(msg); Item item = new Item(msg.getMessageId(), InventoryType.TRX); Assert.assertNotNull(service.getMessage(item)); + + Protocol.Transaction expiredTrx = Protocol.Transaction.newBuilder() + .setRawData( + Protocol.Transaction.raw.newBuilder() + .setRefBlockNum(1) + .setExpiration(System.currentTimeMillis() - 1).build()) + .build(); + CommonParameter.getInstance().setValidContractProtoThreadNum(1); + TransactionMessage msg1 = new TransactionMessage(expiredTrx); + service.broadcast(msg); + Item item1 = new Item(msg1.getMessageId(), InventoryType.TRX); + Assert.assertNull(service.getMessage(item1)); } } From 8d496f8461b98e764dfce25e5bca6ed3364328c5 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Mon, 2 Sep 2024 17:27:41 +0800 Subject: [PATCH 34/42] prefer to disconnect from broadcast nodes when isOpenFullTcpDisconnect is enable --- .../net/service/effective/ResilienceService.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 67c22616bed..cbef2a87742 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -47,7 +47,7 @@ public void init() { } catch (Exception e) { logger.error("DisconnectRandom node failed", e); } - }, initialDelay, 60, TimeUnit.SECONDS); + }, initialDelay, 30, TimeUnit.SECONDS); } else { logger.info("OpenFullTcpDisconnect is disabled"); } @@ -72,13 +72,19 @@ public void init() { private void disconnectRandom() { int peerSize = tronNetDelegate.getActivePeer().size(); if (peerSize >= CommonParameter.getInstance().getMaxConnections()) { - long now = System.currentTimeMillis(); List peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> now - peer.getLastInteractiveTime() >= inactiveThreshold) .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) .collect(Collectors.toList()); - if (!peers.isEmpty()) { + if (peers.size() >= 3) { + Optional one = getEarliestPeer(peers); + one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.RANDOM_ELIMINATION, + DisconnectCause.RANDOM_ELIMINATION)); + } else { + peers = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(peer -> peer.isNeedSyncFromUs() || peer.isNeedSyncFromPeer()) + .collect(Collectors.toList()); int index = new Random().nextInt(peers.size()); disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION, DisconnectCause.RANDOM_ELIMINATION); From f99d21636d3de0f8d2d7365d53447edfa9caa996 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 3 Sep 2024 12:34:10 +0800 Subject: [PATCH 35/42] adjust ResilienceServiceTest --- .../service/effective/ResilienceService.java | 3 +- .../net/services/ResilienceServiceTest.java | 34 ++++++++++++++----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index cbef2a87742..48908cd350a 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -29,6 +29,7 @@ public class ResilienceService { //when node is isolated, retention percent peers will not be disconnected public static final double retentionPercent = 0.8; private static final int initialDelay = 300; + public static final int broadcastPeerSize = 3; private static final String esName = "resilience-service"; private final ScheduledExecutorService executor = ExecutorServiceManager .newSingleThreadScheduledExecutor(esName); @@ -76,7 +77,7 @@ private void disconnectRandom() { .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) .collect(Collectors.toList()); - if (peers.size() >= 3) { + if (peers.size() >= broadcastPeerSize) { Optional one = getEarliestPeer(peers); one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.RANDOM_ELIMINATION, DisconnectCause.RANDOM_ELIMINATION)); diff --git a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java index 2558e089b7e..1c3c6c27232 100644 --- a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java @@ -51,7 +51,7 @@ public void testDisconnectRandom() { clearPeers(); Assert.assertEquals(0, PeerManager.getPeers().size()); - for (int i = 0; i < maxConnection; i++) { + for (int i = 0; i < maxConnection + 1; i++) { InetSocketAddress inetSocketAddress = new InetSocketAddress("201.0.0." + i, 10001); Channel c1 = spy(Channel.class); ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress); @@ -61,21 +61,37 @@ public void testDisconnectRandom() { PeerManager.add(context, c1); } - for (PeerConnection peer : PeerManager.getPeers()) { + for (PeerConnection peer : PeerManager.getPeers() + .subList(0, ResilienceService.broadcastPeerSize)) { peer.setNeedSyncFromPeer(false); peer.setNeedSyncFromUs(false); + peer.setLastInteractiveTime(System.currentTimeMillis() - 1000); + } + for (PeerConnection peer : PeerManager.getPeers() + .subList(ResilienceService.broadcastPeerSize, maxConnection + 1)) { + peer.setNeedSyncFromPeer(false); + peer.setNeedSyncFromUs(true); } + int size1 = (int) PeerManager.getPeers().stream() + .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) + .count(); + Assert.assertEquals(ResilienceService.broadcastPeerSize, size1); + Assert.assertEquals(maxConnection + 1, PeerManager.getPeers().size()); + + //disconnect from broadcasting peer ReflectUtils.invokeMethod(service, "disconnectRandom"); + size1 = (int) PeerManager.getPeers().stream() + .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) + .count(); + Assert.assertEquals(ResilienceService.broadcastPeerSize - 1, size1); Assert.assertEquals(maxConnection, PeerManager.getPeers().size()); - PeerConnection p1 = PeerManager.getPeers().get(1); - p1.setLastInteractiveTime( - System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 1000); - PeerConnection p2 = PeerManager.getPeers().get(10); - p2.setLastInteractiveTime( - System.currentTimeMillis() - Args.getInstance().inactiveThreshold * 1000L - 2000); - + //disconnect from syncing peer ReflectUtils.invokeMethod(service, "disconnectRandom"); + size1 = (int) PeerManager.getPeers().stream() + .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) + .count(); + Assert.assertEquals(ResilienceService.broadcastPeerSize - 1, size1); Assert.assertEquals(maxConnection - 1, PeerManager.getPeers().size()); } From e242ae14738e61b6bf8c65e19cb2cff1fb188536 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 3 Sep 2024 17:38:27 +0800 Subject: [PATCH 36/42] add testcase PeerStatusCheckTest --- .../core/net/peer/PeerStatusCheckTest.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 framework/src/test/java/org/tron/core/net/peer/PeerStatusCheckTest.java diff --git a/framework/src/test/java/org/tron/core/net/peer/PeerStatusCheckTest.java b/framework/src/test/java/org/tron/core/net/peer/PeerStatusCheckTest.java new file mode 100644 index 00000000000..53e678c7ca4 --- /dev/null +++ b/framework/src/test/java/org/tron/core/net/peer/PeerStatusCheckTest.java @@ -0,0 +1,73 @@ +package org.tron.core.net.peer; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.spy; + +import io.netty.channel.ChannelHandlerContext; +import java.io.IOException; +import java.net.InetSocketAddress; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mockito; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.utils.ReflectUtils; +import org.tron.core.Constant; +import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.Parameter.NetConstants; +import org.tron.core.config.args.Args; +import org.tron.p2p.connection.Channel; + + +public class PeerStatusCheckTest { + + protected TronApplicationContext context; + private PeerStatusCheck service; + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Before + public void init() throws IOException { + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + service = context.getBean(PeerStatusCheck.class); + } + + /** + * destroy. + */ + @After + public void destroy() { + Args.clearParam(); + context.destroy(); + } + + @Test + public void testCheck() { + int maxConnection = 30; + Assert.assertEquals(maxConnection, Args.getInstance().getMaxConnections()); + Assert.assertEquals(0, PeerManager.getPeers().size()); + + for (int i = 0; i < maxConnection; i++) { + InetSocketAddress inetSocketAddress = new InetSocketAddress("201.0.0." + i, 10001); + Channel c1 = spy(Channel.class); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress.getAddress()); + ReflectUtils.setFieldValue(c1, "ctx", spy(ChannelHandlerContext.class)); + Mockito.doNothing().when(c1).send((byte[]) any()); + + PeerManager.add(context, c1); + } + + PeerManager.getPeers().get(0).getSyncBlockRequested() + .put(new BlockId(), System.currentTimeMillis() - NetConstants.SYNC_TIME_OUT - 1000); + ReflectUtils.invokeMethod(service, "statusCheck"); + + Assert.assertEquals(maxConnection - 1L, PeerManager.getPeers().size()); + } +} From 6c3a52637ad8816eb1fa2220a26157d8e49495d3 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 4 Sep 2024 12:52:35 +0800 Subject: [PATCH 37/42] use WeightedRandom to choose broadcast peer --- .../service/effective/ResilienceService.java | 73 +++++++++++++++---- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 48908cd350a..89065841d2f 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -1,7 +1,9 @@ package org.tron.core.net.service.effective; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Random; import java.util.concurrent.ScheduledExecutorService; @@ -72,27 +74,40 @@ public void init() { private void disconnectRandom() { int peerSize = tronNetDelegate.getActivePeer().size(); - if (peerSize >= CommonParameter.getInstance().getMaxConnections()) { - List peers = tronNetDelegate.getActivePeer().stream() + if (peerSize < CommonParameter.getInstance().getMaxConnections()) { + return; + } + List peers = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) + .collect(Collectors.toList()); + + if (peers.size() >= broadcastPeerSize) { + long now = System.currentTimeMillis(); + Map weights = new HashMap<>(); + peers.forEach(peer -> weights.put(peer, + (int) Math.ceil((double) (now - peer.getLastInteractiveTime()) / 500))); + WeightedRandom weightedRandom = new WeightedRandom(weights); + PeerConnection one; + try { + one = (PeerConnection) weightedRandom.next(); + } catch (Exception e) { + logger.warn("Get random peer failed: {}", e.getMessage()); + return; + } + disconnectFromPeer(one, ReasonCode.RANDOM_ELIMINATION, DisconnectCause.RANDOM_ELIMINATION); + } else { + peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> !peer.getChannel().isTrustPeer()) - .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) + .filter(peer -> peer.isNeedSyncFromUs() || peer.isNeedSyncFromPeer()) .collect(Collectors.toList()); - if (peers.size() >= broadcastPeerSize) { - Optional one = getEarliestPeer(peers); - one.ifPresent(peer -> disconnectFromPeer(peer, ReasonCode.RANDOM_ELIMINATION, - DisconnectCause.RANDOM_ELIMINATION)); - } else { - peers = tronNetDelegate.getActivePeer().stream() - .filter(peer -> !peer.getChannel().isTrustPeer()) - .filter(peer -> peer.isNeedSyncFromUs() || peer.isNeedSyncFromPeer()) - .collect(Collectors.toList()); - int index = new Random().nextInt(peers.size()); - disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION, - DisconnectCause.RANDOM_ELIMINATION); - } + int index = new Random().nextInt(peers.size()); + disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION, + DisconnectCause.RANDOM_ELIMINATION); } } + private void disconnectLan() { if (!isLanNode()) { return; @@ -205,6 +220,32 @@ private enum DisconnectCause { ISOLATE2_PASSIVE, } + class WeightedRandom { + + private final Map weights; + private final Random random; + + public WeightedRandom(Map weights) { + this.weights = weights; + this.random = new Random(); + } + + public Object next() { + int totalWeight = 0; + for (int weight : weights.values()) { + totalWeight += weight; + } + int randomNum = random.nextInt(totalWeight); + for (Object key : weights.keySet()) { + randomNum -= weights.get(key); + if (randomNum < 0) { + return key; + } + } + throw new IllegalStateException("Sum of weights should not be negative."); + } + } + public void close() { ExecutorServiceManager.shutdownAndAwaitTermination(executor, esName); } From 59e92c8d86d2439cad635bf80a3ed959be809e0c Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 4 Sep 2024 16:36:57 +0800 Subject: [PATCH 38/42] don't disconnect from high peer if its number <=1 --- .../service/effective/ResilienceService.java | 36 ++++++++++++------- .../net/services/ResilienceServiceTest.java | 10 +++--- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java index 89065841d2f..a63fd4bf0a9 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java @@ -31,7 +31,7 @@ public class ResilienceService { //when node is isolated, retention percent peers will not be disconnected public static final double retentionPercent = 0.8; private static final int initialDelay = 300; - public static final int broadcastPeerSize = 3; + public static final int minBroadcastPeerSize = 3; private static final String esName = "resilience-service"; private final ScheduledExecutorService executor = ExecutorServiceManager .newSingleThreadScheduledExecutor(esName); @@ -82,25 +82,35 @@ private void disconnectRandom() { .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) .collect(Collectors.toList()); - if (peers.size() >= broadcastPeerSize) { + if (peers.size() >= minBroadcastPeerSize) { long now = System.currentTimeMillis(); Map weights = new HashMap<>(); - peers.forEach(peer -> weights.put(peer, - (int) Math.ceil((double) (now - peer.getLastInteractiveTime()) / 500))); + peers.forEach(peer -> { + int weight = (int) Math.ceil((double) (now - peer.getLastInteractiveTime()) / 500); + weights.put(peer, Math.max(weight, 1)); + }); WeightedRandom weightedRandom = new WeightedRandom(weights); - PeerConnection one; - try { - one = (PeerConnection) weightedRandom.next(); - } catch (Exception e) { - logger.warn("Get random peer failed: {}", e.getMessage()); - return; - } + PeerConnection one = (PeerConnection) weightedRandom.next(); disconnectFromPeer(one, ReasonCode.RANDOM_ELIMINATION, DisconnectCause.RANDOM_ELIMINATION); - } else { + return; + } + + int needSyncFromPeerCount = (int) tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(PeerConnection::isNeedSyncFromPeer) + .count(); + if (needSyncFromPeerCount >= 2) { peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> !peer.getChannel().isTrustPeer()) .filter(peer -> peer.isNeedSyncFromUs() || peer.isNeedSyncFromPeer()) .collect(Collectors.toList()); + } else { + peers = tronNetDelegate.getActivePeer().stream() + .filter(peer -> !peer.getChannel().isTrustPeer()) + .filter(PeerConnection::isNeedSyncFromUs) + .collect(Collectors.toList()); + } + if (!peers.isEmpty()) { int index = new Random().nextInt(peers.size()); disconnectFromPeer(peers.get(index), ReasonCode.RANDOM_ELIMINATION, DisconnectCause.RANDOM_ELIMINATION); @@ -220,7 +230,7 @@ private enum DisconnectCause { ISOLATE2_PASSIVE, } - class WeightedRandom { + static class WeightedRandom { private final Map weights; private final Random random; diff --git a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java index 1c3c6c27232..ce723e5c991 100644 --- a/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java @@ -62,20 +62,20 @@ public void testDisconnectRandom() { PeerManager.add(context, c1); } for (PeerConnection peer : PeerManager.getPeers() - .subList(0, ResilienceService.broadcastPeerSize)) { + .subList(0, ResilienceService.minBroadcastPeerSize)) { peer.setNeedSyncFromPeer(false); peer.setNeedSyncFromUs(false); peer.setLastInteractiveTime(System.currentTimeMillis() - 1000); } for (PeerConnection peer : PeerManager.getPeers() - .subList(ResilienceService.broadcastPeerSize, maxConnection + 1)) { + .subList(ResilienceService.minBroadcastPeerSize, maxConnection + 1)) { peer.setNeedSyncFromPeer(false); peer.setNeedSyncFromUs(true); } int size1 = (int) PeerManager.getPeers().stream() .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) .count(); - Assert.assertEquals(ResilienceService.broadcastPeerSize, size1); + Assert.assertEquals(ResilienceService.minBroadcastPeerSize, size1); Assert.assertEquals(maxConnection + 1, PeerManager.getPeers().size()); //disconnect from broadcasting peer @@ -83,7 +83,7 @@ public void testDisconnectRandom() { size1 = (int) PeerManager.getPeers().stream() .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) .count(); - Assert.assertEquals(ResilienceService.broadcastPeerSize - 1, size1); + Assert.assertEquals(ResilienceService.minBroadcastPeerSize - 1, size1); Assert.assertEquals(maxConnection, PeerManager.getPeers().size()); //disconnect from syncing peer @@ -91,7 +91,7 @@ public void testDisconnectRandom() { size1 = (int) PeerManager.getPeers().stream() .filter(peer -> !peer.isNeedSyncFromUs() && !peer.isNeedSyncFromPeer()) .count(); - Assert.assertEquals(ResilienceService.broadcastPeerSize - 1, size1); + Assert.assertEquals(ResilienceService.minBroadcastPeerSize - 1, size1); Assert.assertEquals(maxConnection - 1, PeerManager.getPeers().size()); } From 6c73edef1fedab8e05bdd7b0fe3b177e25f29036 Mon Sep 17 00:00:00 2001 From: chengtx01 Date: Thu, 12 Sep 2024 12:35:01 +0800 Subject: [PATCH 39/42] feat(net): delete useless test code --- .../src/test/java/org/tron/core/net/services/AdvServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java b/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java index 5eda8561236..c4ac4b06c43 100644 --- a/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.net.InetSocketAddress; -import com.google.protobuf.Any; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; From ddccce40de79de2c1c1a1ca3e883fae0dbd54763 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 27 Sep 2024 12:40:13 +0800 Subject: [PATCH 40/42] print trx size from pending and repush after generating block --- .../main/java/org/tron/core/db/Manager.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 66aeccdda39..43e5838d1d5 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -1569,6 +1569,7 @@ public BlockCapsule generateBlock(Miner miner, long blockTime, long timeout) { List toBePacked = new ArrayList<>(); long currentSize = blockCapsule.getInstance().getSerializedSize(); boolean isSort = Args.getInstance().isOpenTransactionSort(); + int[] logSize = new int[] {pendingTransactions.size(), rePushTransactions.size(), 0, 0}; while (pendingTransactions.size() > 0 || rePushTransactions.size() > 0) { boolean fromPending = false; TransactionCapsule trx; @@ -1644,6 +1645,11 @@ public BlockCapsule generateBlock(Miner miner, long blockTime, long timeout) { tmpSession.merge(); toBePacked.add(trx); currentSize += trxPackSize; + if (fromPending) { + logSize[2] += 1; + } else { + logSize[3] += 1; + } } catch (Exception e) { logger.warn("Process trx {} failed when generating block {}, {}.", trx.getTransactionId(), blockCapsule.getNum(), e.getMessage()); @@ -1660,11 +1666,14 @@ public BlockCapsule generateBlock(Miner miner, long blockTime, long timeout) { BlockCapsule capsule = new BlockCapsule(blockCapsule.getInstance()); capsule.generatedByMyself = true; Metrics.histogramObserve(timer); - logger.info("Generate block {} success, trxs:{}, pendingCount: {}, rePushCount: {}," - + " postponedCount: {}, blockSize: {} B", - capsule.getNum(), capsule.getTransactions().size(), - pendingTransactions.size(), rePushTransactions.size(), postponedTrxCount, - capsule.getSerializedSize()); + logger.info("Generate block {} success, trxs:{}, before pendingCount: {}, rePushCount: {}, " + + "from pending: {}, rePush: {}, after pendingCount: {}, rePushCount: {}, " + + "postponedCount: {}, blockSize: {} B", + capsule.getNum(), capsule.getTransactions().size(), + logSize[0], logSize[1], logSize[2], logSize[3], + pendingTransactions.size(), rePushTransactions.size(), postponedTrxCount, + capsule.getSerializedSize()); + return capsule; } From 450763b66d662ec854a99b702198dce9ecbace29 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 27 Sep 2024 17:37:40 +0800 Subject: [PATCH 41/42] add some test case --- .../org/tron/plugins/utils/ByteArrayTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 plugins/src/test/java/org/tron/plugins/utils/ByteArrayTest.java diff --git a/plugins/src/test/java/org/tron/plugins/utils/ByteArrayTest.java b/plugins/src/test/java/org/tron/plugins/utils/ByteArrayTest.java new file mode 100644 index 00000000000..300c983db3a --- /dev/null +++ b/plugins/src/test/java/org/tron/plugins/utils/ByteArrayTest.java @@ -0,0 +1,44 @@ +package org.tron.plugins.utils; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; +import org.junit.Test; + +@Slf4j +public class ByteArrayTest { + + @Test + public void testToStrToInt() { + String test = "abc"; + byte[] testBytes = test.getBytes(); + Assert.assertEquals(test, ByteArray.toStr(testBytes)); + + int i = 5; + Assert.assertEquals(ByteArray.toInt(ByteArray.fromInt(i)), 5); + } + + @Test + public void testFromHexString() { + Assert.assertArrayEquals(ByteArray.EMPTY_BYTE_ARRAY, ByteArray.fromHexString(null)); + + Assert.assertArrayEquals(ByteArray.fromHexString("12"), ByteArray.fromHexString("0x12")); + + Assert.assertArrayEquals(ByteArray.fromHexString("0x2"), ByteArray.fromHexString("0x02")); + } + + @Test + public void testCompareUnsigned() { + byte[] a = new byte[] {1, 2}; + Assert.assertEquals(0, ByteArray.compareUnsigned(a, a)); + Assert.assertEquals(-1, ByteArray.compareUnsigned(null, a)); + Assert.assertEquals(1, ByteArray.compareUnsigned(a, null)); + + byte[] b = new byte[] {1, 3}; + Assert.assertEquals(-1, ByteArray.compareUnsigned(a, b)); + Assert.assertEquals(1, ByteArray.compareUnsigned(b, a)); + + byte[] c = new byte[] {1, 2, 3}; + Assert.assertEquals(-1, ByteArray.compareUnsigned(a, c)); + Assert.assertEquals(1, ByteArray.compareUnsigned(c, a)); + } +} From 98a37b15baea9d4aa8d9e6fd1adb1ec962b2d983 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Sun, 22 Sep 2024 14:00:09 +0800 Subject: [PATCH 42/42] feat(dependencies): update dependencies for protobuf-java Bump com.google.protobuf:protobuf-java from 3.21.12 to 3.25.5 Bump io.github.tronprotocol:libp2p from 2.2.1 to 2.2.4 --- build.gradle | 7 ------- common/build.gradle | 2 +- protocol/build.gradle | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index a56be97afa1..f5b144657f3 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,6 @@ subprojects { compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.25' compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.9' - compile group: 'com.google.guava', name: 'guava', version: '30.1-jre' compile "com.google.code.findbugs:jsr305:3.0.0" compile group: 'org.springframework', name: 'spring-context', version: '5.3.18' compile group: 'org.springframework', name: 'spring-tx', version: '5.3.18' @@ -68,12 +67,6 @@ subprojects { preserveFileTimestamps = false reproducibleFileOrder = true } - - configurations.all { - resolutionStrategy { - force group: 'com.google.guava', name: 'guava', version: '30.1-jre' - } - } } task copyToParent(type: Copy) { diff --git a/common/build.gradle b/common/build.gradle index 6c1545e5d13..8c651e48455 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -46,7 +46,7 @@ dependencies { compile 'org.aspectj:aspectjrt:1.8.13' compile 'org.aspectj:aspectjweaver:1.8.13' compile 'org.aspectj:aspectjtools:1.8.13' - compile group: 'io.github.tronprotocol', name: 'libp2p', version: '2.2.1',{ + compile group: 'io.github.tronprotocol', name: 'libp2p', version: '2.2.4',{ exclude group: 'io.grpc', module: 'grpc-context' exclude group: 'io.grpc', module: 'grpc-core' exclude group: 'io.grpc', module: 'grpc-netty' diff --git a/protocol/build.gradle b/protocol/build.gradle index 922d6d19859..d88687227e8 100644 --- a/protocol/build.gradle +++ b/protocol/build.gradle @@ -1,6 +1,6 @@ apply plugin: 'com.google.protobuf' -def protobufVersion = '3.21.12' +def protobufVersion = '3.25.5' def grpcVersion = '1.52.1' dependencies {