Skip to content

Commit ec96ee7

Browse files
committed
Merge branch 'develop' into feature/support_domain
2 parents f5e7ef8 + 645bf20 commit ec96ee7

7 files changed

Lines changed: 76 additions & 3 deletions

File tree

framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ private void processBlock(PeerConnection peer, BlockCapsule block) throws P2pExc
150150

151151
try {
152152
tronNetDelegate.processBlock(block, false);
153+
peer.setBlockRcvTime(System.currentTimeMillis());
153154
witnessProductBlockService.validWitnessProductTwoBlock(block);
154155

155156
Item item = new Item(blockId, InventoryType.BLOCK);

framework/src/main/java/org/tron/core/net/messagehandler/InventoryMsgHandler.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.springframework.beans.factory.annotation.Autowired;
77
import org.springframework.stereotype.Component;
88
import org.tron.common.utils.Sha256Hash;
9+
import org.tron.core.capsule.BlockCapsule.BlockId;
910
import org.tron.core.config.args.Args;
1011
import org.tron.core.exception.P2pException;
1112
import org.tron.core.exception.P2pException.TypeEnum;
@@ -44,7 +45,10 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep
4445
peer.getAdvInvReceive().put(item, System.currentTimeMillis());
4546
advService.addInv(item);
4647
if (type.equals(InventoryType.BLOCK) && peer.getAdvInvSpread().getIfPresent(item) == null) {
47-
peer.setLastInteractiveTime(System.currentTimeMillis());
48+
long headNum = tronNetDelegate.getHeadBlockId().getNum();
49+
if (new BlockId(id).getNum() > headNum) {
50+
peer.setLastInteractiveTime(System.currentTimeMillis());
51+
}
4852
}
4953
}
5054
}

