From 253ec29fa5f030e5d6f1ff56257025748b9cb1fc Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 20 Dec 2024 10:46:03 +0800 Subject: [PATCH 1/7] fix the bug of handshake with lightnode --- .../tron/core/net/service/handshake/HandshakeService.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java index 6cd117c83dd..c7d97e471d4 100644 --- a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java +++ b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Component; import org.tron.common.utils.ByteArray; import org.tron.core.ChainBaseManager; +import org.tron.core.ChainBaseManager.NodeType; import org.tron.core.config.args.Args; import org.tron.core.net.TronNetService; import org.tron.core.net.message.handshake.HelloMessage; @@ -101,7 +102,11 @@ public void processHelloMessage(PeerConnection peer, HelloMessage msg) { peer.getInetSocketAddress(), msg.getSolidBlockId().getString(), chainBaseManager.getSolidBlockId().getString()); - peer.disconnect(ReasonCode.FORKED); + if (chainBaseManager.getNodeType() == NodeType.FULL) { + peer.disconnect(ReasonCode.FORKED); + } else { + peer.disconnect(ReasonCode.LIGHT_NODE_SYNC_FAIL); + } return; } From 6b47ef77ed1bfc3fce2778e6002b5f09aaa64816 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 24 Jun 2025 17:25:46 +0800 Subject: [PATCH 2/7] add more log --- .../net/service/handshake/HandshakeService.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java index c7d97e471d4..5ed1e5612b2 100644 --- a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java +++ b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java @@ -97,14 +97,19 @@ public void processHelloMessage(PeerConnection peer, HelloMessage msg) { } if (chainBaseManager.getSolidBlockId().getNum() >= msg.getSolidBlockId().getNum() - && !chainBaseManager.containBlockInMainChain(msg.getSolidBlockId())) { - logger.info("Peer {} different solid block, peer->{}, me->{}", - peer.getInetSocketAddress(), - msg.getSolidBlockId().getString(), - chainBaseManager.getSolidBlockId().getString()); + && !chainBaseManager.containBlockInMainChain(msg.getSolidBlockId())) { if (chainBaseManager.getNodeType() == NodeType.FULL) { + logger.info("Peer {} solid block is below than we and fork with me, peer->{}, me->{}", + peer.getInetSocketAddress(), + msg.getSolidBlockId().getString(), + chainBaseManager.getSolidBlockId().getString()); peer.disconnect(ReasonCode.FORKED); } else { + logger.info("Peer {} solid block is below than we and light node doesn't contain the block," + + " it's unuseful, peer->{}, me->{}", + peer.getInetSocketAddress(), + msg.getSolidBlockId().getString(), + chainBaseManager.getSolidBlockId().getString()); peer.disconnect(ReasonCode.LIGHT_NODE_SYNC_FAIL); } return; From c06b3723b4cf36725eb014436c736464ea7dc87a Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 24 Jun 2025 18:31:13 +0800 Subject: [PATCH 3/7] add test case --- .../tron/core/net/services/HandShakeServiceTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java b/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java index f4fabce5d64..7d976f4f617 100644 --- a/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java @@ -25,6 +25,7 @@ import org.tron.common.utils.ReflectUtils; import org.tron.common.utils.Sha256Hash; import org.tron.core.ChainBaseManager; +import org.tron.core.ChainBaseManager.NodeType; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; import org.tron.core.config.DefaultConfig; @@ -256,6 +257,15 @@ public void testLowAndGenesisBlockNum() throws NoSuchMethodException { .setNumber(sid.getNum()) .build(); builder.setSolidBlockId(sBlockId); + ChainBaseManager.getChainBaseManager().setNodeType(NodeType.FULL); + try { + HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray()); + method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes()); + } catch (Exception e) { + Assert.fail(); + } + + ChainBaseManager.getChainBaseManager().setNodeType(NodeType.LITE); try { HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray()); method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes()); From b6c6593837b8f45bfd518df0790bdc20705e634b Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 3 Jul 2025 17:27:43 +0800 Subject: [PATCH 4/7] use different condition when judge fork --- .../tron/core/net/service/handshake/HandshakeService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java index 5ed1e5612b2..b024bc80e21 100644 --- a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java +++ b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java @@ -98,14 +98,14 @@ public void processHelloMessage(PeerConnection peer, HelloMessage msg) { if (chainBaseManager.getSolidBlockId().getNum() >= msg.getSolidBlockId().getNum() && !chainBaseManager.containBlockInMainChain(msg.getSolidBlockId())) { - if (chainBaseManager.getNodeType() == NodeType.FULL) { - logger.info("Peer {} solid block is below than we and fork with me, peer->{}, me->{}", + if (chainBaseManager.getLowestBlockNum() <= msg.getSolidBlockId().getNum()) { + logger.info("Peer {} different solid block, fork with me, peer->{}, me->{}", peer.getInetSocketAddress(), msg.getSolidBlockId().getString(), chainBaseManager.getSolidBlockId().getString()); peer.disconnect(ReasonCode.FORKED); } else { - logger.info("Peer {} solid block is below than we and light node doesn't contain the block," + logger.info("Peer {} solid block is below than me and light node doesn't contain the block," + " it's unuseful, peer->{}, me->{}", peer.getInetSocketAddress(), msg.getSolidBlockId().getString(), From da4d2edf27e8dac16f55f40db8e1108e8390d74d Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Mon, 7 Jul 2025 18:04:29 +0800 Subject: [PATCH 5/7] fix the bug of RelayServiceTest --- .../net/services/HandShakeServiceTest.java | 15 ++-- .../core/net/services/RelayServiceTest.java | 85 +++++++++++++++---- 2 files changed, 76 insertions(+), 24 deletions(-) diff --git a/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java b/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java index 7d976f4f617..bde8b3eb654 100644 --- a/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java @@ -21,11 +21,9 @@ import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.ByteArray; import org.tron.common.utils.ReflectUtils; import org.tron.common.utils.Sha256Hash; import org.tron.core.ChainBaseManager; -import org.tron.core.ChainBaseManager.NodeType; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; import org.tron.core.config.DefaultConfig; @@ -215,7 +213,7 @@ public void testLowAndGenesisBlockNum() throws NoSuchMethodException { Node node2 = new Node(NetUtil.getNodeId(), a1.getAddress().getHostAddress(), null, 10002); - //lowestBlockNum > headBlockNum + //peer's lowestBlockNum > my headBlockNum => peer is light, LIGHT_NODE_SYNC_FAIL Protocol.HelloMessage.Builder builder = getHelloMessageBuilder(node2, System.currentTimeMillis(), ChainBaseManager.getChainBaseManager()); @@ -227,7 +225,7 @@ public void testLowAndGenesisBlockNum() throws NoSuchMethodException { Assert.fail(); } - //genesisBlock is not equal + //genesisBlock is not equal => INCOMPATIBLE_CHAIN builder = getHelloMessageBuilder(node2, System.currentTimeMillis(), ChainBaseManager.getChainBaseManager()); BlockCapsule.BlockId gid = ChainBaseManager.getChainBaseManager().getGenesisBlockId(); @@ -243,9 +241,11 @@ public void testLowAndGenesisBlockNum() throws NoSuchMethodException { Assert.fail(); } - //solidityBlock <= us, but not contained + // peer's solidityBlock <= my solidityBlock, but not contained + // and my lowestBlockNum <= peer's solidityBlock => FORKED builder = getHelloMessageBuilder(node2, System.currentTimeMillis(), ChainBaseManager.getChainBaseManager()); + BlockCapsule.BlockId sid = ChainBaseManager.getChainBaseManager().getSolidBlockId(); Random gen = new Random(); @@ -257,7 +257,6 @@ public void testLowAndGenesisBlockNum() throws NoSuchMethodException { .setNumber(sid.getNum()) .build(); builder.setSolidBlockId(sBlockId); - ChainBaseManager.getChainBaseManager().setNodeType(NodeType.FULL); try { HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray()); method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes()); @@ -265,7 +264,9 @@ public void testLowAndGenesisBlockNum() throws NoSuchMethodException { Assert.fail(); } - ChainBaseManager.getChainBaseManager().setNodeType(NodeType.LITE); + // peer's solidityBlock <= my solidityBlock, but not contained + // and my lowestBlockNum > peer's solidityBlock => i am light, LIGHT_NODE_SYNC_FAIL + ChainBaseManager.getChainBaseManager().setLowestBlockNum(2); try { HelloMessage helloMessage = new HelloMessage(builder.build().toByteArray()); method.invoke(p2pEventHandler, peer, helloMessage.getSendBytes()); diff --git a/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java b/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java index 5e22e538e80..2ed09019fc9 100644 --- a/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java @@ -1,8 +1,9 @@ package org.tron.core.net.services; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; -import com.google.common.collect.Lists; import com.google.protobuf.ByteString; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -12,7 +13,6 @@ import java.util.List; import java.util.Set; import javax.annotation.Resource; - import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.Assert; @@ -21,19 +21,27 @@ import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import org.tron.common.BaseTest; +import org.tron.common.crypto.SignInterface; +import org.tron.common.crypto.SignUtils; +import org.tron.common.parameter.CommonParameter; +import org.tron.common.utils.ByteArray; import org.tron.common.utils.ReflectUtils; +import org.tron.common.utils.Sha256Hash; import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.config.args.Args; import org.tron.core.net.P2pEventHandlerImpl; +import org.tron.core.net.TronNetDelegate; +import org.tron.core.net.TronNetService; import org.tron.core.net.message.adv.BlockMessage; import org.tron.core.net.message.handshake.HelloMessage; import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.peer.PeerManager; import org.tron.core.net.service.relay.RelayService; +import org.tron.p2p.P2pConfig; import org.tron.p2p.connection.Channel; import org.tron.p2p.discover.Node; import org.tron.p2p.utils.NetUtil; @@ -44,11 +52,13 @@ public class RelayServiceTest extends BaseTest { @Resource private RelayService service; - @Resource - private PeerConnection peer; + @Resource private P2pEventHandlerImpl p2pEventHandler; + @Resource + private TronNetService tronNetService; + /** * init context. */ @@ -67,8 +77,12 @@ public void test() throws Exception { } private void initWitness() { - byte[] key = Hex.decode("A04711BF7AFBDF44557DEFBDF4C4E7AA6138C6331F"); + // key: 0154435f065a57fec6af1e12eaa2fa600030639448d7809f4c65bdcf8baed7e5 + // Hex: A08A8D690BF36806C36A7DAE3AF796643C1AA9CC01 + // Base58: 27bi7CD8d94AgXY3XFS9A9vx78Si5MqrECz + byte[] key = Hex.decode("A08A8D690BF36806C36A7DAE3AF796643C1AA9CC01");//exist already WitnessCapsule witnessCapsule = chainBaseManager.getWitnessStore().get(key); + System.out.println(witnessCapsule.getInstance()); witnessCapsule.setVoteCount(1000); chainBaseManager.getWitnessStore().put(key, witnessCapsule); List list = new ArrayList<>(); @@ -83,7 +97,7 @@ public void testGetNextWitnesses() throws Exception { "getNextWitnesses", ByteString.class, Integer.class); method.setAccessible(true); Set s1 = (Set) method.invoke( - service, getFromHexString("A04711BF7AFBDF44557DEFBDF4C4E7AA6138C6331F"), 3); + service, getFromHexString("A08A8D690BF36806C36A7DAE3AF796643C1AA9CC01"), 3); Assert.assertEquals(3, s1.size()); assertContains(s1, "A0299F3DB80A24B20A254B89CE639D59132F157F13"); assertContains(s1, "A0807337F180B62A77576377C1D0C9C24DF5C0DD62"); @@ -93,35 +107,51 @@ public void testGetNextWitnesses() throws Exception { service, getFromHexString("A0FAB5FBF6AFB681E4E37E9D33BDDB7E923D6132E5"), 3); Assert.assertEquals(3, s2.size()); assertContains(s2, "A014EEBE4D30A6ACB505C8B00B218BDC4733433C68"); - assertContains(s2, "A04711BF7AFBDF44557DEFBDF4C4E7AA6138C6331F"); + assertContains(s2, "A08A8D690BF36806C36A7DAE3AF796643C1AA9CC01"); assertContains(s2, "A0299F3DB80A24B20A254B89CE639D59132F157F13"); Set s3 = (Set) method.invoke( - service, getFromHexString("A04711BF7AFBDF44557DEFBDF4C4E7AA6138C6331F"), 1); + service, getFromHexString("A08A8D690BF36806C36A7DAE3AF796643C1AA9CC01"), 1); Assert.assertEquals(1, s3.size()); assertContains(s3, "A0299F3DB80A24B20A254B89CE639D59132F157F13"); } private void testBroadcast() { try { + PeerConnection peer = new PeerConnection(); + InetSocketAddress a1 = new InetSocketAddress("127.0.0.2", 10001); + Channel c1 = mock(Channel.class); + Mockito.when(c1.getInetSocketAddress()).thenReturn(a1); + Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress()); + doNothing().when(c1).send((byte[]) any()); + + peer.setChannel(c1); peer.setAddress(getFromHexString("A0299F3DB80A24B20A254B89CE639D59132F157F13")); peer.setNeedSyncFromPeer(false); peer.setNeedSyncFromUs(false); - List peers = Lists.newArrayList(); + List peers = new ArrayList<>(); peers.add(peer); - ReflectUtils.setFieldValue(p2pEventHandler, "activePeers", peers); + + TronNetDelegate tronNetDelegate = Mockito.mock(TronNetDelegate.class); + Mockito.doReturn(peers).when(tronNetDelegate).getActivePeer(); + + Field field = service.getClass().getDeclaredField("tronNetDelegate"); + field.setAccessible(true); + field.set(service, tronNetDelegate); + BlockCapsule blockCapsule = new BlockCapsule(chainBaseManager.getHeadBlockNum() + 1, chainBaseManager.getHeadBlockId(), - 0, getFromHexString("A04711BF7AFBDF44557DEFBDF4C4E7AA6138C6331F")); + 0, getFromHexString("A08A8D690BF36806C36A7DAE3AF796643C1AA9CC01")); BlockMessage msg = new BlockMessage(blockCapsule); service.broadcast(msg); Item item = new Item(blockCapsule.getBlockId(), Protocol.Inventory.InventoryType.BLOCK); Assert.assertEquals(1, peer.getAdvInvSpread().size()); Assert.assertNotNull(peer.getAdvInvSpread().getIfPresent(item)); peer.getChannel().close(); - } catch (NullPointerException e) { - System.out.println(e); + } catch (Exception e) { + logger.info("", e); + assert false; } } @@ -135,20 +165,32 @@ private ByteString getFromHexString(String s) { } private void testCheckHelloMessage() { - ByteString address = getFromHexString("A04711BF7AFBDF44557DEFBDF4C4E7AA6138C6331F"); + String key = "0154435f065a57fec6af1e12eaa2fa600030639448d7809f4c65bdcf8baed7e5"; + ByteString address = getFromHexString("A08A8D690BF36806C36A7DAE3AF796643C1AA9CC01"); InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001); Node node = new Node(NetUtil.getNodeId(), a1.getAddress().getHostAddress(), null, a1.getPort()); + + SignInterface cryptoEngine = SignUtils.fromPrivate(ByteArray.fromHexString(key), + Args.getInstance().isECKeyCryptoEngine()); HelloMessage helloMessage = new HelloMessage(node, System.currentTimeMillis(), ChainBaseManager.getChainBaseManager()); + ByteString sig = ByteString.copyFrom(cryptoEngine.Base64toBytes(cryptoEngine + .signHash(Sha256Hash.of(CommonParameter.getInstance() + .isECKeyCryptoEngine(), ByteArray.fromLong(helloMessage + .getTimestamp())).getBytes()))); helloMessage.setHelloMessage(helloMessage.getHelloMessage().toBuilder() - .setAddress(address).build()); + .setAddress(address) + .setSignature(sig) + .build()); + Channel c1 = mock(Channel.class); Mockito.when(c1.getInetSocketAddress()).thenReturn(a1); Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress()); Channel c2 = mock(Channel.class); Mockito.when(c2.getInetSocketAddress()).thenReturn(a1); Mockito.when(c2.getInetAddress()).thenReturn(a1.getAddress()); + Args.getInstance().fastForward = true; ApplicationContext ctx = (ApplicationContext) ReflectUtils.getFieldObject(p2pEventHandler, "ctx"); @@ -158,14 +200,23 @@ private void testCheckHelloMessage() { PeerConnection peer2 = PeerManager.add(ctx, c2); assert peer2 != null; peer2.setAddress(address); + + ReflectUtils.setFieldValue(tronNetService, "p2pConfig", new P2pConfig()); + try { Field field = service.getClass().getDeclaredField("witnessScheduleStore"); field.setAccessible(true); field.set(service, chainBaseManager.getWitnessScheduleStore()); + + Field field2 = service.getClass().getDeclaredField("manager"); + field2.setAccessible(true); + field2.set(service, dbManager); + boolean res = service.checkHelloMessage(helloMessage, c1); - Assert.assertFalse(res); + Assert.assertTrue(res); } catch (Exception e) { - logger.info("{}", e.getMessage()); + logger.info("", e); + assert false; } } } \ No newline at end of file From 574a7464a658c703c0f63446351038424c0cd2f1 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Mon, 7 Jul 2025 18:05:58 +0800 Subject: [PATCH 6/7] modify SR --- framework/src/test/resources/config-test.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/test/resources/config-test.conf b/framework/src/test/resources/config-test.conf index eaa6659a8c4..f7884eec831 100644 --- a/framework/src/test/resources/config-test.conf +++ b/framework/src/test/resources/config-test.conf @@ -327,7 +327,7 @@ genesis.block = { voteCount = 96 }, { - address: 27VZHn9PFZwNh7o2EporxmLkpe157iWZVkh + address: 27bi7CD8d94AgXY3XFS9A9vx78Si5MqrECz url = "http://AlphaLyrae.org", voteCount = 95 } From cac4e16a22fa11a8ec4d3f9d33438528874ed29a Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 8 Jul 2025 15:55:40 +0800 Subject: [PATCH 7/7] change comment --- .../tron/core/net/service/handshake/HandshakeService.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java index b024bc80e21..5d44edb0810 100644 --- a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java +++ b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java @@ -105,11 +105,7 @@ public void processHelloMessage(PeerConnection peer, HelloMessage msg) { chainBaseManager.getSolidBlockId().getString()); peer.disconnect(ReasonCode.FORKED); } else { - logger.info("Peer {} solid block is below than me and light node doesn't contain the block," - + " it's unuseful, peer->{}, me->{}", - peer.getInetSocketAddress(), - msg.getSolidBlockId().getString(), - chainBaseManager.getSolidBlockId().getString()); + logger.info("Peer {} solid block is below than my lowest", peer.getInetSocketAddress()); peer.disconnect(ReasonCode.LIGHT_NODE_SYNC_FAIL); } return;