Skip to content

Commit 8074a47

Browse files
authored
Merge pull request #640 from tronprotocol/pp2p_handshake
p2p: add handshake
2 parents db4ae6f + 7870ec7 commit 8074a47

File tree

13 files changed

+124
-151
lines changed

13 files changed

+124
-151
lines changed

src/main/java/org/tron/common/overlay/message/HelloMessage.java

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
import com.google.protobuf.ByteString;
44
import com.google.protobuf.InvalidProtocolBufferException;
5+
import org.springframework.beans.factory.annotation.Autowired;
56
import org.tron.common.overlay.discover.Node;
67
import org.tron.common.utils.ByteArray;
8+
import org.tron.core.capsule.BlockCapsule;
79
import org.tron.core.config.args.Args;
10+
import org.tron.core.db.Manager;
811
import org.tron.core.net.message.MessageTypes;
912
import org.tron.protos.Discover.Endpoint;
1013
import org.tron.protos.Protocol;
@@ -33,19 +36,38 @@ public HelloMessage(byte type, byte[] rawData) {
3336
/**
3437
* Create hello message.
3538
*/
36-
public HelloMessage(Node from, long timestamp) {
39+
public HelloMessage(Node from, long timestamp, BlockCapsule.BlockId genesisBlockId,
40+
BlockCapsule.BlockId solidBlockId, BlockCapsule.BlockId headBlockId){
3741

3842
Endpoint fromEndpoint = Endpoint.newBuilder()
3943
.setNodeId(ByteString.copyFrom(from.getId()))
4044
.setPort(from.getPort())
4145
.setAddress(ByteString.copyFrom(ByteArray.fromString(from.getHost())))
4246
.build();
4347

48+
Protocol.HelloMessage.BlockId gBlockId = Protocol.HelloMessage.BlockId.newBuilder()
49+
.setHash(genesisBlockId.getByteString())
50+
.setNumber(genesisBlockId.getNum())
51+
.build();
52+
53+
Protocol.HelloMessage.BlockId sBlockId = Protocol.HelloMessage.BlockId.newBuilder()
54+
.setHash(solidBlockId.getByteString())
55+
.setNumber(solidBlockId.getNum())
56+
.build();
57+
58+
Protocol.HelloMessage.BlockId hBlockId = Protocol.HelloMessage.BlockId.newBuilder()
59+
.setHash(headBlockId.getByteString())
60+
.setNumber(headBlockId.getNum())
61+
.build();
62+
4463
Builder builder = Protocol.HelloMessage.newBuilder();
4564

4665
builder.setFrom(fromEndpoint);
4766
builder.setVersion(Args.getInstance().getNodeP2pVersion());
4867
builder.setTimestamp(timestamp);
68+
builder.setGenesisBlockId(gBlockId);
69+
builder.setSolidBlockId(sBlockId);
70+
builder.setHeadBlockId(hBlockId);
4971

5072
this.helloMessage = builder.build();
5173
this.type = MessageTypes.P2P_HELLO.asByte();
@@ -76,41 +98,25 @@ public long getTimestamp(){
7698
return this.helloMessage.getTimestamp();
7799
}
78100

79-
/**
80-
* Get listen port.
81-
*/
82-
public int getListenPort() {
83-
return this.helloMessage.getFrom().getPort();
101+
public Node getFrom() {
102+
Endpoint from = this.helloMessage.getFrom();
103+
return new Node(from.getNodeId().toByteArray(),
104+
ByteArray.toStr(from.getAddress().toByteArray()), from.getPort());
84105
}
85106

86-
/**
87-
* Get peer ID.
88-
*/
89-
public String getPeerId() {
90-
return ByteArray.toHexString(this.helloMessage.getFrom().getNodeId().toByteArray());
107+
public BlockCapsule.BlockId getGenesisBlockId(){
108+
return new BlockCapsule.BlockId(this.helloMessage.getGenesisBlockId().getHash(),
109+
this.helloMessage.getGenesisBlockId().getNumber());
91110
}
92111

93-
/**
94-
* Set version of p2p protocol.
95-
*/
96-
public void setVersion(byte version) {
97-
Builder builder = this.helloMessage.toBuilder();
98-
builder.setVersion(version);
99-
this.helloMessage = builder.build();
112+
public BlockCapsule.BlockId getSolidBlockId(){
113+
return new BlockCapsule.BlockId(this.helloMessage.getSolidBlockId().getHash(),
114+
this.helloMessage.getSolidBlockId().getNumber());
100115
}
101116

102-
/**
103-
* Get string.
104-
*/
105-
public String toString() {
106-
return helloMessage.toString();
107-
// if (!this.unpacked) {
108-
// this.unPack();
109-
// }
110-
// return "[" + this.getCommand().name() + " p2pVersion="
111-
// + this.getVersion() + " clientId=" + this.getClientId()
112-
// + " peerPort=" + this.getListenPort() + " peerId="
113-
// + this.getPeerId() + "]";
117+
public BlockCapsule.BlockId getHeadBlockId(){
118+
return new BlockCapsule.BlockId(this.helloMessage.getHeadBlockId().getHash(),
119+
this.helloMessage.getHeadBlockId().getNumber());
114120
}
115121

116122
@Override
@@ -123,9 +129,9 @@ public MessageTypes getType() {
123129
return MessageTypes.fromByte(this.type);
124130
}
125131

126-
public Node getFrom() {
127-
Endpoint from = this.helloMessage.getFrom();
128-
return new Node(from.getNodeId().toByteArray(),
129-
ByteArray.toStr(from.getAddress().toByteArray()), from.getPort());
132+
@Override
133+
public String toString() {
134+
return helloMessage.toString();
130135
}
136+
131137
}

src/main/java/org/tron/common/overlay/message/Message.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ public String toString() {
4949

5050
public abstract Class<?> getAnswerMessage();
5151

52-
//public byte getCode() { return type; }
53-
5452
@Override
5553
public boolean equals(Object o) {
5654
if (this == o) {
Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,9 @@
1-
/*
2-
* Copyright (c) [2016] [ <ether.camp> ]
3-
* This file is part of the ethereumJ library.
4-
*
5-
* The ethereumJ library is free software: you can redistribute it and/or modify
6-
* it under the terms of the GNU Lesser General Public License as published by
7-
* the Free Software Foundation, either version 3 of the License, or
8-
* (at your option) any later version.
9-
*
10-
* The ethereumJ library is distributed in the hope that it will be useful,
11-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13-
* GNU Lesser General Public License for more details.
14-
*
15-
* You should have received a copy of the GNU Lesser General Public License
16-
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
17-
*/
181
package org.tron.common.overlay.message;
192

20-
import org.spongycastle.util.encoders.Hex;
21-
import org.springframework.beans.factory.annotation.Autowired;
223
import org.springframework.stereotype.Component;
23-
import org.tron.common.overlay.discover.Node;
24-
import org.tron.core.config.args.Args;
25-
26-
/**
27-
* This class contains static values of messages on the network. These message will always be the
28-
* same and therefore don't need to be created each time.
29-
*
30-
* @author Roman Mandeleil
31-
* @since 13.04.14
32-
*/
334

345
@Component
356
public class StaticMessages {
36-
37-
@Autowired
38-
Args args;
39-
407
public final static PingMessage PING_MESSAGE = new PingMessage();
418
public final static PongMessage PONG_MESSAGE = new PongMessage();
42-
public final static DisconnectMessage DISCONNECT_MESSAGE = new DisconnectMessage(
43-
ReasonCode.REQUESTED);
44-
45-
public static final byte[] SYNC_TOKEN = Hex.decode("22400891");
46-
47-
public HelloMessage createHelloMessage(Node node, long timestamp) {
48-
return new HelloMessage(node, timestamp);
49-
}
50-
51-
private String buildHelloAnnouncement() {
52-
return "java-tron";
53-
// String version = config.projectVersion();
54-
// String numberVersion = version;
55-
// Pattern pattern = Pattern.compile("^\\d+(\\.\\d+)*");
56-
// Matcher matcher = pattern.matcher(numberVersion);
57-
// if (matcher.find()) {
58-
// numberVersion = numberVersion.substring(matcher.start(), matcher.end());
59-
// }
60-
// String system = System.getProperty("os.name");
61-
// if (system.contains(" "))
62-
// system = system.substring(0, system.indexOf(" "));
63-
// if (System.getProperty("java.vm.vendor").contains("Android"))
64-
// system = "Android";
65-
// String phrase = config.helloPhrase();
66-
//
67-
// return String.format("Ethereum(J)/v%s/%s/%s/Java/%s", numberVersion, system,
68-
// config.projectVersionModifier().equalsIgnoreCase("release") ? "Release" : "Dev", phrase);
69-
}
709
}

src/main/java/org/tron/common/overlay/server/Channel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public void initNode(byte[] nodeId, int remotePort) {
146146
}
147147

148148
public void disconnect(ReasonCode reason) {
149-
logger.info("Send disconnect {}, reason:{}", ctx.channel().remoteAddress(), reason);
149+
logger.info("Send disconnect to {}, reason:{}", ctx.channel().remoteAddress(), reason);
150150
getNodeStatistics().nodeDisconnectedLocal(reason);
151151
ctx.writeAndFlush(new DisconnectMessage(reason).getSendData());
152152
close();

src/main/java/org/tron/common/overlay/server/HandshakeHandler.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.netty.handler.codec.ByteToMessageDecoder;
2323
import java.net.InetSocketAddress;
2424
import java.net.SocketAddress;
25+
import java.util.Arrays;
2526
import java.util.List;
2627
import org.slf4j.Logger;
2728
import org.slf4j.LoggerFactory;
@@ -33,6 +34,8 @@
3334
import org.tron.common.overlay.message.*;
3435
import org.tron.common.utils.ByteArray;
3536
import org.tron.core.config.args.Args;
37+
import org.tron.core.db.Manager;
38+
import org.tron.core.net.peer.PeerConnection;
3639

3740
import static org.tron.common.overlay.message.StaticMessages.PONG_MESSAGE;
3841

@@ -48,14 +51,14 @@ public class HandshakeHandler extends ByteToMessageDecoder {
4851

4952
private final NodeManager nodeManager;
5053

51-
private final ChannelManager channelManager;
54+
private Manager manager;
5255

5356
private P2pMessageFactory messageFactory = new P2pMessageFactory();
5457

5558
@Autowired
56-
public HandshakeHandler(final NodeManager nodeManager, final ChannelManager channelManager) {
59+
public HandshakeHandler(final NodeManager nodeManager, final Manager manager) {
5760
this.nodeManager = nodeManager;
58-
this.channelManager = channelManager;
61+
this.manager = manager;
5962
}
6063

6164
@Override
@@ -73,6 +76,9 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> ou
7376
byte[] encoded = new byte[buffer.readableBytes()];
7477
buffer.readBytes(encoded);
7578
P2pMessage msg = messageFactory.create(encoded);
79+
80+
logger.info("Handshake receive from {}, {}", ctx.channel().remoteAddress(), msg);
81+
7682
switch (msg.getType()) {
7783
case P2P_HELLO:
7884
handleHelloMsg(ctx, (HelloMessage)msg);
@@ -100,22 +106,44 @@ public void setChannel(Channel channel, String remoteId) {
100106
}
101107

102108
private void sendHelloMsg(ChannelHandlerContext ctx, long time){
103-
ctx.writeAndFlush(new HelloMessage(nodeManager.getPublicHomeNode(), time).getSendData());
109+
HelloMessage message = new HelloMessage(nodeManager.getPublicHomeNode(), time,
110+
manager.getGenesisBlockId(), manager.getSolidBlockId(), manager.getHeadBlockId());
111+
ctx.writeAndFlush(message.getSendData());
104112
channel.getNodeStatistics().p2pOutHello.add();
105113
}
106114

107115
private void handleHelloMsg(ChannelHandlerContext ctx, HelloMessage msg) {
108116
if (remoteId.length != 64) {
109-
channel.initNode(ByteArray.fromHexString(msg.getPeerId()), msg.getListenPort());
110-
if (msg.getVersion() != Args.getInstance().getNodeP2pVersion()) {
111-
logger.info("Peer {} version not support, peer->{}, me->{}",
112-
ctx.channel().remoteAddress(), msg.getVersion(), Args.getInstance().getNodeP2pVersion());
113-
channel.disconnect(ReasonCode.INCOMPATIBLE_PROTOCOL);
114-
return;
115-
}
117+
channel.initNode(msg.getFrom().getId(), msg.getFrom().getPort());
118+
}
119+
120+
if (msg.getVersion() != Args.getInstance().getNodeP2pVersion()) {
121+
logger.info("Peer {} different p2p version, peer->{}, me->{}",
122+
ctx.channel().remoteAddress(), msg.getVersion(), Args.getInstance().getNodeP2pVersion());
123+
channel.disconnect(ReasonCode.INCOMPATIBLE_PROTOCOL);
124+
return;
125+
}
126+
127+
if (!Arrays.equals(manager.getGenesisBlockId().getBytes(), msg.getGenesisBlockId().getBytes())){
128+
logger.info("Peer {} different genesis block, peer->{}, me->{}", ctx.channel().remoteAddress(),
129+
msg.getGenesisBlockId().getString(), manager.getGenesisBlockId().getString());
130+
channel.disconnect(ReasonCode.INCOMPATIBLE_CHAIN);
131+
return;
132+
}
133+
134+
if (manager.getSolidBlockId().getNum() >= msg.getSolidBlockId().getNum() && !manager.containBlockInMainChain(msg.getSolidBlockId())){
135+
logger.info("Peer {} different solid block, peer->{}, me->{}", ctx.channel().remoteAddress(),
136+
msg.getSolidBlockId().getString(), manager.getSolidBlockId().getString());
137+
channel.disconnect(ReasonCode.FORKED);
138+
return;
139+
}
140+
141+
if (remoteId.length != 64) {
116142
sendHelloMsg(ctx, msg.getTimestamp());
117143
}
118144

145+
((PeerConnection)channel).setHelloMessage(msg);
146+
119147
channel.getNodeStatistics().p2pInHello.add();
120148

121149
channel.publicHandshakeFinished(ctx, msg);

src/main/java/org/tron/common/overlay/server/MessageQueue.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ private void send() {
115115
}
116116
if (messageRoundtrip.getRetryTimes() > 0){
117117
channel.getNodeStatistics().nodeDisconnectedLocal(ReasonCode.PING_TIMEOUT);
118-
logger.warn("wait {} timeout. close channel {}.", messageRoundtrip.getMsg().getAnswerMessage(), ctx.channel().remoteAddress());
118+
logger.warn("Wait {} timeout. close channel {}.", messageRoundtrip.getMsg().getAnswerMessage(), ctx.channel().remoteAddress());
119119
channel.close();
120120
return;
121121
}
@@ -124,8 +124,6 @@ private void send() {
124124

125125
ctx.writeAndFlush(msg.getSendData());
126126

127-
logger.info("send {} to {}", msg.getType(), ctx.channel().remoteAddress());
128-
129127
messageRoundtrip.incRetryTimes();
130128
messageRoundtrip.saveTime();
131129
}

src/main/java/org/tron/core/db/Manager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,15 @@ public long getSyncBeginNumber() {
10081008
return dynamicPropertiesStore.getLatestBlockHeaderNumber() - revokingStore.size();
10091009
}
10101010

1011+
public BlockId getSolidBlockId() {
1012+
try{
1013+
long num = dynamicPropertiesStore.getLatestSolidifiedBlockNum();
1014+
return getBlockIdByNum(num);
1015+
}catch (Exception e){
1016+
return getGenesisBlockId();
1017+
}
1018+
}
1019+
10111020
/**
10121021
* Determine if the current time is maintenance time.
10131022
*/

src/main/java/org/tron/core/net/message/FetchInvDataMessage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public FetchInvDataMessage(List<Sha256Hash> hashList, InventoryType type) {
3333

3434
@Override
3535
public String toString() {
36-
return super.toString() + ", type=" + MessageTypes.fromByte(this.type);
36+
return super.toString();
3737
}
3838

3939
public MessageTypes getInvType() {

src/main/java/org/tron/core/net/message/InventoryMessage.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,14 @@ public InventoryType getInventoryType() {
7878
@Override
7979
public String toString() {
8080
Deque<Sha256Hash> hashes = new LinkedList<>(getHashList());
81-
return getType().toString() + ": First hash: " + hashes.peekFirst()
82-
+ " End hash: " + hashes.peekLast();
81+
StringBuilder builder = new StringBuilder();
82+
builder.append(getType()).append(":").append(getInvMessageType())
83+
.append(", size=").append(hashes.size())
84+
.append(", First hash:").append(hashes.peekFirst());
85+
if (hashes.size() > 1){
86+
builder.append(", End hash: ").append(hashes.peekLast());
87+
}
88+
return builder.toString();
8389
}
8490

8591
private synchronized void unPack() {

src/main/java/org/tron/core/net/node/NodeImpl.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,11 +1117,12 @@ private void syncNextBatchChainIds(PeerConnection peer) {
11171117

11181118
@Override
11191119
public void onConnectPeer(PeerConnection peer) {
1120-
//TODO:when use new p2p framework, remove this
1121-
logger.info("start sync with::" + peer);
1122-
peer.setTronState(TronState.SYNCING);
1123-
peer.setConnectTime(Time.getCurrentMillis());
1124-
startSyncWithPeer(peer);
1120+
if (peer.getHelloMessage().getHeadBlockId().getNum() > del.getHeadBlockId().getNum()){
1121+
peer.setTronState(TronState.SYNCING);
1122+
startSyncWithPeer(peer);
1123+
}else {
1124+
peer.setTronState(TronState.SYNC_COMPLETED);
1125+
}
11251126
}
11261127

11271128
@Override

0 commit comments

Comments
 (0)