framework/src/main/java/org/tron/core/net/peer/PeerConnection.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ public class PeerConnection {
8888
@Setter
8989
private volatile long lastInteractiveTime;
9090

91+
@Setter
92+
@Getter
93+
private volatile long blockRcvTime;
94+
9195
@Getter
9296
@Setter
9397
private volatile TronState tronState = TronState.INIT;

framework/src/main/java/org/tron/core/net/service/effective/ResilienceService.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import static org.tron.common.math.Maths.ceil;
44
import static org.tron.common.math.Maths.max;
55

6+
import java.util.ArrayList;
67
import java.util.Comparator;
78
import java.util.HashMap;
9+
import java.util.IdentityHashMap;
810
import java.util.List;
911
import java.util.Map;
1012
import java.util.Optional;
@@ -44,7 +46,7 @@ public class ResilienceService {
4446

4547
@Autowired
4648
private ChainBaseManager chainBaseManager;
47-
49+
4850
public void init() {
4951
if (Args.getInstance().isOpenFullTcpDisconnect) {
5052
executor.scheduleWithFixedDelay(() -> {
@@ -86,6 +88,7 @@ private void disconnectRandom() {
8688
.collect(Collectors.toList());
8789

8890
if (peers.size() >= minBroadcastPeerSize) {
91+
peers = getRandomDisconnectionPeers(peers);
8992
long now = System.currentTimeMillis();
9093
Map<Object, Integer> weights = new HashMap<>();
9194
peers.forEach(peer -> {
@@ -121,6 +124,14 @@ private void disconnectRandom() {
121124
}
122125

123126

127+
private List<PeerConnection> getRandomDisconnectionPeers(List<PeerConnection> peers) {
128+
Map<PeerConnection, Long> snapshot = new IdentityHashMap<>(peers.size());
129+
peers.forEach(p -> snapshot.put(p, p.getBlockRcvTime()));
130+
List<PeerConnection> sorted = new ArrayList<>(peers);
131+
sorted.sort(Comparator.comparingLong(snapshot::get));
132+
return sorted.subList(0, sorted.size() / 2);
133+
}
134+
124135
private void disconnectLan() {
125136
if (!isLanNode()) {
126137
return;

framework/src/main/java/org/tron/core/net/service/sync/SyncService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ private void processSyncBlock(BlockCapsule block, PeerConnection peerConnection)
337337
try {
338338
tronNetDelegate.validSignature(block);
339339
tronNetDelegate.processBlock(block, true);
340+
peerConnection.setBlockRcvTime(System.currentTimeMillis());
340341
pbftDataSyncHandler.processPBFTCommitData(block);
341342
} catch (P2pException p2pException) {
342343
logger.error("Process sync block {} failed, type: {}",

framework/src/main/java/org/tron/program/Version.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ public class Version {
44

55
public static final String VERSION_NAME = "GreatVoyage-v4.8.0.1-1-g44a4bc8263";
66
public static final String VERSION_CODE = "18636";
7-
private static final String VERSION = "4.8.1";
7+
private static final String VERSION = "4.8.2";
88

99
public static String getVersion() {
1010
return VERSION;

framework/src/test/java/org/tron/core/net/services/ResilienceServiceTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.io.IOException;
88
import java.net.InetSocketAddress;
99
import java.util.HashSet;
10+
import java.util.List;
1011
import java.util.Set;
1112
import javax.annotation.Resource;
1213
import org.junit.After;
@@ -97,6 +98,57 @@ public void testDisconnectRandom() {
9798
Assert.assertEquals(maxConnection - 1, PeerManager.getPeers().size());
9899
}
99100

101+
@Test
102+
public void testDisconnectRandomPreservesRecentBlockRcvTimePeer() {
103+
int maxConnection = 30;
104+
Assert.assertEquals(0, PeerManager.getPeers().size());
105+
106+
ApplicationContext ctx = (ApplicationContext) ReflectUtils.getFieldObject(p2pEventHandler,
107+
"ctx");
108+
109+
// Create maxConnection + 1 peers (triggers disconnectRandom)
110+
for (int i = 0; i < maxConnection + 1; i++) {
111+
InetSocketAddress inetSocketAddress = new InetSocketAddress("202.0.0." + i, 10001);
112+
Channel c1 = spy(Channel.class);
113+
ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress);
114+
ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress.getAddress());
115+
ReflectUtils.setFieldValue(c1, "ctx", spy(ChannelHandlerContext.class));
116+
Mockito.doNothing().when(c1).send((byte[]) any());
117+
PeerManager.add(ctx, c1);
118+
}
119+
120+
// Set first minBroadcastPeerSize peers as broadcast-state
121+
List<PeerConnection> peers = PeerManager.getPeers();
122+
for (PeerConnection peer : peers.subList(0, ResilienceService.minBroadcastPeerSize)) {
123+
peer.setNeedSyncFromPeer(false);
124+
peer.setNeedSyncFromUs(false);
125+
peer.setLastInteractiveTime(System.currentTimeMillis() - 1000);
126+
}
127+
for (PeerConnection peer : peers.subList(ResilienceService.minBroadcastPeerSize,
128+
maxConnection + 1)) {
129+
peer.setNeedSyncFromPeer(false);
130+
peer.setNeedSyncFromUs(true);
131+
}
132+
133+
// Give the LAST broadcast peer a very recent blockRcvTime — it must NOT be disconnected
134+
PeerConnection bestPeer = peers.stream()
135+
.filter(p -> !p.isNeedSyncFromUs() && !p.isNeedSyncFromPeer())
136+
.reduce((a, b) -> b) // last broadcast peer
137+
.orElseThrow(() -> new AssertionError("no broadcast peer"));
138+
bestPeer.setBlockRcvTime(System.currentTimeMillis());
139+
140+
InetSocketAddress bestPeerAddress = bestPeer.getChannel().getInetSocketAddress();
141+
142+
// With minBroadcastPeerSize=3 broadcast peers, getRandomDisconnectionPeers returns
143+
// the 1 peer with oldest blockRcvTime (0). bestPeer has most recent time → exempt.
144+
ReflectUtils.invokeMethod(service, "disconnectRandom");
145+
146+
boolean bestPeerStillConnected = PeerManager.getPeers().stream()
147+
.anyMatch(p -> p.getChannel().getInetSocketAddress().equals(bestPeerAddress));
148+
Assert.assertTrue("Peer with most recent blockRcvTime should not be disconnected",
149+
bestPeerStillConnected);
150+
}
151+
100152
@Test
101153
public void testDisconnectLan() {
102154
int minConnection = 8;

0 commit comments

Comments
 (0)